OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <map> | 5 #include <map> |
6 #include <set> | 6 #include <set> |
7 | 7 |
8 #include "gpu/command_buffer/service/gpu_service_test.h" | 8 #include "gpu/command_buffer/service/gpu_service_test.h" |
9 #include "gpu/command_buffer/service/gpu_tracer.h" | 9 #include "gpu/command_buffer/service/gpu_tracer.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 void Reset() { | 45 void Reset() { |
46 current_time_ = 0; | 46 current_time_ = 0; |
47 next_query_id_ = 23; | 47 next_query_id_ = 23; |
48 alloced_queries_.clear(); | 48 alloced_queries_.clear(); |
49 query_timestamp_.clear(); | 49 query_timestamp_.clear(); |
50 } | 50 } |
51 | 51 |
52 void SetCurrentGLTime(GLint64 current_time) { current_time_ = current_time; } | 52 void SetCurrentGLTime(GLint64 current_time) { current_time_ = current_time; } |
53 | 53 |
54 void GenQueries(GLsizei n, GLuint* ids) { | 54 void GenQueriesARB(GLsizei n, GLuint* ids) { |
55 for (GLsizei i = 0; i < n; i++) { | 55 for (GLsizei i = 0; i < n; i++) { |
56 ids[i] = next_query_id_++; | 56 ids[i] = next_query_id_++; |
57 alloced_queries_.insert(ids[i]); | 57 alloced_queries_.insert(ids[i]); |
58 } | 58 } |
59 } | 59 } |
60 | 60 |
61 void DeleteQueries(GLsizei n, const GLuint* ids) { | 61 void DeleteQueriesARB(GLsizei n, const GLuint* ids) { |
62 for (GLsizei i = 0; i < n; i++) { | 62 for (GLsizei i = 0; i < n; i++) { |
63 alloced_queries_.erase(ids[i]); | 63 alloced_queries_.erase(ids[i]); |
64 query_timestamp_.erase(ids[i]); | 64 query_timestamp_.erase(ids[i]); |
65 } | 65 } |
66 } | 66 } |
67 | 67 |
68 void GetQueryObjectiv(GLuint id, GLenum pname, GLint* params) { | 68 void GetQueryObjectiv(GLuint id, GLenum pname, GLint* params) { |
69 switch (pname) { | 69 switch (pname) { |
70 case GL_QUERY_RESULT_AVAILABLE: { | 70 case GL_QUERY_RESULT_AVAILABLE: { |
71 std::map<GLuint, GLint64>::iterator it = query_timestamp_.find(id); | 71 std::map<GLuint, GLint64>::iterator it = query_timestamp_.find(id); |
72 if (it != query_timestamp_.end() && it->second <= current_time_) | 72 if (it != query_timestamp_.end() && it->second <= current_time_) |
73 *params = 1; | 73 *params = 1; |
74 else | 74 else |
75 *params = 0; | 75 *params = 0; |
76 break; | 76 break; |
77 } | 77 } |
78 default: | 78 default: |
79 ASSERT_TRUE(false); | 79 ASSERT_TRUE(false); |
80 } | 80 } |
81 } | 81 } |
82 | 82 |
| 83 void GetQueryObjectivARB(GLuint id, GLenum pname, GLint* params) { |
| 84 switch (pname) { |
| 85 case GL_QUERY_RESULT_AVAILABLE_EXT: { |
| 86 std::map<GLuint, GLint64>::iterator it = query_timestamp_.find(id); |
| 87 if (it != query_timestamp_.end() && it->second <= current_time_) |
| 88 *params = 1; |
| 89 else |
| 90 *params = 0; |
| 91 break; |
| 92 } |
| 93 default: |
| 94 ASSERT_TRUE(false); |
| 95 } |
| 96 } |
| 97 |
83 void QueryCounter(GLuint id, GLenum target) { | 98 void QueryCounter(GLuint id, GLenum target) { |
84 switch (target) { | 99 switch (target) { |
85 case GL_TIMESTAMP: | 100 case GL_TIMESTAMP: |
86 ASSERT_TRUE(alloced_queries_.find(id) != alloced_queries_.end()); | 101 ASSERT_TRUE(alloced_queries_.find(id) != alloced_queries_.end()); |
87 query_timestamp_[id] = current_time_; | 102 query_timestamp_[id] = current_time_; |
88 break; | 103 break; |
89 default: | 104 default: |
90 ASSERT_TRUE(false); | 105 ASSERT_TRUE(false); |
91 } | 106 } |
92 } | 107 } |
93 | 108 |
94 void GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params) { | 109 void GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params) { |
95 switch (pname) { | 110 switch (pname) { |
96 case GL_QUERY_RESULT: | 111 case GL_QUERY_RESULT: |
97 ASSERT_TRUE(query_timestamp_.find(id) != query_timestamp_.end()); | 112 ASSERT_TRUE(query_timestamp_.find(id) != query_timestamp_.end()); |
98 *params = query_timestamp_.find(id)->second; | 113 *params = query_timestamp_.find(id)->second; |
99 break; | 114 break; |
100 default: | 115 default: |
101 ASSERT_TRUE(false); | 116 ASSERT_TRUE(false); |
102 } | 117 } |
103 } | 118 } |
104 | 119 |
| 120 void GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64* params) { |
| 121 switch (pname) { |
| 122 case GL_QUERY_RESULT_EXT: |
| 123 ASSERT_TRUE(query_timestamp_.find(id) != query_timestamp_.end()); |
| 124 *params = query_timestamp_.find(id)->second; |
| 125 break; |
| 126 default: |
| 127 ASSERT_TRUE(false); |
| 128 } |
| 129 } |
| 130 |
105 protected: | 131 protected: |
106 GLint64 current_time_; | 132 GLint64 current_time_; |
107 GLuint next_query_id_; | 133 GLuint next_query_id_; |
108 std::set<GLuint> alloced_queries_; | 134 std::set<GLuint> alloced_queries_; |
109 std::map<GLuint, GLint64> query_timestamp_; | 135 std::map<GLuint, GLint64> query_timestamp_; |
110 }; | 136 }; |
111 | 137 |
112 class GpuTracerTest : public GpuServiceTest { | 138 class BaseGpuTracerTest : public GpuServiceTest { |
113 public: | 139 public: |
114 GpuTracerTest() {} | 140 BaseGpuTracerTest() {} |
115 | 141 |
116 /////////////////////////////////////////////////////////////////////////// | 142 /////////////////////////////////////////////////////////////////////////// |
117 | 143 |
118 protected: | 144 void DoTraceTest() { |
119 virtual void SetUp() { | |
120 GpuServiceTest::SetUp(); | |
121 gl_fake_queries_.Reset(); | |
122 } | |
123 | |
124 virtual void TearDown() { | |
125 gl_.reset(); | |
126 gl_fake_queries_.Reset(); | |
127 GpuServiceTest::TearDown(); | |
128 } | |
129 | |
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)); | |
134 | |
135 EXPECT_CALL(*gl_, GetQueryObjectiv(_, GL_QUERY_RESULT_AVAILABLE, NotNull())) | |
136 .Times(AtLeast(2)) | |
137 .WillRepeatedly( | |
138 Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectiv)); | |
139 | |
140 EXPECT_CALL(*gl_, QueryCounter(_, GL_TIMESTAMP)) | |
141 .Times(AtLeast(2)) | |
142 .WillRepeatedly( | |
143 Invoke(&gl_fake_queries_, &GlFakeQueries::QueryCounter)); | |
144 | |
145 EXPECT_CALL(*gl_, GetQueryObjectui64v(_, GL_QUERY_RESULT, NotNull())) | |
146 .Times(AtLeast(2)) | |
147 .WillRepeatedly( | |
148 Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectui64v)); | |
149 | |
150 EXPECT_CALL(*gl_, DeleteQueries(2, NotNull())) | |
151 .Times(AtLeast(1)) | |
152 .WillRepeatedly( | |
153 Invoke(&gl_fake_queries_, &GlFakeQueries::DeleteQueries)); | |
154 } | |
155 | |
156 GlFakeQueries gl_fake_queries_; | |
157 }; | |
158 | |
159 TEST_F(GpuTracerTest, GPUTrace) { | |
160 // Test basic timer query functionality | |
161 { | |
162 MockOutputter* outputter = new MockOutputter(); | 145 MockOutputter* outputter = new MockOutputter(); |
163 scoped_refptr<Outputter> outputter_ref = outputter; | 146 scoped_refptr<Outputter> outputter_ref = outputter; |
164 | 147 |
165 SetupTimerQueryMocks(); | 148 SetupTimerQueryMocks(); |
166 | 149 |
167 // Expected results | 150 // Expected results |
168 const std::string trace_name("trace_test"); | 151 const std::string trace_name("trace_test"); |
169 const int64 offset_time = 3231; | 152 const int64 offset_time = 3231; |
170 const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond; | 153 const GLint64 start_timestamp = 7 * base::Time::kNanosecondsPerMicrosecond; |
171 const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond; | 154 const GLint64 end_timestamp = 32 * base::Time::kNanosecondsPerMicrosecond; |
172 const int64 expect_start_time = | 155 const int64 expect_start_time = |
173 (start_timestamp / base::Time::kNanosecondsPerMicrosecond) + | 156 (start_timestamp / base::Time::kNanosecondsPerMicrosecond) + |
174 offset_time; | 157 offset_time; |
175 const int64 expect_end_time = | 158 const int64 expect_end_time = |
176 (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time; | 159 (end_timestamp / base::Time::kNanosecondsPerMicrosecond) + offset_time; |
177 | 160 |
178 // Expected Outputter::Trace call | 161 // Expected Outputter::Trace call |
179 EXPECT_CALL(*outputter, | 162 EXPECT_CALL(*outputter, |
180 Trace(trace_name, expect_start_time, expect_end_time)); | 163 Trace(trace_name, expect_start_time, expect_end_time)); |
181 | 164 |
182 scoped_refptr<GPUTrace> trace = | 165 scoped_refptr<GPUTrace> trace = |
183 new GPUTrace(outputter_ref, trace_name, offset_time); | 166 new GPUTrace(outputter_ref, trace_name, offset_time, |
| 167 GetTracerType()); |
184 | 168 |
185 gl_fake_queries_.SetCurrentGLTime(start_timestamp); | 169 gl_fake_queries_.SetCurrentGLTime(start_timestamp); |
186 trace->Start(); | 170 trace->Start(); |
187 | 171 |
188 // Shouldn't be available before End() call | 172 // Shouldn't be available before End() call |
189 gl_fake_queries_.SetCurrentGLTime(end_timestamp); | 173 gl_fake_queries_.SetCurrentGLTime(end_timestamp); |
190 EXPECT_FALSE(trace->IsAvailable()); | 174 EXPECT_FALSE(trace->IsAvailable()); |
191 | 175 |
192 trace->End(); | 176 trace->End(); |
193 | 177 |
194 // Shouldn't be available until the queries complete | 178 // Shouldn't be available until the queries complete |
195 gl_fake_queries_.SetCurrentGLTime(end_timestamp - | 179 gl_fake_queries_.SetCurrentGLTime(end_timestamp - |
196 base::Time::kNanosecondsPerMicrosecond); | 180 base::Time::kNanosecondsPerMicrosecond); |
197 EXPECT_FALSE(trace->IsAvailable()); | 181 EXPECT_FALSE(trace->IsAvailable()); |
198 | 182 |
199 // Now it should be available | 183 // Now it should be available |
200 gl_fake_queries_.SetCurrentGLTime(end_timestamp); | 184 gl_fake_queries_.SetCurrentGLTime(end_timestamp); |
201 EXPECT_TRUE(trace->IsAvailable()); | 185 EXPECT_TRUE(trace->IsAvailable()); |
202 | 186 |
203 // Proces should output expected Trace results to MockOutputter | 187 // Proces should output expected Trace results to MockOutputter |
204 trace->Process(); | 188 trace->Process(); |
205 } | 189 } |
| 190 |
| 191 protected: |
| 192 virtual void SetUp() { |
| 193 GpuServiceTest::SetUp(); |
| 194 gl_fake_queries_.Reset(); |
| 195 } |
| 196 |
| 197 virtual void TearDown() { |
| 198 gl_.reset(); |
| 199 gl_fake_queries_.Reset(); |
| 200 GpuServiceTest::TearDown(); |
| 201 } |
| 202 |
| 203 virtual void SetupTimerQueryMocks() = 0; |
| 204 |
| 205 virtual GpuTracerType GetTracerType() = 0; |
| 206 |
| 207 GlFakeQueries gl_fake_queries_; |
| 208 }; |
| 209 |
| 210 class GpuARBTimerTracerTest : public BaseGpuTracerTest { |
| 211 protected: |
| 212 virtual void SetupTimerQueryMocks() OVERRIDE { |
| 213 // Delegate query APIs used by GPUTrace to a GlFakeQueries |
| 214 EXPECT_CALL(*gl_, GenQueriesARB(_, NotNull())).Times(AtLeast(1)).WillOnce( |
| 215 Invoke(&gl_fake_queries_, &GlFakeQueries::GenQueriesARB)); |
| 216 |
| 217 EXPECT_CALL(*gl_, GetQueryObjectiv(_, GL_QUERY_RESULT_AVAILABLE, NotNull())) |
| 218 .Times(AtLeast(2)) |
| 219 .WillRepeatedly( |
| 220 Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectiv)); |
| 221 |
| 222 EXPECT_CALL(*gl_, QueryCounter(_, GL_TIMESTAMP)) |
| 223 .Times(AtLeast(2)) |
| 224 .WillRepeatedly( |
| 225 Invoke(&gl_fake_queries_, &GlFakeQueries::QueryCounter)); |
| 226 |
| 227 EXPECT_CALL(*gl_, GetQueryObjectui64v(_, GL_QUERY_RESULT, NotNull())) |
| 228 .Times(AtLeast(2)) |
| 229 .WillRepeatedly( |
| 230 Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectui64v)); |
| 231 |
| 232 EXPECT_CALL(*gl_, DeleteQueriesARB(2, NotNull())) |
| 233 .Times(AtLeast(1)) |
| 234 .WillRepeatedly( |
| 235 Invoke(&gl_fake_queries_, &GlFakeQueries::DeleteQueriesARB)); |
| 236 } |
| 237 |
| 238 virtual GpuTracerType GetTracerType() OVERRIDE { |
| 239 return kTracerTypeARBTimer; |
| 240 } |
| 241 }; |
| 242 |
| 243 class GpuDisjointTimerTracerTest : public BaseGpuTracerTest { |
| 244 protected: |
| 245 virtual void SetupTimerQueryMocks() OVERRIDE { |
| 246 // Delegate query APIs used by GPUTrace to a GlFakeQueries |
| 247 EXPECT_CALL(*gl_, GenQueriesARB(_, NotNull())).Times(AtLeast(1)).WillOnce( |
| 248 Invoke(&gl_fake_queries_, &GlFakeQueries::GenQueriesARB)); |
| 249 |
| 250 EXPECT_CALL(*gl_, GetQueryObjectivARB(_, GL_QUERY_RESULT_AVAILABLE_EXT, |
| 251 NotNull())) |
| 252 .Times(AtLeast(2)) |
| 253 .WillRepeatedly( |
| 254 Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectivARB)); |
| 255 |
| 256 EXPECT_CALL(*gl_, QueryCounter(_, GL_TIMESTAMP_EXT)) |
| 257 .Times(AtLeast(2)) |
| 258 .WillRepeatedly( |
| 259 Invoke(&gl_fake_queries_, &GlFakeQueries::QueryCounter)); |
| 260 |
| 261 EXPECT_CALL(*gl_, GetQueryObjectui64vEXT(_, GL_QUERY_RESULT_EXT, NotNull())) |
| 262 .Times(AtLeast(2)) |
| 263 .WillRepeatedly( |
| 264 Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectui64vEXT)); |
| 265 |
| 266 EXPECT_CALL(*gl_, DeleteQueriesARB(2, NotNull())) |
| 267 .Times(AtLeast(1)) |
| 268 .WillRepeatedly( |
| 269 Invoke(&gl_fake_queries_, &GlFakeQueries::DeleteQueriesARB)); |
| 270 } |
| 271 |
| 272 virtual GpuTracerType GetTracerType() OVERRIDE { |
| 273 return kTracerTypeDisjointTimer; |
| 274 } |
| 275 }; |
| 276 |
| 277 TEST_F(GpuARBTimerTracerTest, GPUTrace) { |
| 278 // Test basic timer query functionality |
| 279 { |
| 280 DoTraceTest(); |
| 281 } |
| 282 } |
| 283 |
| 284 TEST_F(GpuDisjointTimerTracerTest, GPUTrace) { |
| 285 // Test basic timer query functionality |
| 286 { |
| 287 DoTraceTest(); |
| 288 } |
206 } | 289 } |
207 | 290 |
208 } // namespace gles2 | 291 } // namespace gles2 |
209 } // namespace gpu | 292 } // namespace gpu |
OLD | NEW |