| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/ipc/service/direct_composition_surface_win.h" | 5 #include "gpu/ipc/service/direct_composition_surface_win.h" |
| 6 | 6 |
| 7 #include <d3d11_1.h> | 7 #include <d3d11_1.h> |
| 8 #include <dcomptypes.h> | 8 #include <dcomptypes.h> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 } | 225 } |
| 226 | 226 |
| 227 void DCLayerTree::InitializeVideoProcessor(const gfx::Size& input_size, | 227 void DCLayerTree::InitializeVideoProcessor(const gfx::Size& input_size, |
| 228 const gfx::Size& output_size) { | 228 const gfx::Size& output_size) { |
| 229 if (SizeContains(video_input_size_, input_size) && | 229 if (SizeContains(video_input_size_, input_size) && |
| 230 SizeContains(video_output_size_, output_size)) | 230 SizeContains(video_output_size_, output_size)) |
| 231 return; | 231 return; |
| 232 video_input_size_ = input_size; | 232 video_input_size_ = input_size; |
| 233 video_output_size_ = output_size; | 233 video_output_size_ = output_size; |
| 234 | 234 |
| 235 video_processor_.Release(); | 235 video_processor_.Reset(); |
| 236 video_processor_enumerator_.Receive(); | 236 video_processor_enumerator_.Receive(); |
| 237 D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc = {}; | 237 D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc = {}; |
| 238 desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE; | 238 desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE; |
| 239 desc.InputFrameRate.Numerator = 60; | 239 desc.InputFrameRate.Numerator = 60; |
| 240 desc.InputFrameRate.Denominator = 1; | 240 desc.InputFrameRate.Denominator = 1; |
| 241 desc.InputWidth = input_size.width(); | 241 desc.InputWidth = input_size.width(); |
| 242 desc.InputHeight = input_size.height(); | 242 desc.InputHeight = input_size.height(); |
| 243 desc.OutputFrameRate.Numerator = 60; | 243 desc.OutputFrameRate.Numerator = 60; |
| 244 desc.OutputFrameRate.Denominator = 1; | 244 desc.OutputFrameRate.Denominator = 1; |
| 245 desc.OutputWidth = output_size.width(); | 245 desc.OutputWidth = output_size.width(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 // YUY2 surfaces must have an even width. | 298 // YUY2 surfaces must have an even width. |
| 299 if (swap_chain_size.width() % 2 == 1) | 299 if (swap_chain_size.width() % 2 == 1) |
| 300 swap_chain_size.set_width(swap_chain_size.width() + 1); | 300 swap_chain_size.set_width(swap_chain_size.width() + 1); |
| 301 | 301 |
| 302 InitializeVideoProcessor(ceiled_input_size, swap_chain_size); | 302 InitializeVideoProcessor(ceiled_input_size, swap_chain_size); |
| 303 | 303 |
| 304 bool first_present = false; | 304 bool first_present = false; |
| 305 if (!swap_chain_ || swap_chain_size_ != swap_chain_size) { | 305 if (!swap_chain_ || swap_chain_size_ != swap_chain_size) { |
| 306 first_present = true; | 306 first_present = true; |
| 307 swap_chain_size_ = swap_chain_size; | 307 swap_chain_size_ = swap_chain_size; |
| 308 swap_chain_.Release(); | 308 swap_chain_.Reset(); |
| 309 ReallocateSwapChain(); | 309 ReallocateSwapChain(); |
| 310 } else if (last_gl_image_ == image_dxgi) { | 310 } else if (last_gl_image_ == image_dxgi) { |
| 311 // The swap chain is presenting the same image as last swap, which means | 311 // The swap chain is presenting the same image as last swap, which means |
| 312 // that the image was never returned to the video decoder and should have | 312 // that the image was never returned to the video decoder and should have |
| 313 // the same contents as last time. It shouldn't need to be redrawn. | 313 // the same contents as last time. It shouldn't need to be redrawn. |
| 314 return; | 314 return; |
| 315 } | 315 } |
| 316 | 316 |
| 317 last_gl_image_ = image_dxgi; | 317 last_gl_image_ = image_dxgi; |
| 318 | 318 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 SizeContains(processor_output_size_, out_size)) | 383 SizeContains(processor_output_size_, out_size)) |
| 384 return false; | 384 return false; |
| 385 processor_input_size_ = in_size; | 385 processor_input_size_ = in_size; |
| 386 processor_output_size_ = out_size; | 386 processor_output_size_ = out_size; |
| 387 surface_->InitializeVideoProcessor(in_size, out_size); | 387 surface_->InitializeVideoProcessor(in_size, out_size); |
| 388 | 388 |
| 389 video_processor_enumerator_ = surface_->video_processor_enumerator(); | 389 video_processor_enumerator_ = surface_->video_processor_enumerator(); |
| 390 video_processor_ = surface_->video_processor(); | 390 video_processor_ = surface_->video_processor(); |
| 391 // out_view_ depends on video_processor_enumerator_, so ensure it's | 391 // out_view_ depends on video_processor_enumerator_, so ensure it's |
| 392 // recreated if the enumerator is. | 392 // recreated if the enumerator is. |
| 393 out_view_.Release(); | 393 out_view_.Reset(); |
| 394 return true; | 394 return true; |
| 395 } | 395 } |
| 396 | 396 |
| 397 void DCLayerTree::SwapChainPresenter::ReallocateSwapChain() { | 397 void DCLayerTree::SwapChainPresenter::ReallocateSwapChain() { |
| 398 TRACE_EVENT0("gpu", "DCLayerTree::SwapChainPresenter::ReallocateSwapChain"); | 398 TRACE_EVENT0("gpu", "DCLayerTree::SwapChainPresenter::ReallocateSwapChain"); |
| 399 DCHECK(!swap_chain_); | 399 DCHECK(!swap_chain_); |
| 400 | 400 |
| 401 base::win::ScopedComPtr<IDXGIDevice> dxgi_device; | 401 base::win::ScopedComPtr<IDXGIDevice> dxgi_device; |
| 402 d3d11_device_.QueryInterface(dxgi_device.Receive()); | 402 d3d11_device_.QueryInterface(dxgi_device.Receive()); |
| 403 base::win::ScopedComPtr<IDXGIAdapter> dxgi_adapter; | 403 base::win::ScopedComPtr<IDXGIAdapter> dxgi_adapter; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 CHECK(SUCCEEDED(hr)); | 445 CHECK(SUCCEEDED(hr)); |
| 446 } else { | 446 } else { |
| 447 // This is a sensible default colorspace for most videos. | 447 // This is a sensible default colorspace for most videos. |
| 448 // TODO(jbauman): Use correct colorspace. | 448 // TODO(jbauman): Use correct colorspace. |
| 449 base::win::ScopedComPtr<IDXGISwapChain3> swap_chain3; | 449 base::win::ScopedComPtr<IDXGISwapChain3> swap_chain3; |
| 450 swap_chain_.QueryInterface(swap_chain3.Receive()); | 450 swap_chain_.QueryInterface(swap_chain3.Receive()); |
| 451 hr = swap_chain3->SetColorSpace1( | 451 hr = swap_chain3->SetColorSpace1( |
| 452 DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709); | 452 DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709); |
| 453 CHECK(SUCCEEDED(hr)); | 453 CHECK(SUCCEEDED(hr)); |
| 454 } | 454 } |
| 455 out_view_.Release(); | 455 out_view_.Reset(); |
| 456 } | 456 } |
| 457 | 457 |
| 458 void DCLayerTree::InitVisual(size_t i) { | 458 void DCLayerTree::InitVisual(size_t i) { |
| 459 DCHECK_GT(visual_info_.size(), i); | 459 DCHECK_GT(visual_info_.size(), i); |
| 460 VisualInfo* visual_info = &visual_info_[i]; | 460 VisualInfo* visual_info = &visual_info_[i]; |
| 461 if (visual_info->content_visual) | 461 if (visual_info->content_visual) |
| 462 return; | 462 return; |
| 463 DCHECK(!visual_info->clip_visual); | 463 DCHECK(!visual_info->clip_visual); |
| 464 base::win::ScopedComPtr<IDCompositionVisual2> visual; | 464 base::win::ScopedComPtr<IDCompositionVisual2> visual; |
| 465 dcomp_device_->CreateVisual(visual_info->clip_visual.Receive()); | 465 dcomp_device_->CreateVisual(visual_info->clip_visual.Receive()); |
| 466 dcomp_device_->CreateVisual(visual.Receive()); | 466 dcomp_device_->CreateVisual(visual.Receive()); |
| 467 visual_info->content_visual = visual; | 467 visual_info->content_visual = visual; |
| 468 visual_info->clip_visual->AddVisual(visual.get(), FALSE, nullptr); | 468 visual_info->clip_visual->AddVisual(visual.get(), FALSE, nullptr); |
| 469 | 469 |
| 470 IDCompositionVisual2* last_visual = | 470 IDCompositionVisual2* last_visual = |
| 471 (i > 0) ? visual_info_[i - 1].clip_visual.get() : nullptr; | 471 (i > 0) ? visual_info_[i - 1].clip_visual.get() : nullptr; |
| 472 root_visual_->AddVisual(visual_info->clip_visual.get(), TRUE, last_visual); | 472 root_visual_->AddVisual(visual_info->clip_visual.get(), TRUE, last_visual); |
| 473 } | 473 } |
| 474 | 474 |
| 475 void DCLayerTree::UpdateVisualForVideo( | 475 void DCLayerTree::UpdateVisualForVideo( |
| 476 VisualInfo* visual_info, | 476 VisualInfo* visual_info, |
| 477 const ui::DCRendererLayerParams& params) { | 477 const ui::DCRendererLayerParams& params) { |
| 478 base::win::ScopedComPtr<IDCompositionVisual2> dc_visual = | 478 base::win::ScopedComPtr<IDCompositionVisual2> dc_visual = |
| 479 visual_info->content_visual; | 479 visual_info->content_visual; |
| 480 | 480 |
| 481 gfx::Rect bounds_rect = params.rect; | 481 gfx::Rect bounds_rect = params.rect; |
| 482 visual_info->surface.Release(); | 482 visual_info->surface.Reset(); |
| 483 if (!visual_info->swap_chain_presenter) { | 483 if (!visual_info->swap_chain_presenter) { |
| 484 visual_info->swap_chain_presenter = | 484 visual_info->swap_chain_presenter = |
| 485 base::MakeUnique<SwapChainPresenter>(this, d3d11_device_); | 485 base::MakeUnique<SwapChainPresenter>(this, d3d11_device_); |
| 486 } | 486 } |
| 487 visual_info->swap_chain_presenter->PresentToSwapChain(params); | 487 visual_info->swap_chain_presenter->PresentToSwapChain(params); |
| 488 if (visual_info->swap_chain != | 488 if (visual_info->swap_chain != |
| 489 visual_info->swap_chain_presenter->swap_chain()) { | 489 visual_info->swap_chain_presenter->swap_chain()) { |
| 490 visual_info->swap_chain = visual_info->swap_chain_presenter->swap_chain(); | 490 visual_info->swap_chain = visual_info->swap_chain_presenter->swap_chain(); |
| 491 dc_visual->SetContent(visual_info->swap_chain.get()); | 491 dc_visual->SetContent(visual_info->swap_chain.get()); |
| 492 } | 492 } |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 pbuffer_attribs.push_back(EGL_NONE); | 738 pbuffer_attribs.push_back(EGL_NONE); |
| 739 default_surface_ = | 739 default_surface_ = |
| 740 eglCreatePbufferSurface(display, GetConfig(), &pbuffer_attribs[0]); | 740 eglCreatePbufferSurface(display, GetConfig(), &pbuffer_attribs[0]); |
| 741 CHECK(!!default_surface_); | 741 CHECK(!!default_surface_); |
| 742 | 742 |
| 743 return true; | 743 return true; |
| 744 } | 744 } |
| 745 | 745 |
| 746 void DirectCompositionSurfaceWin::ReleaseCurrentSurface() { | 746 void DirectCompositionSurfaceWin::ReleaseCurrentSurface() { |
| 747 ReleaseDrawTexture(true); | 747 ReleaseDrawTexture(true); |
| 748 dcomp_surface_.Release(); | 748 dcomp_surface_.Reset(); |
| 749 swap_chain_.Release(); | 749 swap_chain_.Reset(); |
| 750 } | 750 } |
| 751 | 751 |
| 752 void DirectCompositionSurfaceWin::InitializeSurface() { | 752 void DirectCompositionSurfaceWin::InitializeSurface() { |
| 753 TRACE_EVENT1("gpu", "DirectCompositionSurfaceWin::InitializeSurface()", | 753 TRACE_EVENT1("gpu", "DirectCompositionSurfaceWin::InitializeSurface()", |
| 754 "enable_dc_layers_", enable_dc_layers_); | 754 "enable_dc_layers_", enable_dc_layers_); |
| 755 DCHECK(!dcomp_surface_); | 755 DCHECK(!dcomp_surface_); |
| 756 DCHECK(!swap_chain_); | 756 DCHECK(!swap_chain_); |
| 757 DXGI_FORMAT output_format = | 757 DXGI_FORMAT output_format = |
| 758 base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableHDR) | 758 base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableHDR) |
| 759 ? DXGI_FORMAT_R16G16B16A16_FLOAT | 759 ? DXGI_FORMAT_R16G16B16A16_FLOAT |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 795 CHECK(SUCCEEDED(hr)); | 795 CHECK(SUCCEEDED(hr)); |
| 796 } | 796 } |
| 797 } | 797 } |
| 798 | 798 |
| 799 void DirectCompositionSurfaceWin::ReleaseDrawTexture(bool will_discard) { | 799 void DirectCompositionSurfaceWin::ReleaseDrawTexture(bool will_discard) { |
| 800 if (real_surface_) { | 800 if (real_surface_) { |
| 801 eglDestroySurface(GetDisplay(), real_surface_); | 801 eglDestroySurface(GetDisplay(), real_surface_); |
| 802 real_surface_ = nullptr; | 802 real_surface_ = nullptr; |
| 803 } | 803 } |
| 804 if (draw_texture_) { | 804 if (draw_texture_) { |
| 805 draw_texture_.Release(); | 805 draw_texture_.Reset(); |
| 806 if (dcomp_surface_) { | 806 if (dcomp_surface_) { |
| 807 HRESULT hr = dcomp_surface_->EndDraw(); | 807 HRESULT hr = dcomp_surface_->EndDraw(); |
| 808 CHECK(SUCCEEDED(hr)); | 808 CHECK(SUCCEEDED(hr)); |
| 809 } else if (!will_discard) { | 809 } else if (!will_discard) { |
| 810 DXGI_PRESENT_PARAMETERS params = {}; | 810 DXGI_PRESENT_PARAMETERS params = {}; |
| 811 RECT dirty_rect = swap_rect_.ToRECT(); | 811 RECT dirty_rect = swap_rect_.ToRECT(); |
| 812 params.DirtyRectsCount = 1; | 812 params.DirtyRectsCount = 1; |
| 813 params.pDirtyRects = &dirty_rect; | 813 params.pDirtyRects = &dirty_rect; |
| 814 swap_chain_->Present1(first_swap_ ? 0 : 1, 0, ¶ms); | 814 swap_chain_->Present1(first_swap_ ? 0 : 1, 0, ¶ms); |
| 815 if (first_swap_) { | 815 if (first_swap_) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 845 DLOG(ERROR) << "eglDestroySurface failed with error " | 845 DLOG(ERROR) << "eglDestroySurface failed with error " |
| 846 << ui::GetLastEGLErrorString(); | 846 << ui::GetLastEGLErrorString(); |
| 847 } | 847 } |
| 848 real_surface_ = nullptr; | 848 real_surface_ = nullptr; |
| 849 } | 849 } |
| 850 if (dcomp_surface_ && (dcomp_surface_ == g_current_surface)) { | 850 if (dcomp_surface_ && (dcomp_surface_ == g_current_surface)) { |
| 851 HRESULT hr = dcomp_surface_->EndDraw(); | 851 HRESULT hr = dcomp_surface_->EndDraw(); |
| 852 CHECK(SUCCEEDED(hr)); | 852 CHECK(SUCCEEDED(hr)); |
| 853 g_current_surface = nullptr; | 853 g_current_surface = nullptr; |
| 854 } | 854 } |
| 855 draw_texture_.Release(); | 855 draw_texture_.Reset(); |
| 856 dcomp_surface_.Release(); | 856 dcomp_surface_.Reset(); |
| 857 } | 857 } |
| 858 | 858 |
| 859 gfx::Size DirectCompositionSurfaceWin::GetSize() { | 859 gfx::Size DirectCompositionSurfaceWin::GetSize() { |
| 860 return size_; | 860 return size_; |
| 861 } | 861 } |
| 862 | 862 |
| 863 bool DirectCompositionSurfaceWin::IsOffscreen() { | 863 bool DirectCompositionSurfaceWin::IsOffscreen() { |
| 864 return false; | 864 return false; |
| 865 } | 865 } |
| 866 | 866 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { | 1019 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { |
| 1020 return child_window_.GetTaskRunnerForTesting(); | 1020 return child_window_.GetTaskRunnerForTesting(); |
| 1021 } | 1021 } |
| 1022 | 1022 |
| 1023 base::win::ScopedComPtr<IDXGISwapChain1> | 1023 base::win::ScopedComPtr<IDXGISwapChain1> |
| 1024 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { | 1024 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { |
| 1025 return layer_tree_->GetLayerSwapChainForTesting(index); | 1025 return layer_tree_->GetLayerSwapChainForTesting(index); |
| 1026 } | 1026 } |
| 1027 | 1027 |
| 1028 } // namespace gpu | 1028 } // namespace gpu |
| OLD | NEW |