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/service/buffer_manager.h"
6 #include "gpu/command_buffer/service/error_state_mock.h"
7 #include "gpu/command_buffer/service/feature_info.h"
8 #include "gpu/command_buffer/service/gpu_service_test.h"
9 #include "gpu/command_buffer/service/mocks.h"
10 #include "gpu/command_buffer/service/test_helper.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gl/gl_mock.h"
15 using ::testing::Return
;
16 using ::testing::StrictMock
;
21 class BufferManagerTestBase
: public GpuServiceTest
{
24 MemoryTracker
* memory_tracker
,
25 FeatureInfo
* feature_info
,
26 const char* extensions
) {
27 GpuServiceTest::SetUp();
29 TestHelper::SetupFeatureInfoInitExpectations(gl_
.get(), extensions
);
30 feature_info
->Initialize();
32 error_state_
.reset(new MockErrorState());
33 manager_
.reset(new BufferManager(memory_tracker
, feature_info
));
36 void TearDown() override
{
37 manager_
->Destroy(false);
40 GpuServiceTest::TearDown();
43 GLenum
GetInitialTarget(const Buffer
* buffer
) const {
44 return buffer
->initial_target();
48 Buffer
* buffer
, GLenum target
, GLsizeiptr size
, GLenum usage
,
49 const GLvoid
* data
, GLenum error
) {
50 TestHelper::DoBufferData(
51 gl_
.get(), error_state_
.get(), manager_
.get(),
52 buffer
, target
, size
, usage
, data
, error
);
56 Buffer
* buffer
, GLenum target
, GLintptr offset
, GLsizeiptr size
,
59 if (!buffer
->CheckRange(offset
, size
)) {
60 EXPECT_CALL(*error_state_
, SetGLError(_
, _
, GL_INVALID_VALUE
, _
, _
))
62 .RetiresOnSaturation();
64 } else if (!buffer
->IsClientSideArray()) {
65 EXPECT_CALL(*gl_
, BufferSubData(target
, offset
, size
, _
))
67 .RetiresOnSaturation();
69 manager_
->DoBufferSubData(
70 error_state_
.get(), buffer
, target
, offset
, size
, data
);
74 scoped_ptr
<BufferManager
> manager_
;
75 scoped_ptr
<MockErrorState
> error_state_
;
78 class BufferManagerTest
: public BufferManagerTestBase
{
80 void SetUp() override
{ SetUpBase(NULL
, NULL
, ""); }
83 class BufferManagerMemoryTrackerTest
: public BufferManagerTestBase
{
85 void SetUp() override
{
86 mock_memory_tracker_
= new StrictMock
<MockMemoryTracker
>();
87 SetUpBase(mock_memory_tracker_
.get(), NULL
, "");
90 scoped_refptr
<MockMemoryTracker
> mock_memory_tracker_
;
93 class BufferManagerClientSideArraysTest
: public BufferManagerTestBase
{
95 void SetUp() override
{
96 feature_info_
= new FeatureInfo();
97 feature_info_
->workarounds_
.use_client_side_arrays_for_stream_buffers
=
99 SetUpBase(NULL
, feature_info_
.get(), "");
102 scoped_refptr
<FeatureInfo
> feature_info_
;
105 #define EXPECT_MEMORY_ALLOCATION_CHANGE(old_size, new_size, pool) \
106 EXPECT_CALL(*mock_memory_tracker_.get(), \
107 TrackMemoryAllocatedChange(old_size, new_size, pool)) \
108 .Times(1).RetiresOnSaturation()
110 TEST_F(BufferManagerTest
, Basic
) {
111 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
112 const GLuint kClientBuffer1Id
= 1;
113 const GLuint kServiceBuffer1Id
= 11;
114 const GLsizeiptr kBuffer1Size
= 123;
115 const GLuint kClientBuffer2Id
= 2;
116 // Check we can create buffer.
117 manager_
->CreateBuffer(kClientBuffer1Id
, kServiceBuffer1Id
);
118 // Check buffer got created.
119 Buffer
* buffer1
= manager_
->GetBuffer(kClientBuffer1Id
);
120 ASSERT_TRUE(buffer1
!= NULL
);
121 EXPECT_EQ(0u, GetInitialTarget(buffer1
));
122 EXPECT_EQ(0, buffer1
->size());
123 EXPECT_EQ(static_cast<GLenum
>(GL_STATIC_DRAW
), buffer1
->usage());
124 EXPECT_FALSE(buffer1
->IsDeleted());
125 EXPECT_FALSE(buffer1
->IsClientSideArray());
126 EXPECT_EQ(kServiceBuffer1Id
, buffer1
->service_id());
127 GLuint client_id
= 0;
128 EXPECT_TRUE(manager_
->GetClientId(buffer1
->service_id(), &client_id
));
129 EXPECT_EQ(kClientBuffer1Id
, client_id
);
130 manager_
->SetTarget(buffer1
, kTarget
);
131 EXPECT_EQ(kTarget
, GetInitialTarget(buffer1
));
132 // Check we and set its size.
134 buffer1
, kTarget
, kBuffer1Size
, GL_DYNAMIC_DRAW
, NULL
, GL_NO_ERROR
);
135 EXPECT_EQ(kBuffer1Size
, buffer1
->size());
136 EXPECT_EQ(static_cast<GLenum
>(GL_DYNAMIC_DRAW
), buffer1
->usage());
137 // Check we get nothing for a non-existent buffer.
138 EXPECT_TRUE(manager_
->GetBuffer(kClientBuffer2Id
) == NULL
);
139 // Check trying to a remove non-existent buffers does not crash.
140 manager_
->RemoveBuffer(kClientBuffer2Id
);
141 // Check that it gets deleted when the last reference is released.
142 EXPECT_CALL(*gl_
, DeleteBuffersARB(1, ::testing::Pointee(kServiceBuffer1Id
)))
144 .RetiresOnSaturation();
145 // Check we can't get the buffer after we remove it.
146 manager_
->RemoveBuffer(kClientBuffer1Id
);
147 EXPECT_TRUE(manager_
->GetBuffer(kClientBuffer1Id
) == NULL
);
150 TEST_F(BufferManagerMemoryTrackerTest
, Basic
) {
151 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
152 const GLuint kClientBuffer1Id
= 1;
153 const GLuint kServiceBuffer1Id
= 11;
154 const GLsizeiptr kBuffer1Size1
= 123;
155 const GLsizeiptr kBuffer1Size2
= 456;
156 // Check we can create buffer.
157 EXPECT_MEMORY_ALLOCATION_CHANGE(0, 0, MemoryTracker::kManaged
);
158 manager_
->CreateBuffer(kClientBuffer1Id
, kServiceBuffer1Id
);
159 // Check buffer got created.
160 Buffer
* buffer1
= manager_
->GetBuffer(kClientBuffer1Id
);
161 ASSERT_TRUE(buffer1
!= NULL
);
162 manager_
->SetTarget(buffer1
, kTarget
);
163 // Check we and set its size.
164 EXPECT_MEMORY_ALLOCATION_CHANGE(0, kBuffer1Size1
, MemoryTracker::kManaged
);
166 buffer1
, kTarget
, kBuffer1Size1
, GL_DYNAMIC_DRAW
, NULL
, GL_NO_ERROR
);
167 EXPECT_MEMORY_ALLOCATION_CHANGE(kBuffer1Size1
, 0, MemoryTracker::kManaged
);
168 EXPECT_MEMORY_ALLOCATION_CHANGE(0, kBuffer1Size2
, MemoryTracker::kManaged
);
170 buffer1
, kTarget
, kBuffer1Size2
, GL_DYNAMIC_DRAW
, NULL
, GL_NO_ERROR
);
171 // On delete it will get freed.
172 EXPECT_MEMORY_ALLOCATION_CHANGE(kBuffer1Size2
, 0, MemoryTracker::kManaged
);
175 TEST_F(BufferManagerTest
, Destroy
) {
176 const GLuint kClient1Id
= 1;
177 const GLuint kService1Id
= 11;
178 // Check we can create buffer.
179 manager_
->CreateBuffer(kClient1Id
, kService1Id
);
180 // Check buffer got created.
181 Buffer
* buffer1
= manager_
->GetBuffer(kClient1Id
);
182 ASSERT_TRUE(buffer1
!= NULL
);
183 EXPECT_CALL(*gl_
, DeleteBuffersARB(1, ::testing::Pointee(kService1Id
)))
185 .RetiresOnSaturation();
186 manager_
->Destroy(true);
187 // Check the resources were released.
188 buffer1
= manager_
->GetBuffer(kClient1Id
);
189 ASSERT_TRUE(buffer1
== NULL
);
192 TEST_F(BufferManagerTest
, DoBufferSubData
) {
193 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
194 const GLuint kClientBufferId
= 1;
195 const GLuint kServiceBufferId
= 11;
196 const uint8 data
[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
197 manager_
->CreateBuffer(kClientBufferId
, kServiceBufferId
);
198 Buffer
* buffer
= manager_
->GetBuffer(kClientBufferId
);
199 ASSERT_TRUE(buffer
!= NULL
);
200 manager_
->SetTarget(buffer
, kTarget
);
202 buffer
, kTarget
, sizeof(data
), GL_STATIC_DRAW
, NULL
, GL_NO_ERROR
);
203 EXPECT_TRUE(DoBufferSubData(buffer
, kTarget
, 0, sizeof(data
), data
));
204 EXPECT_TRUE(DoBufferSubData(buffer
, kTarget
, sizeof(data
), 0, data
));
205 EXPECT_FALSE(DoBufferSubData(buffer
, kTarget
, sizeof(data
), 1, data
));
206 EXPECT_FALSE(DoBufferSubData(buffer
, kTarget
, 0, sizeof(data
) + 1, data
));
207 EXPECT_FALSE(DoBufferSubData(buffer
, kTarget
, -1, sizeof(data
), data
));
208 EXPECT_FALSE(DoBufferSubData(buffer
, kTarget
, 0, -1, data
));
209 DoBufferData(buffer
, kTarget
, 1, GL_STATIC_DRAW
, NULL
, GL_NO_ERROR
);
210 const int size
= 0x20000;
211 scoped_ptr
<uint8
[]> temp(new uint8
[size
]);
212 EXPECT_FALSE(DoBufferSubData(buffer
, kTarget
, 0 - size
, size
, temp
.get()));
213 EXPECT_FALSE(DoBufferSubData(buffer
, kTarget
, 1, size
/ 2, temp
.get()));
216 TEST_F(BufferManagerTest
, GetRange
) {
217 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
218 const GLuint kClientBufferId
= 1;
219 const GLuint kServiceBufferId
= 11;
220 const GLsizeiptr kDataSize
= 10;
221 manager_
->CreateBuffer(kClientBufferId
, kServiceBufferId
);
222 Buffer
* buffer
= manager_
->GetBuffer(kClientBufferId
);
223 ASSERT_TRUE(buffer
!= NULL
);
224 manager_
->SetTarget(buffer
, kTarget
);
225 DoBufferData(buffer
, kTarget
, kDataSize
, GL_STATIC_DRAW
, NULL
, GL_NO_ERROR
);
227 static_cast<const char*>(buffer
->GetRange(0, kDataSize
));
228 ASSERT_TRUE(buf
!= NULL
);
230 static_cast<const char*>(buffer
->GetRange(1, kDataSize
- 1));
231 EXPECT_EQ(buf
+ 1, buf1
);
232 EXPECT_TRUE(buffer
->GetRange(kDataSize
, 1) == NULL
);
233 EXPECT_TRUE(buffer
->GetRange(0, kDataSize
+ 1) == NULL
);
234 EXPECT_TRUE(buffer
->GetRange(-1, kDataSize
) == NULL
);
235 EXPECT_TRUE(buffer
->GetRange(-0, -1) == NULL
);
236 const int size
= 0x20000;
237 DoBufferData(buffer
, kTarget
, size
/ 2, GL_STATIC_DRAW
, NULL
, GL_NO_ERROR
);
238 EXPECT_TRUE(buffer
->GetRange(0 - size
, size
) == NULL
);
239 EXPECT_TRUE(buffer
->GetRange(1, size
/ 2) == NULL
);
242 TEST_F(BufferManagerTest
, GetMaxValueForRangeUint8
) {
243 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
244 const GLuint kClientBufferId
= 1;
245 const GLuint kServiceBufferId
= 11;
246 const uint8 data
[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
247 const uint8 new_data
[] = {100, 120, 110};
248 manager_
->CreateBuffer(kClientBufferId
, kServiceBufferId
);
249 Buffer
* buffer
= manager_
->GetBuffer(kClientBufferId
);
250 ASSERT_TRUE(buffer
!= NULL
);
251 manager_
->SetTarget(buffer
, kTarget
);
253 buffer
, kTarget
, sizeof(data
), GL_STATIC_DRAW
, NULL
, GL_NO_ERROR
);
254 EXPECT_TRUE(DoBufferSubData(buffer
, kTarget
, 0, sizeof(data
), data
));
256 // Check entire range succeeds.
257 EXPECT_TRUE(buffer
->GetMaxValueForRange(
258 0, 10, GL_UNSIGNED_BYTE
, &max_value
));
259 EXPECT_EQ(10u, max_value
);
260 // Check sub range succeeds.
261 EXPECT_TRUE(buffer
->GetMaxValueForRange(
262 4, 3, GL_UNSIGNED_BYTE
, &max_value
));
263 EXPECT_EQ(6u, max_value
);
264 // Check changing sub range succeeds.
265 EXPECT_TRUE(DoBufferSubData(buffer
, kTarget
, 4, sizeof(new_data
), new_data
));
266 EXPECT_TRUE(buffer
->GetMaxValueForRange(
267 4, 3, GL_UNSIGNED_BYTE
, &max_value
));
268 EXPECT_EQ(120u, max_value
);
270 EXPECT_TRUE(buffer
->GetMaxValueForRange(
271 0, 10, GL_UNSIGNED_BYTE
, &max_value
));
272 EXPECT_EQ(120u, max_value
);
273 // Check out of range fails.
274 EXPECT_FALSE(buffer
->GetMaxValueForRange(
275 0, 11, GL_UNSIGNED_BYTE
, &max_value
));
276 EXPECT_FALSE(buffer
->GetMaxValueForRange(
277 10, 1, GL_UNSIGNED_BYTE
, &max_value
));
280 TEST_F(BufferManagerTest
, GetMaxValueForRangeUint16
) {
281 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
282 const GLuint kClientBufferId
= 1;
283 const GLuint kServiceBufferId
= 11;
284 const uint16 data
[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
285 const uint16 new_data
[] = {100, 120, 110};
286 manager_
->CreateBuffer(kClientBufferId
, kServiceBufferId
);
287 Buffer
* buffer
= manager_
->GetBuffer(kClientBufferId
);
288 ASSERT_TRUE(buffer
!= NULL
);
289 manager_
->SetTarget(buffer
, kTarget
);
291 buffer
, kTarget
, sizeof(data
), GL_STATIC_DRAW
, NULL
, GL_NO_ERROR
);
292 EXPECT_TRUE(DoBufferSubData(buffer
, kTarget
, 0, sizeof(data
), data
));
294 // Check entire range succeeds.
295 EXPECT_TRUE(buffer
->GetMaxValueForRange(
296 0, 10, GL_UNSIGNED_SHORT
, &max_value
));
297 EXPECT_EQ(10u, max_value
);
298 // Check odd offset fails for GL_UNSIGNED_SHORT.
299 EXPECT_FALSE(buffer
->GetMaxValueForRange(
300 1, 10, GL_UNSIGNED_SHORT
, &max_value
));
301 // Check sub range succeeds.
302 EXPECT_TRUE(buffer
->GetMaxValueForRange(
303 8, 3, GL_UNSIGNED_SHORT
, &max_value
));
304 EXPECT_EQ(6u, max_value
);
305 // Check changing sub range succeeds.
306 EXPECT_TRUE(DoBufferSubData(buffer
, kTarget
, 8, sizeof(new_data
), new_data
));
307 EXPECT_TRUE(buffer
->GetMaxValueForRange(
308 8, 3, GL_UNSIGNED_SHORT
, &max_value
));
309 EXPECT_EQ(120u, max_value
);
311 EXPECT_TRUE(buffer
->GetMaxValueForRange(
312 0, 10, GL_UNSIGNED_SHORT
, &max_value
));
313 EXPECT_EQ(120u, max_value
);
314 // Check out of range fails.
315 EXPECT_FALSE(buffer
->GetMaxValueForRange(
316 0, 11, GL_UNSIGNED_SHORT
, &max_value
));
317 EXPECT_FALSE(buffer
->GetMaxValueForRange(
318 20, 1, GL_UNSIGNED_SHORT
, &max_value
));
321 TEST_F(BufferManagerTest
, GetMaxValueForRangeUint32
) {
322 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
323 const GLuint kClientBufferId
= 1;
324 const GLuint kServiceBufferId
= 11;
325 const uint32 data
[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
326 const uint32 new_data
[] = {100, 120, 110};
327 manager_
->CreateBuffer(kClientBufferId
, kServiceBufferId
);
328 Buffer
* buffer
= manager_
->GetBuffer(kClientBufferId
);
329 ASSERT_TRUE(buffer
!= NULL
);
330 manager_
->SetTarget(buffer
, kTarget
);
332 buffer
, kTarget
, sizeof(data
), GL_STATIC_DRAW
, NULL
, GL_NO_ERROR
);
333 EXPECT_TRUE(DoBufferSubData(buffer
, kTarget
, 0, sizeof(data
), data
));
335 // Check entire range succeeds.
337 buffer
->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT
, &max_value
));
338 EXPECT_EQ(10u, max_value
);
339 // Check non aligned offsets fails for GL_UNSIGNED_INT.
341 buffer
->GetMaxValueForRange(1, 10, GL_UNSIGNED_INT
, &max_value
));
343 buffer
->GetMaxValueForRange(2, 10, GL_UNSIGNED_INT
, &max_value
));
345 buffer
->GetMaxValueForRange(3, 10, GL_UNSIGNED_INT
, &max_value
));
346 // Check sub range succeeds.
347 EXPECT_TRUE(buffer
->GetMaxValueForRange(16, 3, GL_UNSIGNED_INT
, &max_value
));
348 EXPECT_EQ(6u, max_value
);
349 // Check changing sub range succeeds.
350 EXPECT_TRUE(DoBufferSubData(buffer
, kTarget
, 16, sizeof(new_data
), new_data
));
351 EXPECT_TRUE(buffer
->GetMaxValueForRange(16, 3, GL_UNSIGNED_INT
, &max_value
));
352 EXPECT_EQ(120u, max_value
);
354 EXPECT_TRUE(buffer
->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT
, &max_value
));
355 EXPECT_EQ(120u, max_value
);
356 // Check out of range fails.
358 buffer
->GetMaxValueForRange(0, 11, GL_UNSIGNED_INT
, &max_value
));
360 buffer
->GetMaxValueForRange(40, 1, GL_UNSIGNED_INT
, &max_value
));
363 TEST_F(BufferManagerTest
, UseDeletedBuffer
) {
364 const GLenum kTarget
= GL_ARRAY_BUFFER
;
365 const GLuint kClientBufferId
= 1;
366 const GLuint kServiceBufferId
= 11;
367 const GLsizeiptr kDataSize
= 10;
368 manager_
->CreateBuffer(kClientBufferId
, kServiceBufferId
);
369 scoped_refptr
<Buffer
> buffer
= manager_
->GetBuffer(kClientBufferId
);
370 ASSERT_TRUE(buffer
.get() != NULL
);
371 manager_
->SetTarget(buffer
.get(), kTarget
);
373 manager_
->RemoveBuffer(kClientBufferId
);
374 // Use it after removing
376 buffer
.get(), kTarget
, kDataSize
, GL_STATIC_DRAW
, NULL
, GL_NO_ERROR
);
377 // Check that it gets deleted when the last reference is released.
378 EXPECT_CALL(*gl_
, DeleteBuffersARB(1, ::testing::Pointee(kServiceBufferId
)))
380 .RetiresOnSaturation();
384 // Test buffers get shadowed when they are supposed to be.
385 TEST_F(BufferManagerClientSideArraysTest
, StreamBuffersAreShadowed
) {
386 const GLenum kTarget
= GL_ARRAY_BUFFER
;
387 const GLuint kClientBufferId
= 1;
388 const GLuint kServiceBufferId
= 11;
389 static const uint32 data
[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
390 manager_
->CreateBuffer(kClientBufferId
, kServiceBufferId
);
391 Buffer
* buffer
= manager_
->GetBuffer(kClientBufferId
);
392 ASSERT_TRUE(buffer
!= NULL
);
393 manager_
->SetTarget(buffer
, kTarget
);
395 buffer
, kTarget
, sizeof(data
), GL_STREAM_DRAW
, data
, GL_NO_ERROR
);
396 EXPECT_TRUE(buffer
->IsClientSideArray());
397 EXPECT_EQ(0, memcmp(data
, buffer
->GetRange(0, sizeof(data
)), sizeof(data
)));
399 buffer
, kTarget
, sizeof(data
), GL_DYNAMIC_DRAW
, data
, GL_NO_ERROR
);
400 EXPECT_FALSE(buffer
->IsClientSideArray());
403 TEST_F(BufferManagerTest
, MaxValueCacheClearedCorrectly
) {
404 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
405 const GLuint kClientBufferId
= 1;
406 const GLuint kServiceBufferId
= 11;
407 const uint32 data1
[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
408 const uint32 data2
[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
409 const uint32 data3
[] = {30, 29, 28};
410 manager_
->CreateBuffer(kClientBufferId
, kServiceBufferId
);
411 Buffer
* buffer
= manager_
->GetBuffer(kClientBufferId
);
412 ASSERT_TRUE(buffer
!= NULL
);
413 manager_
->SetTarget(buffer
, kTarget
);
415 // Load the buffer with some initial data, and then get the maximum value for
416 // a range, which has the side effect of caching it.
418 buffer
, kTarget
, sizeof(data1
), GL_STATIC_DRAW
, data1
, GL_NO_ERROR
);
420 buffer
->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT
, &max_value
));
421 EXPECT_EQ(10u, max_value
);
422 // Check that any cached values are invalidated if the buffer is reloaded
423 // with the same amount of data (but different content)
424 ASSERT_EQ(sizeof(data2
), sizeof(data1
));
426 buffer
, kTarget
, sizeof(data2
), GL_STATIC_DRAW
, data2
, GL_NO_ERROR
);
428 buffer
->GetMaxValueForRange(0, 10, GL_UNSIGNED_INT
, &max_value
));
429 EXPECT_EQ(20u, max_value
);
430 // Check that any cached values are invalidated if the buffer is reloaded
431 // with entirely different content.
432 ASSERT_NE(sizeof(data3
), sizeof(data1
));
434 buffer
, kTarget
, sizeof(data3
), GL_STATIC_DRAW
, data3
, GL_NO_ERROR
);
436 buffer
->GetMaxValueForRange(0, 3, GL_UNSIGNED_INT
, &max_value
));
437 EXPECT_EQ(30u, max_value
);
440 TEST_F(BufferManagerTest
, BindBufferConflicts
) {
441 manager_
->set_allow_buffers_on_multiple_targets(false);
442 GLuint client_id
= 1;
443 GLuint service_id
= 101;
446 // Once a buffer is bound to ELEMENT_ARRAY_BUFFER, it can't be bound to
447 // any other targets except for GL_COPY_READ/WRITE_BUFFER.
448 manager_
->CreateBuffer(client_id
, service_id
);
449 Buffer
* buffer
= manager_
->GetBuffer(client_id
);
450 ASSERT_TRUE(buffer
!= NULL
);
451 EXPECT_TRUE(manager_
->SetTarget(buffer
, GL_ELEMENT_ARRAY_BUFFER
));
452 EXPECT_TRUE(manager_
->SetTarget(buffer
, GL_COPY_READ_BUFFER
));
453 EXPECT_TRUE(manager_
->SetTarget(buffer
, GL_COPY_WRITE_BUFFER
));
454 EXPECT_FALSE(manager_
->SetTarget(buffer
, GL_ARRAY_BUFFER
));
455 EXPECT_FALSE(manager_
->SetTarget(buffer
, GL_PIXEL_PACK_BUFFER
));
456 EXPECT_FALSE(manager_
->SetTarget(buffer
, GL_PIXEL_UNPACK_BUFFER
));
457 EXPECT_FALSE(manager_
->SetTarget(buffer
, GL_TRANSFORM_FEEDBACK_BUFFER
));
458 EXPECT_FALSE(manager_
->SetTarget(buffer
, GL_UNIFORM_BUFFER
));
462 // Except for ELEMENT_ARRAY_BUFFER, a buffer can switch to any targets.
463 const GLenum kTargets
[] = {
466 GL_COPY_WRITE_BUFFER
,
467 GL_PIXEL_PACK_BUFFER
,
468 GL_PIXEL_UNPACK_BUFFER
,
469 GL_TRANSFORM_FEEDBACK_BUFFER
,
472 for (size_t ii
= 0; ii
< arraysize(kTargets
); ++ii
) {
475 manager_
->CreateBuffer(client_id
, service_id
);
476 Buffer
* buffer
= manager_
->GetBuffer(client_id
);
477 ASSERT_TRUE(buffer
!= NULL
);
479 EXPECT_TRUE(manager_
->SetTarget(buffer
, kTargets
[ii
]));
480 for (size_t jj
= 0; jj
< arraysize(kTargets
); ++jj
) {
481 EXPECT_TRUE(manager_
->SetTarget(buffer
, kTargets
[jj
]));
483 EXPECT_EQ(kTargets
[ii
], GetInitialTarget(buffer
));
488 // Once a buffer is bound to non ELEMENT_ARRAY_BUFFER target, it can't be
489 // bound to ELEMENT_ARRAY_BUFFER target.
490 const GLenum kTargets
[] = {
493 GL_COPY_WRITE_BUFFER
,
494 GL_PIXEL_PACK_BUFFER
,
495 GL_PIXEL_UNPACK_BUFFER
,
496 GL_TRANSFORM_FEEDBACK_BUFFER
,
499 for (size_t ii
= 0; ii
< arraysize(kTargets
); ++ii
) {
502 manager_
->CreateBuffer(client_id
, service_id
);
503 Buffer
* buffer
= manager_
->GetBuffer(client_id
);
504 ASSERT_TRUE(buffer
!= NULL
);
506 EXPECT_TRUE(manager_
->SetTarget(buffer
, kTargets
[ii
]));
507 for (size_t jj
= 0; jj
< arraysize(kTargets
); ++jj
) {
508 EXPECT_TRUE(manager_
->SetTarget(buffer
, kTargets
[jj
]));