d3d11_copying_texture_wrapper.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/gpu/windows/d3d11_copying_texture_wrapper.h"
  5. #include <memory>
  6. #include "gpu/command_buffer/service/mailbox_manager.h"
  7. #include "media/gpu/windows/d3d11_com_defs.h"
  8. #include "ui/gl/hdr_metadata_helper_win.h"
  9. namespace media {
  10. // TODO(tmathmeyer) What D3D11 Resources do we need to do the copying?
  11. CopyingTexture2DWrapper::CopyingTexture2DWrapper(
  12. const gfx::Size& size,
  13. std::unique_ptr<Texture2DWrapper> output_wrapper,
  14. scoped_refptr<VideoProcessorProxy> processor,
  15. ComD3D11Texture2D output_texture,
  16. absl::optional<gfx::ColorSpace> output_color_space)
  17. : size_(size),
  18. video_processor_(std::move(processor)),
  19. output_texture_wrapper_(std::move(output_wrapper)),
  20. output_texture_(std::move(output_texture)),
  21. output_color_space_(std::move(output_color_space)) {}
  22. CopyingTexture2DWrapper::~CopyingTexture2DWrapper() = default;
  23. // Copy path doesn't need to acquire keyed mutex until calling
  24. // VideoProcessorBlt.
  25. D3D11Status CopyingTexture2DWrapper::AcquireKeyedMutexIfNeeded() {
  26. return D3D11Status::Codes::kOk;
  27. }
  28. D3D11Status CopyingTexture2DWrapper::ProcessTexture(
  29. const gfx::ColorSpace& input_color_space,
  30. MailboxHolderArray* mailbox_dest,
  31. gfx::ColorSpace* output_color_space) {
  32. // Acquire keyed mutex for VideoProcessorBlt ops.
  33. D3D11Status status = output_texture_wrapper_->AcquireKeyedMutexIfNeeded();
  34. if (!status.is_ok()) {
  35. return status;
  36. }
  37. D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC output_view_desc = {
  38. D3D11_VPOV_DIMENSION_TEXTURE2D};
  39. output_view_desc.Texture2D.MipSlice = 0;
  40. ComD3D11VideoProcessorOutputView output_view;
  41. HRESULT hr = video_processor_->CreateVideoProcessorOutputView(
  42. output_texture_.Get(), &output_view_desc, &output_view);
  43. if (!SUCCEEDED(hr))
  44. return {D3D11Status::Codes::kCreateVideoProcessorOutputViewFailed, hr};
  45. D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC input_view_desc = {0};
  46. input_view_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
  47. input_view_desc.Texture2D.ArraySlice = array_slice_;
  48. input_view_desc.Texture2D.MipSlice = 0;
  49. ComD3D11VideoProcessorInputView input_view;
  50. hr = video_processor_->CreateVideoProcessorInputView(
  51. texture_.Get(), &input_view_desc, &input_view);
  52. if (!SUCCEEDED(hr))
  53. return {D3D11Status::Codes::kCreateVideoProcessorInputViewFailed};
  54. D3D11_VIDEO_PROCESSOR_STREAM streams = {0};
  55. streams.Enable = TRUE;
  56. streams.pInputSurface = input_view.Get();
  57. // If we were given an output color space, then that's what we'll use.
  58. // Otherwise, we'll use whatever the input space is.
  59. gfx::ColorSpace copy_color_space =
  60. output_color_space_ ? *output_color_space_ : input_color_space;
  61. // If the input color space has changed, or if this is the first call, then
  62. // notify the video processor about it.
  63. if (!previous_input_color_space_ ||
  64. *previous_input_color_space_ != input_color_space) {
  65. previous_input_color_space_ = input_color_space;
  66. // The VideoProcessor doesn't support tone mapping of HLG content, so treat
  67. // treat it as gamma 2.2 since HLG is designed to look okay that way.
  68. auto adjusted_color_space = input_color_space;
  69. if (input_color_space.GetTransferID() == gfx::ColorSpace::TransferID::HLG &&
  70. !copy_color_space.IsHDR()) {
  71. adjusted_color_space = gfx::ColorSpace(
  72. input_color_space.GetPrimaryID(),
  73. gfx::ColorSpace::TransferID::GAMMA22, input_color_space.GetMatrixID(),
  74. input_color_space.GetRangeID());
  75. }
  76. video_processor_->SetStreamColorSpace(adjusted_color_space);
  77. video_processor_->SetOutputColorSpace(copy_color_space);
  78. }
  79. hr = video_processor_->VideoProcessorBlt(output_view.Get(),
  80. 0, // output_frameno
  81. 1, // stream_count
  82. &streams);
  83. if (!SUCCEEDED(hr))
  84. return {D3D11Status::Codes::kVideoProcessorBltFailed, hr};
  85. return output_texture_wrapper_->ProcessTexture(copy_color_space, mailbox_dest,
  86. output_color_space);
  87. }
  88. D3D11Status CopyingTexture2DWrapper::Init(
  89. scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
  90. GetCommandBufferHelperCB get_helper_cb,
  91. ComD3D11Texture2D texture,
  92. size_t array_slice) {
  93. auto result = video_processor_->Init(size_.width(), size_.height());
  94. if (!result.is_ok())
  95. return std::move(result).AddHere();
  96. // Remember the texture + array_slice so later, ProcessTexture can still use
  97. // it.
  98. texture_ = texture;
  99. array_slice_ = array_slice;
  100. return output_texture_wrapper_->Init(
  101. std::move(gpu_task_runner), std::move(get_helper_cb), output_texture_,
  102. /*array_slice=*/0);
  103. }
  104. void CopyingTexture2DWrapper::SetStreamHDRMetadata(
  105. const gfx::HDRMetadata& stream_metadata) {
  106. auto dxgi_stream_metadata =
  107. gl::HDRMetadataHelperWin::HDRMetadataToDXGI(stream_metadata);
  108. video_processor_->SetStreamHDRMetadata(dxgi_stream_metadata);
  109. }
  110. void CopyingTexture2DWrapper::SetDisplayHDRMetadata(
  111. const DXGI_HDR_METADATA_HDR10& dxgi_display_metadata) {
  112. video_processor_->SetDisplayHDRMetadata(dxgi_display_metadata);
  113. }
  114. } // namespace media