| 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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 uv_image_memory->memory() + y * uv_image_memory->stride(); | 467 uv_image_memory->memory() + y * uv_image_memory->stride(); |
| 468 uint8_t* dest = uv_dest_plane_start + dest_stride * y; | 468 uint8_t* dest = uv_dest_plane_start + dest_stride * y; |
| 469 memcpy(dest, uv_source, texture_size.width()); | 469 memcpy(dest, uv_source, texture_size.width()); |
| 470 } | 470 } |
| 471 context->Unmap(staging_texture_.Get(), 0); | 471 context->Unmap(staging_texture_.Get(), 0); |
| 472 return true; | 472 return true; |
| 473 } | 473 } |
| 474 | 474 |
| 475 void DCLayerTree::SwapChainPresenter::PresentToSwapChain( | 475 void DCLayerTree::SwapChainPresenter::PresentToSwapChain( |
| 476 const ui::DCRendererLayerParams& params) { | 476 const ui::DCRendererLayerParams& params) { |
| 477 gl::GLImageDXGI* image_dxgi = | 477 gl::GLImageDXGIBase* image_dxgi = |
| 478 gl::GLImageDXGI::FromGLImage(params.image[0].get()); | 478 gl::GLImageDXGIBase::FromGLImage(params.image[0].get()); |
| 479 gl::GLImageMemory* y_image_memory = nullptr; | 479 gl::GLImageMemory* y_image_memory = nullptr; |
| 480 gl::GLImageMemory* uv_image_memory = nullptr; | 480 gl::GLImageMemory* uv_image_memory = nullptr; |
| 481 if (params.image.size() >= 2) { | 481 if (params.image.size() >= 2) { |
| 482 y_image_memory = gl::GLImageMemory::FromGLImage(params.image[0].get()); | 482 y_image_memory = gl::GLImageMemory::FromGLImage(params.image[0].get()); |
| 483 uv_image_memory = gl::GLImageMemory::FromGLImage(params.image[1].get()); | 483 uv_image_memory = gl::GLImageMemory::FromGLImage(params.image[1].get()); |
| 484 } | 484 } |
| 485 | 485 |
| 486 if (!image_dxgi && (!y_image_memory || !uv_image_memory)) { | 486 if (!image_dxgi && (!y_image_memory || !uv_image_memory)) { |
| 487 DLOG(ERROR) << "Video GLImages are missing"; | 487 DLOG(ERROR) << "Video GLImages are missing"; |
| 488 last_gl_images_.clear(); | 488 last_gl_images_.clear(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 // The swap chain is presenting the same images as last swap, which means | 550 // The swap chain is presenting the same images as last swap, which means |
| 551 // that the images were never returned to the video decoder and should | 551 // that the images were never returned to the video decoder and should |
| 552 // have the same contents as last time. It shouldn't need to be redrawn. | 552 // have the same contents as last time. It shouldn't need to be redrawn. |
| 553 return; | 553 return; |
| 554 } | 554 } |
| 555 | 555 |
| 556 last_gl_images_ = params.image; | 556 last_gl_images_ = params.image; |
| 557 | 557 |
| 558 base::win::ScopedComPtr<ID3D11Texture2D> input_texture; | 558 base::win::ScopedComPtr<ID3D11Texture2D> input_texture; |
| 559 UINT input_level; | 559 UINT input_level; |
| 560 base::win::ScopedComPtr<IDXGIKeyedMutex> keyed_mutex; |
| 560 if (image_dxgi) { | 561 if (image_dxgi) { |
| 561 input_texture = image_dxgi->texture(); | 562 input_texture = image_dxgi->texture(); |
| 562 input_level = (UINT)image_dxgi->level(); | 563 input_level = (UINT)image_dxgi->level(); |
| 564 if (!input_texture) |
| 565 return; |
| 566 // Keyed mutex may not exist. |
| 567 keyed_mutex = image_dxgi->keyed_mutex(); |
| 563 staging_texture_.Reset(); | 568 staging_texture_.Reset(); |
| 564 } else { | 569 } else { |
| 565 DCHECK(y_image_memory); | 570 DCHECK(y_image_memory); |
| 566 DCHECK(uv_image_memory); | 571 DCHECK(uv_image_memory); |
| 567 if (!UploadVideoImages(y_image_memory, uv_image_memory)) | 572 if (!UploadVideoImages(y_image_memory, uv_image_memory)) |
| 568 return; | 573 return; |
| 569 DCHECK(staging_texture_); | 574 DCHECK(staging_texture_); |
| 570 input_texture = staging_texture_; | 575 input_texture = staging_texture_; |
| 571 input_level = 0; | 576 input_level = 0; |
| 572 } | 577 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 color_space); | 622 color_space); |
| 618 } else { | 623 } else { |
| 619 D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = | 624 D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space = |
| 620 gfx::ColorSpaceWin::GetD3D11ColorSpace(output_color_space); | 625 gfx::ColorSpaceWin::GetD3D11ColorSpace(output_color_space); |
| 621 video_context_->VideoProcessorSetOutputColorSpace(video_processor_.Get(), | 626 video_context_->VideoProcessorSetOutputColorSpace(video_processor_.Get(), |
| 622 &d3d11_color_space); | 627 &d3d11_color_space); |
| 623 } | 628 } |
| 624 } | 629 } |
| 625 | 630 |
| 626 { | 631 { |
| 632 if (keyed_mutex) { |
| 633 // The producer may still be using this texture for a short period of |
| 634 // time, so wait long enough to hopefully avoid glitches. For example, |
| 635 // all levels of the texture share the same keyed mutex, so if the |
| 636 // hardware decoder acquired the mutex to decode into a different array |
| 637 // level then it still may block here temporarily. |
| 638 const int kMaxSyncTimeMs = 1000; |
| 639 HRESULT hr = keyed_mutex->AcquireSync(0, kMaxSyncTimeMs); |
| 640 if (FAILED(hr)) { |
| 641 DLOG(ERROR) << "Error acquiring keyed mutex: " << std::hex << hr; |
| 642 return; |
| 643 } |
| 644 } |
| 627 D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC in_desc = {}; | 645 D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC in_desc = {}; |
| 628 in_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; | 646 in_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; |
| 629 in_desc.Texture2D.ArraySlice = input_level; | 647 in_desc.Texture2D.ArraySlice = input_level; |
| 630 base::win::ScopedComPtr<ID3D11VideoProcessorInputView> in_view; | 648 base::win::ScopedComPtr<ID3D11VideoProcessorInputView> in_view; |
| 631 HRESULT hr = video_device_->CreateVideoProcessorInputView( | 649 HRESULT hr = video_device_->CreateVideoProcessorInputView( |
| 632 input_texture.Get(), video_processor_enumerator_.Get(), &in_desc, | 650 input_texture.Get(), video_processor_enumerator_.Get(), &in_desc, |
| 633 in_view.GetAddressOf()); | 651 in_view.GetAddressOf()); |
| 634 CHECK(SUCCEEDED(hr)); | 652 CHECK(SUCCEEDED(hr)); |
| 635 | 653 |
| 636 D3D11_VIDEO_PROCESSOR_STREAM stream = {}; | 654 D3D11_VIDEO_PROCESSOR_STREAM stream = {}; |
| 637 stream.Enable = true; | 655 stream.Enable = true; |
| 638 stream.OutputIndex = 0; | 656 stream.OutputIndex = 0; |
| 639 stream.InputFrameOrField = 0; | 657 stream.InputFrameOrField = 0; |
| 640 stream.PastFrames = 0; | 658 stream.PastFrames = 0; |
| 641 stream.FutureFrames = 0; | 659 stream.FutureFrames = 0; |
| 642 stream.pInputSurface = in_view.Get(); | 660 stream.pInputSurface = in_view.Get(); |
| 643 RECT dest_rect = gfx::Rect(swap_chain_size).ToRECT(); | 661 RECT dest_rect = gfx::Rect(swap_chain_size).ToRECT(); |
| 644 video_context_->VideoProcessorSetOutputTargetRect(video_processor_.Get(), | 662 video_context_->VideoProcessorSetOutputTargetRect(video_processor_.Get(), |
| 645 TRUE, &dest_rect); | 663 TRUE, &dest_rect); |
| 646 video_context_->VideoProcessorSetStreamDestRect(video_processor_.Get(), 0, | 664 video_context_->VideoProcessorSetStreamDestRect(video_processor_.Get(), 0, |
| 647 TRUE, &dest_rect); | 665 TRUE, &dest_rect); |
| 648 RECT source_rect = gfx::Rect(ceiled_input_size).ToRECT(); | 666 RECT source_rect = gfx::Rect(ceiled_input_size).ToRECT(); |
| 649 video_context_->VideoProcessorSetStreamSourceRect(video_processor_.Get(), 0, | 667 video_context_->VideoProcessorSetStreamSourceRect(video_processor_.Get(), 0, |
| 650 TRUE, &source_rect); | 668 TRUE, &source_rect); |
| 651 | 669 |
| 652 hr = video_context_->VideoProcessorBlt(video_processor_.Get(), | 670 hr = video_context_->VideoProcessorBlt(video_processor_.Get(), |
| 653 out_view_.Get(), 0, 1, &stream); | 671 out_view_.Get(), 0, 1, &stream); |
| 654 CHECK(SUCCEEDED(hr)); | 672 CHECK(SUCCEEDED(hr)); |
| 673 if (keyed_mutex) { |
| 674 HRESULT hr = keyed_mutex->ReleaseSync(0); |
| 675 DCHECK(SUCCEEDED(hr)); |
| 676 } |
| 655 } | 677 } |
| 656 | 678 |
| 657 if (first_present) { | 679 if (first_present) { |
| 658 swap_chain_->Present(0, 0); | 680 swap_chain_->Present(0, 0); |
| 659 | 681 |
| 660 // DirectComposition can display black for a swapchain between the first | 682 // DirectComposition can display black for a swapchain between the first |
| 661 // and second time it's presented to - maybe the first Present can get | 683 // and second time it's presented to - maybe the first Present can get |
| 662 // lost somehow and it shows the wrong buffer. In that case copy the | 684 // lost somehow and it shows the wrong buffer. In that case copy the |
| 663 // buffers so both have the correct contents, which seems to help. The | 685 // buffers so both have the correct contents, which seems to help. The |
| 664 // first Present() after this needs to have SyncInterval > 0, or else the | 686 // first Present() after this needs to have SyncInterval > 0, or else the |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { | 1237 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { |
| 1216 return child_window_.GetTaskRunnerForTesting(); | 1238 return child_window_.GetTaskRunnerForTesting(); |
| 1217 } | 1239 } |
| 1218 | 1240 |
| 1219 base::win::ScopedComPtr<IDXGISwapChain1> | 1241 base::win::ScopedComPtr<IDXGISwapChain1> |
| 1220 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { | 1242 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { |
| 1221 return layer_tree_->GetLayerSwapChainForTesting(index); | 1243 return layer_tree_->GetLayerSwapChainForTesting(index); |
| 1222 } | 1244 } |
| 1223 | 1245 |
| 1224 } // namespace gpu | 1246 } // namespace gpu |
| OLD | NEW |