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 <limits> | 9 #include <limits> |
10 | 10 |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 static const GLuint kTexturesStartId = 1; | 385 static const GLuint kTexturesStartId = 1; |
386 static const GLuint kQueriesStartId = 1; | 386 static const GLuint kQueriesStartId = 1; |
387 static const GLuint kVertexArraysStartId = 1; | 387 static const GLuint kVertexArraysStartId = 1; |
388 | 388 |
389 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo; | 389 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo; |
390 | 390 |
391 class TestContext { | 391 class TestContext { |
392 public: | 392 public: |
393 TestContext() : commands_(NULL), token_(0) {} | 393 TestContext() : commands_(NULL), token_(0) {} |
394 | 394 |
395 void Initialize(ShareGroup* share_group, | 395 bool Initialize(ShareGroup* share_group, |
396 bool bind_generates_resource, | 396 bool bind_generates_resource, |
397 bool lose_context_when_out_of_memory) { | 397 bool lose_context_when_out_of_memory) { |
398 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>()); | 398 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>()); |
399 ASSERT_TRUE(command_buffer_->Initialize()); | 399 if (!command_buffer_->Initialize()) |
| 400 return false; |
400 | 401 |
401 transfer_buffer_.reset( | 402 transfer_buffer_.reset( |
402 new MockTransferBuffer(command_buffer_.get(), | 403 new MockTransferBuffer(command_buffer_.get(), |
403 kTransferBufferSize, | 404 kTransferBufferSize, |
404 GLES2Implementation::kStartingOffset, | 405 GLES2Implementation::kStartingOffset, |
405 GLES2Implementation::kAlignment)); | 406 GLES2Implementation::kAlignment)); |
406 | 407 |
407 helper_.reset(new GLES2CmdHelper(command_buffer())); | 408 helper_.reset(new GLES2CmdHelper(command_buffer())); |
408 helper_->Initialize(kCommandBufferSizeBytes); | 409 helper_->Initialize(kCommandBufferSizeBytes); |
409 | 410 |
410 gpu_control_.reset(new StrictMock<MockClientGpuControl>()); | 411 gpu_control_.reset(new StrictMock<MockClientGpuControl>()); |
411 EXPECT_CALL(*gpu_control_, GetCapabilities()) | 412 EXPECT_CALL(*gpu_control_, GetCapabilities()) |
412 .WillOnce(testing::Return(Capabilities())); | 413 .WillOnce(testing::Return(Capabilities())); |
413 | 414 |
414 GLES2Implementation::GLStaticState state; | 415 GLES2Implementation::GLStaticState state; |
415 GLES2Implementation::GLStaticState::IntState& int_state = state.int_state; | 416 GLES2Implementation::GLStaticState::IntState& int_state = state.int_state; |
416 int_state.max_combined_texture_image_units = | 417 int_state.max_combined_texture_image_units = |
417 kMaxCombinedTextureImageUnits; | 418 kMaxCombinedTextureImageUnits; |
418 int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize; | 419 int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize; |
419 int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; | 420 int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; |
420 int_state.max_renderbuffer_size = kMaxRenderbufferSize; | 421 int_state.max_renderbuffer_size = kMaxRenderbufferSize; |
421 int_state.max_texture_image_units = kMaxTextureImageUnits; | 422 int_state.max_texture_image_units = kMaxTextureImageUnits; |
422 int_state.max_texture_size = kMaxTextureSize; | 423 int_state.max_texture_size = kMaxTextureSize; |
423 int_state.max_varying_vectors = kMaxVaryingVectors; | 424 int_state.max_varying_vectors = kMaxVaryingVectors; |
424 int_state.max_vertex_attribs = kMaxVertexAttribs; | 425 int_state.max_vertex_attribs = kMaxVertexAttribs; |
425 int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits; | 426 int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits; |
426 int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors; | 427 int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors; |
427 int_state.num_compressed_texture_formats = kNumCompressedTextureFormats; | 428 int_state.num_compressed_texture_formats = kNumCompressedTextureFormats; |
428 int_state.num_shader_binary_formats = kNumShaderBinaryFormats; | 429 int_state.num_shader_binary_formats = kNumShaderBinaryFormats; |
| 430 int_state.bind_generates_resource_chromium = |
| 431 bind_generates_resource ? 1 : 0; |
429 | 432 |
430 // This just happens to work for now because IntState has 1 GLint per | 433 // This just happens to work for now because IntState has 1 GLint per |
431 // state. | 434 // state. |
432 // If IntState gets more complicated this code will need to get more | 435 // If IntState gets more complicated this code will need to get more |
433 // complicated. | 436 // complicated. |
434 ExpectedMemoryInfo mem1 = transfer_buffer_->GetExpectedMemory( | 437 ExpectedMemoryInfo mem1 = transfer_buffer_->GetExpectedMemory( |
435 sizeof(GLES2Implementation::GLStaticState::IntState) * 2 + | 438 sizeof(GLES2Implementation::GLStaticState::IntState) * 2 + |
436 sizeof(cmds::GetShaderPrecisionFormat::Result) * 12); | 439 sizeof(cmds::GetShaderPrecisionFormat::Result) * 12); |
437 | 440 |
438 { | 441 { |
439 InSequence sequence; | 442 InSequence sequence; |
440 | 443 |
441 EXPECT_CALL(*command_buffer_, OnFlush()) | 444 EXPECT_CALL(*command_buffer_, OnFlush()) |
442 .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state)) | 445 .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state)) |
443 .RetiresOnSaturation(); | 446 .RetiresOnSaturation(); |
444 GetNextToken(); // eat the token that starting up will use. | 447 GetNextToken(); // eat the token that starting up will use. |
445 | 448 |
446 gl_.reset(new GLES2Implementation(helper_.get(), | 449 gl_.reset(new GLES2Implementation(helper_.get(), |
447 share_group, | 450 share_group, |
448 transfer_buffer_.get(), | 451 transfer_buffer_.get(), |
449 bind_generates_resource, | 452 bind_generates_resource, |
450 lose_context_when_out_of_memory, | 453 lose_context_when_out_of_memory, |
451 gpu_control_.get())); | 454 gpu_control_.get())); |
452 ASSERT_TRUE(gl_->Initialize(kTransferBufferSize, | 455 |
453 kTransferBufferSize, | 456 if (!gl_->Initialize(kTransferBufferSize, |
454 kTransferBufferSize, | 457 kTransferBufferSize, |
455 GLES2Implementation::kNoLimit)); | 458 kTransferBufferSize, |
| 459 GLES2Implementation::kNoLimit)) |
| 460 return false; |
456 } | 461 } |
457 | 462 |
458 EXPECT_CALL(*command_buffer_, OnFlush()).Times(1).RetiresOnSaturation(); | 463 EXPECT_CALL(*command_buffer_, OnFlush()).Times(1).RetiresOnSaturation(); |
459 helper_->CommandBufferHelper::Finish(); | 464 helper_->CommandBufferHelper::Finish(); |
460 ::testing::Mock::VerifyAndClearExpectations(gl_.get()); | 465 ::testing::Mock::VerifyAndClearExpectations(gl_.get()); |
461 | 466 |
462 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer(); | 467 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer(); |
463 commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) + | 468 commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) + |
464 command_buffer()->GetState().put_offset; | 469 command_buffer()->GetState().put_offset; |
465 ClearCommands(); | 470 ClearCommands(); |
466 EXPECT_TRUE(transfer_buffer_->InSync()); | 471 EXPECT_TRUE(transfer_buffer_->InSync()); |
467 | 472 |
468 ::testing::Mock::VerifyAndClearExpectations(command_buffer()); | 473 ::testing::Mock::VerifyAndClearExpectations(command_buffer()); |
| 474 return true; |
469 } | 475 } |
470 | 476 |
471 void TearDown() { | 477 void TearDown() { |
472 Mock::VerifyAndClear(gl_.get()); | 478 Mock::VerifyAndClear(gl_.get()); |
473 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber()); | 479 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber()); |
474 // For command buffer. | 480 // For command buffer. |
475 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) | 481 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) |
476 .Times(AtLeast(1)); | 482 .Times(AtLeast(1)); |
477 gl_.reset(); | 483 gl_.reset(); |
478 } | 484 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 return false; | 517 return false; |
512 } | 518 } |
513 } | 519 } |
514 return true; | 520 return true; |
515 } | 521 } |
516 | 522 |
517 QueryTracker::Query* GetQuery(GLuint id) { | 523 QueryTracker::Query* GetQuery(GLuint id) { |
518 return gl_->query_tracker_->GetQuery(id); | 524 return gl_->query_tracker_->GetQuery(id); |
519 } | 525 } |
520 | 526 |
521 void Initialize(bool bind_generates_resource, | 527 struct ContextInitOptions { |
522 bool lose_context_when_out_of_memory) { | 528 ContextInitOptions() |
523 share_group_ = new ShareGroup(bind_generates_resource); | 529 : bind_generates_resource_client(true), |
| 530 bind_generates_resource_service(true), |
| 531 lose_context_when_out_of_memory(false) {} |
524 | 532 |
525 for (int i = 0; i < kNumTestContexts; i++) | 533 bool bind_generates_resource_client; |
526 test_contexts_[i].Initialize(share_group_.get(), | 534 bool bind_generates_resource_service; |
527 bind_generates_resource, | 535 bool lose_context_when_out_of_memory; |
528 lose_context_when_out_of_memory); | 536 }; |
| 537 |
| 538 bool Initialize(const ContextInitOptions& init_options) { |
| 539 bool success = true; |
| 540 share_group_ = new ShareGroup(init_options.bind_generates_resource_service); |
| 541 |
| 542 for (int i = 0; i < kNumTestContexts; i++) { |
| 543 if (!test_contexts_[i].Initialize( |
| 544 share_group_.get(), |
| 545 init_options.bind_generates_resource_client, |
| 546 init_options.lose_context_when_out_of_memory)) |
| 547 success = false; |
| 548 } |
529 | 549 |
530 // Default to test context 0. | 550 // Default to test context 0. |
531 gpu_control_ = test_contexts_[0].gpu_control_.get(); | 551 gpu_control_ = test_contexts_[0].gpu_control_.get(); |
532 helper_ = test_contexts_[0].helper_.get(); | 552 helper_ = test_contexts_[0].helper_.get(); |
533 transfer_buffer_ = test_contexts_[0].transfer_buffer_.get(); | 553 transfer_buffer_ = test_contexts_[0].transfer_buffer_.get(); |
534 gl_ = test_contexts_[0].gl_.get(); | 554 gl_ = test_contexts_[0].gl_.get(); |
535 commands_ = test_contexts_[0].commands_; | 555 commands_ = test_contexts_[0].commands_; |
| 556 return success; |
536 } | 557 } |
537 | 558 |
538 MockClientCommandBuffer* command_buffer() const { | 559 MockClientCommandBuffer* command_buffer() const { |
539 return test_contexts_[0].command_buffer_.get(); | 560 return test_contexts_[0].command_buffer_.get(); |
540 } | 561 } |
541 | 562 |
542 int GetNextToken() { return test_contexts_[0].GetNextToken(); } | 563 int GetNextToken() { return test_contexts_[0].GetNextToken(); } |
543 | 564 |
544 const void* GetPut() { | 565 const void* GetPut() { |
545 return helper_->GetSpace(0); | 566 return helper_->GetSpace(0); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 | 606 |
586 scoped_refptr<ShareGroup> share_group_; | 607 scoped_refptr<ShareGroup> share_group_; |
587 MockClientGpuControl* gpu_control_; | 608 MockClientGpuControl* gpu_control_; |
588 GLES2CmdHelper* helper_; | 609 GLES2CmdHelper* helper_; |
589 MockTransferBuffer* transfer_buffer_; | 610 MockTransferBuffer* transfer_buffer_; |
590 GLES2Implementation* gl_; | 611 GLES2Implementation* gl_; |
591 CommandBufferEntry* commands_; | 612 CommandBufferEntry* commands_; |
592 }; | 613 }; |
593 | 614 |
594 void GLES2ImplementationTest::SetUp() { | 615 void GLES2ImplementationTest::SetUp() { |
595 bool bind_generates_resource = true; | 616 ContextInitOptions init_options; |
596 bool lose_context_when_out_of_memory = false; | 617 ASSERT_TRUE(Initialize(init_options)); |
597 Initialize(bind_generates_resource, lose_context_when_out_of_memory); | |
598 } | 618 } |
599 | 619 |
600 void GLES2ImplementationTest::TearDown() { | 620 void GLES2ImplementationTest::TearDown() { |
601 for (int i = 0; i < kNumTestContexts; i++) | 621 for (int i = 0; i < kNumTestContexts; i++) |
602 test_contexts_[i].TearDown(); | 622 test_contexts_[i].TearDown(); |
603 } | 623 } |
604 | 624 |
605 class GLES2ImplementationManualInitTest : public GLES2ImplementationTest { | 625 class GLES2ImplementationManualInitTest : public GLES2ImplementationTest { |
606 protected: | 626 protected: |
607 virtual void SetUp() OVERRIDE {} | 627 virtual void SetUp() OVERRIDE {} |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 EXPECT_NE(id1, id3); | 710 EXPECT_NE(id1, id3); |
691 | 711 |
692 // Lazy release triggered by another Delete. Should reuse id1. | 712 // Lazy release triggered by another Delete. Should reuse id1. |
693 ResApi::Delete(gl1, 1, &id2); | 713 ResApi::Delete(gl1, 1, &id2); |
694 ResApi::Gen(gl2, 1, &id3); | 714 ResApi::Gen(gl2, 1, &id3); |
695 EXPECT_EQ(id1, id3); | 715 EXPECT_EQ(id1, id3); |
696 } | 716 } |
697 }; | 717 }; |
698 | 718 |
699 void GLES2ImplementationStrictSharedTest::SetUp() { | 719 void GLES2ImplementationStrictSharedTest::SetUp() { |
700 bool bind_generates_resource = false; | 720 ContextInitOptions init_options; |
701 bool lose_context_when_out_of_memory = false; | 721 init_options.bind_generates_resource_client = false; |
702 Initialize(bind_generates_resource, lose_context_when_out_of_memory); | 722 init_options.bind_generates_resource_service = false; |
| 723 ASSERT_TRUE(Initialize(init_options)); |
703 } | 724 } |
704 | 725 |
705 // GCC requires these declarations, but MSVC requires they not be present | 726 // GCC requires these declarations, but MSVC requires they not be present |
706 #ifndef _MSC_VER | 727 #ifndef _MSC_VER |
707 const uint8 GLES2ImplementationTest::kInitialValue; | 728 const uint8 GLES2ImplementationTest::kInitialValue; |
708 const int32 GLES2ImplementationTest::kNumCommandEntries; | 729 const int32 GLES2ImplementationTest::kNumCommandEntries; |
709 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes; | 730 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes; |
710 const size_t GLES2ImplementationTest::kTransferBufferSize; | 731 const size_t GLES2ImplementationTest::kTransferBufferSize; |
711 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits; | 732 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits; |
712 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize; | 733 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize; |
(...skipping 2397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3110 }; | 3131 }; |
3111 | 3132 |
3112 Mailbox mailbox = Mailbox::Generate(); | 3133 Mailbox mailbox = Mailbox::Generate(); |
3113 Cmds expected; | 3134 Cmds expected; |
3114 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name); | 3135 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name); |
3115 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); | 3136 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); |
3116 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); | 3137 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); |
3117 } | 3138 } |
3118 | 3139 |
3119 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) { | 3140 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) { |
3120 bool bind_generates_resource = false; | 3141 ContextInitOptions init_options; |
3121 bool lose_context_when_out_of_memory = true; | 3142 init_options.lose_context_when_out_of_memory = true; |
3122 Initialize(bind_generates_resource, lose_context_when_out_of_memory); | 3143 ASSERT_TRUE(Initialize(init_options)); |
3123 | 3144 |
3124 struct Cmds { | 3145 struct Cmds { |
3125 cmds::LoseContextCHROMIUM cmd; | 3146 cmds::LoseContextCHROMIUM cmd; |
3126 }; | 3147 }; |
3127 | 3148 |
3128 GLsizei max = std::numeric_limits<GLsizei>::max(); | 3149 GLsizei max = std::numeric_limits<GLsizei>::max(); |
3129 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _)) | 3150 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _)) |
3130 .WillOnce(Return(static_cast<gfx::GpuMemoryBuffer*>(NULL))); | 3151 .WillOnce(Return(static_cast<gfx::GpuMemoryBuffer*>(NULL))); |
3131 gl_->CreateImageCHROMIUM(max, max, 0); | 3152 gl_->CreateImageCHROMIUM(max, max, 0); |
3132 // The context should be lost. | 3153 // The context should be lost. |
3133 Cmds expected; | 3154 Cmds expected; |
3134 expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB); | 3155 expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB); |
3135 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); | 3156 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); |
3136 } | 3157 } |
3137 | 3158 |
3138 TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) { | 3159 TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) { |
3139 bool bind_generates_resource = false; | 3160 ContextInitOptions init_options; |
3140 bool lose_context_when_out_of_memory = false; | 3161 ASSERT_TRUE(Initialize(init_options)); |
3141 Initialize(bind_generates_resource, lose_context_when_out_of_memory); | |
3142 | 3162 |
3143 struct Cmds { | 3163 struct Cmds { |
3144 cmds::LoseContextCHROMIUM cmd; | 3164 cmds::LoseContextCHROMIUM cmd; |
3145 }; | 3165 }; |
3146 | 3166 |
3147 GLsizei max = std::numeric_limits<GLsizei>::max(); | 3167 GLsizei max = std::numeric_limits<GLsizei>::max(); |
3148 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _)) | 3168 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBuffer(max, max, _, _)) |
3149 .WillOnce(Return(static_cast<gfx::GpuMemoryBuffer*>(NULL))); | 3169 .WillOnce(Return(static_cast<gfx::GpuMemoryBuffer*>(NULL))); |
3150 gl_->CreateImageCHROMIUM(max, max, 0); | 3170 gl_->CreateImageCHROMIUM(max, max, 0); |
3151 // The context should not be lost. | 3171 // The context should not be lost. |
3152 EXPECT_TRUE(NoCommandsWritten()); | 3172 EXPECT_TRUE(NoCommandsWritten()); |
3153 } | 3173 } |
3154 | 3174 |
| 3175 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch1) { |
| 3176 ContextInitOptions init_options; |
| 3177 init_options.bind_generates_resource_client = false; |
| 3178 init_options.bind_generates_resource_service = true; |
| 3179 EXPECT_FALSE(Initialize(init_options)); |
| 3180 } |
| 3181 |
| 3182 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch2) { |
| 3183 ContextInitOptions init_options; |
| 3184 init_options.bind_generates_resource_client = true; |
| 3185 init_options.bind_generates_resource_service = false; |
| 3186 EXPECT_FALSE(Initialize(init_options)); |
| 3187 } |
| 3188 |
3155 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h" | 3189 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h" |
3156 | 3190 |
3157 } // namespace gles2 | 3191 } // namespace gles2 |
3158 } // namespace gpu | 3192 } // namespace gpu |
OLD | NEW |