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
15using ::testing::Pointee;
16using ::testing::_;
17
18namespace gpu {
19namespace gles2 {
20
21class 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
59const uint32 VertexAttribManagerTest::kNumVertexAttribs;
60#endif
61
62TEST_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
86TEST_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
109TEST_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
132TEST_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
144TEST_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
192TEST_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