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/vertex_attrib_manager.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "gpu/command_buffer/service/buffer_manager.h" 9 #include "gpu/command_buffer/service/error_state_mock.h" 10 #include "gpu/command_buffer/service/feature_info.h" 11 #include "gpu/command_buffer/service/test_helper.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "ui/gl/gl_mock.h" 14 15 using ::testing::Pointee; 16 using ::testing::_; 17 18 namespace gpu { 19 namespace gles2 { 20 21 class VertexAttribManagerTest : public testing::Test { 22 public: 23 static const uint32 kNumVertexAttribs = 8; 24 25 VertexAttribManagerTest() { 26 } 27 28 virtual ~VertexAttribManagerTest() { 29 } 30 31 protected: 32 virtual void SetUp() { 33 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); 34 ::gfx::GLInterface::SetGLInterface(gl_.get()); 35 36 for (uint32 ii = 0; ii < kNumVertexAttribs; ++ii) { 37 EXPECT_CALL(*gl_, VertexAttrib4f(ii, 0.0f, 0.0f, 0.0f, 1.0f)) 38 .Times(1) 39 .RetiresOnSaturation(); 40 } 41 42 manager_ = new VertexAttribManager(); 43 manager_->Initialize(kNumVertexAttribs); 44 } 45 46 virtual void TearDown() { 47 manager_ = NULL; 48 ::gfx::GLInterface::SetGLInterface(NULL); 49 gl_.reset(); 50 } 51 52 // Use StrictMock to make 100% sure we know how GL will be called. 53 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; 54 scoped_refptr<VertexAttribManager> manager_; 55 }; 56 57 // GCC requires these declarations, but MSVC requires they not be present 58 #ifndef COMPILER_MSVC 59 const uint32 VertexAttribManagerTest::kNumVertexAttribs; 60 #endif 61 62 TEST_F(VertexAttribManagerTest, Basic) { 63 EXPECT_TRUE(manager_->GetVertexAttrib(kNumVertexAttribs) == NULL); 64 EXPECT_FALSE(manager_->HaveFixedAttribs()); 65 66 const VertexAttribManager::VertexAttribList& enabled_attribs = 67 manager_->GetEnabledVertexAttribs(); 68 EXPECT_EQ(0u, enabled_attribs.size()); 69 70 for (uint32 ii = 0; ii < kNumVertexAttribs; ii += kNumVertexAttribs - 1) { 71 VertexAttrib* attrib = manager_->GetVertexAttrib(ii); 72 ASSERT_TRUE(attrib != NULL); 73 EXPECT_EQ(ii, attrib->index()); 74 EXPECT_TRUE(attrib->buffer() == NULL); 75 EXPECT_EQ(0, attrib->offset()); 76 EXPECT_EQ(4, attrib->size()); 77 EXPECT_EQ(static_cast<GLenum>(GL_FLOAT), attrib->type()); 78 EXPECT_EQ(GL_FALSE, attrib->normalized()); 79 EXPECT_EQ(0, attrib->gl_stride()); 80 EXPECT_FALSE(attrib->enabled()); 81 manager_->Enable(ii, true); 82 EXPECT_TRUE(attrib->enabled()); 83 } 84 } 85 86 TEST_F(VertexAttribManagerTest, Enable) { 87 const VertexAttribManager::VertexAttribList& enabled_attribs = 88 manager_->GetEnabledVertexAttribs(); 89 90 VertexAttrib* attrib1 = manager_->GetVertexAttrib(1); 91 VertexAttrib* attrib2 = manager_->GetVertexAttrib(3); 92 93 manager_->Enable(1, true); 94 ASSERT_EQ(1u, enabled_attribs.size()); 95 EXPECT_TRUE(attrib1->enabled()); 96 manager_->Enable(3, true); 97 ASSERT_EQ(2u, enabled_attribs.size()); 98 EXPECT_TRUE(attrib2->enabled()); 99 100 manager_->Enable(1, false); 101 ASSERT_EQ(1u, enabled_attribs.size()); 102 EXPECT_FALSE(attrib1->enabled()); 103 104 manager_->Enable(3, false); 105 ASSERT_EQ(0u, enabled_attribs.size()); 106 EXPECT_FALSE(attrib2->enabled()); 107 } 108 109 TEST_F(VertexAttribManagerTest, SetAttribInfo) { 110 BufferManager buffer_manager(NULL, NULL); 111 buffer_manager.CreateBuffer(1, 2); 112 Buffer* buffer = buffer_manager.GetBuffer(1); 113 ASSERT_TRUE(buffer != NULL); 114 115 VertexAttrib* attrib = manager_->GetVertexAttrib(1); 116 117 manager_->SetAttribInfo(1, buffer, 3, GL_SHORT, GL_TRUE, 32, 32, 4); 118 119 EXPECT_EQ(buffer, attrib->buffer()); 120 EXPECT_EQ(4, attrib->offset()); 121 EXPECT_EQ(3, attrib->size()); 122 EXPECT_EQ(static_cast<GLenum>(GL_SHORT), attrib->type()); 123 EXPECT_EQ(GL_TRUE, attrib->normalized()); 124 EXPECT_EQ(32, attrib->gl_stride()); 125 126 // The VertexAttribManager must be destroyed before the BufferManager 127 // so it releases its buffers. 128 manager_ = NULL; 129 buffer_manager.Destroy(false); 130 } 131 132 TEST_F(VertexAttribManagerTest, HaveFixedAttribs) { 133 EXPECT_FALSE(manager_->HaveFixedAttribs()); 134 manager_->SetAttribInfo(1, NULL, 4, GL_FIXED, GL_FALSE, 0, 16, 0); 135 EXPECT_TRUE(manager_->HaveFixedAttribs()); 136 manager_->SetAttribInfo(3, NULL, 4, GL_FIXED, GL_FALSE, 0, 16, 0); 137 EXPECT_TRUE(manager_->HaveFixedAttribs()); 138 manager_->SetAttribInfo(1, NULL, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); 139 EXPECT_TRUE(manager_->HaveFixedAttribs()); 140 manager_->SetAttribInfo(3, NULL, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); 141 EXPECT_FALSE(manager_->HaveFixedAttribs()); 142 } 143 144 TEST_F(VertexAttribManagerTest, CanAccess) { 145 MockErrorState error_state; 146 BufferManager buffer_manager(NULL, NULL); 147 buffer_manager.CreateBuffer(1, 2); 148 Buffer* buffer = buffer_manager.GetBuffer(1); 149 ASSERT_TRUE(buffer != NULL); 150 151 VertexAttrib* attrib = manager_->GetVertexAttrib(1); 152 153 EXPECT_TRUE(attrib->CanAccess(0)); 154 manager_->Enable(1, true); 155 EXPECT_FALSE(attrib->CanAccess(0)); 156 157 manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); 158 EXPECT_FALSE(attrib->CanAccess(0)); 159 160 EXPECT_TRUE(buffer_manager.SetTarget(buffer, GL_ARRAY_BUFFER)); 161 TestHelper::DoBufferData( 162 gl_.get(), &error_state, &buffer_manager, buffer, 15, GL_STATIC_DRAW, 163 NULL, GL_NO_ERROR); 164 165 EXPECT_FALSE(attrib->CanAccess(0)); 166 TestHelper::DoBufferData( 167 gl_.get(), &error_state, &buffer_manager, buffer, 16, GL_STATIC_DRAW, 168 NULL, GL_NO_ERROR); 169 EXPECT_TRUE(attrib->CanAccess(0)); 170 EXPECT_FALSE(attrib->CanAccess(1)); 171 172 manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 1); 173 EXPECT_FALSE(attrib->CanAccess(0)); 174 175 TestHelper::DoBufferData( 176 gl_.get(), &error_state, &buffer_manager, buffer, 32, GL_STATIC_DRAW, 177 NULL, GL_NO_ERROR); 178 EXPECT_TRUE(attrib->CanAccess(0)); 179 EXPECT_FALSE(attrib->CanAccess(1)); 180 manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 16, 0); 181 EXPECT_TRUE(attrib->CanAccess(1)); 182 manager_->SetAttribInfo(1, buffer, 4, GL_FLOAT, GL_FALSE, 0, 20, 0); 183 EXPECT_TRUE(attrib->CanAccess(0)); 184 EXPECT_FALSE(attrib->CanAccess(1)); 185 186 // The VertexAttribManager must be destroyed before the BufferManager 187 // so it releases its buffers. 188 manager_ = NULL; 189 buffer_manager.Destroy(false); 190 } 191 192 TEST_F(VertexAttribManagerTest, Unbind) { 193 BufferManager buffer_manager(NULL, NULL); 194 buffer_manager.CreateBuffer(1, 2); 195 buffer_manager.CreateBuffer(3, 4); 196 Buffer* buffer1 = buffer_manager.GetBuffer(1); 197 Buffer* buffer2 = buffer_manager.GetBuffer(3); 198 ASSERT_TRUE(buffer1 != NULL); 199 ASSERT_TRUE(buffer2 != NULL); 200 201 VertexAttrib* attrib1 = manager_->GetVertexAttrib(1); 202 VertexAttrib* attrib3 = manager_->GetVertexAttrib(3); 203 204 // Attach to 2 buffers. 205 manager_->SetAttribInfo(1, buffer1, 3, GL_SHORT, GL_TRUE, 32, 32, 4); 206 manager_->SetAttribInfo(3, buffer1, 3, GL_SHORT, GL_TRUE, 32, 32, 4); 207 // Check they were attached. 208 EXPECT_EQ(buffer1, attrib1->buffer()); 209 EXPECT_EQ(buffer1, attrib3->buffer()); 210 // Unbind unattached buffer. 211 manager_->Unbind(buffer2); 212 // Should be no-op. 213 EXPECT_EQ(buffer1, attrib1->buffer()); 214 EXPECT_EQ(buffer1, attrib3->buffer()); 215 // Unbind buffer. 216 manager_->Unbind(buffer1); 217 // Check they were detached 218 EXPECT_TRUE(NULL == attrib1->buffer()); 219 EXPECT_TRUE(NULL == attrib3->buffer()); 220 221 // The VertexAttribManager must be destroyed before the BufferManager 222 // so it releases its buffers. 223 manager_ = NULL; 224 buffer_manager.Destroy(false); 225 } 226 227 // TODO(gman): Test ValidateBindings 228 // TODO(gman): Test ValidateBindings with client side arrays. 229 230 } // namespace gles2 231 } // namespace gpu 232 233 234