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
{
22 cpu_time_bounded_
= false;
25 void TearDown() override
{
27 MockGLInterface::SetGLInterface(NULL
);
28 gfx::ClearGLBindings();
31 cpu_time_bounded_
= false;
34 gpu_timing_fake_queries_
.Reset();
37 void SetupGLContext(const char* gl_version
, const char* gl_extensions
) {
38 ASSERT_FALSE(setup_
) << "Cannot setup GL context twice.";
39 SetGLGetProcAddressProc(MockGLInterface::GetGLProcAddress
);
40 GLSurfaceTestSupport::InitializeOneOffWithMockBindings();
41 gl_
.reset(new ::testing::StrictMock
<MockGLInterface
>());
42 MockGLInterface::SetGLInterface(gl_
.get());
44 context_
= new GLContextStubWithExtensions
;
45 context_
->AddExtensionsString(gl_extensions
);
46 context_
->SetGLVersionString(gl_version
);
47 gpu_timing_fake_queries_
.Reset();
48 GLSurfaceTestSupport::InitializeDynamicMockBindings(context_
.get());
53 scoped_refptr
<GPUTimingClient
> CreateGPUTimingClient() {
55 SetupGLContext("2.0", "");
58 scoped_refptr
<GPUTimingClient
> client
= context_
->CreateGPUTimingClient();
59 if (!cpu_time_bounded_
) {
60 client
->SetCpuTimeForTesting(base::Bind(&GPUTimingFake::GetFakeCPUTime
));
61 cpu_time_bounded_
= true;
68 bool cpu_time_bounded_
= false;
69 scoped_ptr
< ::testing::StrictMock
<MockGLInterface
> > gl_
;
70 scoped_refptr
<GLContextStubWithExtensions
> context_
;
71 GPUTimingFake gpu_timing_fake_queries_
;
74 TEST_F(GPUTimingTest
, FakeTimerTest
) {
75 scoped_refptr
<GPUTimingClient
> gpu_timing_client
= CreateGPUTimingClient();
77 // Tests that we can properly set fake cpu times.
78 gpu_timing_fake_queries_
.SetCurrentCPUTime(123);
79 EXPECT_EQ(123, gpu_timing_client
->GetCurrentCPUTime());
81 base::Callback
<int64_t(void)> empty
;
82 gpu_timing_client
->SetCpuTimeForTesting(empty
);
83 EXPECT_NE(123, gpu_timing_client
->GetCurrentCPUTime());
86 TEST_F(GPUTimingTest
, ForceTimeElapsedQuery
) {
87 // Test that forcing time elapsed query affects all clients.
88 scoped_refptr
<GPUTimingClient
> client1
= CreateGPUTimingClient();
89 EXPECT_FALSE(client1
->IsForceTimeElapsedQuery());
91 scoped_refptr
<GPUTimingClient
> client_force
= CreateGPUTimingClient();
92 EXPECT_FALSE(client1
->IsForceTimeElapsedQuery());
93 client_force
->ForceTimeElapsedQuery();
94 EXPECT_TRUE(client1
->IsForceTimeElapsedQuery());
96 EXPECT_TRUE(client1
->IsForceTimeElapsedQuery());
98 scoped_refptr
<GPUTimingClient
> client2
= CreateGPUTimingClient();
99 EXPECT_TRUE(client2
->IsForceTimeElapsedQuery());
102 TEST_F(GPUTimingTest
, QueryTimeStampTest
) {
103 SetupGLContext("3.2", "GL_ARB_timer_query");
104 scoped_refptr
<GPUTimingClient
> client
= CreateGPUTimingClient();
105 scoped_ptr
<GPUTimer
> gpu_timer
= client
->CreateGPUTimer(false);
107 const int64_t begin_cpu_time
= 123;
108 const int64_t begin_gl_time
= 10 * base::Time::kNanosecondsPerMicrosecond
;
109 const int64_t cpu_gl_offset
=
110 begin_gl_time
/ base::Time::kNanosecondsPerMicrosecond
- begin_cpu_time
;
111 gpu_timing_fake_queries_
.SetCPUGLOffset(cpu_gl_offset
);
112 gpu_timing_fake_queries_
.SetCurrentCPUTime(begin_cpu_time
);
113 gpu_timing_fake_queries_
.ExpectGPUTimeStampQuery(*gl_
, false);
115 gpu_timer
->QueryTimeStamp();
117 gpu_timing_fake_queries_
.SetCurrentCPUTime(begin_cpu_time
- 1);
118 EXPECT_FALSE(gpu_timer
->IsAvailable());
120 gpu_timing_fake_queries_
.SetCurrentCPUTime(begin_cpu_time
);
121 EXPECT_TRUE(gpu_timer
->IsAvailable());
123 gpu_timing_fake_queries_
.SetCurrentCPUTime(begin_cpu_time
+ 1);
124 EXPECT_TRUE(gpu_timer
->IsAvailable());
126 EXPECT_EQ(0, gpu_timer
->GetDeltaElapsed());
129 gpu_timer
->GetStartEndTimestamps(&start
, &end
);
130 EXPECT_EQ(begin_cpu_time
, start
);
131 EXPECT_EQ(begin_cpu_time
, end
);
134 TEST_F(GPUTimingTest
, QueryTimeStampUsingElapsedTest
) {
135 // Test timestamp queries using GL_EXT_timer_query which does not support
136 // timestamp queries. Internally we fall back to time elapsed queries.
137 SetupGLContext("3.2", "GL_EXT_timer_query");
138 scoped_refptr
<GPUTimingClient
> client
= CreateGPUTimingClient();
139 scoped_ptr
<GPUTimer
> gpu_timer
= client
->CreateGPUTimer(false);
140 ASSERT_TRUE(client
->IsForceTimeElapsedQuery());
142 const int64_t begin_cpu_time
= 123;
143 const int64_t begin_gl_time
= 10 * base::Time::kNanosecondsPerMicrosecond
;
144 const int64_t cpu_gl_offset
= begin_gl_time
- begin_cpu_time
;
145 gpu_timing_fake_queries_
.SetCPUGLOffset(cpu_gl_offset
);
146 gpu_timing_fake_queries_
.SetCurrentCPUTime(begin_cpu_time
);
147 gpu_timing_fake_queries_
.ExpectGPUTimeStampQuery(*gl_
, true);
149 gpu_timer
->QueryTimeStamp();
151 gpu_timing_fake_queries_
.SetCurrentCPUTime(begin_cpu_time
- 1);
152 EXPECT_FALSE(gpu_timer
->IsAvailable());
154 gpu_timing_fake_queries_
.SetCurrentCPUTime(begin_cpu_time
+ 1);
155 EXPECT_TRUE(gpu_timer
->IsAvailable());
156 EXPECT_EQ(0, gpu_timer
->GetDeltaElapsed());
159 gpu_timer
->GetStartEndTimestamps(&start
, &end
);
160 EXPECT_EQ(begin_cpu_time
, start
);
161 EXPECT_EQ(begin_cpu_time
, end
);