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.
6 #include "base/memory/scoped_ptr.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/gl/gl_context_stub_with_extensions.h"
9 #include "ui/gl/gl_implementation.h"
10 #include "ui/gl/gl_mock.h"
11 #include "ui/gl/gpu_preference.h"
12 #include "ui/gl/gpu_timing.h"
13 #include "ui/gl/gpu_timing_fake.h"
14 #include "ui/gl/test/gl_surface_test_support.h"
18 class GPUTimingTest
: public testing::Test
{
20 void SetUp() override
{
23 cpu_time_bounded_
= false;
26 void TearDown() override
{
28 MockGLInterface::SetGLInterface(NULL
);
29 gfx::ClearGLBindings();
32 cpu_time_bounded_
= false;
35 gpu_timing_fake_queries_
.Reset();
38 void SetupGLContext(const char* gl_version
, const char* gl_extensions
) {
39 ASSERT_FALSE(setup_
) << "Cannot setup GL context twice.";
40 SetGLGetProcAddressProc(MockGLInterface::GetGLProcAddress
);
41 GLSurfaceTestSupport::InitializeOneOffWithMockBindings();
42 gl_
.reset(new ::testing::StrictMock
<MockGLInterface
>());
43 MockGLInterface::SetGLInterface(gl_
.get());
45 context_
= new GLContextStubWithExtensions
;
46 context_
->AddExtensionsString(gl_extensions
);
47 context_
->SetGLVersionString(gl_version
);
48 gpu_timing_fake_queries_
.Reset();
49 GLSurfaceTestSupport::InitializeDynamicMockBindings(context_
.get());
54 scoped_refptr
<GPUTimingClient
> CreateGPUTimingClient() {
56 SetupGLContext("2.0", "");
59 scoped_refptr
<GPUTimingClient
> client
= context_
->CreateGPUTimingClient();
60 if (!cpu_time_bounded_
) {
61 client
->SetCpuTimeForTesting(base::Bind(&GetFakeCPUTime
));
62 cpu_time_bounded_
= true;
67 void SetFakeCPUTime(int64_t fake_cpu_time
) {
68 fake_cpu_time_
= fake_cpu_time
;
72 static int64_t GetFakeCPUTime() {
73 return fake_cpu_time_
;
76 static int64_t fake_cpu_time_
;
79 bool cpu_time_bounded_
= false;
80 scoped_ptr
< ::testing::StrictMock
<MockGLInterface
> > gl_
;
81 scoped_refptr
<GLContextStubWithExtensions
> context_
;
82 GPUTimingFake gpu_timing_fake_queries_
;
85 int64_t GPUTimingTest::fake_cpu_time_
= 0;
87 TEST_F(GPUTimingTest
, FakeTimerTest
) {
88 // Tests that we can properly set fake cpu times.
91 scoped_refptr
<GPUTimingClient
> gpu_timing_client
= CreateGPUTimingClient();
92 EXPECT_EQ(123, gpu_timing_client
->GetCurrentCPUTime());
94 base::Callback
<int64_t(void)> empty
;
95 gpu_timing_client
->SetCpuTimeForTesting(empty
);
96 EXPECT_NE(123, gpu_timing_client
->GetCurrentCPUTime());
99 TEST_F(GPUTimingTest
, ForceTimeElapsedQuery
) {
100 // Test that forcing time elapsed query affects all clients.
101 scoped_refptr
<GPUTimingClient
> client1
= CreateGPUTimingClient();
102 EXPECT_FALSE(client1
->IsForceTimeElapsedQuery());
104 scoped_refptr
<GPUTimingClient
> client_force
= CreateGPUTimingClient();
105 EXPECT_FALSE(client1
->IsForceTimeElapsedQuery());
106 client_force
->ForceTimeElapsedQuery();
107 EXPECT_TRUE(client1
->IsForceTimeElapsedQuery());
109 EXPECT_TRUE(client1
->IsForceTimeElapsedQuery());
111 scoped_refptr
<GPUTimingClient
> client2
= CreateGPUTimingClient();
112 EXPECT_TRUE(client2
->IsForceTimeElapsedQuery());
115 TEST_F(GPUTimingTest
, QueryTimeStampTest
) {
116 SetupGLContext("3.2", "GL_ARB_timer_query");
117 scoped_refptr
<GPUTimingClient
> client
= CreateGPUTimingClient();
118 scoped_ptr
<GPUTimer
> gpu_timer
= client
->CreateGPUTimer(false);
121 gpu_timing_fake_queries_
.SetCurrentGLTime(
122 10 * base::Time::kNanosecondsPerMicrosecond
);
123 gpu_timing_fake_queries_
.ExpectGPUTimeStampQuery(*gl_
, false);
125 gpu_timer
->QueryTimeStamp();
128 gpu_timing_fake_queries_
.SetCurrentGLTime(
129 9 * base::Time::kNanosecondsPerMicrosecond
);
130 EXPECT_FALSE(gpu_timer
->IsAvailable());
133 gpu_timing_fake_queries_
.SetCurrentGLTime(
134 11 * base::Time::kNanosecondsPerMicrosecond
);
135 EXPECT_TRUE(gpu_timer
->IsAvailable());
136 EXPECT_EQ(0, gpu_timer
->GetDeltaElapsed());
139 gpu_timer
->GetStartEndTimestamps(&start
, &end
);
140 EXPECT_EQ(123, start
);
144 TEST_F(GPUTimingTest
, QueryTimeStampUsingElapsedTest
) {
145 // Test timestamp queries using GL_EXT_timer_query which does not support
146 // timestamp queries. Internally we fall back to time elapsed queries.
147 SetupGLContext("3.2", "GL_EXT_timer_query");
148 scoped_refptr
<GPUTimingClient
> client
= CreateGPUTimingClient();
149 scoped_ptr
<GPUTimer
> gpu_timer
= client
->CreateGPUTimer(false);
150 ASSERT_TRUE(client
->IsForceTimeElapsedQuery());
153 gpu_timing_fake_queries_
.SetCurrentGLTime(
154 10 * base::Time::kNanosecondsPerMicrosecond
);
155 gpu_timing_fake_queries_
.ExpectGPUTimeStampQuery(*gl_
, true);
157 gpu_timer
->QueryTimeStamp();
160 gpu_timing_fake_queries_
.SetCurrentGLTime(
161 9 * base::Time::kNanosecondsPerMicrosecond
);
162 EXPECT_FALSE(gpu_timer
->IsAvailable());
165 gpu_timing_fake_queries_
.SetCurrentGLTime(
166 11 * base::Time::kNanosecondsPerMicrosecond
);
167 EXPECT_TRUE(gpu_timer
->IsAvailable());
168 EXPECT_EQ(0, gpu_timer
->GetDeltaElapsed());
171 gpu_timer
->GetStartEndTimestamps(&start
, &end
);
172 EXPECT_EQ(123, start
);