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;
18 static const bool kSupportClientSideArrays
= true;
20 void SetUp() override
{
21 manager_
.reset(new VertexArrayObjectManager(
23 kClientSideArrayBuffer
,
24 kClientSideElementArrayBuffer
,
25 kSupportClientSideArrays
));
27 void TearDown() override
{}
29 scoped_ptr
<VertexArrayObjectManager
> manager_
;
32 // GCC requires these declarations, but MSVC requires they not be present
34 const GLuint
VertexArrayObjectManagerTest::kMaxAttribs
;
35 const GLuint
VertexArrayObjectManagerTest::kClientSideArrayBuffer
;
36 const GLuint
VertexArrayObjectManagerTest::kClientSideElementArrayBuffer
;
39 TEST_F(VertexArrayObjectManagerTest
, Basic
) {
40 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
41 // Check out of bounds access.
44 EXPECT_FALSE(manager_
->GetVertexAttrib(
45 kMaxAttribs
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, ¶m
));
46 EXPECT_FALSE(manager_
->GetAttribPointer(
47 kMaxAttribs
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr
));
49 for (GLuint ii
= 0; ii
< kMaxAttribs
; ++ii
) {
50 EXPECT_TRUE(manager_
->GetVertexAttrib(
51 ii
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, ¶m
));
53 EXPECT_TRUE(manager_
->GetVertexAttrib(
54 ii
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, ¶m
));
56 EXPECT_TRUE(manager_
->GetVertexAttrib(
57 ii
, GL_VERTEX_ATTRIB_ARRAY_SIZE
, ¶m
));
59 EXPECT_TRUE(manager_
->GetVertexAttrib(
60 ii
, GL_VERTEX_ATTRIB_ARRAY_TYPE
, ¶m
));
61 EXPECT_EQ(static_cast<uint32
>(GL_FLOAT
), param
);
62 EXPECT_TRUE(manager_
->GetVertexAttrib(
63 ii
, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, ¶m
));
65 EXPECT_TRUE(manager_
->GetAttribPointer(
66 ii
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr
));
67 EXPECT_TRUE(NULL
== ptr
);
71 TEST_F(VertexArrayObjectManagerTest
, UnbindBuffer
) {
72 const GLuint kBufferToUnbind
= 123;
73 const GLuint kBufferToRemain
= 456;
74 const GLuint kElementArray
= 789;
76 GLuint ids
[2] = { 1, 3, };
77 manager_
->GenVertexArrays(arraysize(ids
), ids
);
78 // Bind buffers to attribs on 2 vaos.
79 for (size_t ii
= 0; ii
< arraysize(ids
); ++ii
) {
80 EXPECT_TRUE(manager_
->BindVertexArray(ids
[ii
], &changed
));
81 EXPECT_TRUE(manager_
->SetAttribPointer(
82 kBufferToUnbind
, 0, 4, GL_FLOAT
, false, 0, 0));
83 EXPECT_TRUE(manager_
->SetAttribPointer(
84 kBufferToRemain
, 1, 4, GL_FLOAT
, false, 0, 0));
85 EXPECT_TRUE(manager_
->SetAttribPointer(
86 kBufferToUnbind
, 2, 4, GL_FLOAT
, false, 0, 0));
87 EXPECT_TRUE(manager_
->SetAttribPointer(
88 kBufferToRemain
, 3, 4, GL_FLOAT
, false, 0, 0));
89 for (size_t jj
= 0; jj
< 4u; ++jj
) {
90 manager_
->SetAttribEnable(jj
, true);
92 manager_
->BindElementArray(kElementArray
);
94 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
95 EXPECT_TRUE(manager_
->BindVertexArray(ids
[0], &changed
));
97 manager_
->UnbindBuffer(kBufferToUnbind
);
98 manager_
->UnbindBuffer(kElementArray
);
99 // The attribs are still enabled but their buffer is 0.
100 EXPECT_TRUE(manager_
->HaveEnabledClientSideBuffers());
101 // Check the status of the bindings.
102 static const uint32 expected
[][4] = {
103 { 0, kBufferToRemain
, 0, kBufferToRemain
, },
104 { kBufferToUnbind
, kBufferToRemain
, kBufferToUnbind
, kBufferToRemain
, },
106 static const GLuint expected_element_array
[] = {
109 for (size_t ii
= 0; ii
< arraysize(ids
); ++ii
) {
110 EXPECT_TRUE(manager_
->BindVertexArray(ids
[ii
], &changed
));
111 for (size_t jj
= 0; jj
< 4; ++jj
) {
113 EXPECT_TRUE(manager_
->GetVertexAttrib(
114 jj
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, ¶m
));
115 EXPECT_EQ(expected
[ii
][jj
], param
)
116 << "id: " << ids
[ii
] << ", attrib: " << jj
;
118 EXPECT_EQ(expected_element_array
[ii
],
119 manager_
->bound_element_array_buffer());
122 // The vao that was not bound still has all service side bufferws.
123 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
125 // Make sure unbinding 0 does not effect count incorrectly.
126 EXPECT_TRUE(manager_
->BindVertexArray(0, &changed
));
127 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
128 manager_
->SetAttribEnable(2, true);
129 manager_
->UnbindBuffer(0);
130 manager_
->SetAttribEnable(2, false);
131 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
134 TEST_F(VertexArrayObjectManagerTest
, GetSet
) {
135 const char* dummy
= "dummy";
136 const void* p
= reinterpret_cast<const void*>(dummy
);
137 manager_
->SetAttribEnable(1, true);
138 manager_
->SetAttribPointer(123, 1, 3, GL_BYTE
, true, 3, p
);
141 EXPECT_TRUE(manager_
->GetVertexAttrib(
142 1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, ¶m
));
143 EXPECT_EQ(123u, param
);
144 EXPECT_TRUE(manager_
->GetVertexAttrib(
145 1, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, ¶m
));
146 EXPECT_NE(0u, param
);
147 EXPECT_TRUE(manager_
->GetVertexAttrib(
148 1, GL_VERTEX_ATTRIB_ARRAY_SIZE
, ¶m
));
149 EXPECT_EQ(3u, param
);
150 EXPECT_TRUE(manager_
->GetVertexAttrib(
151 1, GL_VERTEX_ATTRIB_ARRAY_TYPE
, ¶m
));
152 EXPECT_EQ(static_cast<uint32
>(GL_BYTE
), param
);
153 EXPECT_TRUE(manager_
->GetVertexAttrib(
154 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, ¶m
));
155 EXPECT_NE(0u, param
);
156 EXPECT_TRUE(manager_
->GetAttribPointer(
157 1, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr
));
160 // Check that getting the divisor is passed to the service.
161 // This is because the divisor is an optional feature which
162 // only the service can validate.
163 EXPECT_FALSE(manager_
->GetVertexAttrib(
164 0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE
, ¶m
));
167 TEST_F(VertexArrayObjectManagerTest
, HaveEnabledClientSideArrays
) {
168 // Check turning on an array.
169 manager_
->SetAttribEnable(1, true);
170 EXPECT_TRUE(manager_
->HaveEnabledClientSideBuffers());
171 // Check turning off an array.
172 manager_
->SetAttribEnable(1, false);
173 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
174 // Check turning on an array and assigning a buffer.
175 manager_
->SetAttribEnable(1, true);
176 manager_
->SetAttribPointer(123, 1, 3, GL_BYTE
, true, 3, NULL
);
177 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
178 // Check unassigning a buffer.
179 manager_
->SetAttribPointer(0, 1, 3, GL_BYTE
, true, 3, NULL
);
180 EXPECT_TRUE(manager_
->HaveEnabledClientSideBuffers());
181 // Check disabling the array.
182 manager_
->SetAttribEnable(1, false);
183 EXPECT_FALSE(manager_
->HaveEnabledClientSideBuffers());
186 TEST_F(VertexArrayObjectManagerTest
, BindElementArray
) {
187 bool changed
= false;
188 GLuint ids
[2] = { 1, 3, };
189 manager_
->GenVertexArrays(arraysize(ids
), ids
);
191 // Check the default element array is 0.
192 EXPECT_EQ(0u, manager_
->bound_element_array_buffer());
193 // Check binding the same array does not need a service call.
194 EXPECT_FALSE(manager_
->BindElementArray(0u));
195 // Check binding a new element array requires a service call.
196 EXPECT_TRUE(manager_
->BindElementArray(55u));
197 // Check the element array was bound.
198 EXPECT_EQ(55u, manager_
->bound_element_array_buffer());
199 // Check binding the same array does not need a service call.
200 EXPECT_FALSE(manager_
->BindElementArray(55u));
202 // Check with a new vao.
203 EXPECT_TRUE(manager_
->BindVertexArray(1, &changed
));
204 // Check the default element array is 0.
205 EXPECT_EQ(0u, manager_
->bound_element_array_buffer());
206 // Check binding a new element array requires a service call.
207 EXPECT_TRUE(manager_
->BindElementArray(11u));
208 // Check the element array was bound.
209 EXPECT_EQ(11u, manager_
->bound_element_array_buffer());
210 // Check binding the same array does not need a service call.
211 EXPECT_FALSE(manager_
->BindElementArray(11u));
213 // check switching vao bindings returns the correct element array.
214 EXPECT_TRUE(manager_
->BindVertexArray(3, &changed
));
215 EXPECT_EQ(0u, manager_
->bound_element_array_buffer());
216 EXPECT_TRUE(manager_
->BindVertexArray(0, &changed
));
217 EXPECT_EQ(55u, manager_
->bound_element_array_buffer());
218 EXPECT_TRUE(manager_
->BindVertexArray(1, &changed
));
219 EXPECT_EQ(11u, manager_
->bound_element_array_buffer());
222 TEST_F(VertexArrayObjectManagerTest
, GenBindDelete
) {
223 // Check unknown array fails.
224 bool changed
= false;
225 EXPECT_FALSE(manager_
->BindVertexArray(123, &changed
));
226 EXPECT_FALSE(changed
);
228 GLuint ids
[2] = { 1, 3, };
229 manager_
->GenVertexArrays(arraysize(ids
), ids
);
230 // Check Genned arrays succeed.
231 EXPECT_TRUE(manager_
->BindVertexArray(1, &changed
));
232 EXPECT_TRUE(changed
);
233 EXPECT_TRUE(manager_
->BindVertexArray(3, &changed
));
234 EXPECT_TRUE(changed
);
236 // Check binding the same array returns changed as false.
237 EXPECT_TRUE(manager_
->BindVertexArray(3, &changed
));
238 EXPECT_FALSE(changed
);
240 // Check deleted ararys fail to bind
241 manager_
->DeleteVertexArrays(2, ids
);
242 EXPECT_FALSE(manager_
->BindVertexArray(1, &changed
));
243 EXPECT_FALSE(changed
);
244 EXPECT_FALSE(manager_
->BindVertexArray(3, &changed
));
245 EXPECT_FALSE(changed
);
247 // Check binding 0 returns changed as false since it's
249 EXPECT_TRUE(manager_
->BindVertexArray(0, &changed
));
250 EXPECT_FALSE(changed
);
253 TEST_F(VertexArrayObjectManagerTest
, IsReservedId
) {
254 EXPECT_TRUE(manager_
->IsReservedId(kClientSideArrayBuffer
));
255 EXPECT_TRUE(manager_
->IsReservedId(kClientSideElementArrayBuffer
));
256 EXPECT_FALSE(manager_
->IsReservedId(0));
257 EXPECT_FALSE(manager_
->IsReservedId(1));
258 EXPECT_FALSE(manager_
->IsReservedId(2));