OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "ui/gl/gpu_timing_fake.h" |
| 6 |
| 7 #include "testing/gtest/include/gtest/gtest.h" |
| 8 #include "ui/gl/gl_mock.h" |
| 9 |
| 10 namespace gfx { |
| 11 |
| 12 using ::testing::_; |
| 13 using ::testing::AtLeast; |
| 14 using ::testing::AtMost; |
| 15 using ::testing::Exactly; |
| 16 using ::testing::Invoke; |
| 17 using ::testing::NotNull; |
| 18 |
| 19 GPUTimingFake::GPUTimingFake() { |
| 20 Reset(); |
| 21 } |
| 22 |
| 23 GPUTimingFake::~GPUTimingFake() { |
| 24 } |
| 25 |
| 26 void GPUTimingFake::Reset() { |
| 27 current_time_ = 0; |
| 28 next_query_id_ = 23; |
| 29 allocated_queries_.clear(); |
| 30 query_results_.clear(); |
| 31 current_elapsed_query_.Reset(); |
| 32 } |
| 33 |
| 34 void GPUTimingFake::SetCurrentGLTime(GLint64 current_time) { |
| 35 current_time_ = current_time; |
| 36 } |
| 37 |
| 38 void GPUTimingFake::SetDisjoint() { |
| 39 disjointed_ = true; |
| 40 } |
| 41 |
| 42 void GPUTimingFake::ExpectGetErrorCalls(MockGLInterface& gl) { |
| 43 EXPECT_CALL(gl, GetError()).Times(AtLeast(0)) |
| 44 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLGetError)); |
| 45 } |
| 46 |
| 47 void GPUTimingFake::ExpectDisjointCalls(MockGLInterface& gl) { |
| 48 EXPECT_CALL(gl, GetIntegerv(GL_GPU_DISJOINT_EXT, _)).Times(AtLeast(1)) |
| 49 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLGetIntegerv)); |
| 50 } |
| 51 |
| 52 void GPUTimingFake::ExpectNoDisjointCalls(MockGLInterface& gl) { |
| 53 EXPECT_CALL(gl, GetIntegerv(GL_GPU_DISJOINT_EXT, _)).Times(Exactly(0)); |
| 54 } |
| 55 |
| 56 void GPUTimingFake::ExpectGPUTimerQuery( |
| 57 MockGLInterface& gl, bool elapsed_query) { |
| 58 if (elapsed_query) { |
| 59 // Currently do not support elapsed queries. |
| 60 return; |
| 61 } |
| 62 |
| 63 EXPECT_CALL(gl, GenQueries(2, NotNull())).Times(AtLeast(1)) |
| 64 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLGenQueries)); |
| 65 |
| 66 if (elapsed_query) { |
| 67 // Time Elapsed based queries. |
| 68 EXPECT_CALL(gl, BeginQuery(GL_TIME_ELAPSED, _)) |
| 69 .WillRepeatedly( |
| 70 Invoke(this, &GPUTimingFake::FakeGLBeginQuery)); |
| 71 |
| 72 EXPECT_CALL(gl, EndQuery(GL_TIME_ELAPSED)) |
| 73 .WillRepeatedly(Invoke(this, &GPUTimingFake::FakeGLEndQuery)); |
| 74 } else { |
| 75 // Time Stamp based queries. |
| 76 EXPECT_CALL(gl, GetInteger64v(GL_TIMESTAMP, _)) |
| 77 .WillRepeatedly( |
| 78 Invoke(this, &GPUTimingFake::FakeGLGetInteger64v)); |
| 79 |
| 80 EXPECT_CALL(gl, QueryCounter(_, GL_TIMESTAMP)).Times(AtLeast(2)) |
| 81 .WillRepeatedly( |
| 82 Invoke(this, &GPUTimingFake::FakeGLQueryCounter)); |
| 83 } |
| 84 |
| 85 EXPECT_CALL(gl, GetQueryObjectiv(_, GL_QUERY_RESULT_AVAILABLE, |
| 86 NotNull())) |
| 87 .WillRepeatedly( |
| 88 Invoke(this, &GPUTimingFake::FakeGLGetQueryObjectiv)); |
| 89 |
| 90 EXPECT_CALL(gl, GetQueryObjectui64v(_, GL_QUERY_RESULT, NotNull())) |
| 91 .WillRepeatedly( |
| 92 Invoke(this, &GPUTimingFake::FakeGLGetQueryObjectui64v)); |
| 93 |
| 94 EXPECT_CALL(gl, DeleteQueries(2, NotNull())).Times(AtLeast(1)) |
| 95 .WillRepeatedly( |
| 96 Invoke(this, &GPUTimingFake::FakeGLDeleteQueries)); |
| 97 } |
| 98 |
| 99 void GPUTimingFake::ExpectOffsetCalculationQuery( |
| 100 MockGLInterface& gl) { |
| 101 EXPECT_CALL(gl, GetInteger64v(GL_TIMESTAMP, NotNull())) |
| 102 .Times(AtMost(1)) |
| 103 .WillRepeatedly( |
| 104 Invoke(this, &GPUTimingFake::FakeGLGetInteger64v)); |
| 105 } |
| 106 |
| 107 void GPUTimingFake::ExpectNoOffsetCalculationQuery( |
| 108 MockGLInterface& gl) { |
| 109 EXPECT_CALL(gl, GetInteger64v(GL_TIMESTAMP, NotNull())).Times(Exactly(0)); |
| 110 } |
| 111 |
| 112 void GPUTimingFake::FakeGLGenQueries(GLsizei n, GLuint* ids) { |
| 113 for (GLsizei i = 0; i < n; i++) { |
| 114 ids[i] = next_query_id_++; |
| 115 allocated_queries_.insert(ids[i]); |
| 116 } |
| 117 } |
| 118 |
| 119 void GPUTimingFake::FakeGLDeleteQueries(GLsizei n, const GLuint* ids) { |
| 120 for (GLsizei i = 0; i < n; i++) { |
| 121 allocated_queries_.erase(ids[i]); |
| 122 query_results_.erase(ids[i]); |
| 123 if (current_elapsed_query_.query_id_ == ids[i]) |
| 124 current_elapsed_query_.Reset(); |
| 125 } |
| 126 } |
| 127 |
| 128 void GPUTimingFake::FakeGLBeginQuery(GLenum target, GLuint id) { |
| 129 switch(target) { |
| 130 case GL_TIME_ELAPSED: |
| 131 ASSERT_FALSE(current_elapsed_query_.active_); |
| 132 current_elapsed_query_.Reset(); |
| 133 current_elapsed_query_.active_ = true; |
| 134 current_elapsed_query_.query_id_ = id; |
| 135 current_elapsed_query_.begin_time_ = current_time_; |
| 136 break; |
| 137 default: |
| 138 FAIL() << "Invalid target passed to BeginQuery: " << target; |
| 139 } |
| 140 } |
| 141 |
| 142 void GPUTimingFake::FakeGLEndQuery(GLenum target) { |
| 143 switch(target) { |
| 144 case GL_TIME_ELAPSED: { |
| 145 ASSERT_TRUE(current_elapsed_query_.active_); |
| 146 QueryResult& query = query_results_[current_elapsed_query_.query_id_]; |
| 147 query.type_ = QueryResult::kQueryResultType_Elapsed; |
| 148 query.begin_time_ = current_elapsed_query_.begin_time_; |
| 149 query.value_ = current_time_; |
| 150 current_elapsed_query_.active_ = false; |
| 151 } break; |
| 152 default: |
| 153 FAIL() << "Invalid target passed to BeginQuery: " << target; |
| 154 } |
| 155 } |
| 156 |
| 157 void GPUTimingFake::FakeGLGetQueryObjectiv(GLuint id, GLenum pname, |
| 158 GLint* params) { |
| 159 switch (pname) { |
| 160 case GL_QUERY_RESULT_AVAILABLE: { |
| 161 std::map<GLuint, QueryResult>::iterator it = query_results_.find(id); |
| 162 if (it != query_results_.end() && it->second.value_ <= current_time_) |
| 163 *params = 1; |
| 164 else |
| 165 *params = 0; |
| 166 } break; |
| 167 default: |
| 168 FAIL() << "Invalid variable passed to GetQueryObjectiv: " << pname; |
| 169 } |
| 170 } |
| 171 |
| 172 void GPUTimingFake::FakeGLQueryCounter(GLuint id, GLenum target) { |
| 173 switch (target) { |
| 174 case GL_TIMESTAMP: { |
| 175 ASSERT_TRUE(allocated_queries_.find(id) != allocated_queries_.end()); |
| 176 QueryResult& query = query_results_[id]; |
| 177 query.type_ = QueryResult::kQueryResultType_TimeStamp; |
| 178 query.value_ = current_time_; |
| 179 } break; |
| 180 |
| 181 default: |
| 182 FAIL() << "Invalid variable passed to QueryCounter: " << target; |
| 183 } |
| 184 } |
| 185 |
| 186 void GPUTimingFake::FakeGLGetInteger64v(GLenum pname, GLint64 * data) { |
| 187 switch (pname) { |
| 188 case GL_TIMESTAMP: |
| 189 *data = current_time_; |
| 190 break; |
| 191 default: |
| 192 FAIL() << "Invalid variable passed to GetInteger64v: " << pname; |
| 193 } |
| 194 } |
| 195 |
| 196 void GPUTimingFake::FakeGLGetQueryObjectui64v(GLuint id, GLenum pname, |
| 197 GLuint64* params) { |
| 198 switch (pname) { |
| 199 case GL_QUERY_RESULT: { |
| 200 std::map<GLuint, QueryResult>::iterator it = query_results_.find(id); |
| 201 ASSERT_TRUE(it != query_results_.end()); |
| 202 switch (it->second.type_) { |
| 203 case QueryResult::kQueryResultType_TimeStamp: |
| 204 *params = it->second.value_; |
| 205 break; |
| 206 case QueryResult::kQueryResultType_Elapsed: |
| 207 *params = it->second.value_ - it->second.begin_time_; |
| 208 break; |
| 209 default: |
| 210 FAIL() << "Invalid Query Result Type: " << it->second.type_; |
| 211 } |
| 212 } break; |
| 213 default: |
| 214 FAIL() << "Invalid variable passed to GetQueryObjectui64v: " << pname; |
| 215 } |
| 216 } |
| 217 |
| 218 void GPUTimingFake::FakeGLGetIntegerv(GLenum pname, GLint* params) { |
| 219 switch (pname) { |
| 220 case GL_GPU_DISJOINT_EXT: |
| 221 *params = static_cast<GLint>(disjointed_); |
| 222 disjointed_ = false; |
| 223 break; |
| 224 default: |
| 225 FAIL() << "Invalid variable passed to GetIntegerv: " << pname; |
| 226 } |
| 227 } |
| 228 |
| 229 GLenum GPUTimingFake::FakeGLGetError() { |
| 230 return GL_NO_ERROR; |
| 231 } |
| 232 |
| 233 } // namespace gfx |
OLD | NEW |