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.
5 #include "gpu/command_buffer/client/vertex_array_object_manager.h"
7 #include <GLES2/gl2ext.h>
8 #include "testing/gtest/include/gtest/gtest.h"
13 class VertexArrayObjectManagerTest
: public testing::Test
{
15 static const GLuint kMaxAttribs
= 4;
16 static const GLuint kClientSideArrayBuffer
= 0x1234;
17 static const GLuint kClientSideElementArrayBuffer
= 0x1235;
19 virtual void SetUp() {
20 manager_
.reset(new VertexArrayObjectManager(
22 kClientSideArrayBuffer
,
23 kClientSideElementArrayBuffer
));
25 virtual void TearDown() {
28 scoped_ptr
<VertexArrayObjectManager
> manager_
;
31 // GCC requires these declarations, but MSVC requires they not be present
33 const GLuint
VertexArrayObjectManagerTest::kMaxAttribs
;
34 const GLuint
VertexArrayObjectManagerTest::kClientSideArrayBuffer
;
35 const GLuint
VertexArrayObjectManagerTest::kClientSideElementArrayBuffer
;
38 TEST_F(VertexArrayObjectManagerTest
, Basic
) {
39 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
40 // Check out of bounds access.
43 EXPECT_FALSE(manager_
->GetVertexAttrib(
44 kMaxAttribs
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, ¶m
));
45 EXPECT_FALSE(manager_
->GetAttribPointer(
46 kMaxAttribs
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr
));
48 for (GLuint ii
= 0; ii
< kMaxAttribs
; ++ii
) {
49 EXPECT_TRUE(manager_
->GetVertexAttrib(
50 ii
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, ¶m
));
52 EXPECT_TRUE(manager_
->GetVertexAttrib(
53 ii
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, ¶m
));
55 EXPECT_TRUE(manager_
->GetVertexAttrib(
56 ii
, GL_VERTEX_ATTRIB_ARRAY_SIZE
, ¶m
));
58 EXPECT_TRUE(manager_
->GetVertexAttrib(
59 ii
, GL_VERTEX_ATTRIB_ARRAY_TYPE
, ¶m
));
60 EXPECT_EQ(static_cast<uint32
>(GL_FLOAT
), param
);
61 EXPECT_TRUE(manager_
->GetVertexAttrib(
62 ii
, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, ¶m
));
64 EXPECT_TRUE(manager_
->GetAttribPointer(
65 ii
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr
));
66 EXPECT_TRUE(NULL
== ptr
);
70 TEST_F(VertexArrayObjectManagerTest
, UnbindBuffer
) {
71 const GLuint kBufferToUnbind
= 123;
72 const GLuint kBufferToRemain
= 456;
73 const GLuint kElementArray
= 789;
75 GLuint ids
[2] = { 1, 3, };
76 manager_
->GenVertexArrays(arraysize(ids
), ids
);
77 // Bind buffers to attribs on 2 vaos.
78 for (size_t ii
= 0; ii
< arraysize(ids
); ++ii
) {
79 EXPECT_TRUE(manager_
->BindVertexArray(ids
[ii
], &changed
));
80 EXPECT_TRUE(manager_
->SetAttribPointer(
81 kBufferToUnbind
, 0, 4, GL_FLOAT
, false, 0, 0));
82 EXPECT_TRUE(manager_
->SetAttribPointer(
83 kBufferToRemain
, 1, 4, GL_FLOAT
, false, 0, 0));
84 EXPECT_TRUE(manager_
->SetAttribPointer(
85 kBufferToUnbind
, 2, 4, GL_FLOAT
, false, 0, 0));
86 EXPECT_TRUE(manager_
->SetAttribPointer(
87 kBufferToRemain
, 3, 4, GL_FLOAT
, false, 0, 0));
88 for (size_t jj
= 0; jj
< 4u; ++jj
) {
89 manager_
->SetAttribEnable(jj
, true);
91 manager_
->BindElementArray(kElementArray
);
93 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
94 EXPECT_TRUE(manager_
->BindVertexArray(ids
[0], &changed
));
96 manager_
->UnbindBuffer(kBufferToUnbind
);
97 manager_
->UnbindBuffer(kElementArray
);
98 // The attribs are still enabled but their buffer is 0.
99 EXPECT_TRUE(manager_
->HaveEnabledClientSideBuffers());
100 // Check the status of the bindings.
101 static const uint32 expected
[][4] = {
102 { 0, kBufferToRemain
, 0, kBufferToRemain
, },
103 { kBufferToUnbind
, kBufferToRemain
, kBufferToUnbind
, kBufferToRemain
, },
105 static const GLuint expected_element_array
[] = {
108 for (size_t ii
= 0; ii
< arraysize(ids
); ++ii
) {
109 EXPECT_TRUE(manager_
->BindVertexArray(ids
[ii
], &changed
));
110 for (size_t jj
= 0; jj
< 4; ++jj
) {
112 EXPECT_TRUE(manager_
->GetVertexAttrib(
113 jj
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, ¶m
));
114 EXPECT_EQ(expected
[ii
][jj
], param
)
115 << "id: " << ids
[ii
] << ", attrib: " << jj
;
117 EXPECT_EQ(expected_element_array
[ii
],
118 manager_
->bound_element_array_buffer());
121 // The vao that was not bound still has all service side bufferws.
122 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
124 // Make sure unbinding 0 does not effect count incorrectly.
125 EXPECT_TRUE(manager_
->BindVertexArray(0, &changed
));
126 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
127 manager_
->SetAttribEnable(2, true);
128 manager_
->UnbindBuffer(0);
129 manager_
->SetAttribEnable(2, false);
130 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
133 TEST_F(VertexArrayObjectManagerTest
, GetSet
) {
134 const char* dummy
= "dummy";
135 const void* p
= reinterpret_cast<const void*>(dummy
);
136 manager_
->SetAttribEnable(1, true);
137 manager_
->SetAttribPointer(123, 1, 3, GL_BYTE
, true, 3, p
);
140 EXPECT_TRUE(manager_
->GetVertexAttrib(
141 1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, ¶m
));
142 EXPECT_EQ(123u, param
);
143 EXPECT_TRUE(manager_
->GetVertexAttrib(
144 1, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, ¶m
));
145 EXPECT_NE(0u, param
);
146 EXPECT_TRUE(manager_
->GetVertexAttrib(
147 1, GL_VERTEX_ATTRIB_ARRAY_SIZE
, ¶m
));
148 EXPECT_EQ(3u, param
);
149 EXPECT_TRUE(manager_
->GetVertexAttrib(
150 1, GL_VERTEX_ATTRIB_ARRAY_TYPE
, ¶m
));
151 EXPECT_EQ(static_cast<uint32
>(GL_BYTE
), param
);
152 EXPECT_TRUE(manager_
->GetVertexAttrib(
153 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, ¶m
));
154 EXPECT_NE(0u, param
);
155 EXPECT_TRUE(manager_
->GetAttribPointer(
156 1, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr
));
159 // Check that getting the divisor is passed to the service.
160 // This is because the divisor is an optional feature which
161 // only the service can validate.
162 EXPECT_FALSE(manager_
->GetVertexAttrib(
163 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE
, ¶m
));
166 TEST_F(VertexArrayObjectManagerTest
, HaveEnabledClientSideArrays
) {
167 // Check turning on an array.
168 manager_
->SetAttribEnable(1, true);
169 EXPECT_TRUE(manager_
->HaveEnabledClientSideBuffers());
170 // Check turning off an array.
171 manager_
->SetAttribEnable(1, false);
172 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
173 // Check turning on an array and assigning a buffer.
174 manager_
->SetAttribEnable(1, true);
175 manager_
->SetAttribPointer(123, 1, 3, GL_BYTE
, true, 3, NULL
);
176 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
177 // Check unassigning a buffer.
178 manager_
->SetAttribPointer(0, 1, 3, GL_BYTE
, true, 3, NULL
);
179 EXPECT_TRUE(manager_
->HaveEnabledClientSideBuffers());
180 // Check disabling the array.
181 manager_
->SetAttribEnable(1, false);
182 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
185 TEST_F(VertexArrayObjectManagerTest
, BindElementArray
) {
186 bool changed
= false;
187 GLuint ids
[2] = { 1, 3, };
188 manager_
->GenVertexArrays(arraysize(ids
), ids
);
190 // Check the default element array is 0.
191 EXPECT_EQ(0u, manager_
->bound_element_array_buffer());
192 // Check binding the same array does not need a service call.
193 EXPECT_FALSE(manager_
->BindElementArray(0u));
194 // Check binding a new element array requires a service call.
195 EXPECT_TRUE(manager_
->BindElementArray(55u));
196 // Check the element array was bound.
197 EXPECT_EQ(55u, manager_
->bound_element_array_buffer());
198 // Check binding the same array does not need a service call.
199 EXPECT_FALSE(manager_
->BindElementArray(55u));
201 // Check with a new vao.
202 EXPECT_TRUE(manager_
->BindVertexArray(1, &changed
));
203 // Check the default element array is 0.
204 EXPECT_EQ(0u, manager_
->bound_element_array_buffer());
205 // Check binding a new element array requires a service call.
206 EXPECT_TRUE(manager_
->BindElementArray(11u));
207 // Check the element array was bound.
208 EXPECT_EQ(11u, manager_
->bound_element_array_buffer());
209 // Check binding the same array does not need a service call.
210 EXPECT_FALSE(manager_
->BindElementArray(11u));
212 // check switching vao bindings returns the correct element array.
213 EXPECT_TRUE(manager_
->BindVertexArray(3, &changed
));
214 EXPECT_EQ(0u, manager_
->bound_element_array_buffer());
215 EXPECT_TRUE(manager_
->BindVertexArray(0, &changed
));
216 EXPECT_EQ(55u, manager_
->bound_element_array_buffer());
217 EXPECT_TRUE(manager_
->BindVertexArray(1, &changed
));
218 EXPECT_EQ(11u, manager_
->bound_element_array_buffer());
221 TEST_F(VertexArrayObjectManagerTest
, GenBindDelete
) {
222 // Check unknown array fails.
223 bool changed
= false;
224 EXPECT_FALSE(manager_
->BindVertexArray(123, &changed
));
225 EXPECT_FALSE(changed
);
227 GLuint ids
[2] = { 1, 3, };
228 manager_
->GenVertexArrays(arraysize(ids
), ids
);
229 // Check Genned arrays succeed.
230 EXPECT_TRUE(manager_
->BindVertexArray(1, &changed
));
231 EXPECT_TRUE(changed
);
232 EXPECT_TRUE(manager_
->BindVertexArray(3, &changed
));
233 EXPECT_TRUE(changed
);
235 // Check binding the same array returns changed as false.
236 EXPECT_TRUE(manager_
->BindVertexArray(3, &changed
));
237 EXPECT_FALSE(changed
);
239 // Check deleted ararys fail to bind
240 manager_
->DeleteVertexArrays(2, ids
);
241 EXPECT_FALSE(manager_
->BindVertexArray(1, &changed
));
242 EXPECT_FALSE(changed
);
243 EXPECT_FALSE(manager_
->BindVertexArray(3, &changed
));
244 EXPECT_FALSE(changed
);
246 // Check binding 0 returns changed as false since it's
248 EXPECT_TRUE(manager_
->BindVertexArray(0, &changed
));
249 EXPECT_FALSE(changed
);
252 TEST_F(VertexArrayObjectManagerTest
, IsReservedId
) {
253 EXPECT_TRUE(manager_
->IsReservedId(kClientSideArrayBuffer
));
254 EXPECT_TRUE(manager_
->IsReservedId(kClientSideElementArrayBuffer
));
255 EXPECT_FALSE(manager_
->IsReservedId(0));
256 EXPECT_FALSE(manager_
->IsReservedId(1));
257 EXPECT_FALSE(manager_
->IsReservedId(2));