1 // Copyright 2015 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/gles2_cmd_decoder.h"
6 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
8 using ::gfx::MockGLInterface
;
10 using ::testing::Return
;
11 using ::testing::SetArgPointee
;
20 } // namespace anonymous
22 TEST_P(GLES2DecoderTest
, MapBufferRangeUnmapBufferReadSucceeds
) {
23 const GLenum kTarget
= GL_ARRAY_BUFFER
;
24 const GLintptr kOffset
= 10;
25 const GLsizeiptr kSize
= 64;
26 const GLbitfield kAccess
= GL_MAP_READ_BIT
;
28 uint32_t result_shm_id
= kSharedMemoryId
;
29 uint32_t result_shm_offset
= kSharedMemoryOffset
;
30 uint32_t data_shm_id
= kSharedMemoryId
;
31 // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
32 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(uint32_t);
34 DoBindBuffer(kTarget
, client_buffer_id_
, kServiceBufferId
);
36 std::vector
<int8_t> data(kSize
);
37 for (GLsizeiptr ii
= 0; ii
< kSize
; ++ii
) {
38 data
[ii
] = static_cast<int8_t>(ii
% 255);
43 MapBufferRange(kTarget
, kOffset
, kSize
, kAccess
))
44 .WillOnce(Return(&data
[0]))
45 .RetiresOnSaturation();
47 typedef MapBufferRange::Result Result
;
48 Result
* result
= GetSharedMemoryAs
<Result
*>();
51 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
, data_shm_id
, data_shm_offset
,
52 result_shm_id
, result_shm_offset
);
53 decoder_
->set_unsafe_es3_apis_enabled(false);
55 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
56 EXPECT_EQ(0u, *result
);
57 decoder_
->set_unsafe_es3_apis_enabled(true);
59 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
60 int8_t* mem
= reinterpret_cast<int8_t*>(&result
[1]);
61 EXPECT_EQ(0, memcmp(&data
[0], mem
, kSize
));
62 EXPECT_EQ(1u, *result
);
66 EXPECT_CALL(*gl_
, UnmapBuffer(kTarget
))
67 .WillOnce(Return(GL_TRUE
))
68 .RetiresOnSaturation();
72 decoder_
->set_unsafe_es3_apis_enabled(false);
73 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
74 decoder_
->set_unsafe_es3_apis_enabled(true);
75 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
78 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
81 TEST_P(GLES2DecoderTest
, MapBufferRangeUnmapBufferWriteSucceeds
) {
82 const GLenum kTarget
= GL_ARRAY_BUFFER
;
83 const GLintptr kOffset
= 10;
84 const GLsizeiptr kSize
= 64;
85 const GLbitfield kAccess
= GL_MAP_WRITE_BIT
;
86 const GLbitfield kMappedAccess
= GL_MAP_WRITE_BIT
| GL_MAP_READ_BIT
;
88 uint32_t result_shm_id
= kSharedMemoryId
;
89 uint32_t result_shm_offset
= kSharedMemoryOffset
;
90 uint32_t data_shm_id
= kSharedMemoryId
;
91 // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
92 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(uint32_t);
94 DoBindBuffer(kTarget
, client_buffer_id_
, kServiceBufferId
);
96 std::vector
<int8_t> data(kSize
);
97 for (GLsizeiptr ii
= 0; ii
< kSize
; ++ii
) {
98 data
[ii
] = static_cast<int8_t>(ii
% 255);
101 { // MapBufferRange succeeds
103 MapBufferRange(kTarget
, kOffset
, kSize
, kMappedAccess
))
104 .WillOnce(Return(&data
[0]))
105 .RetiresOnSaturation();
107 typedef MapBufferRange::Result Result
;
108 Result
* result
= GetSharedMemoryAs
<Result
*>();
111 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
, data_shm_id
, data_shm_offset
,
112 result_shm_id
, result_shm_offset
);
113 decoder_
->set_unsafe_es3_apis_enabled(false);
115 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
116 EXPECT_EQ(0u, *result
);
117 decoder_
->set_unsafe_es3_apis_enabled(true);
119 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
120 int8_t* mem
= reinterpret_cast<int8_t*>(&result
[1]);
121 EXPECT_EQ(0, memcmp(&data
[0], mem
, kSize
));
122 EXPECT_EQ(1u, *result
);
125 { // UnmapBuffer succeeds
126 EXPECT_CALL(*gl_
, UnmapBuffer(kTarget
))
127 .WillOnce(Return(GL_TRUE
))
128 .RetiresOnSaturation();
132 decoder_
->set_unsafe_es3_apis_enabled(false);
133 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
134 decoder_
->set_unsafe_es3_apis_enabled(true);
135 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
138 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
141 TEST_P(GLES2DecoderTest
, MapBufferRangeNotInitFails
) {
142 const GLenum kTarget
= GL_ARRAY_BUFFER
;
143 const GLintptr kOffset
= 10;
144 const GLsizeiptr kSize
= 64;
145 const GLbitfield kAccess
= GL_MAP_READ_BIT
;
146 std::vector
<int8_t> data(kSize
);
148 typedef MapBufferRange::Result Result
;
149 Result
* result
= GetSharedMemoryAs
<Result
*>();
150 *result
= 1; // Any value other than 0.
151 uint32_t result_shm_id
= kSharedMemoryId
;
152 uint32_t result_shm_offset
= kSharedMemoryOffset
;
153 uint32_t data_shm_id
= kSharedMemoryId
;
154 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(*result
);
157 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
, data_shm_id
, data_shm_offset
,
158 result_shm_id
, result_shm_offset
);
159 decoder_
->set_unsafe_es3_apis_enabled(true);
160 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
163 TEST_P(GLES2DecoderTest
, MapBufferRangeWriteInvalidateRangeSucceeds
) {
164 const GLenum kTarget
= GL_ARRAY_BUFFER
;
165 const GLintptr kOffset
= 10;
166 const GLsizeiptr kSize
= 64;
167 // With MAP_INVALIDATE_RANGE_BIT, no need to append MAP_READ_BIT.
168 const GLbitfield kAccess
= GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
;
170 DoBindBuffer(kTarget
, client_buffer_id_
, kServiceBufferId
);
172 std::vector
<int8_t> data(kSize
);
173 for (GLsizeiptr ii
= 0; ii
< kSize
; ++ii
) {
174 data
[ii
] = static_cast<int8_t>(ii
% 255);
177 MapBufferRange(kTarget
, kOffset
, kSize
, kAccess
))
178 .WillOnce(Return(&data
[0]))
179 .RetiresOnSaturation();
181 typedef MapBufferRange::Result Result
;
182 Result
* result
= GetSharedMemoryAs
<Result
*>();
184 uint32_t result_shm_id
= kSharedMemoryId
;
185 uint32_t result_shm_offset
= kSharedMemoryOffset
;
186 uint32_t data_shm_id
= kSharedMemoryId
;
187 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(*result
);
189 int8_t* mem
= reinterpret_cast<int8_t*>(&result
[1]);
190 memset(mem
, 72, kSize
); // Init to a random value other than 0.
193 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
, data_shm_id
, data_shm_offset
,
194 result_shm_id
, result_shm_offset
);
195 decoder_
->set_unsafe_es3_apis_enabled(true);
196 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
199 TEST_P(GLES2DecoderTest
, MapBufferRangeWriteInvalidateBufferSucceeds
) {
200 // Test INVALIDATE_BUFFER_BIT is mapped to INVALIDATE_RANGE_BIT.
201 const GLenum kTarget
= GL_ARRAY_BUFFER
;
202 const GLintptr kOffset
= 10;
203 const GLsizeiptr kSize
= 64;
204 const GLbitfield kAccess
= GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_BUFFER_BIT
;
205 // With MAP_INVALIDATE_BUFFER_BIT, no need to append MAP_READ_BIT.
206 const GLbitfield kFilteredAccess
=
207 GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
;
209 DoBindBuffer(kTarget
, client_buffer_id_
, kServiceBufferId
);
211 std::vector
<int8_t> data(kSize
);
212 for (GLsizeiptr ii
= 0; ii
< kSize
; ++ii
) {
213 data
[ii
] = static_cast<int8_t>(ii
% 255);
216 MapBufferRange(kTarget
, kOffset
, kSize
, kFilteredAccess
))
217 .WillOnce(Return(&data
[0]))
218 .RetiresOnSaturation();
220 typedef MapBufferRange::Result Result
;
221 Result
* result
= GetSharedMemoryAs
<Result
*>();
223 uint32_t result_shm_id
= kSharedMemoryId
;
224 uint32_t result_shm_offset
= kSharedMemoryOffset
;
225 uint32_t data_shm_id
= kSharedMemoryId
;
226 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(*result
);
228 int8_t* mem
= reinterpret_cast<int8_t*>(&result
[1]);
229 memset(mem
, 72, kSize
); // Init to a random value other than 0.
232 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
, data_shm_id
, data_shm_offset
,
233 result_shm_id
, result_shm_offset
);
234 decoder_
->set_unsafe_es3_apis_enabled(true);
235 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
238 TEST_P(GLES2DecoderTest
, MapBufferRangeWriteUnsynchronizedBit
) {
239 // Test UNSYNCHRONIZED_BIT is filtered out.
240 const GLenum kTarget
= GL_ARRAY_BUFFER
;
241 const GLintptr kOffset
= 10;
242 const GLsizeiptr kSize
= 64;
243 const GLbitfield kAccess
= GL_MAP_WRITE_BIT
| GL_MAP_UNSYNCHRONIZED_BIT
;
244 const GLbitfield kFilteredAccess
= GL_MAP_WRITE_BIT
| GL_MAP_READ_BIT
;
246 DoBindBuffer(kTarget
, client_buffer_id_
, kServiceBufferId
);
248 std::vector
<int8_t> data(kSize
);
249 for (GLsizeiptr ii
= 0; ii
< kSize
; ++ii
) {
250 data
[ii
] = static_cast<int8_t>(ii
% 255);
253 MapBufferRange(kTarget
, kOffset
, kSize
, kFilteredAccess
))
254 .WillOnce(Return(&data
[0]))
255 .RetiresOnSaturation();
257 typedef MapBufferRange::Result Result
;
258 Result
* result
= GetSharedMemoryAs
<Result
*>();
260 uint32_t result_shm_id
= kSharedMemoryId
;
261 uint32_t result_shm_offset
= kSharedMemoryOffset
;
262 uint32_t data_shm_id
= kSharedMemoryId
;
263 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(*result
);
265 int8_t* mem
= reinterpret_cast<int8_t*>(&result
[1]);
266 memset(mem
, 72, kSize
); // Init to a random value other than 0.
269 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
, data_shm_id
, data_shm_offset
,
270 result_shm_id
, result_shm_offset
);
271 decoder_
->set_unsafe_es3_apis_enabled(true);
272 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
273 EXPECT_EQ(0, memcmp(&data
[0], mem
, kSize
));
276 TEST_P(GLES2DecoderTest
, MapBufferRangeWithError
) {
277 const GLenum kTarget
= GL_ARRAY_BUFFER
;
278 const GLintptr kOffset
= 10;
279 const GLsizeiptr kSize
= 64;
280 const GLbitfield kAccess
= GL_MAP_READ_BIT
;
281 std::vector
<int8_t> data(kSize
);
282 for (GLsizeiptr ii
= 0; ii
< kSize
; ++ii
) {
283 data
[ii
] = static_cast<int8_t>(ii
% 255);
286 MapBufferRange(kTarget
, kOffset
, kSize
, kAccess
))
287 .WillOnce(Return(nullptr)) // Return nullptr to indicate a GL error.
288 .RetiresOnSaturation();
290 typedef MapBufferRange::Result Result
;
291 Result
* result
= GetSharedMemoryAs
<Result
*>();
293 uint32_t result_shm_id
= kSharedMemoryId
;
294 uint32_t result_shm_offset
= kSharedMemoryOffset
;
295 uint32_t data_shm_id
= kSharedMemoryId
;
296 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(*result
);
298 int8_t* mem
= reinterpret_cast<int8_t*>(&result
[1]);
299 memset(mem
, 72, kSize
); // Init to a random value other than 0.
302 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
, data_shm_id
, data_shm_offset
,
303 result_shm_id
, result_shm_offset
);
304 decoder_
->set_unsafe_es3_apis_enabled(true);
305 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
306 memset(&data
[0], 72, kSize
);
308 EXPECT_EQ(0, memcmp(&data
[0], mem
, kSize
));
309 EXPECT_EQ(0u, *result
);
312 TEST_P(GLES2DecoderTest
, MapBufferRangeBadSharedMemoryFails
) {
313 const GLenum kTarget
= GL_ARRAY_BUFFER
;
314 const GLintptr kOffset
= 10;
315 const GLsizeiptr kSize
= 64;
316 const GLbitfield kAccess
= GL_MAP_READ_BIT
;
317 std::vector
<int8_t> data(kSize
);
318 for (GLsizeiptr ii
= 0; ii
< kSize
; ++ii
) {
319 data
[ii
] = static_cast<int8_t>(ii
% 255);
322 typedef MapBufferRange::Result Result
;
323 Result
* result
= GetSharedMemoryAs
<Result
*>();
325 uint32_t result_shm_id
= kSharedMemoryId
;
326 uint32_t result_shm_offset
= kSharedMemoryOffset
;
327 uint32_t data_shm_id
= kSharedMemoryId
;
328 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(*result
);
330 decoder_
->set_unsafe_es3_apis_enabled(true);
332 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
,
333 kInvalidSharedMemoryId
, data_shm_offset
,
334 result_shm_id
, result_shm_offset
);
335 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
336 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
,
337 data_shm_id
, data_shm_offset
,
338 kInvalidSharedMemoryId
, result_shm_offset
);
339 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
340 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
,
341 data_shm_id
, kInvalidSharedMemoryOffset
,
342 result_shm_id
, result_shm_offset
);
343 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
344 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
,
345 data_shm_id
, data_shm_offset
,
346 result_shm_id
, kInvalidSharedMemoryOffset
);
347 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
350 TEST_P(GLES2DecoderTest
, UnmapBufferWriteNotMappedFails
) {
351 const GLenum kTarget
= GL_ARRAY_BUFFER
;
353 DoBindBuffer(kTarget
, client_buffer_id_
, kServiceBufferId
);
357 decoder_
->set_unsafe_es3_apis_enabled(true);
358 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
359 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
362 TEST_P(GLES2DecoderTest
, UnmapBufferWriteNoBoundBufferFails
) {
363 const GLenum kTarget
= GL_ARRAY_BUFFER
;
367 decoder_
->set_unsafe_es3_apis_enabled(true);
368 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
369 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
372 TEST_P(GLES2DecoderTest
, BufferDataDestroysDataStore
) {
373 const GLenum kTarget
= GL_ARRAY_BUFFER
;
374 const GLintptr kOffset
= 10;
375 const GLsizeiptr kSize
= 64;
376 const GLbitfield kAccess
= GL_MAP_WRITE_BIT
;
377 const GLbitfield kFilteredAccess
= GL_MAP_WRITE_BIT
| GL_MAP_READ_BIT
;
379 uint32_t result_shm_id
= kSharedMemoryId
;
380 uint32_t result_shm_offset
= kSharedMemoryOffset
;
381 uint32_t data_shm_id
= kSharedMemoryId
;
382 // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
383 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(uint32_t);
385 DoBindBuffer(kTarget
, client_buffer_id_
, kServiceBufferId
);
387 std::vector
<int8_t> data(kSize
);
389 decoder_
->set_unsafe_es3_apis_enabled(true);
391 { // MapBufferRange succeeds
393 MapBufferRange(kTarget
, kOffset
, kSize
, kFilteredAccess
))
394 .WillOnce(Return(&data
[0]))
395 .RetiresOnSaturation();
397 typedef MapBufferRange::Result Result
;
398 Result
* result
= GetSharedMemoryAs
<Result
*>();
401 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
, data_shm_id
, data_shm_offset
,
402 result_shm_id
, result_shm_offset
);
404 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
405 EXPECT_EQ(1u, *result
);
408 { // BufferData unmaps the data store.
409 DoBufferData(kTarget
, kSize
* 2);
410 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
413 { // UnmapBuffer fails.
416 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
417 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
421 TEST_P(GLES2DecoderTest
, DeleteBuffersDestroysDataStore
) {
422 const GLenum kTarget
= GL_ARRAY_BUFFER
;
423 const GLintptr kOffset
= 10;
424 const GLsizeiptr kSize
= 64;
425 const GLbitfield kAccess
= GL_MAP_WRITE_BIT
;
426 const GLbitfield kFilteredAccess
= GL_MAP_WRITE_BIT
| GL_MAP_READ_BIT
;
428 uint32_t result_shm_id
= kSharedMemoryId
;
429 uint32_t result_shm_offset
= kSharedMemoryOffset
;
430 uint32_t data_shm_id
= kSharedMemoryId
;
431 // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
432 uint32_t data_shm_offset
= kSharedMemoryOffset
+ sizeof(uint32_t);
434 DoBindBuffer(kTarget
, client_buffer_id_
, kServiceBufferId
);
436 std::vector
<int8_t> data(kSize
);
438 decoder_
->set_unsafe_es3_apis_enabled(true);
440 { // MapBufferRange succeeds
442 MapBufferRange(kTarget
, kOffset
, kSize
, kFilteredAccess
))
443 .WillOnce(Return(&data
[0]))
444 .RetiresOnSaturation();
446 typedef MapBufferRange::Result Result
;
447 Result
* result
= GetSharedMemoryAs
<Result
*>();
450 cmd
.Init(kTarget
, kOffset
, kSize
, kAccess
, data_shm_id
, data_shm_offset
,
451 result_shm_id
, result_shm_offset
);
453 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
454 EXPECT_EQ(1u, *result
);
457 { // DeleteBuffers unmaps the data store.
458 DoDeleteBuffer(client_buffer_id_
, kServiceBufferId
);
459 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
462 { // UnmapBuffer fails.
465 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
466 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());