1 // Copyright (c) 2012 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_unittest.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.h" 20 #include "gpu/command_buffer/service/gpu_switches.h" 21 #include "gpu/command_buffer/service/image_manager.h" 22 #include "gpu/command_buffer/service/mailbox_manager.h" 23 #include "gpu/command_buffer/service/mocks.h" 24 #include "gpu/command_buffer/service/program_manager.h" 25 #include "gpu/command_buffer/service/test_helper.h" 26 #include "testing/gtest/include/gtest/gtest.h" 27 #include "ui/gl/gl_implementation.h" 28 #include "ui/gl/gl_mock.h" 29 #include "ui/gl/gl_surface_stub.h" 30 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::AtLeast; 39 using ::testing::DoAll; 40 using ::testing::InSequence; 41 using ::testing::Invoke; 42 using ::testing::MatcherCast; 43 using ::testing::Mock; 44 using ::testing::Pointee; 45 using ::testing::Return; 46 using ::testing::SaveArg; 47 using ::testing::SetArrayArgument; 48 using ::testing::SetArgumentPointee; 49 using ::testing::SetArgPointee; 50 using ::testing::StrEq; 51 using ::testing::StrictMock; 52 53 namespace gpu { 54 namespace gles2 { 55 56 using namespace cmds; 57 58 void GLES2DecoderRGBBackbufferTest::SetUp() { 59 // Test codepath with workaround clear_alpha_in_readpixels because 60 // ReadPixelsEmulator emulates the incorrect driver behavior. 61 CommandLine command_line(0, NULL); 62 command_line.AppendSwitchASCII( 63 switches::kGpuDriverBugWorkarounds, 64 base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS)); 65 InitState init; 66 init.gl_version = "3.0"; 67 init.bind_generates_resource = true; 68 InitDecoderWithCommandLine(init, &command_line); 69 SetupDefaultProgram(); 70 } 71 72 // Override default setup so nothing gets setup. 73 void GLES2DecoderManualInitTest::SetUp() { 74 } 75 76 void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap, 77 bool enable, 78 bool expect_set) { 79 if (expect_set) { 80 SetupExpectationsForEnableDisable(cap, enable); 81 } 82 if (enable) { 83 Enable cmd; 84 cmd.Init(cap); 85 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 86 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 87 } else { 88 Disable cmd; 89 cmd.Init(cap); 90 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 91 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 92 } 93 } 94 95 TEST_P(GLES2DecoderTest, GetIntegervCached) { 96 struct TestInfo { 97 GLenum pname; 98 GLint expected; 99 }; 100 TestInfo tests[] = { 101 { 102 GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize, 103 }, 104 { 105 GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize, 106 }, 107 { 108 GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize, 109 }, 110 }; 111 typedef GetIntegerv::Result Result; 112 for (size_t ii = 0; ii < sizeof(tests) / sizeof(tests[0]); ++ii) { 113 const TestInfo& test = tests[ii]; 114 Result* result = static_cast<Result*>(shared_memory_address_); 115 EXPECT_CALL(*gl_, GetError()) 116 .WillOnce(Return(GL_NO_ERROR)) 117 .WillOnce(Return(GL_NO_ERROR)) 118 .RetiresOnSaturation(); 119 EXPECT_CALL(*gl_, GetIntegerv(test.pname, _)).Times(0); 120 result->size = 0; 121 GetIntegerv cmd2; 122 cmd2.Init(test.pname, shared_memory_id_, shared_memory_offset_); 123 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); 124 EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname), 125 result->GetNumResults()); 126 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 127 EXPECT_EQ(test.expected, result->GetData()[0]); 128 } 129 } 130 131 TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) { 132 SetupIndexBuffer(); 133 GetMaxValueInBufferCHROMIUM::Result* result = 134 static_cast<GetMaxValueInBufferCHROMIUM::Result*>(shared_memory_address_); 135 *result = 0; 136 137 GetMaxValueInBufferCHROMIUM cmd; 138 cmd.Init(client_element_buffer_id_, 139 kValidIndexRangeCount, 140 GL_UNSIGNED_SHORT, 141 kValidIndexRangeStart * 2, 142 kSharedMemoryId, 143 kSharedMemoryOffset); 144 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 145 EXPECT_EQ(7u, *result); 146 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 147 cmd.Init(client_element_buffer_id_, 148 kValidIndexRangeCount + 1, 149 GL_UNSIGNED_SHORT, 150 kValidIndexRangeStart * 2, 151 kSharedMemoryId, 152 kSharedMemoryOffset); 153 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 154 EXPECT_EQ(100u, *result); 155 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 156 157 cmd.Init(kInvalidClientId, 158 kValidIndexRangeCount, 159 GL_UNSIGNED_SHORT, 160 kValidIndexRangeStart * 2, 161 kSharedMemoryId, 162 kSharedMemoryOffset); 163 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 164 EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); 165 cmd.Init(client_element_buffer_id_, 166 kOutOfRangeIndexRangeEnd, 167 GL_UNSIGNED_SHORT, 168 kValidIndexRangeStart * 2, 169 kSharedMemoryId, 170 kSharedMemoryOffset); 171 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 172 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 173 cmd.Init(client_element_buffer_id_, 174 kValidIndexRangeCount + 1, 175 GL_UNSIGNED_SHORT, 176 kOutOfRangeIndexRangeEnd * 2, 177 kSharedMemoryId, 178 kSharedMemoryOffset); 179 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 180 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 181 cmd.Init(client_element_buffer_id_, 182 kValidIndexRangeCount + 1, 183 GL_UNSIGNED_SHORT, 184 kValidIndexRangeStart * 2, 185 kSharedMemoryId, 186 kSharedMemoryOffset); 187 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 188 cmd.Init(client_buffer_id_, 189 kValidIndexRangeCount + 1, 190 GL_UNSIGNED_SHORT, 191 kValidIndexRangeStart * 2, 192 kSharedMemoryId, 193 kSharedMemoryOffset); 194 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 195 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 196 cmd.Init(client_element_buffer_id_, 197 kValidIndexRangeCount + 1, 198 GL_UNSIGNED_SHORT, 199 kValidIndexRangeStart * 2, 200 kInvalidSharedMemoryId, 201 kSharedMemoryOffset); 202 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 203 cmd.Init(client_element_buffer_id_, 204 kValidIndexRangeCount + 1, 205 GL_UNSIGNED_SHORT, 206 kValidIndexRangeStart * 2, 207 kSharedMemoryId, 208 kInvalidSharedMemoryOffset); 209 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 210 } 211 212 TEST_P(GLES2DecoderTest, SharedIds) { 213 GenSharedIdsCHROMIUM gen_cmd; 214 RegisterSharedIdsCHROMIUM reg_cmd; 215 DeleteSharedIdsCHROMIUM del_cmd; 216 217 const GLuint kNamespaceId = id_namespaces::kTextures; 218 const GLuint kExpectedId1 = 1; 219 const GLuint kExpectedId2 = 2; 220 const GLuint kExpectedId3 = 4; 221 const GLuint kRegisterId = 3; 222 GLuint* ids = GetSharedMemoryAs<GLuint*>(); 223 gen_cmd.Init(kNamespaceId, 0, 2, kSharedMemoryId, kSharedMemoryOffset); 224 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); 225 IdAllocatorInterface* id_allocator = GetIdAllocator(kNamespaceId); 226 ASSERT_TRUE(id_allocator != NULL); 227 // This check is implementation dependant but it's kind of hard to check 228 // otherwise. 229 EXPECT_EQ(kExpectedId1, ids[0]); 230 EXPECT_EQ(kExpectedId2, ids[1]); 231 EXPECT_TRUE(id_allocator->InUse(kExpectedId1)); 232 EXPECT_TRUE(id_allocator->InUse(kExpectedId2)); 233 EXPECT_FALSE(id_allocator->InUse(kRegisterId)); 234 EXPECT_FALSE(id_allocator->InUse(kExpectedId3)); 235 236 ClearSharedMemory(); 237 ids[0] = kRegisterId; 238 reg_cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset); 239 EXPECT_EQ(error::kNoError, ExecuteCmd(reg_cmd)); 240 EXPECT_TRUE(id_allocator->InUse(kExpectedId1)); 241 EXPECT_TRUE(id_allocator->InUse(kExpectedId2)); 242 EXPECT_TRUE(id_allocator->InUse(kRegisterId)); 243 EXPECT_FALSE(id_allocator->InUse(kExpectedId3)); 244 245 ClearSharedMemory(); 246 gen_cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kSharedMemoryOffset); 247 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); 248 EXPECT_EQ(kExpectedId3, ids[0]); 249 EXPECT_TRUE(id_allocator->InUse(kExpectedId1)); 250 EXPECT_TRUE(id_allocator->InUse(kExpectedId2)); 251 EXPECT_TRUE(id_allocator->InUse(kRegisterId)); 252 EXPECT_TRUE(id_allocator->InUse(kExpectedId3)); 253 254 ClearSharedMemory(); 255 ids[0] = kExpectedId1; 256 ids[1] = kRegisterId; 257 del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset); 258 EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd)); 259 EXPECT_FALSE(id_allocator->InUse(kExpectedId1)); 260 EXPECT_TRUE(id_allocator->InUse(kExpectedId2)); 261 EXPECT_FALSE(id_allocator->InUse(kRegisterId)); 262 EXPECT_TRUE(id_allocator->InUse(kExpectedId3)); 263 264 ClearSharedMemory(); 265 ids[0] = kExpectedId3; 266 ids[1] = kExpectedId2; 267 del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset); 268 EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd)); 269 EXPECT_FALSE(id_allocator->InUse(kExpectedId1)); 270 EXPECT_FALSE(id_allocator->InUse(kExpectedId2)); 271 EXPECT_FALSE(id_allocator->InUse(kRegisterId)); 272 EXPECT_FALSE(id_allocator->InUse(kExpectedId3)); 273 274 // Check passing in an id_offset. 275 ClearSharedMemory(); 276 const GLuint kOffset = 0xABCDEF; 277 gen_cmd.Init(kNamespaceId, kOffset, 2, kSharedMemoryId, kSharedMemoryOffset); 278 EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); 279 EXPECT_EQ(kOffset, ids[0]); 280 EXPECT_EQ(kOffset + 1, ids[1]); 281 } 282 283 TEST_P(GLES2DecoderTest, GenSharedIdsCHROMIUMBadArgs) { 284 const GLuint kNamespaceId = id_namespaces::kTextures; 285 GenSharedIdsCHROMIUM cmd; 286 cmd.Init(kNamespaceId, 0, -1, kSharedMemoryId, kSharedMemoryOffset); 287 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 288 cmd.Init(kNamespaceId, 0, 1, kInvalidSharedMemoryId, kSharedMemoryOffset); 289 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 290 cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kInvalidSharedMemoryOffset); 291 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 292 } 293 294 TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMBadArgs) { 295 const GLuint kNamespaceId = id_namespaces::kTextures; 296 RegisterSharedIdsCHROMIUM cmd; 297 cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset); 298 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 299 cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset); 300 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 301 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset); 302 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 303 } 304 305 TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMDuplicateIds) { 306 const GLuint kNamespaceId = id_namespaces::kTextures; 307 const GLuint kRegisterId = 3; 308 RegisterSharedIdsCHROMIUM cmd; 309 GLuint* ids = GetSharedMemoryAs<GLuint*>(); 310 ids[0] = kRegisterId; 311 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset); 312 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 313 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset); 314 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 315 EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); 316 } 317 318 TEST_P(GLES2DecoderTest, DeleteSharedIdsCHROMIUMBadArgs) { 319 const GLuint kNamespaceId = id_namespaces::kTextures; 320 DeleteSharedIdsCHROMIUM cmd; 321 cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset); 322 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 323 cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset); 324 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 325 cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset); 326 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 327 } 328 329 TEST_P(GLES2DecoderTest, IsBuffer) { 330 EXPECT_FALSE(DoIsBuffer(client_buffer_id_)); 331 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); 332 EXPECT_TRUE(DoIsBuffer(client_buffer_id_)); 333 DoDeleteBuffer(client_buffer_id_, kServiceBufferId); 334 EXPECT_FALSE(DoIsBuffer(client_buffer_id_)); 335 } 336 337 TEST_P(GLES2DecoderTest, IsFramebuffer) { 338 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_)); 339 DoBindFramebuffer( 340 GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId); 341 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_)); 342 DoDeleteFramebuffer(client_framebuffer_id_, 343 kServiceFramebufferId, 344 true, 345 GL_FRAMEBUFFER, 346 0, 347 true, 348 GL_FRAMEBUFFER, 349 0); 350 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_)); 351 } 352 353 TEST_P(GLES2DecoderTest, IsProgram) { 354 // IsProgram is true as soon as the program is created. 355 EXPECT_TRUE(DoIsProgram(client_program_id_)); 356 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId)) 357 .Times(1) 358 .RetiresOnSaturation(); 359 DoDeleteProgram(client_program_id_, kServiceProgramId); 360 EXPECT_FALSE(DoIsProgram(client_program_id_)); 361 } 362 363 TEST_P(GLES2DecoderTest, IsRenderbuffer) { 364 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_)); 365 DoBindRenderbuffer( 366 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId); 367 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_)); 368 DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId); 369 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_)); 370 } 371 372 TEST_P(GLES2DecoderTest, IsShader) { 373 // IsShader is true as soon as the program is created. 374 EXPECT_TRUE(DoIsShader(client_shader_id_)); 375 DoDeleteShader(client_shader_id_, kServiceShaderId); 376 EXPECT_FALSE(DoIsShader(client_shader_id_)); 377 } 378 379 TEST_P(GLES2DecoderTest, IsTexture) { 380 EXPECT_FALSE(DoIsTexture(client_texture_id_)); 381 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); 382 EXPECT_TRUE(DoIsTexture(client_texture_id_)); 383 DoDeleteTexture(client_texture_id_, kServiceTextureId); 384 EXPECT_FALSE(DoIsTexture(client_texture_id_)); 385 } 386 387 TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMValidArgs) { 388 const GLsizei kCount = 3; 389 GLenum* pnames = GetSharedMemoryAs<GLenum*>(); 390 pnames[0] = GL_DEPTH_WRITEMASK; 391 pnames[1] = GL_COLOR_WRITEMASK; 392 pnames[2] = GL_STENCIL_WRITEMASK; 393 GLint* results = 394 GetSharedMemoryAsWithOffset<GLint*>(sizeof(*pnames) * kCount); 395 396 GLsizei num_results = 0; 397 for (GLsizei ii = 0; ii < kCount; ++ii) { 398 num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]); 399 } 400 const GLsizei result_size = num_results * sizeof(*results); 401 memset(results, 0, result_size); 402 403 const GLint kSentinel = 0x12345678; 404 results[num_results] = kSentinel; 405 406 GetMultipleIntegervCHROMIUM cmd; 407 cmd.Init(kSharedMemoryId, 408 kSharedMemoryOffset, 409 kCount, 410 kSharedMemoryId, 411 kSharedMemoryOffset + sizeof(*pnames) * kCount, 412 result_size); 413 414 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 415 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 416 EXPECT_EQ(1, results[0]); // Depth writemask 417 EXPECT_EQ(1, results[1]); // color writemask red 418 EXPECT_EQ(1, results[2]); // color writemask green 419 EXPECT_EQ(1, results[3]); // color writemask blue 420 EXPECT_EQ(1, results[4]); // color writemask alpha 421 EXPECT_EQ(-1, results[5]); // stencil writemask alpha 422 EXPECT_EQ(kSentinel, results[num_results]); // End of results 423 } 424 425 TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) { 426 const GLsizei kCount = 3; 427 // Offset the pnames because GLGetError will use the first uint32. 428 const uint32 kPnameOffset = sizeof(uint32); 429 const uint32 kResultsOffset = kPnameOffset + sizeof(GLint) * kCount; 430 GLenum* pnames = GetSharedMemoryAsWithOffset<GLenum*>(kPnameOffset); 431 pnames[0] = GL_DEPTH_WRITEMASK; 432 pnames[1] = GL_COLOR_WRITEMASK; 433 pnames[2] = GL_STENCIL_WRITEMASK; 434 GLint* results = GetSharedMemoryAsWithOffset<GLint*>(kResultsOffset); 435 436 GLsizei num_results = 0; 437 for (GLsizei ii = 0; ii < kCount; ++ii) { 438 num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]); 439 } 440 const GLsizei result_size = num_results * sizeof(*results); 441 memset(results, 0, result_size); 442 443 const GLint kSentinel = 0x12345678; 444 results[num_results] = kSentinel; 445 446 GetMultipleIntegervCHROMIUM cmd; 447 // Check bad pnames pointer. 448 cmd.Init(kInvalidSharedMemoryId, 449 kSharedMemoryOffset + kPnameOffset, 450 kCount, 451 kSharedMemoryId, 452 kSharedMemoryOffset + kResultsOffset, 453 result_size); 454 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); 455 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 456 // Check bad pnames pointer. 457 cmd.Init(kSharedMemoryId, 458 kInvalidSharedMemoryOffset, 459 kCount, 460 kSharedMemoryId, 461 kSharedMemoryOffset + kResultsOffset, 462 result_size); 463 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); 464 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 465 // Check bad count. 466 cmd.Init(kSharedMemoryId, 467 kSharedMemoryOffset + kPnameOffset, 468 static_cast<GLuint>(-1), 469 kSharedMemoryId, 470 kSharedMemoryOffset + kResultsOffset, 471 result_size); 472 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); 473 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 474 // Check bad results pointer. 475 cmd.Init(kSharedMemoryId, 476 kSharedMemoryOffset + kPnameOffset, 477 kCount, 478 kInvalidSharedMemoryId, 479 kSharedMemoryOffset + kResultsOffset, 480 result_size); 481 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); 482 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 483 // Check bad results pointer. 484 cmd.Init(kSharedMemoryId, 485 kSharedMemoryOffset + kPnameOffset, 486 kCount, 487 kSharedMemoryId, 488 kInvalidSharedMemoryOffset, 489 result_size); 490 EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); 491 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 492 // Check bad size. 493 cmd.Init(kSharedMemoryId, 494 kSharedMemoryOffset + kPnameOffset, 495 kCount, 496 kSharedMemoryId, 497 kSharedMemoryOffset + kResultsOffset, 498 result_size + 1); 499 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 500 EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); 501 // Check bad size. 502 cmd.Init(kSharedMemoryId, 503 kSharedMemoryOffset + kPnameOffset, 504 kCount, 505 kSharedMemoryId, 506 kSharedMemoryOffset + kResultsOffset, 507 result_size - 1); 508 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 509 EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); 510 // Check bad enum. 511 cmd.Init(kSharedMemoryId, 512 kSharedMemoryOffset + kPnameOffset, 513 kCount, 514 kSharedMemoryId, 515 kSharedMemoryOffset + kResultsOffset, 516 result_size); 517 GLenum temp = pnames[2]; 518 pnames[2] = GL_TRUE; 519 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 520 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 521 pnames[2] = temp; 522 // Check results area has not been cleared by client. 523 results[1] = 1; 524 EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); 525 // Check buffer is what we expect 526 EXPECT_EQ(0, results[0]); 527 EXPECT_EQ(1, results[1]); 528 EXPECT_EQ(0, results[2]); 529 EXPECT_EQ(0, results[3]); 530 EXPECT_EQ(0, results[4]); 531 EXPECT_EQ(0, results[5]); 532 EXPECT_EQ(kSentinel, results[num_results]); // End of results 533 } 534 535 TEST_P(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) { 536 InitState init; 537 init.gl_version = "3.0"; 538 InitDecoder(init); 539 540 BindTexture cmd1; 541 cmd1.Init(GL_TEXTURE_2D, kInvalidClientId); 542 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1)); 543 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 544 545 BindBuffer cmd2; 546 cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId); 547 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); 548 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 549 550 BindFramebuffer cmd3; 551 cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId); 552 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd3)); 553 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 554 555 BindRenderbuffer cmd4; 556 cmd4.Init(GL_RENDERBUFFER, kInvalidClientId); 557 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd4)); 558 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 559 } 560 561 TEST_P(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) { 562 const uint32 kBadBucketId = 123; 563 EnableFeatureCHROMIUM cmd; 564 cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_); 565 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 566 } 567 568 TEST_P(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) { 569 const uint32 kBadBucketId = 123; 570 RequestExtensionCHROMIUM cmd; 571 cmd.Init(kBadBucketId); 572 EXPECT_NE(error::kNoError, ExecuteCmd(cmd)); 573 } 574 575 TEST_P(GLES2DecoderTest, BeginQueryEXTDisabled) { 576 // Test something fails if off. 577 } 578 579 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) { 580 InitState init; 581 init.extensions = "GL_EXT_occlusion_query_boolean"; 582 init.gl_version = "opengl es 2.0"; 583 init.has_alpha = true; 584 init.request_alpha = true; 585 init.bind_generates_resource = true; 586 InitDecoder(init); 587 588 // Test end fails if no begin. 589 EndQueryEXT end_cmd; 590 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1); 591 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd)); 592 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 593 594 BeginQueryEXT begin_cmd; 595 596 // Test id = 0 fails. 597 begin_cmd.Init( 598 GL_ANY_SAMPLES_PASSED_EXT, 0, kSharedMemoryId, kSharedMemoryOffset); 599 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); 600 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 601 602 GenHelper<GenQueriesEXTImmediate>(kNewClientId); 603 604 // Test valid parameters work. 605 EXPECT_CALL(*gl_, GenQueriesARB(1, _)) 606 .WillOnce(SetArgumentPointee<1>(kNewServiceId)) 607 .RetiresOnSaturation(); 608 EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId)) 609 .Times(1) 610 .RetiresOnSaturation(); 611 612 // Query object should not be created untill BeginQueriesEXT. 613 QueryManager* query_manager = decoder_->GetQueryManager(); 614 ASSERT_TRUE(query_manager != NULL); 615 QueryManager::Query* query = query_manager->GetQuery(kNewClientId); 616 EXPECT_TRUE(query == NULL); 617 618 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT. 619 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 620 kInvalidClientId, 621 kSharedMemoryId, 622 kSharedMemoryOffset); 623 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); 624 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 625 626 begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 627 kNewClientId, 628 kSharedMemoryId, 629 kSharedMemoryOffset); 630 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); 631 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 632 633 // After BeginQueriesEXT id name should have query object associated with it. 634 query = query_manager->GetQuery(kNewClientId); 635 ASSERT_TRUE(query != NULL); 636 EXPECT_FALSE(query->pending()); 637 638 // Test trying begin again fails 639 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); 640 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 641 642 // Test end fails with different target 643 end_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1); 644 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd)); 645 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 646 647 // Test end succeeds 648 EXPECT_CALL(*gl_, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT)) 649 .Times(1) 650 .RetiresOnSaturation(); 651 end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1); 652 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd)); 653 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 654 EXPECT_TRUE(query->pending()); 655 656 EXPECT_CALL(*gl_, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation(); 657 } 658 659 struct QueryType { 660 GLenum type; 661 bool is_gl; 662 }; 663 664 const QueryType kQueryTypes[] = { 665 {GL_COMMANDS_ISSUED_CHROMIUM, false}, 666 {GL_LATENCY_QUERY_CHROMIUM, false}, 667 {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, false}, 668 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false}, 669 {GL_GET_ERROR_QUERY_CHROMIUM, false}, 670 {GL_COMMANDS_COMPLETED_CHROMIUM, false}, 671 {GL_ANY_SAMPLES_PASSED_EXT, true}, 672 }; 673 674 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test, 675 GLuint client_id, 676 GLuint service_id, 677 const QueryType& query_type, 678 int32 shm_id, 679 uint32 shm_offset) { 680 // We need to reset the decoder on each iteration, because we lose the 681 // context every time. 682 GLES2DecoderTestBase::InitState init; 683 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync"; 684 init.gl_version = "opengl es 2.0"; 685 init.has_alpha = true; 686 init.request_alpha = true; 687 init.bind_generates_resource = true; 688 test->InitDecoder(init); 689 ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock(); 690 691 BeginQueryEXT begin_cmd; 692 693 test->GenHelper<GenQueriesEXTImmediate>(client_id); 694 695 if (query_type.is_gl) { 696 EXPECT_CALL(*gl, GenQueriesARB(1, _)) 697 .WillOnce(SetArgumentPointee<1>(service_id)) 698 .RetiresOnSaturation(); 699 EXPECT_CALL(*gl, BeginQueryARB(query_type.type, service_id)) 700 .Times(1) 701 .RetiresOnSaturation(); 702 } 703 704 // Test bad shared memory fails 705 begin_cmd.Init(query_type.type, client_id, shm_id, shm_offset); 706 error::Error error1 = test->ExecuteCmd(begin_cmd); 707 708 if (query_type.is_gl) { 709 EXPECT_CALL(*gl, EndQueryARB(query_type.type)) 710 .Times(1) 711 .RetiresOnSaturation(); 712 } 713 if (query_type.type == GL_GET_ERROR_QUERY_CHROMIUM) { 714 EXPECT_CALL(*gl, GetError()) 715 .WillOnce(Return(GL_NO_ERROR)) 716 .RetiresOnSaturation(); 717 } 718 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef); 719 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) { 720 EXPECT_CALL(*gl, Flush()).RetiresOnSaturation(); 721 EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) 722 .WillOnce(Return(kGlSync)) 723 .RetiresOnSaturation(); 724 #if DCHECK_IS_ON 725 EXPECT_CALL(*gl, IsSync(kGlSync)) 726 .WillOnce(Return(GL_TRUE)) 727 .RetiresOnSaturation(); 728 #endif 729 } 730 731 EndQueryEXT end_cmd; 732 end_cmd.Init(query_type.type, 1); 733 error::Error error2 = test->ExecuteCmd(end_cmd); 734 735 if (query_type.is_gl) { 736 EXPECT_CALL( 737 *gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _)) 738 .WillOnce(SetArgumentPointee<2>(1)) 739 .RetiresOnSaturation(); 740 EXPECT_CALL(*gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _)) 741 .WillOnce(SetArgumentPointee<2>(1)) 742 .RetiresOnSaturation(); 743 } 744 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) { 745 #if DCHECK_IS_ON 746 EXPECT_CALL(*gl, IsSync(kGlSync)) 747 .WillOnce(Return(GL_TRUE)) 748 .RetiresOnSaturation(); 749 #endif 750 EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _)) 751 .WillOnce(Return(GL_ALREADY_SIGNALED)) 752 .RetiresOnSaturation(); 753 } 754 755 QueryManager* query_manager = test->GetDecoder()->GetQueryManager(); 756 ASSERT_TRUE(query_manager != NULL); 757 bool process_success = query_manager->ProcessPendingQueries(); 758 759 EXPECT_TRUE(error1 != error::kNoError || error2 != error::kNoError || 760 !process_success); 761 762 if (query_type.is_gl) { 763 EXPECT_CALL(*gl, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation(); 764 } 765 if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) { 766 #if DCHECK_IS_ON 767 EXPECT_CALL(*gl, IsSync(kGlSync)) 768 .WillOnce(Return(GL_TRUE)) 769 .RetiresOnSaturation(); 770 #endif 771 EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation(); 772 } 773 test->ResetDecoder(); 774 } 775 776 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) { 777 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) { 778 CheckBeginEndQueryBadMemoryFails(this, 779 kNewClientId, 780 kNewServiceId, 781 kQueryTypes[i], 782 kInvalidSharedMemoryId, 783 kSharedMemoryOffset); 784 } 785 } 786 787 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) { 788 for (size_t i = 0; i < arraysize(kQueryTypes); ++i) { 789 // Out-of-bounds. 790 CheckBeginEndQueryBadMemoryFails(this, 791 kNewClientId, 792 kNewServiceId, 793 kQueryTypes[i], 794 kSharedMemoryId, 795 kInvalidSharedMemoryOffset); 796 // Overflow. 797 CheckBeginEndQueryBadMemoryFails(this, 798 kNewClientId, 799 kNewServiceId, 800 kQueryTypes[i], 801 kSharedMemoryId, 802 0xfffffffcu); 803 } 804 } 805 806 TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) { 807 BeginQueryEXT begin_cmd; 808 809 GenHelper<GenQueriesEXTImmediate>(kNewClientId); 810 811 // Test valid parameters work. 812 begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 813 kNewClientId, 814 kSharedMemoryId, 815 kSharedMemoryOffset); 816 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); 817 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 818 819 QueryManager* query_manager = decoder_->GetQueryManager(); 820 ASSERT_TRUE(query_manager != NULL); 821 QueryManager::Query* query = query_manager->GetQuery(kNewClientId); 822 ASSERT_TRUE(query != NULL); 823 EXPECT_FALSE(query->pending()); 824 825 // Test end succeeds 826 EndQueryEXT end_cmd; 827 end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1); 828 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd)); 829 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 830 EXPECT_FALSE(query->pending()); 831 } 832 833 TEST_P(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) { 834 BeginQueryEXT begin_cmd; 835 836 GenHelper<GenQueriesEXTImmediate>(kNewClientId); 837 838 // Test valid parameters work. 839 begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 840 kNewClientId, 841 kSharedMemoryId, 842 kSharedMemoryOffset); 843 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); 844 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 845 846 QueryManager* query_manager = decoder_->GetQueryManager(); 847 ASSERT_TRUE(query_manager != NULL); 848 QueryManager::Query* query = query_manager->GetQuery(kNewClientId); 849 ASSERT_TRUE(query != NULL); 850 EXPECT_FALSE(query->pending()); 851 852 // Test end succeeds 853 QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_); 854 855 EXPECT_CALL(*gl_, GetError()) 856 .WillOnce(Return(GL_INVALID_VALUE)) 857 .RetiresOnSaturation(); 858 859 EndQueryEXT end_cmd; 860 end_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 1); 861 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd)); 862 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 863 EXPECT_FALSE(query->pending()); 864 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), 865 static_cast<GLenum>(sync->result)); 866 } 867 868 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) { 869 InitState init; 870 init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync"; 871 init.gl_version = "opengl es 2.0"; 872 init.has_alpha = true; 873 init.request_alpha = true; 874 init.bind_generates_resource = true; 875 InitDecoder(init); 876 877 GenHelper<GenQueriesEXTImmediate>(kNewClientId); 878 879 BeginQueryEXT begin_cmd; 880 begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 881 kNewClientId, 882 kSharedMemoryId, 883 kSharedMemoryOffset); 884 EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); 885 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 886 887 QueryManager* query_manager = decoder_->GetQueryManager(); 888 ASSERT_TRUE(query_manager != NULL); 889 QueryManager::Query* query = query_manager->GetQuery(kNewClientId); 890 ASSERT_TRUE(query != NULL); 891 EXPECT_FALSE(query->pending()); 892 893 GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef); 894 EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation(); 895 EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)) 896 .WillOnce(Return(kGlSync)) 897 .RetiresOnSaturation(); 898 #if DCHECK_IS_ON 899 EXPECT_CALL(*gl_, IsSync(kGlSync)) 900 .WillOnce(Return(GL_TRUE)) 901 .RetiresOnSaturation(); 902 #endif 903 904 EndQueryEXT end_cmd; 905 end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1); 906 EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd)); 907 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 908 EXPECT_TRUE(query->pending()); 909 910 #if DCHECK_IS_ON 911 EXPECT_CALL(*gl_, IsSync(kGlSync)) 912 .WillOnce(Return(GL_TRUE)) 913 .RetiresOnSaturation(); 914 #endif 915 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _)) 916 .WillOnce(Return(GL_TIMEOUT_EXPIRED)) 917 .RetiresOnSaturation(); 918 bool process_success = query_manager->ProcessPendingQueries(); 919 920 EXPECT_TRUE(process_success); 921 EXPECT_TRUE(query->pending()); 922 923 #if DCHECK_IS_ON 924 EXPECT_CALL(*gl_, IsSync(kGlSync)) 925 .WillOnce(Return(GL_TRUE)) 926 .RetiresOnSaturation(); 927 #endif 928 EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _)) 929 .WillOnce(Return(GL_ALREADY_SIGNALED)) 930 .RetiresOnSaturation(); 931 process_success = query_manager->ProcessPendingQueries(); 932 933 EXPECT_TRUE(process_success); 934 EXPECT_FALSE(query->pending()); 935 QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_); 936 EXPECT_EQ(static_cast<GLenum>(0), static_cast<GLenum>(sync->result)); 937 938 #if DCHECK_IS_ON 939 EXPECT_CALL(*gl_, IsSync(kGlSync)) 940 .WillOnce(Return(GL_TRUE)) 941 .RetiresOnSaturation(); 942 #endif 943 EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation(); 944 ResetDecoder(); 945 } 946 947 TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) { 948 // NOTE: There are no expectations because no GL functions should be 949 // called for DEPTH_TEST or STENCIL_TEST 950 static const GLenum kStates[] = { 951 GL_DEPTH_TEST, GL_STENCIL_TEST, 952 }; 953 for (size_t ii = 0; ii < arraysize(kStates); ++ii) { 954 Enable enable_cmd; 955 GLenum state = kStates[ii]; 956 enable_cmd.Init(state); 957 EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd)); 958 IsEnabled::Result* result = 959 static_cast<IsEnabled::Result*>(shared_memory_address_); 960 IsEnabled is_enabled_cmd; 961 is_enabled_cmd.Init(state, shared_memory_id_, shared_memory_offset_); 962 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd)); 963 EXPECT_NE(0u, *result); 964 Disable disable_cmd; 965 disable_cmd.Init(state); 966 EXPECT_EQ(error::kNoError, ExecuteCmd(disable_cmd)); 967 EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd)); 968 EXPECT_EQ(0u, *result); 969 } 970 } 971 972 TEST_P(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) { 973 InitState init; 974 init.extensions = "GL_ARB_texture_rectangle"; 975 init.gl_version = "3.0"; 976 init.bind_generates_resource = true; 977 InitDecoder(init); 978 979 Texture* texture = GetTexture(client_texture_id_)->texture(); 980 EXPECT_TRUE(texture != NULL); 981 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM); 982 983 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); 984 985 TexParameteri cmd; 986 cmd.Init(GL_TEXTURE_2D, 987 GL_TEXTURE_POOL_CHROMIUM, 988 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM); 989 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 990 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 991 992 cmd.Init(GL_TEXTURE_2D, 993 GL_TEXTURE_POOL_CHROMIUM, 994 GL_TEXTURE_POOL_MANAGED_CHROMIUM); 995 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 996 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 997 998 EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM); 999 1000 cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_NONE); 1001 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1002 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 1003 } 1004 1005 namespace { 1006 1007 class SizeOnlyMemoryTracker : public MemoryTracker { 1008 public: 1009 SizeOnlyMemoryTracker() { 1010 // These are the default textures. 1 for TEXTURE_2D and 6 faces for 1011 // TEXTURE_CUBE_MAP. 1012 const size_t kInitialUnmanagedPoolSize = 7 * 4; 1013 const size_t kInitialManagedPoolSize = 0; 1014 pool_infos_[MemoryTracker::kUnmanaged].initial_size = 1015 kInitialUnmanagedPoolSize; 1016 pool_infos_[MemoryTracker::kManaged].initial_size = kInitialManagedPoolSize; 1017 } 1018 1019 // Ensure a certain amount of GPU memory is free. Returns true on success. 1020 MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed)); 1021 1022 virtual void TrackMemoryAllocatedChange(size_t old_size, 1023 size_t new_size, 1024 Pool pool) { 1025 PoolInfo& info = pool_infos_[pool]; 1026 info.size += new_size - old_size; 1027 } 1028 1029 size_t GetPoolSize(Pool pool) { 1030 const PoolInfo& info = pool_infos_[pool]; 1031 return info.size - info.initial_size; 1032 } 1033 1034 private: 1035 virtual ~SizeOnlyMemoryTracker() {} 1036 struct PoolInfo { 1037 PoolInfo() : initial_size(0), size(0) {} 1038 size_t initial_size; 1039 size_t size; 1040 }; 1041 std::map<Pool, PoolInfo> pool_infos_; 1042 }; 1043 1044 } // anonymous namespace. 1045 1046 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) { 1047 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = 1048 new SizeOnlyMemoryTracker(); 1049 set_memory_tracker(memory_tracker.get()); 1050 InitState init; 1051 init.gl_version = "3.0"; 1052 init.bind_generates_resource = true; 1053 InitDecoder(init); 1054 // Expect that initial size - size is 0. 1055 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); 1056 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged)); 1057 } 1058 1059 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) { 1060 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = 1061 new SizeOnlyMemoryTracker(); 1062 set_memory_tracker(memory_tracker.get()); 1063 InitState init; 1064 init.gl_version = "3.0"; 1065 init.bind_generates_resource = true; 1066 InitDecoder(init); 1067 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); 1068 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128)) 1069 .WillOnce(Return(true)) 1070 .RetiresOnSaturation(); 1071 DoTexImage2D(GL_TEXTURE_2D, 1072 0, 1073 GL_RGBA, 1074 8, 1075 4, 1076 0, 1077 GL_RGBA, 1078 GL_UNSIGNED_BYTE, 1079 kSharedMemoryId, 1080 kSharedMemoryOffset); 1081 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); 1082 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64)) 1083 .WillOnce(Return(true)) 1084 .RetiresOnSaturation(); 1085 DoTexImage2D(GL_TEXTURE_2D, 1086 0, 1087 GL_RGBA, 1088 4, 1089 4, 1090 0, 1091 GL_RGBA, 1092 GL_UNSIGNED_BYTE, 1093 kSharedMemoryId, 1094 kSharedMemoryOffset); 1095 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); 1096 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1097 // Check we get out of memory and no call to glTexImage2D if Ensure fails. 1098 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64)) 1099 .WillOnce(Return(false)) 1100 .RetiresOnSaturation(); 1101 TexImage2D cmd; 1102 cmd.Init(GL_TEXTURE_2D, 1103 0, 1104 GL_RGBA, 1105 4, 1106 4, 1107 GL_RGBA, 1108 GL_UNSIGNED_BYTE, 1109 kSharedMemoryId, 1110 kSharedMemoryOffset); 1111 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1112 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); 1113 EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); 1114 } 1115 1116 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) { 1117 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = 1118 new SizeOnlyMemoryTracker(); 1119 set_memory_tracker(memory_tracker.get()); 1120 InitState init; 1121 init.gl_version = "3.0"; 1122 init.bind_generates_resource = true; 1123 InitDecoder(init); 1124 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); 1125 // Check we get out of memory and no call to glTexStorage2DEXT 1126 // if Ensure fails. 1127 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128)) 1128 .WillOnce(Return(false)) 1129 .RetiresOnSaturation(); 1130 TexStorage2DEXT cmd; 1131 cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4); 1132 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1133 EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); 1134 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); 1135 } 1136 1137 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) { 1138 GLenum target = GL_TEXTURE_2D; 1139 GLint level = 0; 1140 GLenum internal_format = GL_RGBA; 1141 GLsizei width = 4; 1142 GLsizei height = 8; 1143 GLint border = 0; 1144 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = 1145 new SizeOnlyMemoryTracker(); 1146 set_memory_tracker(memory_tracker.get()); 1147 InitState init; 1148 init.gl_version = "3.0"; 1149 init.has_alpha = true; 1150 init.request_alpha = true; 1151 init.bind_generates_resource = true; 1152 InitDecoder(init); 1153 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); 1154 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128)) 1155 .WillOnce(Return(true)) 1156 .RetiresOnSaturation(); 1157 EXPECT_CALL(*gl_, GetError()) 1158 .WillOnce(Return(GL_NO_ERROR)) 1159 .WillOnce(Return(GL_NO_ERROR)) 1160 .RetiresOnSaturation(); 1161 EXPECT_CALL(*gl_, 1162 CopyTexImage2D( 1163 target, level, internal_format, 0, 0, width, height, border)) 1164 .Times(1) 1165 .RetiresOnSaturation(); 1166 CopyTexImage2D cmd; 1167 cmd.Init(target, level, internal_format, 0, 0, width, height); 1168 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1169 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); 1170 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1171 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails. 1172 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128)) 1173 .WillOnce(Return(false)) 1174 .RetiresOnSaturation(); 1175 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1176 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); 1177 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); 1178 } 1179 1180 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) { 1181 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = 1182 new SizeOnlyMemoryTracker(); 1183 set_memory_tracker(memory_tracker.get()); 1184 InitState init; 1185 init.gl_version = "3.0"; 1186 init.bind_generates_resource = true; 1187 InitDecoder(init); 1188 DoBindRenderbuffer( 1189 GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId); 1190 EnsureRenderbufferBound(false); 1191 EXPECT_CALL(*gl_, GetError()) 1192 .WillOnce(Return(GL_NO_ERROR)) 1193 .WillOnce(Return(GL_NO_ERROR)) 1194 .RetiresOnSaturation(); 1195 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128)) 1196 .WillOnce(Return(true)) 1197 .RetiresOnSaturation(); 1198 EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 8, 4)) 1199 .Times(1) 1200 .RetiresOnSaturation(); 1201 RenderbufferStorage cmd; 1202 cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4); 1203 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1204 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1205 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); 1206 // Check we get out of memory and no call to glRenderbufferStorage if Ensure 1207 // fails. 1208 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128)) 1209 .WillOnce(Return(false)) 1210 .RetiresOnSaturation(); 1211 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1212 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); 1213 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged)); 1214 } 1215 1216 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerBufferData) { 1217 scoped_refptr<SizeOnlyMemoryTracker> memory_tracker = 1218 new SizeOnlyMemoryTracker(); 1219 set_memory_tracker(memory_tracker.get()); 1220 InitState init; 1221 init.gl_version = "3.0"; 1222 init.bind_generates_resource = true; 1223 InitDecoder(init); 1224 DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); 1225 EXPECT_CALL(*gl_, GetError()) 1226 .WillOnce(Return(GL_NO_ERROR)) 1227 .WillOnce(Return(GL_NO_ERROR)) 1228 .RetiresOnSaturation(); 1229 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128)) 1230 .WillOnce(Return(true)) 1231 .RetiresOnSaturation(); 1232 EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW)) 1233 .Times(1) 1234 .RetiresOnSaturation(); 1235 BufferData cmd; 1236 cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW); 1237 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1238 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1239 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged)); 1240 // Check we get out of memory and no call to glBufferData if Ensure 1241 // fails. 1242 EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128)) 1243 .WillOnce(Return(false)) 1244 .RetiresOnSaturation(); 1245 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1246 EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError()); 1247 EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged)); 1248 } 1249 1250 TEST_P(GLES2DecoderManualInitTest, ImmutableCopyTexImage2D) { 1251 const GLenum kTarget = GL_TEXTURE_2D; 1252 const GLint kLevel = 0; 1253 const GLenum kInternalFormat = GL_RGBA; 1254 const GLenum kSizedInternalFormat = GL_RGBA8; 1255 const GLsizei kWidth = 4; 1256 const GLsizei kHeight = 8; 1257 const GLint kBorder = 0; 1258 InitState init; 1259 init.extensions = "GL_EXT_texture_storage"; 1260 init.gl_version = "3.0"; 1261 init.has_alpha = true; 1262 init.request_alpha = true; 1263 init.bind_generates_resource = true; 1264 InitDecoder(init); 1265 DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); 1266 1267 // CopyTexImage2D will call arbitrary amount of GetErrors. 1268 EXPECT_CALL(*gl_, GetError()) 1269 .Times(AtLeast(1)); 1270 1271 EXPECT_CALL(*gl_, 1272 CopyTexImage2D( 1273 kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight, 1274 kBorder)) 1275 .Times(1); 1276 1277 EXPECT_CALL(*gl_, 1278 TexStorage2DEXT( 1279 kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight)) 1280 .Times(1); 1281 CopyTexImage2D copy_cmd; 1282 copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight); 1283 EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd)); 1284 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1285 1286 TexStorage2DEXT storage_cmd; 1287 storage_cmd.Init(kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight); 1288 EXPECT_EQ(error::kNoError, ExecuteCmd(storage_cmd)); 1289 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1290 1291 // This should not invoke CopyTexImage2D. 1292 copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight); 1293 EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd)); 1294 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); 1295 } 1296 1297 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMValidArgs) { 1298 EXPECT_CALL(*mock_decoder_, LoseContext(GL_GUILTY_CONTEXT_RESET_ARB)) 1299 .Times(1); 1300 cmds::LoseContextCHROMIUM cmd; 1301 cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_GUILTY_CONTEXT_RESET_ARB); 1302 EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd)); 1303 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1304 } 1305 1306 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs0_0) { 1307 EXPECT_CALL(*mock_decoder_, LoseContext(_)) 1308 .Times(0); 1309 cmds::LoseContextCHROMIUM cmd; 1310 cmd.Init(GL_NONE, GL_GUILTY_CONTEXT_RESET_ARB); 1311 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1312 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 1313 } 1314 1315 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs1_0) { 1316 EXPECT_CALL(*mock_decoder_, LoseContext(_)) 1317 .Times(0); 1318 cmds::LoseContextCHROMIUM cmd; 1319 cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_NONE); 1320 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); 1321 EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); 1322 } 1323 1324 class GLES2DecoderDoCommandsTest : public GLES2DecoderTest { 1325 public: 1326 GLES2DecoderDoCommandsTest() { 1327 for (int i = 0; i < 3; i++) { 1328 cmds_[i].Init(GL_BLEND); 1329 } 1330 entries_per_cmd_ = ComputeNumEntries(cmds_[0].ComputeSize()); 1331 } 1332 1333 void SetExpectationsForNCommands(int num_commands) { 1334 for (int i = 0; i < num_commands; i++) 1335 SetupExpectationsForEnableDisable(GL_BLEND, true); 1336 } 1337 1338 protected: 1339 Enable cmds_[3]; 1340 int entries_per_cmd_; 1341 }; 1342 1343 // Test that processing with 0 entries does nothing. 1344 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfZero) { 1345 int num_processed = -1; 1346 SetExpectationsForNCommands(0); 1347 EXPECT_EQ( 1348 error::kNoError, 1349 decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 0, &num_processed)); 1350 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1351 EXPECT_EQ(0, num_processed); 1352 } 1353 1354 // Test processing at granularity of single commands. 1355 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfOne) { 1356 int num_processed = -1; 1357 SetExpectationsForNCommands(1); 1358 EXPECT_EQ( 1359 error::kNoError, 1360 decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 1, &num_processed)); 1361 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1362 EXPECT_EQ(entries_per_cmd_, num_processed); 1363 } 1364 1365 // Test processing at granularity of multiple commands. 1366 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsThreeOfThree) { 1367 int num_processed = -1; 1368 SetExpectationsForNCommands(3); 1369 EXPECT_EQ( 1370 error::kNoError, 1371 decoder_->DoCommands(3, &cmds_, entries_per_cmd_ * 3, &num_processed)); 1372 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1373 EXPECT_EQ(entries_per_cmd_ * 3, num_processed); 1374 } 1375 1376 // Test processing a request smaller than available entries. 1377 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsTwoOfThree) { 1378 int num_processed = -1; 1379 SetExpectationsForNCommands(2); 1380 EXPECT_EQ( 1381 error::kNoError, 1382 decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 3, &num_processed)); 1383 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1384 EXPECT_EQ(entries_per_cmd_ * 2, num_processed); 1385 } 1386 1387 // Test that processing stops on a command with size 0. 1388 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsZeroCmdSize) { 1389 cmds_[1].header.size = 0; 1390 int num_processed = -1; 1391 SetExpectationsForNCommands(1); 1392 EXPECT_EQ( 1393 error::kInvalidSize, 1394 decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 2, &num_processed)); 1395 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1396 EXPECT_EQ(entries_per_cmd_, num_processed); 1397 } 1398 1399 // Test that processing stops on a command with size greater than available. 1400 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOutOfBounds) { 1401 int num_processed = -1; 1402 SetExpectationsForNCommands(1); 1403 EXPECT_EQ(error::kOutOfBounds, 1404 decoder_->DoCommands( 1405 2, &cmds_, entries_per_cmd_ * 2 - 1, &num_processed)); 1406 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1407 EXPECT_EQ(entries_per_cmd_, num_processed); 1408 } 1409 1410 // Test that commands with bad argument size are skipped without processing. 1411 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsBadArgSize) { 1412 cmds_[1].header.size += 1; 1413 int num_processed = -1; 1414 SetExpectationsForNCommands(1); 1415 EXPECT_EQ(error::kInvalidArguments, 1416 decoder_->DoCommands( 1417 2, &cmds_, entries_per_cmd_ * 2 + 1, &num_processed)); 1418 EXPECT_EQ(GL_NO_ERROR, GetGLError()); 1419 EXPECT_EQ(entries_per_cmd_ + cmds_[1].header.size, num_processed); 1420 } 1421 1422 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool()); 1423 1424 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool()); 1425 1426 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderManualInitTest, ::testing::Bool()); 1427 1428 INSTANTIATE_TEST_CASE_P(Service, 1429 GLES2DecoderRGBBackbufferTest, 1430 ::testing::Bool()); 1431 1432 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDoCommandsTest, ::testing::Bool()); 1433 1434 } // namespace gles2 1435 } // namespace gpu 1436