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>
9 #include "testing/gtest/include/gtest/gtest.h"
14 class VertexArrayObjectManagerTest
: public testing::Test
{
16 static const GLuint kMaxAttribs
= 4;
17 static const GLuint kClientSideArrayBuffer
= 0x1234;
18 static const GLuint kClientSideElementArrayBuffer
= 0x1235;
19 static const bool kSupportClientSideArrays
= true;
21 void SetUp() override
{
22 manager_
.reset(new VertexArrayObjectManager(
24 kClientSideArrayBuffer
,
25 kClientSideElementArrayBuffer
,
26 kSupportClientSideArrays
));
28 void TearDown() override
{}
30 scoped_ptr
<VertexArrayObjectManager
> manager_
;
33 // GCC requires these declarations, but MSVC requires they not be present
35 const GLuint
VertexArrayObjectManagerTest::kMaxAttribs
;
36 const GLuint
VertexArrayObjectManagerTest::kClientSideArrayBuffer
;
37 const GLuint
VertexArrayObjectManagerTest::kClientSideElementArrayBuffer
;
40 TEST_F(VertexArrayObjectManagerTest
, Basic
) {
41 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
42 // Check out of bounds access.
45 EXPECT_FALSE(manager_
->GetVertexAttrib(
46 kMaxAttribs
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, ¶m
));
47 EXPECT_FALSE(manager_
->GetAttribPointer(
48 kMaxAttribs
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr
));
50 for (GLuint ii
= 0; ii
< kMaxAttribs
; ++ii
) {
51 EXPECT_TRUE(manager_
->GetVertexAttrib(
52 ii
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, ¶m
));
54 EXPECT_TRUE(manager_
->GetVertexAttrib(
55 ii
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, ¶m
));
57 EXPECT_TRUE(manager_
->GetVertexAttrib(
58 ii
, GL_VERTEX_ATTRIB_ARRAY_SIZE
, ¶m
));
60 EXPECT_TRUE(manager_
->GetVertexAttrib(
61 ii
, GL_VERTEX_ATTRIB_ARRAY_TYPE
, ¶m
));
62 EXPECT_EQ(static_cast<uint32
>(GL_FLOAT
), param
);
63 EXPECT_TRUE(manager_
->GetVertexAttrib(
64 ii
, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, ¶m
));
66 EXPECT_TRUE(manager_
->GetAttribPointer(
67 ii
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr
));
68 EXPECT_TRUE(NULL
== ptr
);
72 TEST_F(VertexArrayObjectManagerTest
, UnbindBuffer
) {
73 const GLuint kBufferToUnbind
= 123;
74 const GLuint kBufferToRemain
= 456;
75 const GLuint kElementArray
= 789;
77 GLuint ids
[2] = { 1, 3, };
78 manager_
->GenVertexArrays(arraysize(ids
), ids
);
79 // Bind buffers to attribs on 2 vaos.
80 for (size_t ii
= 0; ii
< arraysize(ids
); ++ii
) {
81 EXPECT_TRUE(manager_
->BindVertexArray(ids
[ii
], &changed
));
82 EXPECT_TRUE(manager_
->SetAttribPointer(
83 kBufferToUnbind
, 0, 4, GL_FLOAT
, false, 0, 0, GL_FALSE
));
84 EXPECT_TRUE(manager_
->SetAttribPointer(
85 kBufferToRemain
, 1, 4, GL_FLOAT
, false, 0, 0, GL_FALSE
));
86 EXPECT_TRUE(manager_
->SetAttribPointer(
87 kBufferToUnbind
, 2, 4, GL_FLOAT
, false, 0, 0, GL_FALSE
));
88 EXPECT_TRUE(manager_
->SetAttribPointer(
89 kBufferToRemain
, 3, 4, GL_FLOAT
, false, 0, 0, GL_FALSE
));
90 for (size_t jj
= 0; jj
< 4u; ++jj
) {
91 manager_
->SetAttribEnable(jj
, true);
93 manager_
->BindElementArray(kElementArray
);
95 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
96 EXPECT_TRUE(manager_
->BindVertexArray(ids
[0], &changed
));
98 manager_
->UnbindBuffer(kBufferToUnbind
);
99 manager_
->UnbindBuffer(kElementArray
);
100 // The attribs are still enabled but their buffer is 0.
101 EXPECT_TRUE(manager_
->HaveEnabledClientSideBuffers());
102 // Check the status of the bindings.
103 static const uint32 expected
[][4] = {
104 { 0, kBufferToRemain
, 0, kBufferToRemain
, },
105 { kBufferToUnbind
, kBufferToRemain
, kBufferToUnbind
, kBufferToRemain
, },
107 static const GLuint expected_element_array
[] = {
110 for (size_t ii
= 0; ii
< arraysize(ids
); ++ii
) {
111 EXPECT_TRUE(manager_
->BindVertexArray(ids
[ii
], &changed
));
112 for (size_t jj
= 0; jj
< 4; ++jj
) {
114 EXPECT_TRUE(manager_
->GetVertexAttrib(
115 jj
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, ¶m
));
116 EXPECT_EQ(expected
[ii
][jj
], param
)
117 << "id: " << ids
[ii
] << ", attrib: " << jj
;
119 EXPECT_EQ(expected_element_array
[ii
],
120 manager_
->bound_element_array_buffer());
123 // The vao that was not bound still has all service side bufferws.
124 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
126 // Make sure unbinding 0 does not effect count incorrectly.
127 EXPECT_TRUE(manager_
->BindVertexArray(0, &changed
));
128 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
129 manager_
->SetAttribEnable(2, true);
130 manager_
->UnbindBuffer(0);
131 manager_
->SetAttribEnable(2, false);
132 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
135 TEST_F(VertexArrayObjectManagerTest
, GetSet
) {
136 const char* dummy
= "dummy";
137 const void* p
= reinterpret_cast<const void*>(dummy
);
138 manager_
->SetAttribEnable(1, true);
139 manager_
->SetAttribPointer(123, 1, 3, GL_BYTE
, true, 3, p
, GL_TRUE
);
142 EXPECT_TRUE(manager_
->GetVertexAttrib(
143 1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, ¶m
));
144 EXPECT_EQ(123u, param
);
145 EXPECT_TRUE(manager_
->GetVertexAttrib(
146 1, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, ¶m
));
147 EXPECT_NE(0u, param
);
148 EXPECT_TRUE(manager_
->GetVertexAttrib(
149 1, GL_VERTEX_ATTRIB_ARRAY_SIZE
, ¶m
));
150 EXPECT_EQ(3u, param
);
151 EXPECT_TRUE(manager_
->GetVertexAttrib(
152 1, GL_VERTEX_ATTRIB_ARRAY_TYPE
, ¶m
));
153 EXPECT_EQ(static_cast<uint32
>(GL_BYTE
), param
);
154 EXPECT_TRUE(manager_
->GetVertexAttrib(
155 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, ¶m
));
156 EXPECT_NE(0u, param
);
157 EXPECT_TRUE(manager_
->GetVertexAttrib(
158 1, GL_VERTEX_ATTRIB_ARRAY_INTEGER
, ¶m
));
159 EXPECT_EQ(1u, param
);
160 EXPECT_TRUE(manager_
->GetAttribPointer(
161 1, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr
));
164 // Check that getting the divisor is passed to the service.
165 // This is because the divisor is an optional feature which
166 // only the service can validate.
167 EXPECT_FALSE(manager_
->GetVertexAttrib(
168 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE
, ¶m
));
171 TEST_F(VertexArrayObjectManagerTest
, HaveEnabledClientSideArrays
) {
172 // Check turning on an array.
173 manager_
->SetAttribEnable(1, true);
174 EXPECT_TRUE(manager_
->HaveEnabledClientSideBuffers());
175 // Check turning off an array.
176 manager_
->SetAttribEnable(1, false);
177 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
178 // Check turning on an array and assigning a buffer.
179 manager_
->SetAttribEnable(1, true);
180 manager_
->SetAttribPointer(123, 1, 3, GL_BYTE
, true, 3, NULL
, GL_FALSE
);
181 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
182 // Check unassigning a buffer.
183 manager_
->SetAttribPointer(0, 1, 3, GL_BYTE
, true, 3, NULL
, GL_FALSE
);
184 EXPECT_TRUE(manager_
->HaveEnabledClientSideBuffers());
185 // Check disabling the array.
186 manager_
->SetAttribEnable(1, false);
187 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
190 TEST_F(VertexArrayObjectManagerTest
, BindElementArray
) {
191 bool changed
= false;
192 GLuint ids
[2] = { 1, 3, };
193 manager_
->GenVertexArrays(arraysize(ids
), ids
);
195 // Check the default element array is 0.
196 EXPECT_EQ(0u, manager_
->bound_element_array_buffer());
197 // Check binding the same array does not need a service call.
198 EXPECT_FALSE(manager_
->BindElementArray(0u));
199 // Check binding a new element array requires a service call.
200 EXPECT_TRUE(manager_
->BindElementArray(55u));
201 // Check the element array was bound.
202 EXPECT_EQ(55u, manager_
->bound_element_array_buffer());
203 // Check binding the same array does not need a service call.
204 EXPECT_FALSE(manager_
->BindElementArray(55u));
206 // Check with a new vao.
207 EXPECT_TRUE(manager_
->BindVertexArray(1, &changed
));
208 // Check the default element array is 0.
209 EXPECT_EQ(0u, manager_
->bound_element_array_buffer());
210 // Check binding a new element array requires a service call.
211 EXPECT_TRUE(manager_
->BindElementArray(11u));
212 // Check the element array was bound.
213 EXPECT_EQ(11u, manager_
->bound_element_array_buffer());
214 // Check binding the same array does not need a service call.
215 EXPECT_FALSE(manager_
->BindElementArray(11u));
217 // check switching vao bindings returns the correct element array.
218 EXPECT_TRUE(manager_
->BindVertexArray(3, &changed
));
219 EXPECT_EQ(0u, manager_
->bound_element_array_buffer());
220 EXPECT_TRUE(manager_
->BindVertexArray(0, &changed
));
221 EXPECT_EQ(55u, manager_
->bound_element_array_buffer());
222 EXPECT_TRUE(manager_
->BindVertexArray(1, &changed
));
223 EXPECT_EQ(11u, manager_
->bound_element_array_buffer());
226 TEST_F(VertexArrayObjectManagerTest
, GenBindDelete
) {
227 // Check unknown array fails.
228 bool changed
= false;
229 EXPECT_FALSE(manager_
->BindVertexArray(123, &changed
));
230 EXPECT_FALSE(changed
);
232 GLuint ids
[2] = { 1, 3, };
233 manager_
->GenVertexArrays(arraysize(ids
), ids
);
234 // Check Genned arrays succeed.
235 EXPECT_TRUE(manager_
->BindVertexArray(1, &changed
));
236 EXPECT_TRUE(changed
);
237 EXPECT_TRUE(manager_
->BindVertexArray(3, &changed
));
238 EXPECT_TRUE(changed
);
240 // Check binding the same array returns changed as false.
241 EXPECT_TRUE(manager_
->BindVertexArray(3, &changed
));
242 EXPECT_FALSE(changed
);
244 // Check deleted ararys fail to bind
245 manager_
->DeleteVertexArrays(2, ids
);
246 EXPECT_FALSE(manager_
->BindVertexArray(1, &changed
));
247 EXPECT_FALSE(changed
);
248 EXPECT_FALSE(manager_
->BindVertexArray(3, &changed
));
249 EXPECT_FALSE(changed
);
251 // Check binding 0 returns changed as false since it's
253 EXPECT_TRUE(manager_
->BindVertexArray(0, &changed
));
254 EXPECT_FALSE(changed
);
257 TEST_F(VertexArrayObjectManagerTest
, IsReservedId
) {
258 EXPECT_TRUE(manager_
->IsReservedId(kClientSideArrayBuffer
));
259 EXPECT_TRUE(manager_
->IsReservedId(kClientSideElementArrayBuffer
));
260 EXPECT_FALSE(manager_
->IsReservedId(0));
261 EXPECT_FALSE(manager_
->IsReservedId(1));
262 EXPECT_FALSE(manager_
->IsReservedId(2));