| 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 |