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 3 // found in the LICENSE file. 4 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 6 7 #include "base/command_line.h" 8 #include "base/strings/string_number_conversions.h" 9 #include "gpu/command_buffer/common/gles2_cmd_format.h" 10 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 11 #include "gpu/command_buffer/common/id_allocator.h" 12 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h" 13 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" 14 #include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h" 15 #include "gpu/command_buffer/service/cmd_buffer_engine.h" 16 #include "gpu/command_buffer/service/context_group.h" 17 #include "gpu/command_buffer/service/context_state.h" 18 #include "gpu/command_buffer/service/gl_surface_mock.h" 19 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" 20 21 #include "gpu/command_buffer/service/gpu_switches.h" 22 #include "gpu/command_buffer/service/image_manager.h" 23 #include "gpu/command_buffer/service/mailbox_manager.h" 24 #include "gpu/command_buffer/service/mocks.h" 25 #include "gpu/command_buffer/service/program_manager.h" 26 #include "gpu/command_buffer/service/test_helper.h" 27 #include "testing/gtest/include/gtest/gtest.h" 28 #include "ui/gl/gl_implementation.h" 29 #include "ui/gl/gl_mock.h" 30 #include "ui/gl/gl_surface_stub.h" 31 32 #if !defined(GL_DEPTH24_STENCIL8) 33 #define GL_DEPTH24_STENCIL8 0x88F0 34 #endif 35 36 using ::gfx::MockGLInterface; 37 using ::testing::_; 38 using ::testing::DoAll; 39 using ::testing::InSequence; 40 using ::testing::Invoke; 41 using ::testing::MatcherCast; 42 using ::testing::Mock; 43 using ::testing::Pointee; 44 using ::testing::Return; 45 using ::testing::SaveArg; 46 using ::testing::SetArrayArgument; 47 using ::testing::SetArgumentPointee; 48 using ::testing::SetArgPointee; 49 using ::testing::StrEq; 50 using ::testing::StrictMock; 51 52 namespace gpu { 53 namespace gles2 { 54 55 using namespace cmds; 56 57 TEST_P(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) { 58 const float dummy = 0; 59 const GLuint kOffsetToTestFor = sizeof(dummy) * 4; 60 const GLuint kIndexToTest = 1; 61 GetVertexAttribPointerv::Result* result = 62 static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_); 63 result->size = 0; 64 const GLuint* result_value = result->GetData(); 65 // Test that initial value is 0. 66 GetVertexAttribPointerv cmd; 67 cmd.Init(kIndexToTest, 68 GL_VERTEX_ATTRIB_ARRAY_POINTER, 69 shared_memory_id_, 70 shared_memory_offset_); 71 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 72 EXPECT_EQ(sizeof(*result_value), result->size); 73 EXPECT_EQ(0u, *result_value); 74 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 75 76 // Set the value and see that we get it. 77 SetupVertexBuffer(); 78 DoVertexAttribPointer(kIndexToTest, 2, GL_FLOAT, 0, kOffsetToTestFor); 79 result->size = 0; 80 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 81 EXPECT_EQ(sizeof(*result_value), result->size); 82 EXPECT_EQ(kOffsetToTestFor, *result_value); 83 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 84 } 85 86 TEST_P(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) { 87 const GLuint kIndexToTest = 1; 88 GetVertexAttribPointerv::Result* result = 89 static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_); 90 result->size = 0; 91 const GLuint* result_value = result->GetData(); 92 // Test pname invalid fails. 93 GetVertexAttribPointerv cmd; 94 cmd.Init(kIndexToTest, 95 GL_VERTEX_ATTRIB_ARRAY_POINTER + 1, 96 shared_memory_id_, 97 shared_memory_offset_); 98 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 99 EXPECT_EQ(0u, result->size); 100 EXPECT_EQ(kInitialResult, *result_value); 101 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 102 103 // Test index out of range fails. 104 result->size = 0; 105 cmd.Init(kNumVertexAttribs, 106 GL_VERTEX_ATTRIB_ARRAY_POINTER, 107 shared_memory_id_, 108 shared_memory_offset_); 109 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 110 EXPECT_EQ(0u, result->size); 111 EXPECT_EQ(kInitialResult, *result_value); 112 EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); 113 114 // Test memory id bad fails. 115 cmd.Init(kIndexToTest, 116 GL_VERTEX_ATTRIB_ARRAY_POINTER, 117 kInvalidSharedMemoryId, 118 shared_memory_offset_); 119 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 120 121 // Test memory offset bad fails. 122 cmd.Init(kIndexToTest, 123 GL_VERTEX_ATTRIB_ARRAY_POINTER, 124 shared_memory_id_, 125 kInvalidSharedMemoryOffset); 126 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 127 } 128 129 TEST_P(GLES2DecoderWithShaderTest, BindBufferToDifferentTargetFails) { 130 // Bind the buffer to GL_ARRAY_BUFFER 131 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); 132 // Attempt to rebind to GL_ELEMENT_ARRAY_BUFFER 133 // NOTE: Real GLES2 does not have this restriction but WebGL and we do. 134 // This can be restriction can be removed at runtime. 135 EXPECT_CALL(*gl_, BindBuffer(_, _)).Times(0); 136 BindBuffer cmd; 137 cmd.Init(GL_ELEMENT_ARRAY_BUFFER, client_buffer_id_); 138 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 139 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 140 } 141 142 TEST_P(GLES2DecoderWithShaderTest, VertexAttribPointer) { 143 SetupVertexBuffer(); 144 static const GLenum types[] = { 145 GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, 146 GL_FLOAT, GL_FIXED, GL_INT, GL_UNSIGNED_INT, 147 }; 148 static const GLsizei sizes[] = { 149 1, 1, 2, 2, 4, 4, 4, 4, 150 }; 151 static const GLuint indices[] = { 152 0, 1, kNumVertexAttribs - 1, kNumVertexAttribs, 153 }; 154 static const GLsizei offset_mult[] = { 155 0, 0, 1, 1, 2, 1000, 156 }; 157 static const GLsizei offset_offset[] = { 158 0, 1, 0, 1, 0, 0, 159 }; 160 static const GLsizei stride_mult[] = { 161 -1, 0, 0, 1, 1, 2, 1000, 162 }; 163 static const GLsizei stride_offset[] = { 164 0, 0, 1, 0, 1, 0, 0, 165 }; 166 for (size_t tt = 0; tt < arraysize(types); ++tt) { 167 GLenum type = types[tt]; 168 GLsizei num_bytes = sizes[tt]; 169 for (size_t ii = 0; ii < arraysize(indices); ++ii) { 170 GLuint index = indices[ii]; 171 for (GLint size = 0; size < 5; ++size) { 172 for (size_t oo = 0; oo < arraysize(offset_mult); ++oo) { 173 GLuint offset = num_bytes * offset_mult[oo] + offset_offset[oo]; 174 for (size_t ss = 0; ss < arraysize(stride_mult); ++ss) { 175 GLsizei stride = num_bytes * stride_mult[ss] + stride_offset[ss]; 176 for (int normalize = 0; normalize < 2; ++normalize) { 177 bool index_good = index < static_cast<GLuint>(kNumVertexAttribs); 178 bool size_good = (size > 0 && size < 5); 179 bool offset_good = (offset % num_bytes == 0); 180 bool stride_good = 181 (stride % num_bytes == 0) && stride >= 0 && stride <= 255; 182 bool type_good = (type != GL_INT && type != GL_UNSIGNED_INT && 183 type != GL_FIXED); 184 bool good = size_good && offset_good && stride_good && 185 type_good && index_good; 186 bool call = good && (type != GL_FIXED); 187 if (call) { 188 EXPECT_CALL(*gl_, 189 VertexAttribPointer(index, 190 size, 191 type, 192 normalize, 193 stride, 194 BufferOffset(offset))); 195 } 196 VertexAttribPointer cmd; 197 cmd.Init(index, size, type, normalize, stride, offset); 198 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 199 if (good) { 200 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 201 } else if (size_good && offset_good && stride_good && type_good && 202 !index_good) { 203 EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); 204 } else if (size_good && offset_good && stride_good && 205 !type_good && index_good) { 206 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 207 } else if (size_good && offset_good && !stride_good && 208 type_good && index_good) { 209 if (stride < 0 || stride > 255) { 210 EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); 211 } else { 212 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 213 } 214 } else if (size_good && !offset_good && stride_good && 215 type_good && index_good) { 216 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 217 } else if (!size_good && offset_good && stride_good && 218 type_good && index_good) { 219 EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); 220 } else { 221 EXPECT_NE(GL_NO_ERROR, GetGLError()); 222 } 223 } 224 } 225 } 226 } 227 } 228 } 229 } 230 231 class GLES2DecoderVertexArraysOESTest : public GLES2DecoderWithShaderTest { 232 public: 233 GLES2DecoderVertexArraysOESTest() {} 234 235 bool vertex_array_deleted_manually_; 236 237 virtual void SetUp() { 238 InitState init; 239 init.gl_version = "opengl es 2.0"; 240 init.bind_generates_resource = true; 241 InitDecoder(init); 242 SetupDefaultProgram(); 243 244 AddExpectationsForGenVertexArraysOES(); 245 GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_); 246 247 vertex_array_deleted_manually_ = false; 248 } 249 250 virtual void TearDown() { 251 // This should only be set if the test handled deletion of the vertex array 252 // itself. Necessary because vertex_array_objects are not sharable, and thus 253 // not managed in the ContextGroup, meaning they will be destroyed during 254 // test tear down 255 if (!vertex_array_deleted_manually_) { 256 AddExpectationsForDeleteVertexArraysOES(); 257 } 258 259 GLES2DecoderWithShaderTest::TearDown(); 260 } 261 262 void GenVertexArraysOESImmediateValidArgs() { 263 AddExpectationsForGenVertexArraysOES(); 264 GenVertexArraysOESImmediate* cmd = 265 GetImmediateAs<GenVertexArraysOESImmediate>(); 266 GLuint temp = kNewClientId; 267 cmd->Init(1, &temp); 268 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp))); 269 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 270 EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL); 271 AddExpectationsForDeleteVertexArraysOES(); 272 } 273 274 void GenVertexArraysOESImmediateInvalidArgs() { 275 EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0); 276 GenVertexArraysOESImmediate* cmd = 277 GetImmediateAs<GenVertexArraysOESImmediate>(); 278 cmd->Init(1, &client_vertexarray_id_); 279 EXPECT_EQ(error::kInvalidArguments, 280 ExecuteImmediateCmd(*cmd, sizeof(&client_vertexarray_id_))); 281 } 282 283 void DeleteVertexArraysOESImmediateValidArgs() { 284 AddExpectationsForDeleteVertexArraysOES(); 285 DeleteVertexArraysOESImmediate& cmd = 286 *GetImmediateAs<DeleteVertexArraysOESImmediate>(); 287 cmd.Init(1, &client_vertexarray_id_); 288 EXPECT_EQ(error::kNoError, 289 ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_))); 290 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 291 EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_) == NULL); 292 vertex_array_deleted_manually_ = true; 293 } 294 295 void DeleteVertexArraysOESImmediateInvalidArgs() { 296 DeleteVertexArraysOESImmediate& cmd = 297 *GetImmediateAs<DeleteVertexArraysOESImmediate>(); 298 GLuint temp = kInvalidClientId; 299 cmd.Init(1, &temp); 300 EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); 301 } 302 303 void DeleteBoundVertexArraysOESImmediateValidArgs() { 304 BindVertexArrayOESValidArgs(); 305 306 AddExpectationsForDeleteBoundVertexArraysOES(); 307 DeleteVertexArraysOESImmediate& cmd = 308 *GetImmediateAs<DeleteVertexArraysOESImmediate>(); 309 cmd.Init(1, &client_vertexarray_id_); 310 EXPECT_EQ(error::kNoError, 311 ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_))); 312 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 313 EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_) == NULL); 314 vertex_array_deleted_manually_ = true; 315 } 316 317 void IsVertexArrayOESValidArgs() { 318 IsVertexArrayOES cmd; 319 cmd.Init(client_vertexarray_id_, shared_memory_id_, shared_memory_offset_); 320 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 321 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 322 } 323 324 void IsVertexArrayOESInvalidArgsBadSharedMemoryId() { 325 IsVertexArrayOES cmd; 326 cmd.Init( 327 client_vertexarray_id_, kInvalidSharedMemoryId, shared_memory_offset_); 328 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); 329 cmd.Init( 330 client_vertexarray_id_, shared_memory_id_, kInvalidSharedMemoryOffset); 331 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); 332 } 333 334 void BindVertexArrayOESValidArgs() { 335 AddExpectationsForBindVertexArrayOES(); 336 BindVertexArrayOES cmd; 337 cmd.Init(client_vertexarray_id_); 338 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 339 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 340 } 341 342 void BindVertexArrayOESValidArgsNewId() { 343 BindVertexArrayOES cmd; 344 cmd.Init(kNewClientId); 345 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 346 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 347 } 348 }; 349 350 INSTANTIATE_TEST_CASE_P(Service, 351 GLES2DecoderVertexArraysOESTest, 352 ::testing::Bool()); 353 354 class GLES2DecoderEmulatedVertexArraysOESTest 355 : public GLES2DecoderVertexArraysOESTest { 356 public: 357 GLES2DecoderEmulatedVertexArraysOESTest() {} 358 359 virtual void SetUp() { 360 InitState init; 361 init.gl_version = "3.0"; 362 init.bind_generates_resource = true; 363 init.use_native_vao = false; 364 InitDecoder(init); 365 SetupDefaultProgram(); 366 367 AddExpectationsForGenVertexArraysOES(); 368 GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_); 369 370 vertex_array_deleted_manually_ = false; 371 } 372 }; 373 374 INSTANTIATE_TEST_CASE_P(Service, 375 GLES2DecoderEmulatedVertexArraysOESTest, 376 ::testing::Bool()); 377 378 // Test vertex array objects with native support 379 TEST_P(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESImmediateValidArgs) { 380 GenVertexArraysOESImmediateValidArgs(); 381 } 382 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, 383 GenVertexArraysOESImmediateValidArgs) { 384 GenVertexArraysOESImmediateValidArgs(); 385 } 386 387 TEST_P(GLES2DecoderVertexArraysOESTest, 388 GenVertexArraysOESImmediateInvalidArgs) { 389 GenVertexArraysOESImmediateInvalidArgs(); 390 } 391 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, 392 GenVertexArraysOESImmediateInvalidArgs) { 393 GenVertexArraysOESImmediateInvalidArgs(); 394 } 395 396 TEST_P(GLES2DecoderVertexArraysOESTest, 397 DeleteVertexArraysOESImmediateValidArgs) { 398 DeleteVertexArraysOESImmediateValidArgs(); 399 } 400 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, 401 DeleteVertexArraysOESImmediateValidArgs) { 402 DeleteVertexArraysOESImmediateValidArgs(); 403 } 404 405 TEST_P(GLES2DecoderVertexArraysOESTest, 406 DeleteVertexArraysOESImmediateInvalidArgs) { 407 DeleteVertexArraysOESImmediateInvalidArgs(); 408 } 409 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, 410 DeleteVertexArraysOESImmediateInvalidArgs) { 411 DeleteVertexArraysOESImmediateInvalidArgs(); 412 } 413 414 TEST_P(GLES2DecoderVertexArraysOESTest, 415 DeleteBoundVertexArraysOESImmediateValidArgs) { 416 DeleteBoundVertexArraysOESImmediateValidArgs(); 417 } 418 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, 419 DeleteBoundVertexArraysOESImmediateValidArgs) { 420 DeleteBoundVertexArraysOESImmediateValidArgs(); 421 } 422 423 TEST_P(GLES2DecoderVertexArraysOESTest, IsVertexArrayOESValidArgs) { 424 IsVertexArrayOESValidArgs(); 425 } 426 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, IsVertexArrayOESValidArgs) { 427 IsVertexArrayOESValidArgs(); 428 } 429 430 TEST_P(GLES2DecoderVertexArraysOESTest, 431 IsVertexArrayOESInvalidArgsBadSharedMemoryId) { 432 IsVertexArrayOESInvalidArgsBadSharedMemoryId(); 433 } 434 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, 435 IsVertexArrayOESInvalidArgsBadSharedMemoryId) { 436 IsVertexArrayOESInvalidArgsBadSharedMemoryId(); 437 } 438 439 TEST_P(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgs) { 440 BindVertexArrayOESValidArgs(); 441 } 442 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, BindVertexArrayOESValidArgs) { 443 BindVertexArrayOESValidArgs(); 444 } 445 446 TEST_P(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgsNewId) { 447 BindVertexArrayOESValidArgsNewId(); 448 } 449 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest, 450 BindVertexArrayOESValidArgsNewId) { 451 BindVertexArrayOESValidArgsNewId(); 452 } 453 454 TEST_P(GLES2DecoderTest, BufferDataGLError) { 455 GLenum target = GL_ARRAY_BUFFER; 456 GLsizeiptr size = 4; 457 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); 458 BufferManager* manager = group().buffer_manager(); 459 Buffer* buffer = manager->GetBuffer(client_buffer_id_); 460 ASSERT_TRUE(buffer != NULL); 461 EXPECT_EQ(0, buffer->size()); 462 EXPECT_CALL(*gl_, GetError()) 463 .WillOnce(Return(GL_NO_ERROR)) 464 .WillOnce(Return(GL_OUT_OF_MEMORY)) 465 .RetiresOnSaturation(); 466 EXPECT_CALL(*gl_, BufferData(target, size, _, GL_STREAM_DRAW)) 467 .Times(1) 468 .RetiresOnSaturation(); 469 BufferData cmd; 470 cmd.Init(target, size, 0, 0, GL_STREAM_DRAW); 471 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 472 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); 473 EXPECT_EQ(0, buffer->size()); 474 } 475 476 // TODO(gman): BufferData 477 478 // TODO(gman): BufferDataImmediate 479 480 // TODO(gman): BufferSubData 481 482 // TODO(gman): BufferSubDataImmediate 483 484 } // namespace gles2 485 } // namespace gpu 486