gpu_timing_unittest.cc 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // Copyright 2015 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/gpu_timing.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include "base/bind.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/time/time.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. #include "ui/gl/gl_context_stub.h"
  12. #include "ui/gl/gl_implementation.h"
  13. #include "ui/gl/gl_mock.h"
  14. #include "ui/gl/gl_surface_stub.h"
  15. #include "ui/gl/gpu_preference.h"
  16. #include "ui/gl/gpu_timing_fake.h"
  17. #include "ui/gl/init/gl_factory.h"
  18. #include "ui/gl/test/gl_surface_test_support.h"
  19. namespace gl {
  20. using ::testing::Exactly;
  21. using ::testing::NotNull;
  22. using ::testing::DoAll;
  23. using ::testing::Return;
  24. using ::testing::SetArgPointee;
  25. class GPUTimingTest : public testing::Test {
  26. public:
  27. void SetUp() override {
  28. setup_ = false;
  29. cpu_time_bounded_ = false;
  30. }
  31. void TearDown() override {
  32. context_ = nullptr;
  33. surface_ = nullptr;
  34. if (setup_) {
  35. MockGLInterface::SetGLInterface(nullptr);
  36. GLSurfaceTestSupport::ShutdownGL(display_);
  37. }
  38. setup_ = false;
  39. cpu_time_bounded_ = false;
  40. gl_.reset();
  41. gpu_timing_fake_queries_.Reset();
  42. }
  43. void SetupGLContext(const char* gl_version, const char* gl_extensions) {
  44. ASSERT_FALSE(setup_) << "Cannot setup GL context twice.";
  45. SetGLGetProcAddressProc(MockGLInterface::GetGLProcAddress);
  46. display_ = GLSurfaceTestSupport::InitializeOneOffWithMockBindings();
  47. gl_ = std::make_unique<::testing::StrictMock<MockGLInterface>>();
  48. MockGLInterface::SetGLInterface(gl_.get());
  49. context_ = new GLContextStub;
  50. context_->SetExtensionsString(gl_extensions);
  51. context_->SetGLVersionString(gl_version);
  52. surface_ = new GLSurfaceStub;
  53. context_->MakeCurrent(surface_.get());
  54. gpu_timing_fake_queries_.Reset();
  55. setup_ = true;
  56. }
  57. scoped_refptr<GPUTimingClient> CreateGPUTimingClient() {
  58. if (!setup_) {
  59. SetupGLContext("2.0", "");
  60. }
  61. scoped_refptr<GPUTimingClient> client = context_->CreateGPUTimingClient();
  62. if (!cpu_time_bounded_) {
  63. client->SetCpuTimeForTesting(
  64. base::BindRepeating(&GPUTimingFake::GetFakeCPUTime));
  65. cpu_time_bounded_ = true;
  66. }
  67. return client;
  68. }
  69. protected:
  70. bool setup_ = false;
  71. bool cpu_time_bounded_ = false;
  72. std::unique_ptr<::testing::StrictMock<MockGLInterface>> gl_;
  73. scoped_refptr<GLContextStub> context_;
  74. scoped_refptr<GLSurfaceStub> surface_;
  75. GPUTimingFake gpu_timing_fake_queries_;
  76. raw_ptr<GLDisplay> display_ = nullptr;
  77. };
  78. TEST_F(GPUTimingTest, FakeTimerTest) {
  79. scoped_refptr<GPUTimingClient> gpu_timing_client = CreateGPUTimingClient();
  80. // Tests that we can properly set fake cpu times.
  81. gpu_timing_fake_queries_.SetCurrentCPUTime(123);
  82. EXPECT_EQ(123, gpu_timing_client->GetCurrentCPUTime());
  83. base::RepeatingCallback<int64_t(void)> empty;
  84. gpu_timing_client->SetCpuTimeForTesting(empty);
  85. EXPECT_NE(123, gpu_timing_client->GetCurrentCPUTime());
  86. }
  87. TEST_F(GPUTimingTest, ForceTimeElapsedQuery) {
  88. // Test that forcing time elapsed query affects all clients.
  89. SetupGLContext("3.2", "GL_ARB_timer_query");
  90. scoped_refptr<GPUTimingClient> client1 = CreateGPUTimingClient();
  91. EXPECT_FALSE(client1->IsForceTimeElapsedQuery());
  92. scoped_refptr<GPUTimingClient> client_force = CreateGPUTimingClient();
  93. EXPECT_FALSE(client1->IsForceTimeElapsedQuery());
  94. client_force->ForceTimeElapsedQuery();
  95. EXPECT_TRUE(client1->IsForceTimeElapsedQuery());
  96. EXPECT_TRUE(client1->IsForceTimeElapsedQuery());
  97. scoped_refptr<GPUTimingClient> client2 = CreateGPUTimingClient();
  98. EXPECT_TRUE(client2->IsForceTimeElapsedQuery());
  99. }
  100. TEST_F(GPUTimingTest, QueryTimeStampTest) {
  101. SetupGLContext("3.2", "GL_ARB_timer_query");
  102. scoped_refptr<GPUTimingClient> client = CreateGPUTimingClient();
  103. std::unique_ptr<GPUTimer> gpu_timer = client->CreateGPUTimer(false);
  104. const int64_t begin_cpu_time = 1230;
  105. const int64_t begin_gl_time = 10 * base::Time::kNanosecondsPerMicrosecond;
  106. const int64_t cpu_gl_offset =
  107. begin_gl_time / base::Time::kNanosecondsPerMicrosecond - begin_cpu_time;
  108. gpu_timing_fake_queries_.SetCPUGLOffset(cpu_gl_offset);
  109. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time);
  110. gpu_timing_fake_queries_.ExpectGPUTimeStampQuery(*gl_, false);
  111. gpu_timer->QueryTimeStamp();
  112. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time - 1);
  113. EXPECT_FALSE(gpu_timer->IsAvailable());
  114. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time);
  115. EXPECT_TRUE(gpu_timer->IsAvailable());
  116. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time + 1);
  117. EXPECT_TRUE(gpu_timer->IsAvailable());
  118. EXPECT_EQ(0, gpu_timer->GetDeltaElapsed());
  119. int64_t start, end;
  120. gpu_timer->GetStartEndTimestamps(&start, &end);
  121. EXPECT_EQ(begin_cpu_time, start);
  122. EXPECT_EQ(begin_cpu_time, end);
  123. }
  124. TEST_F(GPUTimingTest, QueryTimeStampUsingElapsedTest) {
  125. // Test timestamp queries using GL_EXT_timer_query which does not support
  126. // timestamp queries. Internally we fall back to time elapsed queries.
  127. SetupGLContext("3.2", "GL_EXT_timer_query");
  128. scoped_refptr<GPUTimingClient> client = CreateGPUTimingClient();
  129. std::unique_ptr<GPUTimer> gpu_timer = client->CreateGPUTimer(false);
  130. ASSERT_TRUE(client->IsForceTimeElapsedQuery());
  131. const int64_t begin_cpu_time = 123;
  132. const int64_t begin_gl_time = 10 * base::Time::kNanosecondsPerMicrosecond;
  133. const int64_t cpu_gl_offset = begin_gl_time - begin_cpu_time;
  134. gpu_timing_fake_queries_.SetCPUGLOffset(cpu_gl_offset);
  135. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time);
  136. gpu_timing_fake_queries_.ExpectGPUTimeStampQuery(*gl_, true);
  137. gpu_timer->QueryTimeStamp();
  138. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time - 1);
  139. EXPECT_FALSE(gpu_timer->IsAvailable());
  140. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time + 1);
  141. EXPECT_TRUE(gpu_timer->IsAvailable());
  142. EXPECT_EQ(0, gpu_timer->GetDeltaElapsed());
  143. int64_t start, end;
  144. gpu_timer->GetStartEndTimestamps(&start, &end);
  145. EXPECT_EQ(begin_cpu_time, start);
  146. EXPECT_EQ(begin_cpu_time, end);
  147. }
  148. TEST_F(GPUTimingTest, QueryTimestampUsingElapsedARBTest) {
  149. // Test timestamp queries on platforms with GL_ARB_timer_query but still lack
  150. // support for timestamp queries
  151. SetupGLContext("3.2", "GL_ARB_timer_query");
  152. scoped_refptr<GPUTimingClient> client = CreateGPUTimingClient();
  153. std::unique_ptr<GPUTimer> gpu_timer = client->CreateGPUTimer(false);
  154. const int64_t begin_cpu_time = 123;
  155. const int64_t begin_gl_time = 10 * base::Time::kNanosecondsPerMicrosecond;
  156. const int64_t cpu_gl_offset = begin_gl_time - begin_cpu_time;
  157. gpu_timing_fake_queries_.SetCPUGLOffset(cpu_gl_offset);
  158. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time);
  159. gpu_timing_fake_queries_.ExpectGPUTimeStampQuery(*gl_, true);
  160. // Custom mock override to ensure the timestamp bits are 0
  161. EXPECT_CALL(*gl_, GetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, NotNull()))
  162. .Times(Exactly(1))
  163. .WillRepeatedly(DoAll(SetArgPointee<2>(0), Return()));
  164. gpu_timer->QueryTimeStamp();
  165. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time - 1);
  166. EXPECT_FALSE(gpu_timer->IsAvailable());
  167. gpu_timing_fake_queries_.SetCurrentCPUTime(begin_cpu_time + 1);
  168. EXPECT_TRUE(gpu_timer->IsAvailable());
  169. EXPECT_EQ(0, gpu_timer->GetDeltaElapsed());
  170. int64_t start, end;
  171. gpu_timer->GetStartEndTimestamps(&start, &end);
  172. // Force time elapsed won't be set until a query is actually attempted
  173. ASSERT_TRUE(client->IsForceTimeElapsedQuery());
  174. EXPECT_EQ(begin_cpu_time, start);
  175. EXPECT_EQ(begin_cpu_time, end);
  176. }
  177. } // namespace gl