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.
5 #include "ui/gl/gpu_timing_fake.h"
7 #include "base/time/time.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/gl/gl_mock.h"
14 using ::testing::AtLeast
;
15 using ::testing::AtMost
;
16 using ::testing::Exactly
;
17 using ::testing::Invoke
;
18 using ::testing::NotNull
;
20 int64_t GPUTimingFake::fake_cpu_time_
= 0;
22 GPUTimingFake::GPUTimingFake() {
26 GPUTimingFake::~GPUTimingFake() {
29 void GPUTimingFake::Reset() {
31 gl_cpu_time_offset_
= 0;
33 allocated_queries_
.clear();
34 query_results_
.clear();
35 current_elapsed_query_
.Reset();
40 int64_t GPUTimingFake::GetFakeCPUTime() {
41 return fake_cpu_time_
;
44 void GPUTimingFake::SetCPUGLOffset(int64_t offset
) {
45 gl_cpu_time_offset_
= offset
;
48 void GPUTimingFake::SetCurrentCPUTime(int64_t current_time
) {
49 fake_cpu_time_
= current_time
;
50 current_gl_time_
= (fake_cpu_time_
+ gl_cpu_time_offset_
) *
51 base::Time::kNanosecondsPerMicrosecond
;
54 void GPUTimingFake::SetCurrentGLTime(GLint64 current_time
) {
55 current_gl_time_
= current_time
;
56 fake_cpu_time_
= (current_gl_time_
/ base::Time::kNanosecondsPerMicrosecond
) -
60 void GPUTimingFake::SetDisjoint() {
64 void GPUTimingFake::ExpectGetErrorCalls(MockGLInterface
& gl
) {
65 EXPECT_CALL(gl
, GetError()).Times(AtLeast(0))
66 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLGetError
));
69 void GPUTimingFake::ExpectDisjointCalls(MockGLInterface
& gl
) {
70 EXPECT_CALL(gl
, GetIntegerv(GL_GPU_DISJOINT_EXT
, _
)).Times(AtLeast(1))
71 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLGetIntegerv
));
74 void GPUTimingFake::ExpectNoDisjointCalls(MockGLInterface
& gl
) {
75 EXPECT_CALL(gl
, GetIntegerv(GL_GPU_DISJOINT_EXT
, _
)).Times(Exactly(0));
78 void GPUTimingFake::ExpectGPUTimeStampQuery(
79 MockGLInterface
& gl
, bool elapsed_query
) {
80 EXPECT_CALL(gl
, GenQueries(1, NotNull())).Times(Exactly(1))
81 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLGenQueries
));
84 // Time Stamp based queries.
85 EXPECT_CALL(gl
, GetInteger64v(GL_TIMESTAMP
, _
))
87 Invoke(this, &GPUTimingFake::FakeGLGetInteger64v
));
89 EXPECT_CALL(gl
, QueryCounter(_
, GL_TIMESTAMP
)).Times(Exactly(1))
91 Invoke(this, &GPUTimingFake::FakeGLQueryCounter
));
93 // Time Elapsed based queries.
94 EXPECT_CALL(gl
, BeginQuery(GL_TIME_ELAPSED
, _
)).Times(Exactly(1))
96 Invoke(this, &GPUTimingFake::FakeGLBeginQuery
));
98 EXPECT_CALL(gl
, EndQuery(GL_TIME_ELAPSED
)).Times(Exactly(1))
99 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLEndQuery
));
102 EXPECT_CALL(gl
, GetQueryObjectuiv(_
, GL_QUERY_RESULT_AVAILABLE
,
105 Invoke(this, &GPUTimingFake::FakeGLGetQueryObjectuiv
));
107 EXPECT_CALL(gl
, GetQueryObjectui64v(_
, GL_QUERY_RESULT
, NotNull()))
109 Invoke(this, &GPUTimingFake::FakeGLGetQueryObjectui64v
));
111 EXPECT_CALL(gl
, DeleteQueries(1, NotNull())).Times(AtLeast(1))
113 Invoke(this, &GPUTimingFake::FakeGLDeleteQueries
));
116 void GPUTimingFake::ExpectGPUTimerQuery(
117 MockGLInterface
& gl
, bool elapsed_query
) {
118 EXPECT_CALL(gl
, GenQueries(1, NotNull()))
119 .Times(AtLeast(elapsed_query
? 1 : 2))
120 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLGenQueries
));
122 if (!elapsed_query
) {
123 // Time Stamp based queries.
124 EXPECT_CALL(gl
, GetInteger64v(GL_TIMESTAMP
, _
))
126 Invoke(this, &GPUTimingFake::FakeGLGetInteger64v
));
128 EXPECT_CALL(gl
, QueryCounter(_
, GL_TIMESTAMP
)).Times(AtLeast(1))
130 Invoke(this, &GPUTimingFake::FakeGLQueryCounter
));
133 // Time Elapsed based queries.
134 EXPECT_CALL(gl
, BeginQuery(GL_TIME_ELAPSED
, _
))
136 Invoke(this, &GPUTimingFake::FakeGLBeginQuery
));
138 EXPECT_CALL(gl
, EndQuery(GL_TIME_ELAPSED
))
139 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLEndQuery
));
141 EXPECT_CALL(gl
, GetQueryObjectuiv(_
, GL_QUERY_RESULT_AVAILABLE
,
144 Invoke(this, &GPUTimingFake::FakeGLGetQueryObjectuiv
));
146 EXPECT_CALL(gl
, GetQueryObjectui64v(_
, GL_QUERY_RESULT
, NotNull()))
148 Invoke(this, &GPUTimingFake::FakeGLGetQueryObjectui64v
));
150 EXPECT_CALL(gl
, DeleteQueries(1, NotNull()))
151 .Times(AtLeast(elapsed_query
? 1 : 2))
153 Invoke(this, &GPUTimingFake::FakeGLDeleteQueries
));
156 void GPUTimingFake::ExpectOffsetCalculationQuery(
157 MockGLInterface
& gl
) {
158 EXPECT_CALL(gl
, GetInteger64v(GL_TIMESTAMP
, NotNull()))
161 Invoke(this, &GPUTimingFake::FakeGLGetInteger64v
));
164 void GPUTimingFake::ExpectNoOffsetCalculationQuery(
165 MockGLInterface
& gl
) {
166 EXPECT_CALL(gl
, GetInteger64v(GL_TIMESTAMP
, NotNull())).Times(Exactly(0));
169 void GPUTimingFake::FakeGLGenQueries(GLsizei n
, GLuint
* ids
) {
170 for (GLsizei i
= 0; i
< n
; i
++) {
171 ids
[i
] = next_query_id_
++;
172 allocated_queries_
.insert(ids
[i
]);
176 void GPUTimingFake::FakeGLDeleteQueries(GLsizei n
, const GLuint
* ids
) {
177 for (GLsizei i
= 0; i
< n
; i
++) {
178 allocated_queries_
.erase(ids
[i
]);
179 query_results_
.erase(ids
[i
]);
180 if (current_elapsed_query_
.query_id_
== ids
[i
])
181 current_elapsed_query_
.Reset();
185 void GPUTimingFake::FakeGLBeginQuery(GLenum target
, GLuint id
) {
187 case GL_TIME_ELAPSED
:
188 ASSERT_FALSE(current_elapsed_query_
.active_
);
189 current_elapsed_query_
.Reset();
190 current_elapsed_query_
.active_
= true;
191 current_elapsed_query_
.query_id_
= id
;
192 current_elapsed_query_
.begin_time_
= current_gl_time_
;
195 FAIL() << "Invalid target passed to BeginQuery: " << target
;
199 void GPUTimingFake::FakeGLEndQuery(GLenum target
) {
201 case GL_TIME_ELAPSED
: {
202 ASSERT_TRUE(current_elapsed_query_
.active_
);
203 QueryResult
& query
= query_results_
[current_elapsed_query_
.query_id_
];
204 query
.type_
= QueryResult::kQueryResultType_Elapsed
;
205 query
.begin_time_
= current_elapsed_query_
.begin_time_
;
206 query
.value_
= current_gl_time_
;
207 current_elapsed_query_
.active_
= false;
210 FAIL() << "Invalid target passed to BeginQuery: " << target
;
214 void GPUTimingFake::FakeGLGetQueryObjectuiv(GLuint id
, GLenum pname
,
217 case GL_QUERY_RESULT_AVAILABLE
: {
218 std::map
<GLuint
, QueryResult
>::iterator it
= query_results_
.find(id
);
219 if (it
!= query_results_
.end() && it
->second
.value_
<= current_gl_time_
)
225 FAIL() << "Invalid variable passed to GetQueryObjectuiv: " << pname
;
229 void GPUTimingFake::FakeGLQueryCounter(GLuint id
, GLenum target
) {
232 ASSERT_TRUE(allocated_queries_
.find(id
) != allocated_queries_
.end());
233 QueryResult
& query
= query_results_
[id
];
234 query
.type_
= QueryResult::kQueryResultType_TimeStamp
;
235 query
.value_
= current_gl_time_
;
239 FAIL() << "Invalid variable passed to QueryCounter: " << target
;
243 void GPUTimingFake::FakeGLGetInteger64v(GLenum pname
, GLint64
* data
) {
246 *data
= current_gl_time_
;
249 FAIL() << "Invalid variable passed to GetInteger64v: " << pname
;
253 void GPUTimingFake::FakeGLGetQueryObjectui64v(GLuint id
, GLenum pname
,
256 case GL_QUERY_RESULT
: {
257 std::map
<GLuint
, QueryResult
>::iterator it
= query_results_
.find(id
);
258 ASSERT_TRUE(it
!= query_results_
.end());
259 switch (it
->second
.type_
) {
260 case QueryResult::kQueryResultType_TimeStamp
:
261 *params
= it
->second
.value_
;
263 case QueryResult::kQueryResultType_Elapsed
:
264 *params
= it
->second
.value_
- it
->second
.begin_time_
;
267 FAIL() << "Invalid Query Result Type: " << it
->second
.type_
;
271 FAIL() << "Invalid variable passed to GetQueryObjectui64v: " << pname
;
275 void GPUTimingFake::FakeGLGetIntegerv(GLenum pname
, GLint
* params
) {
277 case GL_GPU_DISJOINT_EXT
:
278 *params
= static_cast<GLint
>(disjointed_
);
282 FAIL() << "Invalid variable passed to GetIntegerv: " << pname
;
286 GLenum
GPUTimingFake::FakeGLGetError() {