1 // Copyright 2014 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.
8 #include "gpu/command_buffer/service/gpu_service_test.h"
9 #include "gpu/command_buffer/service/gpu_tracer.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/gl/gl_mock.h"
16 using ::testing::InvokeWithoutArgs
;
17 using ::testing::Return
;
18 using ::testing::ReturnRef
;
19 using ::testing::ReturnPointee
;
20 using ::testing::NotNull
;
21 using ::testing::ElementsAreArray
;
22 using ::testing::ElementsAre
;
23 using ::testing::SetArrayArgument
;
24 using ::testing::AtLeast
;
25 using ::testing::SetArgPointee
;
26 using ::testing::Pointee
;
27 using ::testing::Unused
;
28 using ::testing::Invoke
;
31 class MockOutputter
: public Outputter
{
35 void(const std::string
& name
, int64 start_time
, int64 end_time
));
48 alloced_queries_
.clear();
49 query_timestamp_
.clear();
52 void SetCurrentGLTime(GLint64 current_time
) { current_time_
= current_time
; }
54 void GenQueries(GLsizei n
, GLuint
* ids
) {
55 for (GLsizei i
= 0; i
< n
; i
++) {
56 ids
[i
] = next_query_id_
++;
57 alloced_queries_
.insert(ids
[i
]);
61 void DeleteQueries(GLsizei n
, const GLuint
* ids
) {
62 for (GLsizei i
= 0; i
< n
; i
++) {
63 alloced_queries_
.erase(ids
[i
]);
64 query_timestamp_
.erase(ids
[i
]);
68 void GetQueryObjectiv(GLuint id
, GLenum pname
, GLint
* params
) {
70 case GL_QUERY_RESULT_AVAILABLE
: {
71 std::map
<GLuint
, GLint64
>::iterator it
= query_timestamp_
.find(id
);
72 if (it
!= query_timestamp_
.end() && it
->second
<= current_time_
)
83 void QueryCounter(GLuint id
, GLenum target
) {
86 ASSERT_TRUE(alloced_queries_
.find(id
) != alloced_queries_
.end());
87 query_timestamp_
[id
] = current_time_
;
94 void GetQueryObjectui64v(GLuint id
, GLenum pname
, GLuint64
* params
) {
97 ASSERT_TRUE(query_timestamp_
.find(id
) != query_timestamp_
.end());
98 *params
= query_timestamp_
.find(id
)->second
;
106 GLint64 current_time_
;
107 GLuint next_query_id_
;
108 std::set
<GLuint
> alloced_queries_
;
109 std::map
<GLuint
, GLint64
> query_timestamp_
;
112 class GpuTracerTest
: public GpuServiceTest
{
116 ///////////////////////////////////////////////////////////////////////////
119 virtual void SetUp() {
120 GpuServiceTest::SetUp();
121 gl_fake_queries_
.Reset();
124 virtual void TearDown() {
126 gl_fake_queries_
.Reset();
127 GpuServiceTest::TearDown();
130 void SetupTimerQueryMocks() {
131 // Delegate query APIs used by GPUTrace to a GlFakeQueries
132 EXPECT_CALL(*gl_
, GenQueries(_
, NotNull())).Times(AtLeast(1)).WillOnce(
133 Invoke(&gl_fake_queries_
, &GlFakeQueries::GenQueries
));
135 EXPECT_CALL(*gl_
, GetQueryObjectiv(_
, GL_QUERY_RESULT_AVAILABLE
, NotNull()))
138 Invoke(&gl_fake_queries_
, &GlFakeQueries::GetQueryObjectiv
));
140 EXPECT_CALL(*gl_
, QueryCounter(_
, GL_TIMESTAMP
))
143 Invoke(&gl_fake_queries_
, &GlFakeQueries::QueryCounter
));
145 EXPECT_CALL(*gl_
, GetQueryObjectui64v(_
, GL_QUERY_RESULT
, NotNull()))
148 Invoke(&gl_fake_queries_
, &GlFakeQueries::GetQueryObjectui64v
));
150 EXPECT_CALL(*gl_
, DeleteQueries(2, NotNull()))
153 Invoke(&gl_fake_queries_
, &GlFakeQueries::DeleteQueries
));
156 GlFakeQueries gl_fake_queries_
;
159 TEST_F(GpuTracerTest
, GPUTrace
) {
160 // Test basic timer query functionality
162 MockOutputter
* outputter
= new MockOutputter();
163 scoped_refptr
<Outputter
> outputter_ref
= outputter
;
165 SetupTimerQueryMocks();
168 const std::string
trace_name("trace_test");
169 const int64 offset_time
= 3231;
170 const GLint64 start_timestamp
= 7 * base::Time::kNanosecondsPerMicrosecond
;
171 const GLint64 end_timestamp
= 32 * base::Time::kNanosecondsPerMicrosecond
;
172 const int64 expect_start_time
=
173 (start_timestamp
/ base::Time::kNanosecondsPerMicrosecond
) +
175 const int64 expect_end_time
=
176 (end_timestamp
/ base::Time::kNanosecondsPerMicrosecond
) + offset_time
;
178 // Expected Outputter::Trace call
179 EXPECT_CALL(*outputter
,
180 Trace(trace_name
, expect_start_time
, expect_end_time
));
182 scoped_refptr
<GPUTrace
> trace
=
183 new GPUTrace(outputter_ref
, trace_name
, offset_time
);
185 gl_fake_queries_
.SetCurrentGLTime(start_timestamp
);
188 // Shouldn't be available before End() call
189 gl_fake_queries_
.SetCurrentGLTime(end_timestamp
);
190 EXPECT_FALSE(trace
->IsAvailable());
194 // Shouldn't be available until the queries complete
195 gl_fake_queries_
.SetCurrentGLTime(end_timestamp
-
196 base::Time::kNanosecondsPerMicrosecond
);
197 EXPECT_FALSE(trace
->IsAvailable());
199 // Now it should be available
200 gl_fake_queries_
.SetCurrentGLTime(end_timestamp
);
201 EXPECT_TRUE(trace
->IsAvailable());
203 // Proces should output expected Trace results to MockOutputter