| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 // Tests for GLES2Implementation. | 5 // Tests for GLES2Implementation. |
| 6 | 6 |
| 7 #include "gpu/command_buffer/client/gles2_implementation.h" | 7 #include "gpu/command_buffer/client/gles2_implementation.h" |
| 8 | 8 |
| 9 #include <GLES2/gl2ext.h> | 9 #include <GLES2/gl2ext.h> |
| 10 #include <GLES2/gl2extchromium.h> | 10 #include <GLES2/gl2extchromium.h> |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const { | 290 RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const { |
| 291 // Make sure each buffer has a different offset. | 291 // Make sure each buffer has a different offset. |
| 292 return static_cast<uint8*>(pointer) - actual_buffer(); | 292 return static_cast<uint8*>(pointer) - actual_buffer(); |
| 293 } | 293 } |
| 294 | 294 |
| 295 void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) { | 295 void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) { |
| 296 EXPECT_EQ(last_alloc_, p); | 296 EXPECT_EQ(last_alloc_, p); |
| 297 last_alloc_ = NULL; | 297 last_alloc_ = NULL; |
| 298 } | 298 } |
| 299 | 299 |
| 300 // API wrapper for Buffers. |
| 301 class GenBuffersAPI { |
| 302 public: |
| 303 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) { |
| 304 gl_impl->GenBuffers(n, ids); |
| 305 } |
| 306 |
| 307 static void Delete(GLES2Implementation* gl_impl, |
| 308 GLsizei n, |
| 309 const GLuint* ids) { |
| 310 gl_impl->DeleteBuffers(n, ids); |
| 311 } |
| 312 }; |
| 313 |
| 314 // API wrapper for Framebuffers. |
| 315 class GenFramebuffersAPI { |
| 316 public: |
| 317 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) { |
| 318 gl_impl->GenFramebuffers(n, ids); |
| 319 } |
| 320 |
| 321 static void Delete(GLES2Implementation* gl_impl, |
| 322 GLsizei n, |
| 323 const GLuint* ids) { |
| 324 gl_impl->DeleteFramebuffers(n, ids); |
| 325 } |
| 326 }; |
| 327 |
| 328 // API wrapper for Renderbuffers. |
| 329 class GenRenderbuffersAPI { |
| 330 public: |
| 331 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) { |
| 332 gl_impl->GenRenderbuffers(n, ids); |
| 333 } |
| 334 |
| 335 static void Delete(GLES2Implementation* gl_impl, |
| 336 GLsizei n, |
| 337 const GLuint* ids) { |
| 338 gl_impl->DeleteRenderbuffers(n, ids); |
| 339 } |
| 340 }; |
| 341 |
| 342 // API wrapper for Textures. |
| 343 class GenTexturesAPI { |
| 344 public: |
| 345 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) { |
| 346 gl_impl->GenTextures(n, ids); |
| 347 } |
| 348 |
| 349 static void Delete(GLES2Implementation* gl_impl, |
| 350 GLsizei n, |
| 351 const GLuint* ids) { |
| 352 gl_impl->DeleteTextures(n, ids); |
| 353 } |
| 354 }; |
| 355 |
| 300 class GLES2ImplementationTest : public testing::Test { | 356 class GLES2ImplementationTest : public testing::Test { |
| 301 protected: | 357 protected: |
| 358 static const int kNumTestContexts = 2; |
| 302 static const uint8 kInitialValue = 0xBD; | 359 static const uint8 kInitialValue = 0xBD; |
| 303 static const int32 kNumCommandEntries = 500; | 360 static const int32 kNumCommandEntries = 500; |
| 304 static const int32 kCommandBufferSizeBytes = | 361 static const int32 kCommandBufferSizeBytes = |
| 305 kNumCommandEntries * sizeof(CommandBufferEntry); | 362 kNumCommandEntries * sizeof(CommandBufferEntry); |
| 306 static const size_t kTransferBufferSize = 512; | 363 static const size_t kTransferBufferSize = 512; |
| 307 | 364 |
| 308 static const GLint kMaxCombinedTextureImageUnits = 8; | 365 static const GLint kMaxCombinedTextureImageUnits = 8; |
| 309 static const GLint kMaxCubeMapTextureSize = 64; | 366 static const GLint kMaxCubeMapTextureSize = 64; |
| 310 static const GLint kMaxFragmentUniformVectors = 16; | 367 static const GLint kMaxFragmentUniformVectors = 16; |
| 311 static const GLint kMaxRenderbufferSize = 64; | 368 static const GLint kMaxRenderbufferSize = 64; |
| 312 static const GLint kMaxTextureImageUnits = 8; | 369 static const GLint kMaxTextureImageUnits = 8; |
| 313 static const GLint kMaxTextureSize = 128; | 370 static const GLint kMaxTextureSize = 128; |
| 314 static const GLint kMaxVaryingVectors = 8; | 371 static const GLint kMaxVaryingVectors = 8; |
| 315 static const GLint kMaxVertexAttribs = 8; | 372 static const GLint kMaxVertexAttribs = 8; |
| 316 static const GLint kMaxVertexTextureImageUnits = 0; | 373 static const GLint kMaxVertexTextureImageUnits = 0; |
| 317 static const GLint kMaxVertexUniformVectors = 128; | 374 static const GLint kMaxVertexUniformVectors = 128; |
| 318 static const GLint kNumCompressedTextureFormats = 0; | 375 static const GLint kNumCompressedTextureFormats = 0; |
| 319 static const GLint kNumShaderBinaryFormats = 0; | 376 static const GLint kNumShaderBinaryFormats = 0; |
| 320 static const GLuint kStartId = 1024; | 377 static const GLuint kStartId = 1024; |
| 321 static const GLuint kBuffersStartId = | 378 static const GLuint kBuffersStartId = |
| 322 GLES2Implementation::kClientSideArrayId + 2; | 379 GLES2Implementation::kClientSideArrayId + 2 * kNumTestContexts; |
| 323 static const GLuint kFramebuffersStartId = 1; | 380 static const GLuint kFramebuffersStartId = 1; |
| 324 static const GLuint kProgramsAndShadersStartId = 1; | 381 static const GLuint kProgramsAndShadersStartId = 1; |
| 325 static const GLuint kRenderbuffersStartId = 1; | 382 static const GLuint kRenderbuffersStartId = 1; |
| 326 static const GLuint kTexturesStartId = 1; | 383 static const GLuint kTexturesStartId = 1; |
| 327 static const GLuint kQueriesStartId = 1; | 384 static const GLuint kQueriesStartId = 1; |
| 328 static const GLuint kVertexArraysStartId = 1; | 385 static const GLuint kVertexArraysStartId = 1; |
| 329 | 386 |
| 330 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo; | 387 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo; |
| 331 | 388 |
| 332 GLES2ImplementationTest() | 389 class TestContext { |
| 333 : commands_(NULL), | 390 public: |
| 334 token_(0) { | 391 TestContext() : commands_(NULL), token_(0) {} |
| 335 } | 392 |
| 393 void Initialize(ShareGroup* share_group, bool bind_generates_resource) { |
| 394 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>()); |
| 395 ASSERT_TRUE(command_buffer_->Initialize()); |
| 396 |
| 397 transfer_buffer_.reset( |
| 398 new MockTransferBuffer(command_buffer_.get(), |
| 399 kTransferBufferSize, |
| 400 GLES2Implementation::kStartingOffset, |
| 401 GLES2Implementation::kAlignment)); |
| 402 |
| 403 helper_.reset(new GLES2CmdHelper(command_buffer())); |
| 404 helper_->Initialize(kCommandBufferSizeBytes); |
| 405 |
| 406 gpu_control_.reset(new StrictMock<MockClientGpuControl>()); |
| 407 EXPECT_CALL(*gpu_control_, GetCapabilities()) |
| 408 .WillOnce(testing::Return(Capabilities())); |
| 409 |
| 410 GLES2Implementation::GLStaticState state; |
| 411 GLES2Implementation::GLStaticState::IntState& int_state = state.int_state; |
| 412 int_state.max_combined_texture_image_units = |
| 413 kMaxCombinedTextureImageUnits; |
| 414 int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize; |
| 415 int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; |
| 416 int_state.max_renderbuffer_size = kMaxRenderbufferSize; |
| 417 int_state.max_texture_image_units = kMaxTextureImageUnits; |
| 418 int_state.max_texture_size = kMaxTextureSize; |
| 419 int_state.max_varying_vectors = kMaxVaryingVectors; |
| 420 int_state.max_vertex_attribs = kMaxVertexAttribs; |
| 421 int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits; |
| 422 int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors; |
| 423 int_state.num_compressed_texture_formats = kNumCompressedTextureFormats; |
| 424 int_state.num_shader_binary_formats = kNumShaderBinaryFormats; |
| 425 |
| 426 // This just happens to work for now because IntState has 1 GLint per |
| 427 // state. |
| 428 // If IntState gets more complicated this code will need to get more |
| 429 // complicated. |
| 430 ExpectedMemoryInfo mem1 = transfer_buffer_->GetExpectedMemory( |
| 431 sizeof(GLES2Implementation::GLStaticState::IntState) * 2 + |
| 432 sizeof(cmds::GetShaderPrecisionFormat::Result) * 12); |
| 433 |
| 434 { |
| 435 InSequence sequence; |
| 436 |
| 437 EXPECT_CALL(*command_buffer_, OnFlush()) |
| 438 .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state)) |
| 439 .RetiresOnSaturation(); |
| 440 GetNextToken(); // eat the token that starting up will use. |
| 441 |
| 442 gl_.reset( |
| 443 new GLES2Implementation(helper_.get(), |
| 444 share_group, |
| 445 transfer_buffer_.get(), |
| 446 bind_generates_resource, |
| 447 false /* free_everything_when_invisible */, |
| 448 gpu_control_.get())); |
| 449 ASSERT_TRUE(gl_->Initialize(kTransferBufferSize, |
| 450 kTransferBufferSize, |
| 451 kTransferBufferSize, |
| 452 GLES2Implementation::kNoLimit)); |
| 453 } |
| 454 |
| 455 EXPECT_CALL(*command_buffer_, OnFlush()).Times(1).RetiresOnSaturation(); |
| 456 helper_->CommandBufferHelper::Finish(); |
| 457 ::testing::Mock::VerifyAndClearExpectations(gl_.get()); |
| 458 |
| 459 Buffer ring_buffer = helper_->get_ring_buffer(); |
| 460 commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + |
| 461 command_buffer()->GetState().put_offset; |
| 462 ClearCommands(); |
| 463 EXPECT_TRUE(transfer_buffer_->InSync()); |
| 464 |
| 465 ::testing::Mock::VerifyAndClearExpectations(command_buffer()); |
| 466 } |
| 467 |
| 468 void TearDown() { |
| 469 Mock::VerifyAndClear(gl_.get()); |
| 470 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber()); |
| 471 // For command buffer. |
| 472 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) |
| 473 .Times(AtLeast(1)); |
| 474 gl_.reset(); |
| 475 } |
| 476 |
| 477 MockClientCommandBuffer* command_buffer() const { |
| 478 return command_buffer_.get(); |
| 479 } |
| 480 |
| 481 int GetNextToken() { return ++token_; } |
| 482 |
| 483 void ClearCommands() { |
| 484 Buffer ring_buffer = helper_->get_ring_buffer(); |
| 485 memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); |
| 486 } |
| 487 |
| 488 scoped_ptr<MockClientCommandBuffer> command_buffer_; |
| 489 scoped_ptr<MockClientGpuControl> gpu_control_; |
| 490 scoped_ptr<GLES2CmdHelper> helper_; |
| 491 scoped_ptr<MockTransferBuffer> transfer_buffer_; |
| 492 scoped_ptr<GLES2Implementation> gl_; |
| 493 CommandBufferEntry* commands_; |
| 494 int token_; |
| 495 }; |
| 496 |
| 497 GLES2ImplementationTest() : commands_(NULL) {} |
| 336 | 498 |
| 337 virtual void SetUp() OVERRIDE; | 499 virtual void SetUp() OVERRIDE; |
| 338 virtual void TearDown() OVERRIDE; | 500 virtual void TearDown() OVERRIDE; |
| 339 | 501 |
| 340 bool NoCommandsWritten() { | 502 bool NoCommandsWritten() { |
| 341 Buffer ring_buffer = helper_->get_ring_buffer(); | 503 Buffer ring_buffer = helper_->get_ring_buffer(); |
| 342 const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer.ptr); | 504 const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer.ptr); |
| 343 const uint8* end = cmds + ring_buffer.size; | 505 const uint8* end = cmds + ring_buffer.size; |
| 344 for (; cmds < end; ++cmds) { | 506 for (; cmds < end; ++cmds) { |
| 345 if (*cmds != kInitialValue) { | 507 if (*cmds != kInitialValue) { |
| 346 return false; | 508 return false; |
| 347 } | 509 } |
| 348 } | 510 } |
| 349 return true; | 511 return true; |
| 350 } | 512 } |
| 351 | 513 |
| 352 QueryTracker::Query* GetQuery(GLuint id) { | 514 QueryTracker::Query* GetQuery(GLuint id) { |
| 353 return gl_->query_tracker_->GetQuery(id); | 515 return gl_->query_tracker_->GetQuery(id); |
| 354 } | 516 } |
| 355 | 517 |
| 356 void Initialize(bool bind_generates_resource) { | 518 void Initialize(bool bind_generates_resource) { |
| 357 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>()); | 519 share_group_ = new ShareGroup(bind_generates_resource); |
| 358 ASSERT_TRUE(command_buffer_->Initialize()); | |
| 359 | 520 |
| 360 transfer_buffer_.reset(new MockTransferBuffer( | 521 for (int i = 0; i < kNumTestContexts; i++) |
| 361 command_buffer(), | 522 test_contexts_[i].Initialize(share_group_.get(), bind_generates_resource); |
| 362 kTransferBufferSize, | |
| 363 GLES2Implementation::kStartingOffset, | |
| 364 GLES2Implementation::kAlignment)); | |
| 365 | 523 |
| 366 helper_.reset(new GLES2CmdHelper(command_buffer())); | 524 // Default to test context 0. |
| 367 helper_->Initialize(kCommandBufferSizeBytes); | 525 gpu_control_ = test_contexts_[0].gpu_control_.get(); |
| 368 | 526 helper_ = test_contexts_[0].helper_.get(); |
| 369 gpu_control_.reset(new StrictMock<MockClientGpuControl>()); | 527 transfer_buffer_ = test_contexts_[0].transfer_buffer_.get(); |
| 370 EXPECT_CALL(*gpu_control_, GetCapabilities()) | 528 gl_ = test_contexts_[0].gl_.get(); |
| 371 .WillOnce(testing::Return(Capabilities())); | 529 commands_ = test_contexts_[0].commands_; |
| 372 | |
| 373 GLES2Implementation::GLStaticState state; | |
| 374 GLES2Implementation::GLStaticState::IntState& int_state = state.int_state; | |
| 375 int_state.max_combined_texture_image_units = kMaxCombinedTextureImageUnits; | |
| 376 int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize; | |
| 377 int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; | |
| 378 int_state.max_renderbuffer_size = kMaxRenderbufferSize; | |
| 379 int_state.max_texture_image_units = kMaxTextureImageUnits; | |
| 380 int_state.max_texture_size = kMaxTextureSize; | |
| 381 int_state.max_varying_vectors = kMaxVaryingVectors; | |
| 382 int_state.max_vertex_attribs = kMaxVertexAttribs; | |
| 383 int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits; | |
| 384 int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors; | |
| 385 int_state.num_compressed_texture_formats = kNumCompressedTextureFormats; | |
| 386 int_state.num_shader_binary_formats = kNumShaderBinaryFormats; | |
| 387 | |
| 388 // This just happens to work for now because IntState has 1 GLint per state. | |
| 389 // If IntState gets more complicated this code will need to get more | |
| 390 // complicated. | |
| 391 ExpectedMemoryInfo mem1 = GetExpectedMemory( | |
| 392 sizeof(GLES2Implementation::GLStaticState::IntState) * 2 + | |
| 393 sizeof(cmds::GetShaderPrecisionFormat::Result) * 12); | |
| 394 | |
| 395 { | |
| 396 InSequence sequence; | |
| 397 | |
| 398 EXPECT_CALL(*command_buffer(), OnFlush()) | |
| 399 .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state)) | |
| 400 .RetiresOnSaturation(); | |
| 401 GetNextToken(); // eat the token that starting up will use. | |
| 402 | |
| 403 gl_.reset(new GLES2Implementation( | |
| 404 helper_.get(), | |
| 405 NULL, | |
| 406 transfer_buffer_.get(), | |
| 407 bind_generates_resource, | |
| 408 false /* free_everything_when_invisible */, | |
| 409 gpu_control_.get())); | |
| 410 ASSERT_TRUE(gl_->Initialize( | |
| 411 kTransferBufferSize, | |
| 412 kTransferBufferSize, | |
| 413 kTransferBufferSize, | |
| 414 GLES2Implementation::kNoLimit)); | |
| 415 } | |
| 416 | |
| 417 EXPECT_CALL(*command_buffer(), OnFlush()) | |
| 418 .Times(1) | |
| 419 .RetiresOnSaturation(); | |
| 420 helper_->CommandBufferHelper::Finish(); | |
| 421 ::testing::Mock::VerifyAndClearExpectations(gl_.get()); | |
| 422 | |
| 423 Buffer ring_buffer = helper_->get_ring_buffer(); | |
| 424 commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + | |
| 425 command_buffer()->GetState().put_offset; | |
| 426 ClearCommands(); | |
| 427 EXPECT_TRUE(transfer_buffer_->InSync()); | |
| 428 | |
| 429 ::testing::Mock::VerifyAndClearExpectations(command_buffer()); | |
| 430 } | 530 } |
| 431 | 531 |
| 432 MockClientCommandBuffer* command_buffer() const { | 532 MockClientCommandBuffer* command_buffer() const { |
| 433 return command_buffer_.get(); | 533 return test_contexts_[0].command_buffer_.get(); |
| 434 } | 534 } |
| 435 | 535 |
| 436 int GetNextToken() { | 536 int GetNextToken() { return test_contexts_[0].GetNextToken(); } |
| 437 return ++token_; | |
| 438 } | |
| 439 | 537 |
| 440 const void* GetPut() { | 538 const void* GetPut() { |
| 441 return helper_->GetSpace(0); | 539 return helper_->GetSpace(0); |
| 442 } | 540 } |
| 443 | 541 |
| 444 void ClearCommands() { | 542 void ClearCommands() { |
| 445 Buffer ring_buffer = helper_->get_ring_buffer(); | 543 Buffer ring_buffer = helper_->get_ring_buffer(); |
| 446 memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); | 544 memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); |
| 447 } | 545 } |
| 448 | 546 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 470 EXPECT_CALL(*command_buffer(), OnFlush()) | 568 EXPECT_CALL(*command_buffer(), OnFlush()) |
| 471 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR))) | 569 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR))) |
| 472 .RetiresOnSaturation(); | 570 .RetiresOnSaturation(); |
| 473 return gl_->GetError(); | 571 return gl_->GetError(); |
| 474 } | 572 } |
| 475 | 573 |
| 476 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) { | 574 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) { |
| 477 return gl_->GetBucketContents(bucket_id, data); | 575 return gl_->GetBucketContents(bucket_id, data); |
| 478 } | 576 } |
| 479 | 577 |
| 480 Sequence sequence_; | 578 TestContext test_contexts_[kNumTestContexts]; |
| 481 scoped_ptr<MockClientCommandBuffer> command_buffer_; | 579 |
| 482 scoped_ptr<MockClientGpuControl> gpu_control_; | 580 scoped_refptr<ShareGroup> share_group_; |
| 483 scoped_ptr<GLES2CmdHelper> helper_; | 581 MockClientGpuControl* gpu_control_; |
| 484 scoped_ptr<MockTransferBuffer> transfer_buffer_; | 582 GLES2CmdHelper* helper_; |
| 485 scoped_ptr<GLES2Implementation> gl_; | 583 MockTransferBuffer* transfer_buffer_; |
| 584 GLES2Implementation* gl_; |
| 486 CommandBufferEntry* commands_; | 585 CommandBufferEntry* commands_; |
| 487 int token_; | |
| 488 }; | 586 }; |
| 489 | 587 |
| 490 void GLES2ImplementationTest::SetUp() { | 588 void GLES2ImplementationTest::SetUp() { |
| 491 Initialize(true); | 589 Initialize(true); |
| 492 } | 590 } |
| 493 | 591 |
| 494 void GLES2ImplementationTest::TearDown() { | 592 void GLES2ImplementationTest::TearDown() { |
| 495 Mock::VerifyAndClear(gl_.get()); | 593 for (int i = 0; i < kNumTestContexts; i++) |
| 496 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber()); | 594 test_contexts_[i].TearDown(); |
| 497 // For command buffer. | |
| 498 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | |
| 499 .Times(AtLeast(1)); | |
| 500 gl_.reset(); | |
| 501 } | 595 } |
| 502 | 596 |
| 503 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest { | 597 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest { |
| 504 protected: | 598 protected: |
| 505 virtual void SetUp() OVERRIDE; | 599 virtual void SetUp() OVERRIDE; |
| 600 |
| 601 template <class ResApi> |
| 602 void FlushGenerationTest() { |
| 603 GLuint id1, id2, id3; |
| 604 |
| 605 // Generate valid id. |
| 606 ResApi::Gen(gl_, 1, &id1); |
| 607 EXPECT_NE(id1, 0u); |
| 608 |
| 609 // Delete id1 and generate id2. id1 should not be reused. |
| 610 ResApi::Delete(gl_, 1, &id1); |
| 611 ResApi::Gen(gl_, 1, &id2); |
| 612 EXPECT_NE(id2, 0u); |
| 613 EXPECT_NE(id2, id1); |
| 614 |
| 615 // Expect id1 reuse after Flush. |
| 616 gl_->Flush(); |
| 617 ResApi::Gen(gl_, 1, &id3); |
| 618 EXPECT_EQ(id3, id1); |
| 619 } |
| 620 |
| 621 // Ids should not be reused unless the |Deleting| context does a Flush() |
| 622 // AND triggers a lazy release after that. |
| 623 template <class ResApi> |
| 624 void CrossContextGenerationTest() { |
| 625 GLES2Implementation* gl1 = test_contexts_[0].gl_.get(); |
| 626 GLES2Implementation* gl2 = test_contexts_[1].gl_.get(); |
| 627 GLuint id1, id2, id3; |
| 628 |
| 629 // Delete, no flush on context 1. No reuse. |
| 630 ResApi::Gen(gl1, 1, &id1); |
| 631 ResApi::Delete(gl1, 1, &id1); |
| 632 ResApi::Gen(gl1, 1, &id2); |
| 633 EXPECT_NE(id1, id2); |
| 634 |
| 635 // Flush context 2. Still no reuse. |
| 636 gl2->Flush(); |
| 637 ResApi::Gen(gl2, 1, &id3); |
| 638 EXPECT_NE(id1, id3); |
| 639 EXPECT_NE(id2, id3); |
| 640 |
| 641 // Flush on context 1, but no lazy release. Still no reuse. |
| 642 gl1->Flush(); |
| 643 ResApi::Gen(gl2, 1, &id3); |
| 644 EXPECT_NE(id1, id3); |
| 645 |
| 646 // Lazy release triggered by another Delete. Should reuse id1. |
| 647 ResApi::Delete(gl1, 1, &id2); |
| 648 ResApi::Gen(gl2, 1, &id3); |
| 649 EXPECT_EQ(id1, id3); |
| 650 } |
| 651 |
| 652 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on |
| 653 // the Delete(). Tests an edge case regression. |
| 654 template <class ResApi> |
| 655 void CrossContextGenerationAutoFlushTest() { |
| 656 GLES2Implementation* gl1 = test_contexts_[0].gl_.get(); |
| 657 GLES2Implementation* gl2 = test_contexts_[1].gl_.get(); |
| 658 GLuint id1, id2, id3; |
| 659 |
| 660 // Delete, no flush on context 1. No reuse. |
| 661 // By half filling the buffer, an internal flush is forced on the Delete(). |
| 662 ResApi::Gen(gl1, 1, &id1); |
| 663 gl1->helper()->Noop(kNumCommandEntries / 2); |
| 664 ResApi::Delete(gl1, 1, &id1); |
| 665 ResApi::Gen(gl1, 1, &id2); |
| 666 EXPECT_NE(id1, id2); |
| 667 |
| 668 // Flush context 2. Still no reuse. |
| 669 gl2->Flush(); |
| 670 ResApi::Gen(gl2, 1, &id3); |
| 671 EXPECT_NE(id1, id3); |
| 672 EXPECT_NE(id2, id3); |
| 673 |
| 674 // Flush on context 1, but no lazy release. Still no reuse. |
| 675 gl1->Flush(); |
| 676 ResApi::Gen(gl2, 1, &id3); |
| 677 EXPECT_NE(id1, id3); |
| 678 |
| 679 // Lazy release triggered by another Delete. Should reuse id1. |
| 680 ResApi::Delete(gl1, 1, &id2); |
| 681 ResApi::Gen(gl2, 1, &id3); |
| 682 EXPECT_EQ(id1, id3); |
| 683 } |
| 506 }; | 684 }; |
| 507 | 685 |
| 508 void GLES2ImplementationStrictSharedTest::SetUp() { | 686 void GLES2ImplementationStrictSharedTest::SetUp() { |
| 509 Initialize(false); | 687 Initialize(false); |
| 510 } | 688 } |
| 511 | 689 |
| 512 // GCC requires these declarations, but MSVC requires they not be present | 690 // GCC requires these declarations, but MSVC requires they not be present |
| 513 #ifndef _MSC_VER | 691 #ifndef _MSC_VER |
| 514 const uint8 GLES2ImplementationTest::kInitialValue; | 692 const uint8 GLES2ImplementationTest::kInitialValue; |
| 515 const int32 GLES2ImplementationTest::kNumCommandEntries; | 693 const int32 GLES2ImplementationTest::kNumCommandEntries; |
| (...skipping 1921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2437 GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result)); | 2615 GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result)); |
| 2438 EXPECT_CALL(*command_buffer(), OnFlush()) | 2616 EXPECT_CALL(*command_buffer(), OnFlush()) |
| 2439 .WillOnce(SetMemory(result1.ptr, | 2617 .WillOnce(SetMemory(result1.ptr, |
| 2440 SizedResultHelper<GLuint>(pv.expected))) | 2618 SizedResultHelper<GLuint>(pv.expected))) |
| 2441 .RetiresOnSaturation(); | 2619 .RetiresOnSaturation(); |
| 2442 gl_->GetIntegerv(pv.pname, &v); | 2620 gl_->GetIntegerv(pv.pname, &v); |
| 2443 EXPECT_EQ(pv.expected, v); | 2621 EXPECT_EQ(pv.expected, v); |
| 2444 } | 2622 } |
| 2445 } | 2623 } |
| 2446 | 2624 |
| 2625 // glGen* Ids must not be reused until glDelete* commands have been |
| 2626 // flushed by glFlush. |
| 2627 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) { |
| 2628 FlushGenerationTest<GenBuffersAPI>(); |
| 2629 } |
| 2630 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) { |
| 2631 FlushGenerationTest<GenFramebuffersAPI>(); |
| 2632 } |
| 2633 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) { |
| 2634 FlushGenerationTest<GenRenderbuffersAPI>(); |
| 2635 } |
| 2636 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestTextures) { |
| 2637 FlushGenerationTest<GenTexturesAPI>(); |
| 2638 } |
| 2639 |
| 2640 // glGen* Ids must not be reused cross-context until glDelete* commands are |
| 2641 // flushed by glFlush, and the Ids are lazily freed after. |
| 2642 TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) { |
| 2643 CrossContextGenerationTest<GenBuffersAPI>(); |
| 2644 } |
| 2645 TEST_F(GLES2ImplementationStrictSharedTest, |
| 2646 CrossContextGenerationTestFramebuffers) { |
| 2647 CrossContextGenerationTest<GenFramebuffersAPI>(); |
| 2648 } |
| 2649 TEST_F(GLES2ImplementationStrictSharedTest, |
| 2650 CrossContextGenerationTestRenderbuffers) { |
| 2651 CrossContextGenerationTest<GenRenderbuffersAPI>(); |
| 2652 } |
| 2653 TEST_F(GLES2ImplementationStrictSharedTest, |
| 2654 CrossContextGenerationTestTextures) { |
| 2655 CrossContextGenerationTest<GenTexturesAPI>(); |
| 2656 } |
| 2657 |
| 2658 // Test Delete which causes auto flush. Tests a regression case that occurred |
| 2659 // in testing. |
| 2660 TEST_F(GLES2ImplementationStrictSharedTest, |
| 2661 CrossContextGenerationAutoFlushTestBuffers) { |
| 2662 CrossContextGenerationAutoFlushTest<GenBuffersAPI>(); |
| 2663 } |
| 2664 TEST_F(GLES2ImplementationStrictSharedTest, |
| 2665 CrossContextGenerationAutoFlushTestFramebuffers) { |
| 2666 CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>(); |
| 2667 } |
| 2668 TEST_F(GLES2ImplementationStrictSharedTest, |
| 2669 CrossContextGenerationAutoFlushTestRenderbuffers) { |
| 2670 CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>(); |
| 2671 } |
| 2672 TEST_F(GLES2ImplementationStrictSharedTest, |
| 2673 CrossContextGenerationAutoFlushTestTextures) { |
| 2674 CrossContextGenerationAutoFlushTest<GenTexturesAPI>(); |
| 2675 } |
| 2676 |
| 2447 TEST_F(GLES2ImplementationTest, GetString) { | 2677 TEST_F(GLES2ImplementationTest, GetString) { |
| 2448 const uint32 kBucketId = GLES2Implementation::kResultBucketId; | 2678 const uint32 kBucketId = GLES2Implementation::kResultBucketId; |
| 2449 const Str7 kString = {"foobar"}; | 2679 const Str7 kString = {"foobar"}; |
| 2450 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into | 2680 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into |
| 2451 // GLES2Implementation. | 2681 // GLES2Implementation. |
| 2452 const char* expected_str = | 2682 const char* expected_str = |
| 2453 "foobar " | 2683 "foobar " |
| 2454 "GL_CHROMIUM_flipy " | 2684 "GL_CHROMIUM_flipy " |
| 2455 "GL_EXT_unpack_subimage"; | 2685 "GL_EXT_unpack_subimage"; |
| 2456 const char kBad = 0x12; | 2686 const char kBad = 0x12; |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2843 ClearCommands(); | 3073 ClearCommands(); |
| 2844 gl_->Enable(GL_BLEND); | 3074 gl_->Enable(GL_BLEND); |
| 2845 EXPECT_TRUE(NoCommandsWritten()); | 3075 EXPECT_TRUE(NoCommandsWritten()); |
| 2846 } | 3076 } |
| 2847 | 3077 |
| 2848 | 3078 |
| 2849 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h" | 3079 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h" |
| 2850 | 3080 |
| 2851 } // namespace gles2 | 3081 } // namespace gles2 |
| 2852 } // namespace gpu | 3082 } // namespace gpu |
| OLD | NEW |