gl_fence_win_unittest.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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 <d3d11_3.h>
  5. #include "media/base/win/d3d11_mocks.h"
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. #include "ui/gl/gl_fence_win.h"
  8. using ::testing::_;
  9. using ::testing::DoAll;
  10. using ::testing::InSequence;
  11. using ::testing::Return;
  12. using ::testing::SetArgPointee;
  13. namespace gl {
  14. class GLFenceWinTest : public ::testing::Test {
  15. public:
  16. void SetUp() override {
  17. // By default, the D3D11 device, context and fence object will allow
  18. // successful calls to QueryInterface, GetImmediateContext and GetDevice,
  19. // and return objects of the latest interfaces. Tests may override this
  20. // behavior to simulate interfaces which are not available.
  21. ON_CALL(d3d11_device_, QueryInterface(IID_ID3D11Device5, _))
  22. .WillByDefault(media::SetComPointeeAndReturnOk<1>(&d3d11_device_));
  23. ON_CALL(d3d11_device_, GetImmediateContext(_))
  24. .WillByDefault(media::SetComPointee<0>(&d3d11_device_context_));
  25. ON_CALL(d3d11_device_context_, QueryInterface(IID_ID3D11DeviceContext4, _))
  26. .WillByDefault(
  27. media::SetComPointeeAndReturnOk<1>(&d3d11_device_context_));
  28. ON_CALL(d3d11_fence_, GetDevice(_))
  29. .WillByDefault(media::SetComPointee<0>(&d3d11_device_));
  30. }
  31. protected:
  32. media::D3D11DeviceMock d3d11_device_;
  33. media::D3D11DeviceContextMock d3d11_device_context_;
  34. media::D3D11FenceMock d3d11_fence_;
  35. };
  36. // Ensure graceful failure when ID3D11Device5 is not available.
  37. TEST_F(GLFenceWinTest, CreateForGpuFenceNoDevice5) {
  38. EXPECT_CALL(d3d11_device_, QueryInterface(IID_ID3D11Device5, _))
  39. .WillOnce(Return(E_NOINTERFACE));
  40. std::unique_ptr<GLFenceWin> gl_fence_win =
  41. GLFenceWin::CreateForGpuFence(&d3d11_device_);
  42. EXPECT_EQ(gl_fence_win.get(), nullptr);
  43. }
  44. TEST_F(GLFenceWinTest, CreateForGpuFence) {
  45. // Ensure created fences are made with the D3D11_FENCE_FLAG_SHARED flag so
  46. // they can be used across processes.
  47. EXPECT_CALL(d3d11_device_,
  48. CreateFence(0, D3D11_FENCE_FLAG_SHARED, IID_ID3D11Fence, _))
  49. .WillOnce(media::SetComPointeeAndReturnOk<3>(&d3d11_fence_));
  50. // GLFenceWin internally uses base::win::ScopedHandle, which calls global
  51. // functions like CloseHandle to do its job. To avoid mocking ScopedHandle,
  52. // have D3D11FenceMock use a real, closeable event.
  53. const HANDLE mock_handle = ::CreateEvent(nullptr, FALSE, FALSE, nullptr);
  54. // Ensure the share handle is created with the correct read+write flags
  55. // to be shared across processes.
  56. EXPECT_CALL(d3d11_fence_, CreateSharedHandle(nullptr,
  57. DXGI_SHARED_RESOURCE_READ |
  58. DXGI_SHARED_RESOURCE_WRITE,
  59. nullptr, _))
  60. .WillOnce(DoAll(SetArgPointee<3>(mock_handle), Return(S_OK)));
  61. // Ensure we signal the fence with 1 to match the wait in ServerWait.
  62. EXPECT_CALL(d3d11_device_context_, Signal(&d3d11_fence_, 1))
  63. .WillOnce(Return(S_OK));
  64. std::unique_ptr<GLFenceWin> gl_fence_win =
  65. GLFenceWin::CreateForGpuFence(&d3d11_device_);
  66. EXPECT_NE(gl_fence_win.get(), nullptr);
  67. std::unique_ptr<gfx::GpuFence> gpu_fence = gl_fence_win->GetGpuFence();
  68. EXPECT_NE(gpu_fence, nullptr);
  69. EXPECT_FALSE(gpu_fence->GetGpuFenceHandle().is_null());
  70. }
  71. TEST_F(GLFenceWinTest, CreateFromGpuFence) {
  72. // GLFenceWin internally uses base::win::ScopedHandle, which calls global
  73. // functions like CloseHandle to do its job. To avoid mocking ScopedHandle,
  74. // have gfx::GpuFenceHandle use a real, closeable event.
  75. const HANDLE mock_handle = ::CreateEvent(nullptr, FALSE, FALSE, nullptr);
  76. gfx::GpuFenceHandle gpu_fence_handle;
  77. EXPECT_TRUE(gpu_fence_handle.is_null());
  78. gpu_fence_handle.owned_handle.Set(mock_handle);
  79. EXPECT_FALSE(gpu_fence_handle.is_null());
  80. gfx::GpuFence gpu_fence(std::move(gpu_fence_handle));
  81. EXPECT_TRUE(gpu_fence_handle.is_null());
  82. const gfx::GpuFenceHandle& fence_handle_ref = gpu_fence.GetGpuFenceHandle();
  83. EXPECT_EQ(fence_handle_ref.owned_handle.Get(), mock_handle);
  84. EXPECT_FALSE(fence_handle_ref.is_null());
  85. // Ensure that CreateFromGpuFence opens the shared handle.
  86. EXPECT_CALL(d3d11_device_, OpenSharedFence(_, IID_ID3D11Fence, _))
  87. .WillOnce(media::SetComPointeeAndReturnOk<2>(&d3d11_fence_));
  88. std::unique_ptr<GLFenceWin> gl_fence_win =
  89. GLFenceWin::CreateFromGpuFence(&d3d11_device_, gpu_fence);
  90. EXPECT_NE(gl_fence_win.get(), nullptr);
  91. std::unique_ptr<gfx::GpuFence> gpu_fence_out = gl_fence_win->GetGpuFence();
  92. EXPECT_NE(gpu_fence_out, nullptr);
  93. EXPECT_FALSE(gpu_fence_out->GetGpuFenceHandle().is_null());
  94. // Verify that Wait is called with 1 to match the Signal in CreateForGpuFence.
  95. EXPECT_CALL(d3d11_device_context_, Wait(&d3d11_fence_, 1))
  96. .WillOnce(Return(S_OK));
  97. gl_fence_win->ServerWait();
  98. }
  99. } // namespace gl