| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "gpu/command_buffer/service/vertex_attrib_manager.h" |
| |
| #include "base/memory/scoped_ptr.h" |
| #include "gpu/command_buffer/service/buffer_manager.h" |
| #include "gpu/command_buffer/service/error_state_mock.h" |
| #include "gpu/command_buffer/service/feature_info.h" |
| #include "gpu/command_buffer/service/test_helper.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/gl/gl_mock.h" |
| |
| using ::testing::Pointee; |
| using ::testing::_; |
| |
| namespace gpu { |
| namespace gles2 { |
| |
| class VertexAttribManagerTest : public testing::Test { |
| public: |
| static const uint32 kNumVertexAttribs = 8; |
| |
| VertexAttribManagerTest() { |
| } |
| |
| virtual ~VertexAttribManagerTest() { |
| } |
| |
| protected: |
| virtual void SetUp() { |
| gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); |
| ::gfx::GLInterface::SetGLInterface(gl_.get()); |
| |
| for (uint32 ii = 0; ii < kNumVertexAttribs; ++ii) { |
| EXPECT_CALL(*gl_, VertexAttrib4f(ii, 0.0f, 0.0f, 0.0f, 1.0f)) |
| .Times(1) |
| .RetiresOnSaturation(); |
| } |
| |
| manager_ = new VertexAttribManager(); |
| manager_->Initialize(kNumVertexAttribs); |
| } |
| |
| virtual void TearDown() { |
| manager_ = NULL; |
| ::gfx::GLInterface::SetGLInterface(NULL); |
| gl_.reset(); |
| } |
| |
| // Use StrictMock to make 100% sure we know how GL will be called. |
| scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; |
| scoped_refptr<VertexAttribManager> manager_; |
| }; |
| |
| // GCC requires these declarations, but MSVC requires they not be present |
| #ifndef COMPILER_MSVC |
| const uint32 VertexAttribManagerTest::kNumVertexAttribs; |
| #endif |
| |
| TEST_F(VertexAttribManagerTest, Basic) { |
| EXPECT_TRUE(manager_->GetVertexAttrib(kNumVertexAttribs) == NULL); |
| EXPECT_FALSE(manager_->HaveFixedAttribs()); |
| |
| const VertexAttribManager::VertexAttribList& enabled_attribs = |
| manager_->GetEnabledVertexAttribs(); |
| EXPECT_EQ(0u, enabled_attribs.size()); |
| |
| for (uint32 ii = 0; ii < kNumVertexAttribs; ii += kNumVertexAttribs - 1) { |
| VertexAttrib* attrib = manager_->GetVertexAttrib(ii); |
| ASSERT_TRUE(attrib != NULL); |
| EXPECT_EQ(ii, attrib->index()); |
| EXPECT_TRUE(attrib->buffer() == NULL); |
| EXPECT_EQ(0, attrib->offset()); |
| EXPECT_EQ(4, attrib->size()); |
| EXPECT_EQ(static_cast<GLenum>(GL_FLOAT), attrib->type()); |
| EXPECT_EQ(GL_FALSE, attrib->normalized()); |
| EXPECT_EQ(0, attrib->gl_stride()); |
| EXPECT_FALSE(attrib->enabled()); |
| manager_->Enable(ii, true); |
| EXPECT_TRUE(attrib->enabled()); |
| } |
| } |
| |
| TEST_F(VertexAttribManagerTest, Enable) { |
| const VertexAttribManager::VertexAttribList& enabled_attribs = |
| manager_->GetEnabledVertexAttribs(); |
| |
| VertexAttrib* attrib1 = manager_->GetVertexAttrib(1); |
| VertexAttrib* attrib2 = manager_->GetVertexAttrib(3); |
| |
| manager_->Enable(1, true); |
| ASSERT_EQ(1u, enabled_attribs.size()); |
| EXPECT_TRUE(attrib1->enabled()); |
| manager_->Enable(3, true); |
| ASSERT_EQ(2u, enabled_attribs.size()); |
| EXPECT_TRUE(attrib2->enabled()); |
| |
| manager_->Enable(1, false); |
| ASSERT_EQ(1u, enabled_attribs.size()); |
| EXPECT_FALSE(attrib1->enabled()); |
| |
| manager_->Enable(3, false); |
| ASSERT_EQ(0u, enabled_attribs.size()); |
| EXPECT_FALSE(attrib2->enabled()); |
| } |
| |
| TEST_F(VertexAttribManagerTest, SetAttribInfo) { |
| BufferManager buffer_manager(NULL, NULL); |
| buffer_manager.CreateBuffer(1, 2); |
| Buffer* buffer = buffer_manager.GetBuffer(1); |
| ASSERT_TRUE(buffer != NULL); |
| |
| VertexAttrib* attrib = manager_->GetVertexAttrib(1); |
| |
| manager_->SetAttribInfo(1, buffer, 3, GL_SHORT, GL_TRUE, 32, 32, 4); |
| |
| EXPECT_EQ(buffer, attrib->buffer()); |
| EXPECT_EQ(4, attrib->offset()); |
| EXPECT_EQ(3, attrib->size()); |
| EXPECT_EQ(static_cast<GLenum>(GL_SHORT), attrib->type()); |
| EXPECT_EQ(GL_TRUE, attrib->normalized()); |
| EXPECT_EQ(32, attrib->gl_stride()); |
| |
| // The VertexAttribManager must be destroyed before the BufferManager |
| // so it releases its buffers. |
| manager_ = NULL; |
| buffer_manager.Destroy(false); |
| } |
| |
| TEST_F(VertexAttribManagerTest, HaveFixedAttribs) { |
| EXPECT_FALSE(manager_->HaveFixedAttribs()); |
| manager_->SetAttribInfo(1, NULL, 4, GL_FIXED, GL_FALSE, 0, 16, 0); |
| EXPECT_TRUE(manager_->HaveFixedAttribs()); |
| manager_->SetAttribInfo(3, NULL, 4, GL_FIXED, GL_FALSE, 0, 16, 0); |
| EXPECT_TRUE(manager_->HaveFixedAttribs()); |
| manager_->SetAttribInfo(1, NULL, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); |
| EXPECT_TRUE(manager_->HaveFixedAttribs()); |
| manager_->SetAttribInfo(3, NULL, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); |
| EXPECT_FALSE(manager_->HaveFixedAttribs()); |
| } |
| |
| TEST_F(VertexAttribManagerTest, CanAccess) { |
| MockErrorState error_state; |
| BufferManager buffer_manager(NULL, NULL); |
| buffer_manager.CreateBuffer(1, 2); |
| Buffer* buffer = buffer_manager.GetBuffer(1); |
| ASSERT_TRUE(buffer != NULL); |
| |
| VertexAttrib* attrib = manager_->GetVertexAttrib(1); |
| |
| EXPECT_TRUE(attrib->CanAccess(0)); |
| manager_->Enable(1, true); |
| EXPECT_FALSE(attrib->CanAccess(0)); |
| |
| manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); |
| EXPECT_FALSE(attrib->CanAccess(0)); |
| |
| EXPECT_TRUE(buffer_manager.SetTarget(buffer, GL_ARRAY_BUFFER)); |
| TestHelper::DoBufferData( |
| gl_.get(), &error_state, &buffer_manager, buffer, 15, GL_STATIC_DRAW, |
| NULL, GL_NO_ERROR); |
| |
| EXPECT_FALSE(attrib->CanAccess(0)); |
| TestHelper::DoBufferData( |
| gl_.get(), &error_state, &buffer_manager, buffer, 16, GL_STATIC_DRAW, |
| NULL, GL_NO_ERROR); |
| EXPECT_TRUE(attrib->CanAccess(0)); |
| EXPECT_FALSE(attrib->CanAccess(1)); |
| |
| manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 1); |
| EXPECT_FALSE(attrib->CanAccess(0)); |
| |
| TestHelper::DoBufferData( |
| gl_.get(), &error_state, &buffer_manager, buffer, 32, GL_STATIC_DRAW, |
| NULL, GL_NO_ERROR); |
| EXPECT_TRUE(attrib->CanAccess(0)); |
| EXPECT_FALSE(attrib->CanAccess(1)); |
| manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); |
| EXPECT_TRUE(attrib->CanAccess(1)); |
| manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 20, 0); |
| EXPECT_TRUE(attrib->CanAccess(0)); |
| EXPECT_FALSE(attrib->CanAccess(1)); |
| |
| // The VertexAttribManager must be destroyed before the BufferManager |
| // so it releases its buffers. |
| manager_ = NULL; |
| buffer_manager.Destroy(false); |
| } |
| |
| TEST_F(VertexAttribManagerTest, Unbind) { |
| BufferManager buffer_manager(NULL, NULL); |
| buffer_manager.CreateBuffer(1, 2); |
| buffer_manager.CreateBuffer(3, 4); |
| Buffer* buffer1 = buffer_manager.GetBuffer(1); |
| Buffer* buffer2 = buffer_manager.GetBuffer(3); |
| ASSERT_TRUE(buffer1 != NULL); |
| ASSERT_TRUE(buffer2 != NULL); |
| |
| VertexAttrib* attrib1 = manager_->GetVertexAttrib(1); |
| VertexAttrib* attrib3 = manager_->GetVertexAttrib(3); |
| |
| // Attach to 2 buffers. |
| manager_->SetAttribInfo(1, buffer1, 3, GL_SHORT, GL_TRUE, 32, 32, 4); |
| manager_->SetAttribInfo(3, buffer1, 3, GL_SHORT, GL_TRUE, 32, 32, 4); |
| // Check they were attached. |
| EXPECT_EQ(buffer1, attrib1->buffer()); |
| EXPECT_EQ(buffer1, attrib3->buffer()); |
| // Unbind unattached buffer. |
| manager_->Unbind(buffer2); |
| // Should be no-op. |
| EXPECT_EQ(buffer1, attrib1->buffer()); |
| EXPECT_EQ(buffer1, attrib3->buffer()); |
| // Unbind buffer. |
| manager_->Unbind(buffer1); |
| // Check they were detached |
| EXPECT_TRUE(NULL == attrib1->buffer()); |
| EXPECT_TRUE(NULL == attrib3->buffer()); |
| |
| // The VertexAttribManager must be destroyed before the BufferManager |
| // so it releases its buffers. |
| manager_ = NULL; |
| buffer_manager.Destroy(false); |
| } |
| |
| // TODO(gman): Test ValidateBindings |
| // TODO(gman): Test ValidateBindings with client side arrays. |
| |
| } // namespace gles2 |
| } // namespace gpu |
| |
| |