hdr_metadata_helper_win_unittest.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2020 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 "ui/gl/hdr_metadata_helper_win.h"
  5. #include "media/base/win/d3d11_mocks.h"
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. using ::testing::_;
  8. using ::testing::DoAll;
  9. // using ::testing::Eq;
  10. using ::testing::NiceMock;
  11. using ::testing::Return;
  12. // using ::testing::SaveArg;
  13. using ::testing::SetArgPointee;
  14. namespace gl {
  15. class HDRMetadataHelperWinTest : public ::testing::Test {
  16. public:
  17. void SetUp() override {
  18. mock_dxgi_factory_ = media::MakeComPtr<NiceMock<media::DXGIFactoryMock>>();
  19. ON_CALL(*mock_dxgi_factory_.Get(), EnumAdapters(_, _))
  20. .WillByDefault(Return(DXGI_ERROR_NOT_FOUND));
  21. mock_dxgi_device_ = media::MakeComPtr<NiceMock<media::DXGIDeviceMock>>();
  22. mock_d3d11_device_ = media::MakeComPtr<NiceMock<media::D3D11DeviceMock>>();
  23. ON_CALL(*mock_d3d11_device_.Get(), QueryInterface(IID_IDXGIDevice, _))
  24. .WillByDefault(
  25. media::SetComPointeeAndReturnOk<1>(mock_dxgi_device_.Get()));
  26. }
  27. std::unique_ptr<HDRMetadataHelperWin> CreateHelper() {
  28. // Set the D3D11 device's adapter to the first one, somewhat arbitrarily.
  29. ON_CALL(*mock_dxgi_device_.Get(), GetAdapter(_))
  30. .WillByDefault(
  31. media::SetComPointeeAndReturnOk<0>(mock_dxgi_adapters_[0].Get()));
  32. return std::make_unique<HDRMetadataHelperWin>(mock_d3d11_device_);
  33. }
  34. // Adds an adapter that |mock_dxgi_factory_| will enumerate.
  35. void AddAdapter() {
  36. Microsoft::WRL::ComPtr<media::DXGIAdapterMock> dxgi_adapter =
  37. media::MakeComPtr<NiceMock<media::DXGIAdapterMock>>();
  38. ON_CALL(*dxgi_adapter.Get(), GetParent(_, _))
  39. .WillByDefault(
  40. media::SetComPointeeAndReturnOk<1>(mock_dxgi_factory_.Get()));
  41. // By default, the adapter has no outputs.
  42. ON_CALL(*dxgi_adapter.Get(), EnumOutputs(_, _))
  43. .WillByDefault(Return(DXGI_ERROR_NOT_FOUND));
  44. // Make the factory enumerate this adapter.
  45. ON_CALL(*mock_dxgi_factory_.Get(),
  46. EnumAdapters(mock_dxgi_adapters_.size(), _))
  47. .WillByDefault(media::SetComPointeeAndReturnOk<1>(dxgi_adapter.Get()));
  48. mock_dxgi_adapters_.push_back(std::move(dxgi_adapter));
  49. }
  50. // Add |desc1| to the most recent adapter.
  51. // Note that, for now, this can only be called once, since we only set
  52. // an expectation for output 0.
  53. void AddOutput(const DXGI_OUTPUT_DESC1& desc1) {
  54. // Create a DXGIOutput6 that can return |desc1|.
  55. Microsoft::WRL::ComPtr<media::DXGIOutput6Mock> output6 =
  56. media::MakeComPtr<media::DXGIOutput6Mock>();
  57. mock_dxgi_output6s_.push_back(output6);
  58. ON_CALL(*output6.Get(), GetDesc1(_))
  59. .WillByDefault(DoAll(SetArgPointee<0>(desc1), Return(S_OK)));
  60. // Tell the current adapter to return |output6| as its 0-th output.
  61. auto& dxgi_adapter = mock_dxgi_adapters_[mock_dxgi_adapters_.size() - 1];
  62. ON_CALL(*dxgi_adapter.Get(), EnumOutputs(0, _))
  63. .WillByDefault(media::SetComPointeeAndReturnOk<1>(output6.Get()));
  64. }
  65. Microsoft::WRL::ComPtr<media::D3D11DeviceMock> mock_d3d11_device_;
  66. Microsoft::WRL::ComPtr<media::DXGIDeviceMock> mock_dxgi_device_;
  67. Microsoft::WRL::ComPtr<media::DXGIFactoryMock> mock_dxgi_factory_;
  68. std::vector<Microsoft::WRL::ComPtr<media::DXGIAdapterMock>>
  69. mock_dxgi_adapters_;
  70. std::vector<Microsoft::WRL::ComPtr<media::DXGIOutput6Mock>>
  71. mock_dxgi_output6s_;
  72. std::vector<Microsoft::WRL::ComPtr<media::DXGIOutputMock>> mock_dxgi_outputs_;
  73. };
  74. TEST_F(HDRMetadataHelperWinTest, CachesMetadataIfAvailable) {
  75. // Set up two adapters with one monitor each.
  76. AddAdapter();
  77. DXGI_OUTPUT_DESC1 desc{};
  78. desc.RedPrimary[0] = 0.1;
  79. desc.RedPrimary[1] = 0.2;
  80. desc.GreenPrimary[0] = 0.3;
  81. desc.GreenPrimary[1] = 0.4;
  82. desc.BluePrimary[0] = 0.5;
  83. desc.BluePrimary[1] = 0.6;
  84. desc.WhitePoint[0] = 0.7;
  85. desc.WhitePoint[1] = 0.8;
  86. desc.MinLuminance = 0.9;
  87. desc.MaxLuminance = 1.0;
  88. desc.MaxFullFrameLuminance = 100;
  89. AddOutput(desc);
  90. AddAdapter();
  91. DXGI_OUTPUT_DESC1 desc_second = desc;
  92. // Make the second one less bright.
  93. desc_second.RedPrimary[0] = 0.5;
  94. desc_second.MaxLuminance /= 2.0;
  95. AddOutput(desc);
  96. auto helper = CreateHelper();
  97. auto result = helper->GetDisplayMetadata();
  98. EXPECT_TRUE(result);
  99. // From MSDN.
  100. static constexpr int kPrimariesFixedPoint = 50000;
  101. static constexpr int kMinLuminanceFixedPoint = 10000;
  102. EXPECT_EQ(result->RedPrimary[0],
  103. static_cast<int>(desc.RedPrimary[0] * kPrimariesFixedPoint));
  104. EXPECT_EQ(result->RedPrimary[1],
  105. static_cast<int>(desc.RedPrimary[1] * kPrimariesFixedPoint));
  106. EXPECT_EQ(result->GreenPrimary[0],
  107. static_cast<int>(desc.GreenPrimary[0] * kPrimariesFixedPoint));
  108. EXPECT_EQ(result->GreenPrimary[1],
  109. static_cast<int>(desc.GreenPrimary[1] * kPrimariesFixedPoint));
  110. EXPECT_EQ(result->BluePrimary[0],
  111. static_cast<int>(desc.BluePrimary[0] * kPrimariesFixedPoint));
  112. EXPECT_EQ(result->BluePrimary[1],
  113. static_cast<int>(desc.BluePrimary[1] * kPrimariesFixedPoint));
  114. EXPECT_EQ(result->WhitePoint[0],
  115. static_cast<int>(desc.WhitePoint[0] * kPrimariesFixedPoint));
  116. EXPECT_EQ(result->WhitePoint[1],
  117. static_cast<int>(desc.WhitePoint[1] * kPrimariesFixedPoint));
  118. EXPECT_EQ(result->MaxMasteringLuminance,
  119. static_cast<unsigned>(desc.MaxLuminance));
  120. EXPECT_EQ(result->MinMasteringLuminance,
  121. static_cast<unsigned>(desc.MinLuminance * kMinLuminanceFixedPoint));
  122. EXPECT_EQ(result->MaxContentLightLevel, desc.MaxFullFrameLuminance);
  123. EXPECT_EQ(result->MaxFrameAverageLightLevel, desc.MaxFullFrameLuminance);
  124. }
  125. TEST_F(HDRMetadataHelperWinTest, DoesntCacheMetadataIfNotAvailble) {
  126. // Add an empty adapter.
  127. AddAdapter();
  128. auto helper = CreateHelper();
  129. EXPECT_FALSE(helper->GetDisplayMetadata());
  130. }
  131. } // namespace gl