OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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 | |
5 #include <map> | |
6 #include <set> | |
7 | |
8 #include "gpu/command_buffer/service/gpu_tracer.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 #include "ui/gl/gl_mock.h" | |
11 | |
12 namespace gpu { | |
13 namespace gles2 { | |
14 | |
15 using ::gfx::MockGLInterface; | |
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; | |
29 using ::testing::_; | |
30 | |
31 class MockOutputter : public Outputter { | |
32 public: | |
33 MockOutputter() {} | |
34 MOCK_METHOD3(Trace, void(const std::string& name, int64 start_time, | |
35 int64 end_time)); | |
36 | |
37 protected: | |
38 ~MockOutputter() {} | |
39 }; | |
40 | |
41 class GlFakeQueries { | |
42 public: | |
43 GlFakeQueries() { | |
44 } | |
45 | |
46 void Reset() { | |
47 current_time_ = 0; | |
48 next_query_id_ = 23; | |
49 alloced_queries_.clear(); | |
50 query_timestamp_.clear(); | |
51 } | |
52 | |
53 void SetCurrentGLTime(GLint64 current_time) { | |
54 current_time_ = current_time; | |
55 } | |
56 | |
57 void GenQueries(GLsizei n, GLuint* ids) { | |
58 for (GLsizei i = 0; i < n; i++) { | |
59 ids[i] = next_query_id_++; | |
60 alloced_queries_.insert(ids[i]); | |
61 } | |
62 } | |
63 | |
64 void DeleteQueries(GLsizei n, const GLuint* ids) { | |
65 for (GLsizei i = 0; i < n; i++) { | |
66 alloced_queries_.erase(ids[i]); | |
67 query_timestamp_.erase(ids[i]); | |
68 } | |
69 } | |
70 | |
71 void GetQueryObjectiv(GLuint id, GLenum pname, GLint* params) { | |
72 switch (pname) { | |
73 case GL_QUERY_RESULT_AVAILABLE: { | |
74 std::map<GLuint, GLint64>::iterator it = query_timestamp_.find(id); | |
75 if (it != query_timestamp_.end() && it->second <= current_time_) | |
76 *params = 1; | |
77 else | |
78 *params = 0; | |
79 break; | |
80 } | |
81 default: | |
82 ASSERT_TRUE(false); | |
83 } | |
84 } | |
85 | |
86 void QueryCounter(GLuint id, GLenum target) { | |
87 switch (target) { | |
88 case GL_TIMESTAMP: | |
89 ASSERT_TRUE(alloced_queries_.find(id) != alloced_queries_.end()); | |
90 query_timestamp_[id] = current_time_; | |
91 break; | |
92 default: | |
93 ASSERT_TRUE(false); | |
94 } | |
95 } | |
96 | |
97 void GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params) { | |
98 switch (pname) { | |
99 case GL_QUERY_RESULT: | |
100 ASSERT_TRUE(query_timestamp_.find(id) != query_timestamp_.end()); | |
101 *params = query_timestamp_.find(id)->second; | |
102 break; | |
103 default: | |
104 ASSERT_TRUE(false); | |
105 } | |
106 } | |
107 | |
108 protected: | |
109 GLint64 current_time_; | |
110 GLuint next_query_id_; | |
111 std::set<GLuint> alloced_queries_; | |
112 std::map<GLuint, GLint64> query_timestamp_; | |
113 }; | |
114 | |
115 class GpuTracerTest : public testing::Test { | |
116 public: | |
117 GpuTracerTest() { | |
118 } | |
119 | |
120 /////////////////////////////////////////////////////////////////////////// | |
121 | |
122 protected: | |
123 virtual void SetUp() { | |
124 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); | |
125 ::gfx::GLInterface::SetGLInterface(gl_.get()); | |
126 gl_fake_queries_.Reset(); | |
127 } | |
128 | |
129 virtual void TearDown() { | |
130 ::gfx::GLInterface::SetGLInterface(NULL); | |
131 gl_.reset(); | |
132 gl_fake_queries_.Reset(); | |
133 } | |
134 | |
135 void SetupTimerQueryMocks() { | |
136 // Delegate queri APIs used by GLARBTimerTrace to a GlFakeQueries | |
jbauman
2014/01/04 00:24:12
"query"
vmiura
2014/01/07 21:57:20
Done.
| |
137 EXPECT_CALL(*gl_, GenQueries(_, NotNull())) | |
138 .Times(AtLeast(1)) | |
139 .WillOnce(Invoke(&gl_fake_queries_, &GlFakeQueries::GenQueries)); | |
140 | |
141 EXPECT_CALL(*gl_, | |
142 GetQueryObjectiv(_, GL_QUERY_RESULT_AVAILABLE, NotNull())) | |
143 .Times(AtLeast(2)) | |
144 .WillRepeatedly(Invoke(&gl_fake_queries_, | |
145 &GlFakeQueries::GetQueryObjectiv)); | |
146 | |
147 EXPECT_CALL(*gl_, QueryCounter(_, GL_TIMESTAMP)) | |
148 .Times(AtLeast(2)) | |
149 .WillRepeatedly(Invoke(&gl_fake_queries_, | |
150 &GlFakeQueries::QueryCounter)); | |
151 | |
152 EXPECT_CALL(*gl_, | |
153 GetQueryObjectui64v(_, GL_QUERY_RESULT, NotNull())) | |
154 .Times(AtLeast(2)) | |
155 .WillRepeatedly(Invoke(&gl_fake_queries_, | |
156 &GlFakeQueries::GetQueryObjectui64v)); | |
157 | |
158 EXPECT_CALL(*gl_, DeleteQueries(2, NotNull())) | |
159 .Times(AtLeast(1)) | |
160 .WillRepeatedly(Invoke(&gl_fake_queries_, | |
161 &GlFakeQueries::DeleteQueries)); | |
162 } | |
163 | |
164 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; | |
165 GlFakeQueries gl_fake_queries_; | |
166 }; | |
167 | |
168 | |
169 TEST_F(GpuTracerTest, GLARBTimerTrace) { | |
170 // Test basic timer query functionality | |
171 { | |
172 MockOutputter* outputter = new MockOutputter(); | |
173 scoped_refptr<Outputter> outputter_ref = outputter; | |
174 | |
175 SetupTimerQueryMocks(); | |
176 | |
177 // Expected results | |
178 const std::string trace_name("trace_test"); | |
179 const int64 offset_time = 3231; | |
180 const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond; | |
181 const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond; | |
182 const int64 expect_start_time = | |
183 (start_timestamp / base::Time::kNanosecondsPerMicrosecond) | |
184 + offset_time; | |
185 const int64 expect_end_time = | |
186 (end_timestamp / base::Time::kNanosecondsPerMicrosecond) | |
187 + offset_time; | |
188 | |
189 // Expected Outputter::Trace call | |
190 EXPECT_CALL(*outputter, Trace(trace_name, expect_start_time, | |
191 expect_end_time)); | |
192 | |
193 // Construct in place (we're going to reuse the space in the next test) | |
194 scoped_refptr<GLARBTimerTrace> trace = | |
195 new GLARBTimerTrace(outputter_ref, trace_name, offset_time); | |
196 | |
197 gl_fake_queries_.SetCurrentGLTime(start_timestamp); | |
198 trace->Start(); | |
199 | |
200 // Shouldn't be available before End() call | |
201 gl_fake_queries_.SetCurrentGLTime(end_timestamp); | |
202 EXPECT_FALSE(trace->IsAvailable()); | |
203 | |
204 trace->End(); | |
205 | |
206 // Shouldn't be available until the queries complete | |
207 gl_fake_queries_.SetCurrentGLTime(end_timestamp - | |
208 base::Time::kNanosecondsPerMicrosecond); | |
209 EXPECT_FALSE(trace->IsAvailable()); | |
210 | |
211 // Now it should be available | |
212 gl_fake_queries_.SetCurrentGLTime(end_timestamp); | |
213 EXPECT_TRUE(trace->IsAvailable()); | |
214 | |
215 // Proces should output expected Trace results to MockOutputter | |
216 trace->Process(); | |
217 } | |
218 } | |
219 | |
220 } // namespace gles2 | |
221 } // namespace gpu | |
OLD | NEW |