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 |