OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 6 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
7 #include "gpu/command_buffer/service/gl_mock.h" | 7 #include "gpu/command_buffer/service/gl_mock.h" |
8 #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 8 #include "gpu/command_buffer/service/cmd_buffer_engine.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
10 | 10 |
11 using ::testing::_; | 11 using ::testing::_; |
| 12 using ::testing::DoAll; |
| 13 using ::testing::InSequence; |
| 14 using ::testing::MatcherCast; |
| 15 using ::testing::Pointee; |
12 using ::testing::Return; | 16 using ::testing::Return; |
| 17 using ::testing::SetArrayArgument; |
13 using ::testing::SetArgumentPointee; | 18 using ::testing::SetArgumentPointee; |
14 using ::testing::InSequence; | 19 using ::testing::StrEq; |
15 using ::testing::Pointee; | |
16 | 20 |
17 namespace gpu { | 21 namespace gpu { |
18 namespace gles2 { | 22 namespace gles2 { |
19 | 23 |
20 class GLES2DecoderTest : public testing::Test { | 24 class GLES2DecoderTest : public testing::Test { |
21 public: | 25 public: |
22 GLES2DecoderTest() | 26 GLES2DecoderTest() |
23 : client_buffer_id_(100), | 27 : client_buffer_id_(100), |
24 client_framebuffer_id_(101), | 28 client_framebuffer_id_(101), |
25 client_program_id_(102), | 29 client_program_id_(102), |
26 client_renderbuffer_id_(103), | 30 client_renderbuffer_id_(103), |
27 client_shader_id_(104), | 31 client_shader_id_(104), |
28 client_texture_id_(105) { | 32 client_texture_id_(105), |
| 33 client_element_buffer_id_(106) { |
29 memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_)); | 34 memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_)); |
30 } | 35 } |
31 | 36 |
32 protected: | 37 protected: |
33 static const GLint kNumVertexAttribs = 16; | 38 static const GLint kNumVertexAttribs = 16; |
34 | 39 |
35 static const GLuint kServiceBufferId = 301; | 40 static const GLuint kServiceBufferId = 301; |
36 static const GLuint kServiceFramebufferId = 302; | 41 static const GLuint kServiceFramebufferId = 302; |
37 static const GLuint kServiceRenderbufferId = 303; | 42 static const GLuint kServiceRenderbufferId = 303; |
38 static const GLuint kServiceTextureId = 304; | 43 static const GLuint kServiceTextureId = 304; |
39 static const GLuint kServiceProgramId = 305; | 44 static const GLuint kServiceProgramId = 305; |
40 static const GLuint kServiceShaderId = 306; | 45 static const GLuint kServiceShaderId = 306; |
| 46 static const GLuint kServiceElementBufferId = 307; |
41 | 47 |
42 static const int32 kSharedMemoryId = 401; | 48 static const int32 kSharedMemoryId = 401; |
43 static const size_t kSharedBufferSize = 2048; | 49 static const size_t kSharedBufferSize = 2048; |
44 static const uint32 kSharedMemoryOffset = 132; | 50 static const uint32 kSharedMemoryOffset = 132; |
45 static const int32 kInvalidSharedMemoryId = 402; | 51 static const int32 kInvalidSharedMemoryId = 402; |
46 static const uint32 kInvalidSharedMemoryOffset = kSharedBufferSize + 1; | 52 static const uint32 kInvalidSharedMemoryOffset = kSharedBufferSize + 1; |
47 | 53 |
48 static const uint32 kNewClientId = 501; | 54 static const uint32 kNewClientId = 501; |
49 static const uint32 kNewServiceId = 502; | 55 static const uint32 kNewServiceId = 502; |
50 static const uint32 kInvalidClientId = 601; | 56 static const uint32 kInvalidClientId = 601; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 shared_memory_offset_; | 98 shared_memory_offset_; |
93 shared_memory_id_ = kSharedMemoryId; | 99 shared_memory_id_ = kSharedMemoryId; |
94 | 100 |
95 decoder_.reset(GLES2Decoder::Create()); | 101 decoder_.reset(GLES2Decoder::Create()); |
96 decoder_->Initialize(); | 102 decoder_->Initialize(); |
97 decoder_->set_engine(engine_.get()); | 103 decoder_->set_engine(engine_.get()); |
98 | 104 |
99 EXPECT_CALL(*gl_, GenBuffersARB(_, _)) | 105 EXPECT_CALL(*gl_, GenBuffersARB(_, _)) |
100 .WillOnce(SetArgumentPointee<1>(kServiceBufferId)) | 106 .WillOnce(SetArgumentPointee<1>(kServiceBufferId)) |
101 .RetiresOnSaturation(); | 107 .RetiresOnSaturation(); |
| 108 GenHelper<GenBuffersImmediate>(client_buffer_id_); |
102 EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _)) | 109 EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _)) |
103 .WillOnce(SetArgumentPointee<1>(kServiceFramebufferId)) | 110 .WillOnce(SetArgumentPointee<1>(kServiceFramebufferId)) |
104 .RetiresOnSaturation(); | 111 .RetiresOnSaturation(); |
| 112 GenHelper<GenFramebuffersImmediate>(client_framebuffer_id_); |
105 EXPECT_CALL(*gl_, GenRenderbuffersEXT(_, _)) | 113 EXPECT_CALL(*gl_, GenRenderbuffersEXT(_, _)) |
106 .WillOnce(SetArgumentPointee<1>(kServiceRenderbufferId)) | 114 .WillOnce(SetArgumentPointee<1>(kServiceRenderbufferId)) |
107 .RetiresOnSaturation(); | 115 .RetiresOnSaturation(); |
| 116 GenHelper<GenRenderbuffersImmediate>(client_renderbuffer_id_); |
108 EXPECT_CALL(*gl_, GenTextures(_, _)) | 117 EXPECT_CALL(*gl_, GenTextures(_, _)) |
109 .WillOnce(SetArgumentPointee<1>(kServiceTextureId)) | 118 .WillOnce(SetArgumentPointee<1>(kServiceTextureId)) |
110 .RetiresOnSaturation(); | 119 .RetiresOnSaturation(); |
111 | |
112 GenHelper<GenBuffersImmediate>(client_buffer_id_); | |
113 GenHelper<GenFramebuffersImmediate>(client_framebuffer_id_); | |
114 GenHelper<GenRenderbuffersImmediate>(client_renderbuffer_id_); | |
115 GenHelper<GenTexturesImmediate>(client_texture_id_); | 120 GenHelper<GenTexturesImmediate>(client_texture_id_); |
| 121 EXPECT_CALL(*gl_, GenBuffersARB(_, _)) |
| 122 .WillOnce(SetArgumentPointee<1>(kServiceElementBufferId)) |
| 123 .RetiresOnSaturation(); |
| 124 GenHelper<GenBuffersImmediate>(client_element_buffer_id_); |
116 | 125 |
117 { | 126 { |
118 EXPECT_CALL(*gl_, CreateProgram()) | 127 EXPECT_CALL(*gl_, CreateProgram()) |
119 .Times(1) | 128 .Times(1) |
120 .WillOnce(Return(kServiceProgramId)) | 129 .WillOnce(Return(kServiceProgramId)) |
121 .RetiresOnSaturation(); | 130 .RetiresOnSaturation(); |
122 CreateProgram cmd; | 131 CreateProgram cmd; |
123 cmd.Init(client_program_id_); | 132 cmd.Init(client_program_id_); |
124 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); | 133 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
125 } | 134 } |
126 | 135 |
127 { | 136 { |
128 EXPECT_CALL(*gl_, CreateShader(_)) | 137 EXPECT_CALL(*gl_, CreateShader(_)) |
129 .Times(1) | 138 .Times(1) |
130 .WillOnce(Return(kServiceShaderId)) | 139 .WillOnce(Return(kServiceShaderId)) |
131 .RetiresOnSaturation(); | 140 .RetiresOnSaturation(); |
132 CreateShader cmd; | 141 CreateShader cmd; |
133 cmd.Init(GL_VERTEX_SHADER, client_shader_id_); | 142 cmd.Init(GL_VERTEX_SHADER, client_shader_id_); |
134 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); | 143 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
135 } | 144 } |
| 145 |
| 146 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
136 } | 147 } |
137 | 148 |
138 virtual void TearDown() { | 149 virtual void TearDown() { |
139 decoder_->Destroy(); | 150 decoder_->Destroy(); |
140 decoder_.reset(); | 151 decoder_.reset(); |
141 engine_.reset(); | 152 engine_.reset(); |
142 ::gles2::GLInterface::SetGLInterface(NULL); | 153 ::gles2::GLInterface::SetGLInterface(NULL); |
143 gl_.reset(); | 154 gl_.reset(); |
144 } | 155 } |
145 | 156 |
(...skipping 15 matching lines...) Expand all Loading... |
161 | 172 |
162 template <typename T> | 173 template <typename T> |
163 T GetSharedMemoryAs() { | 174 T GetSharedMemoryAs() { |
164 return reinterpret_cast<T>(shared_memory_address_); | 175 return reinterpret_cast<T>(shared_memory_address_); |
165 } | 176 } |
166 | 177 |
167 uint32 GetServiceId(uint32 client_id) { | 178 uint32 GetServiceId(uint32 client_id) { |
168 return decoder_->GetServiceIdForTesting(client_id); | 179 return decoder_->GetServiceIdForTesting(client_id); |
169 } | 180 } |
170 | 181 |
| 182 GLenum GetGLError() { |
| 183 EXPECT_CALL(*gl_, GetError()) |
| 184 .WillOnce(Return(GL_NO_ERROR)) |
| 185 .RetiresOnSaturation(); |
| 186 GetError cmd; |
| 187 cmd.Init(shared_memory_id_, shared_memory_offset_); |
| 188 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 189 return *GetSharedMemoryAs<GLenum*>(); |
| 190 } |
| 191 |
171 scoped_ptr<::gles2::MockGLInterface> gl_; | 192 scoped_ptr<::gles2::MockGLInterface> gl_; |
172 scoped_ptr<GLES2Decoder> decoder_; | 193 scoped_ptr<GLES2Decoder> decoder_; |
173 | 194 |
174 GLuint client_buffer_id_; | 195 GLuint client_buffer_id_; |
175 GLuint client_framebuffer_id_; | 196 GLuint client_framebuffer_id_; |
176 GLuint client_program_id_; | 197 GLuint client_program_id_; |
177 GLuint client_renderbuffer_id_; | 198 GLuint client_renderbuffer_id_; |
178 GLuint client_shader_id_; | 199 GLuint client_shader_id_; |
179 GLuint client_texture_id_; | 200 GLuint client_texture_id_; |
| 201 GLuint client_element_buffer_id_; |
180 | 202 |
181 uint32 shared_memory_id_; | 203 uint32 shared_memory_id_; |
182 uint32 shared_memory_offset_; | 204 uint32 shared_memory_offset_; |
183 void* shared_memory_address_; | 205 void* shared_memory_address_; |
184 | 206 |
185 int8 immediate_buffer_[256]; | 207 int8 immediate_buffer_[256]; |
186 | 208 |
187 private: | 209 private: |
188 class MockCommandBufferEngine : public CommandBufferEngine { | 210 class MockCommandBufferEngine : public CommandBufferEngine { |
189 public: | 211 public: |
(...skipping 27 matching lines...) Expand all Loading... |
217 void GLES2DecoderTest::SpecializedSetup<LinkProgram, 0>() { | 239 void GLES2DecoderTest::SpecializedSetup<LinkProgram, 0>() { |
218 InSequence dummy; | 240 InSequence dummy; |
219 EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTES, _)) | 241 EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTES, _)) |
220 .WillOnce(SetArgumentPointee<2>(0)); | 242 .WillOnce(SetArgumentPointee<2>(0)); |
221 EXPECT_CALL( | 243 EXPECT_CALL( |
222 *gl_, | 244 *gl_, |
223 GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) | 245 GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) |
224 .WillOnce(SetArgumentPointee<2>(0)); | 246 .WillOnce(SetArgumentPointee<2>(0)); |
225 }; | 247 }; |
226 | 248 |
| 249 |
| 250 class GLES2DecoderWithShaderTest : public GLES2DecoderTest { |
| 251 public: |
| 252 GLES2DecoderWithShaderTest() |
| 253 : GLES2DecoderTest() { |
| 254 } |
| 255 |
| 256 static const GLint kNumAttribs = 3; |
| 257 static const GLint kMaxAttribLength = 10; |
| 258 static const GLsizei kNumVertices = 100; |
| 259 static const GLsizei kNumIndices = 10; |
| 260 static const int kValidIndexRangeStart = 1; |
| 261 static const int kValidIndexRangeCount = 7; |
| 262 static const int kInvalidIndexRangeStart = 0; |
| 263 static const int kInvalidIndexRangeCount = 7; |
| 264 static const int kOutOfRangeIndexRangeEnd = 10; |
| 265 static const char* kAttrib1Name; |
| 266 static const char* kAttrib2Name; |
| 267 static const char* kAttrib3Name; |
| 268 |
| 269 protected: |
| 270 virtual void SetUp() { |
| 271 GLES2DecoderTest::SetUp(); |
| 272 |
| 273 { |
| 274 struct AttribInfo { |
| 275 const char* name; |
| 276 GLint size; |
| 277 GLenum type; |
| 278 GLint location; |
| 279 }; |
| 280 static AttribInfo attribs[] = { |
| 281 { kAttrib1Name, 1, GL_FLOAT_VEC4, 0, }, |
| 282 { kAttrib2Name, 1, GL_FLOAT_VEC2, 1, }, |
| 283 { kAttrib3Name, 1, GL_FLOAT_VEC3, 2, }, |
| 284 }; |
| 285 LinkProgram cmd; |
| 286 cmd.Init(client_program_id_); |
| 287 |
| 288 EXPECT_CALL(*gl_, LinkProgram(kServiceProgramId)) |
| 289 .Times(1) |
| 290 .RetiresOnSaturation(); |
| 291 EXPECT_CALL(*gl_, GetError()) |
| 292 .WillOnce(Return(GL_NO_ERROR)) |
| 293 .RetiresOnSaturation(); |
| 294 EXPECT_CALL(*gl_, |
| 295 GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTES, _)) |
| 296 .WillOnce(SetArgumentPointee<2>(kNumAttribs)) |
| 297 .RetiresOnSaturation(); |
| 298 EXPECT_CALL(*gl_, |
| 299 GetProgramiv(kServiceProgramId, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _)) |
| 300 .WillOnce(SetArgumentPointee<2>(kMaxAttribLength)) |
| 301 .RetiresOnSaturation(); |
| 302 { |
| 303 InSequence s; |
| 304 for (GLint ii = 0; ii < kNumAttribs; ++ii) { |
| 305 const AttribInfo& info = attribs[ii]; |
| 306 EXPECT_CALL(*gl_, |
| 307 GetActiveAttrib(kServiceProgramId, ii, |
| 308 kMaxAttribLength + 1, _, _, _, _)) |
| 309 .WillOnce(DoAll( |
| 310 SetArgumentPointee<3>(strlen(info.name)), |
| 311 SetArgumentPointee<4>(info.size), |
| 312 SetArgumentPointee<5>(info.type), |
| 313 SetArrayArgument<6>(info.name, |
| 314 info.name + strlen(info.name) + 1))) |
| 315 .RetiresOnSaturation(); |
| 316 EXPECT_CALL(*gl_, GetAttribLocation(kServiceProgramId, |
| 317 StrEq(info.name))) |
| 318 .WillOnce(Return(info.location)) |
| 319 .RetiresOnSaturation(); |
| 320 } |
| 321 } |
| 322 |
| 323 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 324 } |
| 325 |
| 326 { |
| 327 EXPECT_CALL(*gl_, UseProgram(kServiceProgramId)) |
| 328 .Times(1) |
| 329 .RetiresOnSaturation(); |
| 330 UseProgram cmd; |
| 331 cmd.Init(client_program_id_); |
| 332 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 333 } |
| 334 } |
| 335 |
| 336 virtual void TearDown() { |
| 337 GLES2DecoderTest::TearDown(); |
| 338 } |
| 339 |
| 340 inline GLvoid* BufferOffset(unsigned i) { |
| 341 return static_cast<int8 *>(NULL)+(i); |
| 342 } |
| 343 |
| 344 void DoEnableVertexAttribArray(GLint index) { |
| 345 EXPECT_CALL(*gl_, EnableVertexAttribArray(index)) |
| 346 .Times(1) |
| 347 .RetiresOnSaturation(); |
| 348 EnableVertexAttribArray cmd; |
| 349 cmd.Init(index); |
| 350 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 351 } |
| 352 |
| 353 void DoBindBuffer(GLenum target, GLuint client_id, GLuint service_id) { |
| 354 EXPECT_CALL(*gl_, BindBuffer(target, service_id)) |
| 355 .Times(1) |
| 356 .RetiresOnSaturation(); |
| 357 BindBuffer cmd; |
| 358 cmd.Init(target, client_id); |
| 359 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 360 } |
| 361 |
| 362 void DoBufferData(GLenum target, GLsizei size) { |
| 363 EXPECT_CALL(*gl_, BufferData(target, size, _, GL_STREAM_DRAW)) |
| 364 .Times(1) |
| 365 .RetiresOnSaturation(); |
| 366 BufferData cmd; |
| 367 cmd.Init(target, size, 0, 0, GL_STREAM_DRAW); |
| 368 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 369 } |
| 370 |
| 371 void DoBufferSubData( |
| 372 GLenum target, GLint offset, GLsizei size, const void* data) { |
| 373 EXPECT_CALL(*gl_, BufferSubData(target, offset, size, |
| 374 shared_memory_address_)) |
| 375 .Times(1) |
| 376 .RetiresOnSaturation(); |
| 377 memcpy(shared_memory_address_, data, size); |
| 378 BufferSubData cmd; |
| 379 cmd.Init(target, offset, size, shared_memory_id_, shared_memory_offset_); |
| 380 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 381 } |
| 382 |
| 383 void DoDeleteBuffer(GLuint client_id, GLuint service_id) { |
| 384 EXPECT_CALL(*gl_, DeleteBuffersARB(1, Pointee(service_id))) |
| 385 .Times(1) |
| 386 .RetiresOnSaturation(); |
| 387 DeleteBuffers cmd; |
| 388 cmd.Init(1, shared_memory_id_, shared_memory_offset_); |
| 389 memcpy(shared_memory_address_, &client_id, sizeof(client_id)); |
| 390 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 391 } |
| 392 |
| 393 void DoDeleteProgram(GLuint client_id, GLuint service_id) { |
| 394 EXPECT_CALL(*gl_, DeleteProgram(service_id)) |
| 395 .Times(1) |
| 396 .RetiresOnSaturation(); |
| 397 DeleteProgram cmd; |
| 398 cmd.Init(client_id); |
| 399 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 400 } |
| 401 |
| 402 void DoVertexAttribPointer( |
| 403 GLuint index, GLint size, GLenum type, GLsizei stride, GLuint offset) { |
| 404 EXPECT_CALL(*gl_, |
| 405 VertexAttribPointer(index, size, type, GL_FALSE, stride, |
| 406 BufferOffset(offset))) |
| 407 .Times(1) |
| 408 .RetiresOnSaturation(); |
| 409 VertexAttribPointer cmd; |
| 410 cmd.Init(index, size, GL_FLOAT, GL_FALSE, stride, offset); |
| 411 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 412 } |
| 413 |
| 414 void SetupVertexBuffer() { |
| 415 DoEnableVertexAttribArray(1); |
| 416 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); |
| 417 GLfloat f = 0; |
| 418 DoBufferData(GL_ARRAY_BUFFER, kNumVertices * 2 * sizeof(f)); |
| 419 } |
| 420 |
| 421 void SetupIndexBuffer() { |
| 422 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, |
| 423 client_element_buffer_id_, |
| 424 kServiceElementBufferId); |
| 425 static const GLshort indices[] = {100, 1, 2, 3, 4, 5, 6, 7, 100, 9}; |
| 426 COMPILE_ASSERT(arraysize(indices) == kNumIndices, Indices_is_not_10); |
| 427 DoBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices)); |
| 428 DoBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices), indices); |
| 429 } |
| 430 |
| 431 void DeleteVertexBuffer() { |
| 432 DoDeleteBuffer(client_buffer_id_, kServiceBufferId); |
| 433 } |
| 434 |
| 435 void DeleteIndexBuffer() { |
| 436 DoDeleteBuffer(client_element_buffer_id_, kServiceElementBufferId); |
| 437 } |
| 438 }; |
| 439 |
| 440 const char* GLES2DecoderWithShaderTest::kAttrib1Name = "attrib1"; |
| 441 const char* GLES2DecoderWithShaderTest::kAttrib2Name = "attrib2"; |
| 442 const char* GLES2DecoderWithShaderTest::kAttrib3Name = "attrib3"; |
| 443 |
| 444 TEST_F(GLES2DecoderWithShaderTest, DrawArraysNoAttributesSucceeds) { |
| 445 EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) |
| 446 .Times(1) |
| 447 .RetiresOnSaturation(); |
| 448 DrawArrays cmd; |
| 449 cmd.Init(GL_TRIANGLES, 0, kNumVertices); |
| 450 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 451 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 452 } |
| 453 |
| 454 TEST_F(GLES2DecoderWithShaderTest, DrawArraysMissingAttributesFails) { |
| 455 DoEnableVertexAttribArray(1); |
| 456 |
| 457 EXPECT_CALL(*gl_, DrawArrays(_, _, _)) |
| 458 .Times(0); |
| 459 DrawArrays cmd; |
| 460 cmd.Init(GL_TRIANGLES, 0, kNumVertices); |
| 461 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 462 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 463 } |
| 464 |
| 465 TEST_F(GLES2DecoderWithShaderTest, DrawArraysValidAttributesSucceeds) { |
| 466 SetupVertexBuffer(); |
| 467 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 468 |
| 469 EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) |
| 470 .Times(1) |
| 471 .RetiresOnSaturation(); |
| 472 DrawArrays cmd; |
| 473 cmd.Init(GL_TRIANGLES, 0, kNumVertices); |
| 474 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 475 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 476 } |
| 477 |
| 478 TEST_F(GLES2DecoderWithShaderTest, DrawArraysDeletedBufferFails) { |
| 479 SetupVertexBuffer(); |
| 480 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 481 DeleteVertexBuffer(); |
| 482 |
| 483 EXPECT_CALL(*gl_, DrawArrays(_, _, _)) |
| 484 .Times(0); |
| 485 DrawArrays cmd; |
| 486 cmd.Init(GL_TRIANGLES, 0, kNumVertices); |
| 487 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 488 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 489 } |
| 490 |
| 491 TEST_F(GLES2DecoderWithShaderTest, DrawArraysDeletedProgramFails) { |
| 492 SetupVertexBuffer(); |
| 493 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 494 DoDeleteProgram(client_program_id_, kServiceProgramId); |
| 495 |
| 496 EXPECT_CALL(*gl_, DrawArrays(_, _, _)) |
| 497 .Times(0); |
| 498 DrawArrays cmd; |
| 499 cmd.Init(GL_TRIANGLES, 0, kNumVertices); |
| 500 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 501 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 502 } |
| 503 |
| 504 TEST_F(GLES2DecoderWithShaderTest, DrawArraysWithInvalidModeFails) { |
| 505 SetupVertexBuffer(); |
| 506 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 507 |
| 508 EXPECT_CALL(*gl_, DrawArrays(_, _, _)) |
| 509 .Times(0); |
| 510 DrawArrays cmd; |
| 511 cmd.Init(GL_QUADS, 0, 1); |
| 512 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 513 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); |
| 514 cmd.Init(GL_POLYGON, 0, 1); |
| 515 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 516 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); |
| 517 } |
| 518 |
| 519 TEST_F(GLES2DecoderWithShaderTest, DrawArraysInvalidCountFails) { |
| 520 SetupVertexBuffer(); |
| 521 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 522 |
| 523 // Try start > 0 |
| 524 EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0); |
| 525 DrawArrays cmd; |
| 526 cmd.Init(GL_TRIANGLES, 1, kNumVertices); |
| 527 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 528 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 529 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 530 |
| 531 // Try with count > size |
| 532 cmd.Init(GL_TRIANGLES, 0, kNumVertices + 1); |
| 533 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 534 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 535 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 536 |
| 537 // Try with attrib offset > 0 |
| 538 cmd.Init(GL_TRIANGLES, 0, kNumVertices); |
| 539 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 4); |
| 540 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 541 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 542 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 543 |
| 544 // Try with size > 2 (ie, vec3 instead of vec2) |
| 545 DoVertexAttribPointer(1, 3, GL_FLOAT, 0, 0); |
| 546 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 547 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 548 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 549 |
| 550 // Try with stride > 8 (vec2 + vec2 byte) |
| 551 GLfloat f; |
| 552 DoVertexAttribPointer(1, 2, GL_FLOAT, sizeof(f) * 2 + 1, 0); |
| 553 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 554 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 555 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 556 } |
| 557 |
| 558 TEST_F(GLES2DecoderWithShaderTest, DrawElementsNoAttributesSucceeds) { |
| 559 SetupIndexBuffer(); |
| 560 EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount, |
| 561 GL_UNSIGNED_SHORT, |
| 562 BufferOffset(kValidIndexRangeStart))) |
| 563 .Times(1) |
| 564 .RetiresOnSaturation(); |
| 565 DrawElements cmd; |
| 566 cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, |
| 567 kValidIndexRangeStart); |
| 568 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 569 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 570 } |
| 571 |
| 572 TEST_F(GLES2DecoderWithShaderTest, DrawElementsMissingAttributesFails) { |
| 573 SetupIndexBuffer(); |
| 574 DoEnableVertexAttribArray(1); |
| 575 |
| 576 EXPECT_CALL(*gl_, DrawElements(_, _, _, _)) |
| 577 .Times(0); |
| 578 DrawElements cmd; |
| 579 cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, |
| 580 kValidIndexRangeStart); |
| 581 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 582 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 583 } |
| 584 |
| 585 TEST_F(GLES2DecoderWithShaderTest, DrawElementsValidAttributesSucceeds) { |
| 586 SetupVertexBuffer(); |
| 587 SetupIndexBuffer(); |
| 588 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 589 |
| 590 EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount, |
| 591 GL_UNSIGNED_SHORT, |
| 592 BufferOffset(kValidIndexRangeStart))) |
| 593 .Times(1) |
| 594 .RetiresOnSaturation(); |
| 595 DrawElements cmd; |
| 596 cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, |
| 597 kValidIndexRangeStart); |
| 598 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 599 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 600 } |
| 601 |
| 602 TEST_F(GLES2DecoderWithShaderTest, DrawElementsDeletedBufferFails) { |
| 603 SetupVertexBuffer(); |
| 604 SetupIndexBuffer(); |
| 605 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 606 DeleteIndexBuffer(); |
| 607 |
| 608 EXPECT_CALL(*gl_, DrawElements(_, _, _, _)) |
| 609 .Times(0); |
| 610 DrawElements cmd; |
| 611 cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, |
| 612 kValidIndexRangeStart); |
| 613 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 614 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 615 } |
| 616 |
| 617 TEST_F(GLES2DecoderWithShaderTest, DrawElementsDeleteProgramFails) { |
| 618 SetupVertexBuffer(); |
| 619 SetupIndexBuffer(); |
| 620 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 621 DoDeleteProgram(client_program_id_, kServiceProgramId); |
| 622 |
| 623 EXPECT_CALL(*gl_, DrawElements(_, _, _, _)) |
| 624 .Times(0); |
| 625 DrawElements cmd; |
| 626 cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT, |
| 627 kValidIndexRangeStart); |
| 628 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 629 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 630 } |
| 631 |
| 632 TEST_F(GLES2DecoderWithShaderTest, DrawElementsWithInvalidModeFails) { |
| 633 SetupVertexBuffer(); |
| 634 SetupIndexBuffer(); |
| 635 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 636 |
| 637 EXPECT_CALL(*gl_, DrawElements(_, _, _, _)) |
| 638 .Times(0); |
| 639 DrawElements cmd; |
| 640 cmd.Init(GL_QUADS, kValidIndexRangeCount, GL_UNSIGNED_SHORT, |
| 641 kValidIndexRangeStart); |
| 642 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 643 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); |
| 644 cmd.Init(GL_POLYGON, kValidIndexRangeCount, GL_UNSIGNED_SHORT, |
| 645 kValidIndexRangeStart); |
| 646 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 647 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); |
| 648 } |
| 649 |
| 650 TEST_F(GLES2DecoderWithShaderTest, DrawElementsInvalidCountFails) { |
| 651 SetupVertexBuffer(); |
| 652 SetupIndexBuffer(); |
| 653 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 654 |
| 655 // Try start > 0 |
| 656 EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0); |
| 657 DrawElements cmd; |
| 658 cmd.Init(GL_TRIANGLES, kNumIndices, GL_UNSIGNED_SHORT, 1); |
| 659 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 660 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 661 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 662 |
| 663 // Try with count > size |
| 664 cmd.Init(GL_TRIANGLES, kNumIndices + 1, GL_UNSIGNED_SHORT, 0); |
| 665 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 666 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 667 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 668 } |
| 669 |
| 670 #if 0 // TODO(gman): Turn on this test once buffer validation is in |
| 671 TEST_F(GLES2DecoderWithShaderTest, DrawElementsOutOfRangeIndicesFails) { |
| 672 SetupVertexBuffer(); |
| 673 SetupIndexBuffer(); |
| 674 DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0); |
| 675 |
| 676 EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0); |
| 677 DrawElements cmd; |
| 678 cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT, |
| 679 kInvalidIndexRangeStart); |
| 680 EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd)); |
| 681 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
| 682 EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
| 683 } |
| 684 #endif |
| 685 |
227 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h" | 686 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_autogen.h" |
228 | 687 |
229 } // namespace gles2 | 688 } // namespace gles2 |
230 } // namespace gpu | 689 } // namespace gpu |
231 | 690 |
232 | 691 |
OLD | NEW |