| 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 <deque> | 10 #include <deque> |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 | 259 |
| 260 HRESULT hr = desktop_device->CreateTargetForHwnd(window, TRUE, | 260 HRESULT hr = desktop_device->CreateTargetForHwnd(window, TRUE, |
| 261 dcomp_target_.Receive()); | 261 dcomp_target_.Receive()); |
| 262 if (FAILED(hr)) | 262 if (FAILED(hr)) |
| 263 return false; | 263 return false; |
| 264 | 264 |
| 265 hr = dcomp_device_->CreateVisual(root_visual_.Receive()); | 265 hr = dcomp_device_->CreateVisual(root_visual_.Receive()); |
| 266 if (FAILED(hr)) | 266 if (FAILED(hr)) |
| 267 return false; | 267 return false; |
| 268 | 268 |
| 269 dcomp_target_->SetRoot(root_visual_.get()); | 269 dcomp_target_->SetRoot(root_visual_.Get()); |
| 270 return true; | 270 return true; |
| 271 } | 271 } |
| 272 | 272 |
| 273 void DCLayerTree::InitializeVideoProcessor(const gfx::Size& input_size, | 273 void DCLayerTree::InitializeVideoProcessor(const gfx::Size& input_size, |
| 274 const gfx::Size& output_size) { | 274 const gfx::Size& output_size) { |
| 275 if (SizeContains(video_input_size_, input_size) && | 275 if (SizeContains(video_input_size_, input_size) && |
| 276 SizeContains(video_output_size_, output_size)) | 276 SizeContains(video_output_size_, output_size)) |
| 277 return; | 277 return; |
| 278 video_input_size_ = input_size; | 278 video_input_size_ = input_size; |
| 279 video_output_size_ = output_size; | 279 video_output_size_ = output_size; |
| 280 | 280 |
| 281 video_processor_.Reset(); | 281 video_processor_.Reset(); |
| 282 video_processor_enumerator_.Receive(); | 282 video_processor_enumerator_.Receive(); |
| 283 D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc = {}; | 283 D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc = {}; |
| 284 desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE; | 284 desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE; |
| 285 desc.InputFrameRate.Numerator = 60; | 285 desc.InputFrameRate.Numerator = 60; |
| 286 desc.InputFrameRate.Denominator = 1; | 286 desc.InputFrameRate.Denominator = 1; |
| 287 desc.InputWidth = input_size.width(); | 287 desc.InputWidth = input_size.width(); |
| 288 desc.InputHeight = input_size.height(); | 288 desc.InputHeight = input_size.height(); |
| 289 desc.OutputFrameRate.Numerator = 60; | 289 desc.OutputFrameRate.Numerator = 60; |
| 290 desc.OutputFrameRate.Denominator = 1; | 290 desc.OutputFrameRate.Denominator = 1; |
| 291 desc.OutputWidth = output_size.width(); | 291 desc.OutputWidth = output_size.width(); |
| 292 desc.OutputHeight = output_size.height(); | 292 desc.OutputHeight = output_size.height(); |
| 293 desc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL; | 293 desc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL; |
| 294 HRESULT hr = video_device_->CreateVideoProcessorEnumerator( | 294 HRESULT hr = video_device_->CreateVideoProcessorEnumerator( |
| 295 &desc, video_processor_enumerator_.Receive()); | 295 &desc, video_processor_enumerator_.Receive()); |
| 296 CHECK(SUCCEEDED(hr)); | 296 CHECK(SUCCEEDED(hr)); |
| 297 | 297 |
| 298 hr = video_device_->CreateVideoProcessor(video_processor_enumerator_.get(), 0, | 298 hr = video_device_->CreateVideoProcessor(video_processor_enumerator_.Get(), 0, |
| 299 video_processor_.Receive()); | 299 video_processor_.Receive()); |
| 300 CHECK(SUCCEEDED(hr)); | 300 CHECK(SUCCEEDED(hr)); |
| 301 } | 301 } |
| 302 | 302 |
| 303 base::win::ScopedComPtr<IDXGISwapChain1> | 303 base::win::ScopedComPtr<IDXGISwapChain1> |
| 304 DCLayerTree::GetLayerSwapChainForTesting(size_t index) const { | 304 DCLayerTree::GetLayerSwapChainForTesting(size_t index) const { |
| 305 if (index >= visual_info_.size()) | 305 if (index >= visual_info_.size()) |
| 306 return base::win::ScopedComPtr<IDXGISwapChain1>(); | 306 return base::win::ScopedComPtr<IDXGISwapChain1>(); |
| 307 return visual_info_[index].swap_chain; | 307 return visual_info_[index].swap_chain; |
| 308 } | 308 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 | 384 |
| 385 last_gl_image_ = image_dxgi; | 385 last_gl_image_ = image_dxgi; |
| 386 | 386 |
| 387 if (!out_view_) { | 387 if (!out_view_) { |
| 388 base::win::ScopedComPtr<ID3D11Texture2D> texture; | 388 base::win::ScopedComPtr<ID3D11Texture2D> texture; |
| 389 swap_chain_->GetBuffer(0, IID_PPV_ARGS(texture.Receive())); | 389 swap_chain_->GetBuffer(0, IID_PPV_ARGS(texture.Receive())); |
| 390 D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC out_desc = {}; | 390 D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC out_desc = {}; |
| 391 out_desc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D; | 391 out_desc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D; |
| 392 out_desc.Texture2D.MipSlice = 0; | 392 out_desc.Texture2D.MipSlice = 0; |
| 393 HRESULT hr = video_device_->CreateVideoProcessorOutputView( | 393 HRESULT hr = video_device_->CreateVideoProcessorOutputView( |
| 394 texture.get(), video_processor_enumerator_.get(), &out_desc, | 394 texture.Get(), video_processor_enumerator_.Get(), &out_desc, |
| 395 out_view_.Receive()); | 395 out_view_.Receive()); |
| 396 CHECK(SUCCEEDED(hr)); | 396 CHECK(SUCCEEDED(hr)); |
| 397 } | 397 } |
| 398 | 398 |
| 399 // TODO(jbauman): Use correct colorspace. | 399 // TODO(jbauman): Use correct colorspace. |
| 400 gfx::ColorSpace src_color_space = gfx::ColorSpace::CreateREC709(); | 400 gfx::ColorSpace src_color_space = gfx::ColorSpace::CreateREC709(); |
| 401 base::win::ScopedComPtr<ID3D11VideoContext1> context1; | 401 base::win::ScopedComPtr<ID3D11VideoContext1> context1; |
| 402 if (SUCCEEDED(video_context_.QueryInterface(context1.Receive()))) { | 402 if (SUCCEEDED(video_context_.QueryInterface(context1.Receive()))) { |
| 403 context1->VideoProcessorSetStreamColorSpace1( | 403 context1->VideoProcessorSetStreamColorSpace1( |
| 404 video_processor_.get(), 0, | 404 video_processor_.Get(), 0, |
| 405 gfx::ColorSpaceWin::GetDXGIColorSpace(src_color_space)); | 405 gfx::ColorSpaceWin::GetDXGIColorSpace(src_color_space)); |
| 406 } else { | 406 } else { |
| 407 // This can't handle as many different types of color spaces, so use it | 407 // This can't handle as many different types of color spaces, so use it |
| 408 // only if ID3D11VideoContext1 isn't available. | 408 // only if ID3D11VideoContext1 isn't available. |
| 409 D3D11_VIDEO_PROCESSOR_COLOR_SPACE color_space = | 409 D3D11_VIDEO_PROCESSOR_COLOR_SPACE color_space = |
| 410 gfx::ColorSpaceWin::GetD3D11ColorSpace(src_color_space); | 410 gfx::ColorSpaceWin::GetD3D11ColorSpace(src_color_space); |
| 411 video_context_->VideoProcessorSetStreamColorSpace(video_processor_.get(), 0, | 411 video_context_->VideoProcessorSetStreamColorSpace(video_processor_.Get(), 0, |
| 412 &color_space); | 412 &color_space); |
| 413 } | 413 } |
| 414 | 414 |
| 415 gfx::ColorSpace output_color_space = | 415 gfx::ColorSpace output_color_space = |
| 416 is_yuy2_swapchain_ ? src_color_space : gfx::ColorSpace::CreateSRGB(); | 416 is_yuy2_swapchain_ ? src_color_space : gfx::ColorSpace::CreateSRGB(); |
| 417 if (base::FeatureList::IsEnabled(kFallbackBT709VideoToBT601) && | 417 if (base::FeatureList::IsEnabled(kFallbackBT709VideoToBT601) && |
| 418 (output_color_space == gfx::ColorSpace::CreateREC709())) { | 418 (output_color_space == gfx::ColorSpace::CreateREC709())) { |
| 419 output_color_space = gfx::ColorSpace::CreateREC601(); | 419 output_color_space = gfx::ColorSpace::CreateREC601(); |
| 420 } | 420 } |
| 421 | 421 |
| 422 base::win::ScopedComPtr<IDXGISwapChain3> swap_chain3; | 422 base::win::ScopedComPtr<IDXGISwapChain3> swap_chain3; |
| 423 if (SUCCEEDED(swap_chain_.QueryInterface(swap_chain3.Receive()))) { | 423 if (SUCCEEDED(swap_chain_.QueryInterface(swap_chain3.Receive()))) { |
| 424 DXGI_COLOR_SPACE_TYPE color_space = | 424 DXGI_COLOR_SPACE_TYPE color_space = |
| 425 gfx::ColorSpaceWin::GetDXGIColorSpace(output_color_space); | 425 gfx::ColorSpaceWin::GetDXGIColorSpace(output_color_space); |
| 426 HRESULT hr = swap_chain3->SetColorSpace1(color_space); | 426 HRESULT hr = swap_chain3->SetColorSpace1(color_space); |
| 427 CHECK(SUCCEEDED(hr)); | 427 CHECK(SUCCEEDED(hr)); |
| 428 if (context1) { | 428 if (context1) { |
| 429 context1->VideoProcessorSetOutputColorSpace1(video_processor_.get(), | 429 context1->VideoProcessorSetOutputColorSpace1(video_processor_.Get(), |
| 430 color_space); | 430 color_space); |
| 431 } else { | 431 } else { |
| 432 D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = | 432 D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = |
| 433 gfx::ColorSpaceWin::GetD3D11ColorSpace(output_color_space); | 433 gfx::ColorSpaceWin::GetD3D11ColorSpace(output_color_space); |
| 434 video_context_->VideoProcessorSetOutputColorSpace(video_processor_.get(), | 434 video_context_->VideoProcessorSetOutputColorSpace(video_processor_.Get(), |
| 435 &d3d11_color_space); | 435 &d3d11_color_space); |
| 436 } | 436 } |
| 437 } | 437 } |
| 438 | 438 |
| 439 { | 439 { |
| 440 D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC in_desc = {}; | 440 D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC in_desc = {}; |
| 441 in_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; | 441 in_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; |
| 442 in_desc.Texture2D.ArraySlice = (UINT)image_dxgi->level(); | 442 in_desc.Texture2D.ArraySlice = (UINT)image_dxgi->level(); |
| 443 base::win::ScopedComPtr<ID3D11VideoProcessorInputView> in_view; | 443 base::win::ScopedComPtr<ID3D11VideoProcessorInputView> in_view; |
| 444 HRESULT hr = video_device_->CreateVideoProcessorInputView( | 444 HRESULT hr = video_device_->CreateVideoProcessorInputView( |
| 445 image_dxgi->texture().get(), video_processor_enumerator_.get(), | 445 image_dxgi->texture().Get(), video_processor_enumerator_.Get(), |
| 446 &in_desc, in_view.Receive()); | 446 &in_desc, in_view.Receive()); |
| 447 CHECK(SUCCEEDED(hr)); | 447 CHECK(SUCCEEDED(hr)); |
| 448 | 448 |
| 449 D3D11_VIDEO_PROCESSOR_STREAM stream = {}; | 449 D3D11_VIDEO_PROCESSOR_STREAM stream = {}; |
| 450 stream.Enable = true; | 450 stream.Enable = true; |
| 451 stream.OutputIndex = 0; | 451 stream.OutputIndex = 0; |
| 452 stream.InputFrameOrField = 0; | 452 stream.InputFrameOrField = 0; |
| 453 stream.PastFrames = 0; | 453 stream.PastFrames = 0; |
| 454 stream.FutureFrames = 0; | 454 stream.FutureFrames = 0; |
| 455 stream.pInputSurface = in_view.get(); | 455 stream.pInputSurface = in_view.Get(); |
| 456 RECT dest_rect = gfx::Rect(swap_chain_size).ToRECT(); | 456 RECT dest_rect = gfx::Rect(swap_chain_size).ToRECT(); |
| 457 video_context_->VideoProcessorSetOutputTargetRect(video_processor_.get(), | 457 video_context_->VideoProcessorSetOutputTargetRect(video_processor_.Get(), |
| 458 TRUE, &dest_rect); | 458 TRUE, &dest_rect); |
| 459 video_context_->VideoProcessorSetStreamDestRect(video_processor_.get(), 0, | 459 video_context_->VideoProcessorSetStreamDestRect(video_processor_.Get(), 0, |
| 460 TRUE, &dest_rect); | 460 TRUE, &dest_rect); |
| 461 RECT source_rect = gfx::Rect(ceiled_input_size).ToRECT(); | 461 RECT source_rect = gfx::Rect(ceiled_input_size).ToRECT(); |
| 462 video_context_->VideoProcessorSetStreamSourceRect(video_processor_.get(), 0, | 462 video_context_->VideoProcessorSetStreamSourceRect(video_processor_.Get(), 0, |
| 463 TRUE, &source_rect); | 463 TRUE, &source_rect); |
| 464 | 464 |
| 465 video_context_->VideoProcessorSetStreamAutoProcessingMode( | 465 video_context_->VideoProcessorSetStreamAutoProcessingMode( |
| 466 video_processor_.get(), 0, FALSE); | 466 video_processor_.Get(), 0, FALSE); |
| 467 | 467 |
| 468 hr = video_context_->VideoProcessorBlt(video_processor_.get(), | 468 hr = video_context_->VideoProcessorBlt(video_processor_.Get(), |
| 469 out_view_.get(), 0, 1, &stream); | 469 out_view_.Get(), 0, 1, &stream); |
| 470 CHECK(SUCCEEDED(hr)); | 470 CHECK(SUCCEEDED(hr)); |
| 471 } | 471 } |
| 472 | 472 |
| 473 swap_chain_scale_x_ = bounds_rect.width() * 1.0f / swap_chain_size.width(); | 473 swap_chain_scale_x_ = bounds_rect.width() * 1.0f / swap_chain_size.width(); |
| 474 swap_chain_scale_y_ = bounds_rect.height() * 1.0f / swap_chain_size.height(); | 474 swap_chain_scale_y_ = bounds_rect.height() * 1.0f / swap_chain_size.height(); |
| 475 | 475 |
| 476 if (first_present) { | 476 if (first_present) { |
| 477 swap_chain_->Present(0, 0); | 477 swap_chain_->Present(0, 0); |
| 478 | 478 |
| 479 // DirectComposition can display black for a swapchain between the first | 479 // DirectComposition can display black for a swapchain between the first |
| 480 // and second time it's presented to - maybe the first Present can get | 480 // and second time it's presented to - maybe the first Present can get |
| 481 // lost somehow and it shows the wrong buffer. In that case copy the | 481 // lost somehow and it shows the wrong buffer. In that case copy the |
| 482 // buffers so both have the correct contents, which seems to help. The | 482 // buffers so both have the correct contents, which seems to help. The |
| 483 // first Present() after this needs to have SyncInterval > 0, or else the | 483 // first Present() after this needs to have SyncInterval > 0, or else the |
| 484 // workaround doesn't help. | 484 // workaround doesn't help. |
| 485 base::win::ScopedComPtr<ID3D11Texture2D> dest_texture; | 485 base::win::ScopedComPtr<ID3D11Texture2D> dest_texture; |
| 486 HRESULT hr = | 486 HRESULT hr = |
| 487 swap_chain_->GetBuffer(0, IID_PPV_ARGS(dest_texture.Receive())); | 487 swap_chain_->GetBuffer(0, IID_PPV_ARGS(dest_texture.Receive())); |
| 488 DCHECK(SUCCEEDED(hr)); | 488 DCHECK(SUCCEEDED(hr)); |
| 489 base::win::ScopedComPtr<ID3D11Texture2D> src_texture; | 489 base::win::ScopedComPtr<ID3D11Texture2D> src_texture; |
| 490 hr = swap_chain_->GetBuffer(1, IID_PPV_ARGS(src_texture.Receive())); | 490 hr = swap_chain_->GetBuffer(1, IID_PPV_ARGS(src_texture.Receive())); |
| 491 DCHECK(SUCCEEDED(hr)); | 491 DCHECK(SUCCEEDED(hr)); |
| 492 base::win::ScopedComPtr<ID3D11DeviceContext> context; | 492 base::win::ScopedComPtr<ID3D11DeviceContext> context; |
| 493 d3d11_device_->GetImmediateContext(context.Receive()); | 493 d3d11_device_->GetImmediateContext(context.Receive()); |
| 494 context->CopyResource(dest_texture.get(), src_texture.get()); | 494 context->CopyResource(dest_texture.Get(), src_texture.Get()); |
| 495 } | 495 } |
| 496 | 496 |
| 497 swap_chain_->Present(1, 0); | 497 swap_chain_->Present(1, 0); |
| 498 | 498 |
| 499 UMA_HISTOGRAM_BOOLEAN("GPU.DirectComposition.SwapchainFormat", | 499 UMA_HISTOGRAM_BOOLEAN("GPU.DirectComposition.SwapchainFormat", |
| 500 is_yuy2_swapchain_); | 500 is_yuy2_swapchain_); |
| 501 frames_since_color_space_change_++; | 501 frames_since_color_space_change_++; |
| 502 | 502 |
| 503 base::win::ScopedComPtr<IDXGISwapChainMedia> swap_chain_media; | 503 base::win::ScopedComPtr<IDXGISwapChainMedia> swap_chain_media; |
| 504 if (SUCCEEDED(swap_chain_.QueryInterface(swap_chain_media.Receive()))) { | 504 if (SUCCEEDED(swap_chain_.QueryInterface(swap_chain_media.Receive()))) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 } | 568 } |
| 569 | 569 |
| 570 frames_since_color_space_change_ = 0; | 570 frames_since_color_space_change_ = 0; |
| 571 | 571 |
| 572 is_yuy2_swapchain_ = false; | 572 is_yuy2_swapchain_ = false; |
| 573 // The composition surface handle isn't actually used, but | 573 // The composition surface handle isn't actually used, but |
| 574 // CreateSwapChainForComposition can't create YUY2 swapchains. | 574 // CreateSwapChainForComposition can't create YUY2 swapchains. |
| 575 HRESULT hr = E_FAIL; | 575 HRESULT hr = E_FAIL; |
| 576 if (yuy2) { | 576 if (yuy2) { |
| 577 hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( | 577 hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( |
| 578 d3d11_device_.get(), swap_chain_handle_.Get(), &desc, nullptr, | 578 d3d11_device_.Get(), swap_chain_handle_.Get(), &desc, nullptr, |
| 579 swap_chain_.Receive()); | 579 swap_chain_.Receive()); |
| 580 is_yuy2_swapchain_ = SUCCEEDED(hr); | 580 is_yuy2_swapchain_ = SUCCEEDED(hr); |
| 581 failed_to_create_yuy2_swapchain_ = !is_yuy2_swapchain_; | 581 failed_to_create_yuy2_swapchain_ = !is_yuy2_swapchain_; |
| 582 } | 582 } |
| 583 | 583 |
| 584 if (!is_yuy2_swapchain_) { | 584 if (!is_yuy2_swapchain_) { |
| 585 if (yuy2) { | 585 if (yuy2) { |
| 586 DLOG(ERROR) << "YUY2 creation failed with " << std::hex << hr | 586 DLOG(ERROR) << "YUY2 creation failed with " << std::hex << hr |
| 587 << ". Falling back to BGRA"; | 587 << ". Falling back to BGRA"; |
| 588 } | 588 } |
| 589 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; | 589 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; |
| 590 desc.Flags = 0; | 590 desc.Flags = 0; |
| 591 hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( | 591 hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( |
| 592 d3d11_device_.get(), swap_chain_handle_.Get(), &desc, nullptr, | 592 d3d11_device_.Get(), swap_chain_handle_.Get(), &desc, nullptr, |
| 593 swap_chain_.Receive()); | 593 swap_chain_.Receive()); |
| 594 CHECK(SUCCEEDED(hr)); | 594 CHECK(SUCCEEDED(hr)); |
| 595 } | 595 } |
| 596 out_view_.Reset(); | 596 out_view_.Reset(); |
| 597 } | 597 } |
| 598 | 598 |
| 599 void DCLayerTree::InitVisual(size_t i) { | 599 void DCLayerTree::InitVisual(size_t i) { |
| 600 DCHECK_GT(visual_info_.size(), i); | 600 DCHECK_GT(visual_info_.size(), i); |
| 601 VisualInfo* visual_info = &visual_info_[i]; | 601 VisualInfo* visual_info = &visual_info_[i]; |
| 602 if (visual_info->content_visual) | 602 if (visual_info->content_visual) |
| 603 return; | 603 return; |
| 604 DCHECK(!visual_info->clip_visual); | 604 DCHECK(!visual_info->clip_visual); |
| 605 base::win::ScopedComPtr<IDCompositionVisual2> visual; | 605 base::win::ScopedComPtr<IDCompositionVisual2> visual; |
| 606 dcomp_device_->CreateVisual(visual_info->clip_visual.Receive()); | 606 dcomp_device_->CreateVisual(visual_info->clip_visual.Receive()); |
| 607 dcomp_device_->CreateVisual(visual.Receive()); | 607 dcomp_device_->CreateVisual(visual.Receive()); |
| 608 visual_info->content_visual = visual; | 608 visual_info->content_visual = visual; |
| 609 visual_info->clip_visual->AddVisual(visual.get(), FALSE, nullptr); | 609 visual_info->clip_visual->AddVisual(visual.Get(), FALSE, nullptr); |
| 610 | 610 |
| 611 IDCompositionVisual2* last_visual = | 611 IDCompositionVisual2* last_visual = |
| 612 (i > 0) ? visual_info_[i - 1].clip_visual.get() : nullptr; | 612 (i > 0) ? visual_info_[i - 1].clip_visual.Get() : nullptr; |
| 613 root_visual_->AddVisual(visual_info->clip_visual.get(), TRUE, last_visual); | 613 root_visual_->AddVisual(visual_info->clip_visual.Get(), TRUE, last_visual); |
| 614 } | 614 } |
| 615 | 615 |
| 616 void DCLayerTree::UpdateVisualForVideo( | 616 void DCLayerTree::UpdateVisualForVideo( |
| 617 VisualInfo* visual_info, | 617 VisualInfo* visual_info, |
| 618 const ui::DCRendererLayerParams& params) { | 618 const ui::DCRendererLayerParams& params) { |
| 619 base::win::ScopedComPtr<IDCompositionVisual2> dc_visual = | 619 base::win::ScopedComPtr<IDCompositionVisual2> dc_visual = |
| 620 visual_info->content_visual; | 620 visual_info->content_visual; |
| 621 | 621 |
| 622 gfx::Rect bounds_rect = params.rect; | 622 gfx::Rect bounds_rect = params.rect; |
| 623 visual_info->surface.Reset(); | 623 visual_info->surface.Reset(); |
| 624 if (!visual_info->swap_chain_presenter) { | 624 if (!visual_info->swap_chain_presenter) { |
| 625 visual_info->swap_chain_presenter = | 625 visual_info->swap_chain_presenter = |
| 626 base::MakeUnique<SwapChainPresenter>(this, d3d11_device_); | 626 base::MakeUnique<SwapChainPresenter>(this, d3d11_device_); |
| 627 } | 627 } |
| 628 visual_info->swap_chain_presenter->PresentToSwapChain(params); | 628 visual_info->swap_chain_presenter->PresentToSwapChain(params); |
| 629 if (visual_info->swap_chain != | 629 if (visual_info->swap_chain != |
| 630 visual_info->swap_chain_presenter->swap_chain()) { | 630 visual_info->swap_chain_presenter->swap_chain()) { |
| 631 visual_info->swap_chain = visual_info->swap_chain_presenter->swap_chain(); | 631 visual_info->swap_chain = visual_info->swap_chain_presenter->swap_chain(); |
| 632 dc_visual->SetContent(visual_info->swap_chain.get()); | 632 dc_visual->SetContent(visual_info->swap_chain.Get()); |
| 633 } | 633 } |
| 634 | 634 |
| 635 if (visual_info->swap_chain_presenter->swap_chain_scale_x() != | 635 if (visual_info->swap_chain_presenter->swap_chain_scale_x() != |
| 636 visual_info->swap_chain_scale_x || | 636 visual_info->swap_chain_scale_x || |
| 637 visual_info->swap_chain_presenter->swap_chain_scale_y() != | 637 visual_info->swap_chain_presenter->swap_chain_scale_y() != |
| 638 visual_info->swap_chain_scale_y || | 638 visual_info->swap_chain_scale_y || |
| 639 params.transform != visual_info->transform || | 639 params.transform != visual_info->transform || |
| 640 visual_info->bounds != bounds_rect) { | 640 visual_info->bounds != bounds_rect) { |
| 641 visual_info->swap_chain_scale_x = | 641 visual_info->swap_chain_scale_x = |
| 642 visual_info->swap_chain_presenter->swap_chain_scale_x(); | 642 visual_info->swap_chain_presenter->swap_chain_scale_x(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 657 dc_visual->SetOffsetY(bounds_rect.y()); | 657 dc_visual->SetOffsetY(bounds_rect.y()); |
| 658 base::win::ScopedComPtr<IDCompositionMatrixTransform> dcomp_transform; | 658 base::win::ScopedComPtr<IDCompositionMatrixTransform> dcomp_transform; |
| 659 dcomp_device_->CreateMatrixTransform(dcomp_transform.Receive()); | 659 dcomp_device_->CreateMatrixTransform(dcomp_transform.Receive()); |
| 660 D2D_MATRIX_3X2_F d2d_matrix = {{{final_transform.matrix().get(0, 0), | 660 D2D_MATRIX_3X2_F d2d_matrix = {{{final_transform.matrix().get(0, 0), |
| 661 final_transform.matrix().get(0, 1), | 661 final_transform.matrix().get(0, 1), |
| 662 final_transform.matrix().get(1, 0), | 662 final_transform.matrix().get(1, 0), |
| 663 final_transform.matrix().get(1, 1), | 663 final_transform.matrix().get(1, 1), |
| 664 final_transform.matrix().get(3, 0), | 664 final_transform.matrix().get(3, 0), |
| 665 final_transform.matrix().get(3, 1)}}}; | 665 final_transform.matrix().get(3, 1)}}}; |
| 666 dcomp_transform->SetMatrix(d2d_matrix); | 666 dcomp_transform->SetMatrix(d2d_matrix); |
| 667 dc_visual->SetTransform(dcomp_transform.get()); | 667 dc_visual->SetTransform(dcomp_transform.Get()); |
| 668 } | 668 } |
| 669 } | 669 } |
| 670 | 670 |
| 671 void DCLayerTree::UpdateVisualForBackbuffer( | 671 void DCLayerTree::UpdateVisualForBackbuffer( |
| 672 VisualInfo* visual_info, | 672 VisualInfo* visual_info, |
| 673 const ui::DCRendererLayerParams& params) { | 673 const ui::DCRendererLayerParams& params) { |
| 674 base::win::ScopedComPtr<IDCompositionVisual2> dc_visual = | 674 base::win::ScopedComPtr<IDCompositionVisual2> dc_visual = |
| 675 visual_info->content_visual; | 675 visual_info->content_visual; |
| 676 | 676 |
| 677 visual_info->swap_chain_presenter = nullptr; | 677 visual_info->swap_chain_presenter = nullptr; |
| 678 if ((visual_info->surface != surface_->dcomp_surface()) || | 678 if ((visual_info->surface != surface_->dcomp_surface()) || |
| 679 (visual_info->swap_chain != surface_->swap_chain())) { | 679 (visual_info->swap_chain != surface_->swap_chain())) { |
| 680 visual_info->surface = surface_->dcomp_surface(); | 680 visual_info->surface = surface_->dcomp_surface(); |
| 681 visual_info->swap_chain = surface_->swap_chain(); | 681 visual_info->swap_chain = surface_->swap_chain(); |
| 682 if (visual_info->surface) { | 682 if (visual_info->surface) { |
| 683 dc_visual->SetContent(visual_info->surface.get()); | 683 dc_visual->SetContent(visual_info->surface.Get()); |
| 684 } else if (visual_info->swap_chain) { | 684 } else if (visual_info->swap_chain) { |
| 685 dc_visual->SetContent(visual_info->swap_chain.get()); | 685 dc_visual->SetContent(visual_info->swap_chain.Get()); |
| 686 } else { | 686 } else { |
| 687 dc_visual->SetContent(nullptr); | 687 dc_visual->SetContent(nullptr); |
| 688 } | 688 } |
| 689 } | 689 } |
| 690 | 690 |
| 691 gfx::Rect bounds_rect = params.rect; | 691 gfx::Rect bounds_rect = params.rect; |
| 692 if (visual_info->bounds != bounds_rect || | 692 if (visual_info->bounds != bounds_rect || |
| 693 !visual_info->transform.IsIdentity()) { | 693 !visual_info->transform.IsIdentity()) { |
| 694 dc_visual->SetOffsetX(bounds_rect.x()); | 694 dc_visual->SetOffsetX(bounds_rect.x()); |
| 695 dc_visual->SetOffsetY(bounds_rect.y()); | 695 dc_visual->SetOffsetY(bounds_rect.y()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 709 visual_info->is_clipped = params.is_clipped; | 709 visual_info->is_clipped = params.is_clipped; |
| 710 visual_info->clip_rect = params.clip_rect; | 710 visual_info->clip_rect = params.clip_rect; |
| 711 if (params.is_clipped) { | 711 if (params.is_clipped) { |
| 712 base::win::ScopedComPtr<IDCompositionRectangleClip> clip; | 712 base::win::ScopedComPtr<IDCompositionRectangleClip> clip; |
| 713 dcomp_device_->CreateRectangleClip(clip.Receive()); | 713 dcomp_device_->CreateRectangleClip(clip.Receive()); |
| 714 gfx::Rect offset_clip = params.clip_rect; | 714 gfx::Rect offset_clip = params.clip_rect; |
| 715 clip->SetLeft(offset_clip.x()); | 715 clip->SetLeft(offset_clip.x()); |
| 716 clip->SetRight(offset_clip.right()); | 716 clip->SetRight(offset_clip.right()); |
| 717 clip->SetBottom(offset_clip.bottom()); | 717 clip->SetBottom(offset_clip.bottom()); |
| 718 clip->SetTop(offset_clip.y()); | 718 clip->SetTop(offset_clip.y()); |
| 719 visual_info->clip_visual->SetClip(clip.get()); | 719 visual_info->clip_visual->SetClip(clip.Get()); |
| 720 } else { | 720 } else { |
| 721 visual_info->clip_visual->SetClip(nullptr); | 721 visual_info->clip_visual->SetClip(nullptr); |
| 722 } | 722 } |
| 723 } | 723 } |
| 724 } | 724 } |
| 725 | 725 |
| 726 bool DCLayerTree::CommitAndClearPendingOverlays() { | 726 bool DCLayerTree::CommitAndClearPendingOverlays() { |
| 727 TRACE_EVENT1("gpu", "DCLayerTree::CommitAndClearPendingOverlays", "size", | 727 TRACE_EVENT1("gpu", "DCLayerTree::CommitAndClearPendingOverlays", "size", |
| 728 pending_overlays_.size()); | 728 pending_overlays_.size()); |
| 729 UMA_HISTOGRAM_BOOLEAN("GPU.DirectComposition.OverlaysUsed", | 729 UMA_HISTOGRAM_BOOLEAN("GPU.DirectComposition.OverlaysUsed", |
| 730 !pending_overlays_.empty()); | 730 !pending_overlays_.empty()); |
| 731 // Add an overlay with z-order 0 representing the main plane. | 731 // Add an overlay with z-order 0 representing the main plane. |
| 732 gfx::Size surface_size = surface_->GetSize(); | 732 gfx::Size surface_size = surface_->GetSize(); |
| 733 pending_overlays_.push_back(base::MakeUnique<ui::DCRendererLayerParams>( | 733 pending_overlays_.push_back(base::MakeUnique<ui::DCRendererLayerParams>( |
| 734 false, gfx::Rect(), 0, gfx::Transform(), nullptr, | 734 false, gfx::Rect(), 0, gfx::Transform(), nullptr, |
| 735 gfx::RectF(gfx::SizeF(surface_size)), gfx::Rect(surface_size), 0, 0, 1.0, | 735 gfx::RectF(gfx::SizeF(surface_size)), gfx::Rect(surface_size), 0, 0, 1.0, |
| 736 0)); | 736 0)); |
| 737 | 737 |
| 738 // TODO(jbauman): Reuse swapchains that are switched between overlays and | 738 // TODO(jbauman): Reuse swapchains that are switched between overlays and |
| 739 // underlays. | 739 // underlays. |
| 740 std::sort(pending_overlays_.begin(), pending_overlays_.end(), | 740 std::sort(pending_overlays_.begin(), pending_overlays_.end(), |
| 741 [](const auto& a, const auto& b) -> bool { | 741 [](const auto& a, const auto& b) -> bool { |
| 742 return a->z_order < b->z_order; | 742 return a->z_order < b->z_order; |
| 743 }); | 743 }); |
| 744 | 744 |
| 745 while (visual_info_.size() > pending_overlays_.size()) { | 745 while (visual_info_.size() > pending_overlays_.size()) { |
| 746 visual_info_.back().clip_visual->RemoveAllVisuals(); | 746 visual_info_.back().clip_visual->RemoveAllVisuals(); |
| 747 root_visual_->RemoveVisual(visual_info_.back().clip_visual.get()); | 747 root_visual_->RemoveVisual(visual_info_.back().clip_visual.Get()); |
| 748 visual_info_.pop_back(); | 748 visual_info_.pop_back(); |
| 749 } | 749 } |
| 750 | 750 |
| 751 visual_info_.resize(pending_overlays_.size()); | 751 visual_info_.resize(pending_overlays_.size()); |
| 752 | 752 |
| 753 // The overall visual tree has one clip visual for every overlay (including | 753 // The overall visual tree has one clip visual for every overlay (including |
| 754 // the main plane). The clip visuals are in z_order and are all children of | 754 // the main plane). The clip visuals are in z_order and are all children of |
| 755 // a root visual. Each clip visual has a child visual that has the actual | 755 // a root visual. Each clip visual has a child visual that has the actual |
| 756 // plane content. | 756 // plane content. |
| 757 | 757 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 desc.Format = output_format; | 920 desc.Format = output_format; |
| 921 desc.Stereo = FALSE; | 921 desc.Stereo = FALSE; |
| 922 desc.SampleDesc.Count = 1; | 922 desc.SampleDesc.Count = 1; |
| 923 desc.BufferCount = 2; | 923 desc.BufferCount = 2; |
| 924 desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; | 924 desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; |
| 925 desc.Scaling = DXGI_SCALING_STRETCH; | 925 desc.Scaling = DXGI_SCALING_STRETCH; |
| 926 desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; | 926 desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; |
| 927 desc.AlphaMode = alpha_mode; | 927 desc.AlphaMode = alpha_mode; |
| 928 desc.Flags = 0; | 928 desc.Flags = 0; |
| 929 HRESULT hr = dxgi_factory->CreateSwapChainForComposition( | 929 HRESULT hr = dxgi_factory->CreateSwapChainForComposition( |
| 930 d3d11_device_.get(), &desc, nullptr, swap_chain_.Receive()); | 930 d3d11_device_.Get(), &desc, nullptr, swap_chain_.Receive()); |
| 931 has_been_rendered_to_ = false; | 931 has_been_rendered_to_ = false; |
| 932 first_swap_ = true; | 932 first_swap_ = true; |
| 933 CHECK(SUCCEEDED(hr)); | 933 CHECK(SUCCEEDED(hr)); |
| 934 } | 934 } |
| 935 } | 935 } |
| 936 | 936 |
| 937 void DirectCompositionSurfaceWin::ReleaseDrawTexture(bool will_discard) { | 937 void DirectCompositionSurfaceWin::ReleaseDrawTexture(bool will_discard) { |
| 938 if (real_surface_) { | 938 if (real_surface_) { |
| 939 eglDestroySurface(GetDisplay(), real_surface_); | 939 eglDestroySurface(GetDisplay(), real_surface_); |
| 940 real_surface_ = nullptr; | 940 real_surface_ = nullptr; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1073 bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) { | 1073 bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) { |
| 1074 if (g_current_surface != dcomp_surface_) { | 1074 if (g_current_surface != dcomp_surface_) { |
| 1075 if (g_current_surface) { | 1075 if (g_current_surface) { |
| 1076 HRESULT hr = g_current_surface->SuspendDraw(); | 1076 HRESULT hr = g_current_surface->SuspendDraw(); |
| 1077 CHECK(SUCCEEDED(hr)); | 1077 CHECK(SUCCEEDED(hr)); |
| 1078 g_current_surface = nullptr; | 1078 g_current_surface = nullptr; |
| 1079 } | 1079 } |
| 1080 if (draw_texture_) { | 1080 if (draw_texture_) { |
| 1081 HRESULT hr = dcomp_surface_->ResumeDraw(); | 1081 HRESULT hr = dcomp_surface_->ResumeDraw(); |
| 1082 CHECK(SUCCEEDED(hr)); | 1082 CHECK(SUCCEEDED(hr)); |
| 1083 g_current_surface = dcomp_surface_.get(); | 1083 g_current_surface = dcomp_surface_.Get(); |
| 1084 } | 1084 } |
| 1085 } | 1085 } |
| 1086 return true; | 1086 return true; |
| 1087 } | 1087 } |
| 1088 | 1088 |
| 1089 bool DirectCompositionSurfaceWin::SupportsDCLayers() const { | 1089 bool DirectCompositionSurfaceWin::SupportsDCLayers() const { |
| 1090 return true; | 1090 return true; |
| 1091 } | 1091 } |
| 1092 | 1092 |
| 1093 bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rectangle) { | 1093 bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rectangle) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1122 CHECK(SUCCEEDED(hr)); | 1122 CHECK(SUCCEEDED(hr)); |
| 1123 } else { | 1123 } else { |
| 1124 HRESULT hr = | 1124 HRESULT hr = |
| 1125 swap_chain_->GetBuffer(0, IID_PPV_ARGS(draw_texture_.Receive())); | 1125 swap_chain_->GetBuffer(0, IID_PPV_ARGS(draw_texture_.Receive())); |
| 1126 swap_rect_ = rectangle; | 1126 swap_rect_ = rectangle; |
| 1127 draw_offset_ = gfx::Vector2d(); | 1127 draw_offset_ = gfx::Vector2d(); |
| 1128 CHECK(SUCCEEDED(hr)); | 1128 CHECK(SUCCEEDED(hr)); |
| 1129 } | 1129 } |
| 1130 has_been_rendered_to_ = true; | 1130 has_been_rendered_to_ = true; |
| 1131 | 1131 |
| 1132 g_current_surface = dcomp_surface_.get(); | 1132 g_current_surface = dcomp_surface_.Get(); |
| 1133 | 1133 |
| 1134 std::vector<EGLint> pbuffer_attribs{ | 1134 std::vector<EGLint> pbuffer_attribs{ |
| 1135 EGL_WIDTH, | 1135 EGL_WIDTH, |
| 1136 size_.width(), | 1136 size_.width(), |
| 1137 EGL_HEIGHT, | 1137 EGL_HEIGHT, |
| 1138 size_.height(), | 1138 size_.height(), |
| 1139 EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, | 1139 EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, |
| 1140 EGL_TRUE, | 1140 EGL_TRUE, |
| 1141 EGL_NONE}; | 1141 EGL_NONE}; |
| 1142 | 1142 |
| 1143 EGLClientBuffer buffer = | 1143 EGLClientBuffer buffer = |
| 1144 reinterpret_cast<EGLClientBuffer>(draw_texture_.get()); | 1144 reinterpret_cast<EGLClientBuffer>(draw_texture_.Get()); |
| 1145 real_surface_ = eglCreatePbufferFromClientBuffer( | 1145 real_surface_ = eglCreatePbufferFromClientBuffer( |
| 1146 GetDisplay(), EGL_D3D_TEXTURE_ANGLE, buffer, GetConfig(), | 1146 GetDisplay(), EGL_D3D_TEXTURE_ANGLE, buffer, GetConfig(), |
| 1147 &pbuffer_attribs[0]); | 1147 &pbuffer_attribs[0]); |
| 1148 | 1148 |
| 1149 return true; | 1149 return true; |
| 1150 } | 1150 } |
| 1151 | 1151 |
| 1152 gfx::Vector2d DirectCompositionSurfaceWin::GetDrawOffset() const { | 1152 gfx::Vector2d DirectCompositionSurfaceWin::GetDrawOffset() const { |
| 1153 return draw_offset_; | 1153 return draw_offset_; |
| 1154 } | 1154 } |
| 1155 | 1155 |
| 1156 scoped_refptr<base::TaskRunner> | 1156 scoped_refptr<base::TaskRunner> |
| 1157 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { | 1157 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { |
| 1158 return child_window_.GetTaskRunnerForTesting(); | 1158 return child_window_.GetTaskRunnerForTesting(); |
| 1159 } | 1159 } |
| 1160 | 1160 |
| 1161 base::win::ScopedComPtr<IDXGISwapChain1> | 1161 base::win::ScopedComPtr<IDXGISwapChain1> |
| 1162 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { | 1162 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { |
| 1163 return layer_tree_->GetLayerSwapChainForTesting(index); | 1163 return layer_tree_->GetLayerSwapChainForTesting(index); |
| 1164 } | 1164 } |
| 1165 | 1165 |
| 1166 } // namespace gpu | 1166 } // namespace gpu |
| OLD | NEW |