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