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.
4 
5 #include <stdint.h>
6 
7 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
8 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
9 
10 using ::gl::MockGLInterface;
11 using ::testing::_;
12 using ::testing::Return;
13 using ::testing::SetArgPointee;
14 
15 namespace gpu {
16 namespace gles2 {
17 
18 namespace {
19 
20 }  // namespace anonymous
21 
TEST_P(GLES3DecoderTest,BindBufferBaseValidArgs)22 TEST_P(GLES3DecoderTest, BindBufferBaseValidArgs) {
23   EXPECT_CALL(
24       *gl_, BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kServiceBufferId));
25   SpecializedSetup<cmds::BindBufferBase, 0>(true);
26   cmds::BindBufferBase cmd;
27   cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, client_buffer_id_);
28   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
29   EXPECT_EQ(GL_NO_ERROR, GetGLError());
30 }
31 
TEST_P(GLES3DecoderTest,BindBufferBaseValidArgsNewId)32 TEST_P(GLES3DecoderTest, BindBufferBaseValidArgsNewId) {
33   EXPECT_CALL(*gl_,
34               BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewServiceId));
35   EXPECT_CALL(*gl_, GenBuffersARB(1, _))
36       .WillOnce(SetArgPointee<1>(kNewServiceId));
37   SpecializedSetup<cmds::BindBufferBase, 0>(true);
38   cmds::BindBufferBase cmd;
39   cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewClientId);
40   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
41   EXPECT_EQ(GL_NO_ERROR, GetGLError());
42   EXPECT_TRUE(GetBuffer(kNewClientId) != nullptr);
43 }
44 
TEST_P(GLES3DecoderTest,BindBufferRangeValidArgs)45 TEST_P(GLES3DecoderTest, BindBufferRangeValidArgs) {
46   const GLenum kTarget = GL_TRANSFORM_FEEDBACK_BUFFER;
47   const GLintptr kRangeOffset = 4;
48   const GLsizeiptr kRangeSize = 8;
49   const GLsizeiptr kBufferSize = kRangeOffset + kRangeSize;
50   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
51   DoBufferData(kTarget, kBufferSize);
52   EXPECT_CALL(*gl_, BindBufferRange(kTarget, 2, kServiceBufferId,
53                                     kRangeOffset, kRangeSize));
54   SpecializedSetup<cmds::BindBufferRange, 0>(true);
55   cmds::BindBufferRange cmd;
56   cmd.Init(kTarget, 2, client_buffer_id_, kRangeOffset, kRangeSize);
57   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
58   EXPECT_EQ(GL_NO_ERROR, GetGLError());
59 }
60 
TEST_P(GLES3DecoderTest,BindBufferRangeValidArgsWithNoData)61 TEST_P(GLES3DecoderTest, BindBufferRangeValidArgsWithNoData) {
62   const GLenum kTarget = GL_TRANSFORM_FEEDBACK_BUFFER;
63   const GLintptr kRangeOffset = 4;
64   const GLsizeiptr kRangeSize = 8;
65   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
66   EXPECT_CALL(*gl_, BindBufferBase(kTarget, 2, kServiceBufferId));
67   SpecializedSetup<cmds::BindBufferRange, 0>(true);
68   cmds::BindBufferRange cmd;
69   cmd.Init(kTarget, 2, client_buffer_id_, kRangeOffset, kRangeSize);
70   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
71   EXPECT_EQ(GL_NO_ERROR, GetGLError());
72 }
73 
TEST_P(GLES3DecoderTest,BindBufferRangeValidArgsWithLessData)74 TEST_P(GLES3DecoderTest, BindBufferRangeValidArgsWithLessData) {
75   const GLenum kTarget = GL_TRANSFORM_FEEDBACK_BUFFER;
76   const GLintptr kRangeOffset = 4;
77   const GLsizeiptr kRangeSize = 8;
78   const GLsizeiptr kBufferSize = kRangeOffset + kRangeSize - 4;
79   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
80   DoBufferData(kTarget, kBufferSize);
81   EXPECT_CALL(*gl_, BindBufferRange(kTarget, 2, kServiceBufferId,
82                                     kRangeOffset, kRangeSize - 4));
83   SpecializedSetup<cmds::BindBufferRange, 0>(true);
84   cmds::BindBufferRange cmd;
85   cmd.Init(kTarget, 2, client_buffer_id_, kRangeOffset, kRangeSize);
86   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
87   EXPECT_EQ(GL_NO_ERROR, GetGLError());
88 }
89 
TEST_P(GLES3DecoderTest,BindBufferRangeValidArgsNewId)90 TEST_P(GLES3DecoderTest, BindBufferRangeValidArgsNewId) {
91   EXPECT_CALL(*gl_, BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2,
92                                     kNewServiceId));
93   EXPECT_CALL(*gl_, GenBuffersARB(1, _))
94       .WillOnce(SetArgPointee<1>(kNewServiceId));
95   SpecializedSetup<cmds::BindBufferRange, 0>(true);
96   cmds::BindBufferRange cmd;
97   cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewClientId, 4, 4);
98   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
99   EXPECT_EQ(GL_NO_ERROR, GetGLError());
100   EXPECT_TRUE(GetBuffer(kNewClientId) != nullptr);
101 }
102 
TEST_P(GLES3DecoderTest,MapBufferRangeUnmapBufferReadSucceeds)103 TEST_P(GLES3DecoderTest, MapBufferRangeUnmapBufferReadSucceeds) {
104   const GLenum kTarget = GL_ARRAY_BUFFER;
105   const GLintptr kOffset = 10;
106   const GLsizeiptr kSize = 64;
107   const GLbitfield kAccess = GL_MAP_READ_BIT;
108 
109   uint32_t result_shm_id = shared_memory_id_;
110   uint32_t result_shm_offset = kSharedMemoryOffset;
111   uint32_t data_shm_id = shared_memory_id_;
112   // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
113   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t);
114 
115   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
116   DoBufferData(kTarget, kSize + kOffset);
117 
118   std::vector<int8_t> data(kSize);
119   for (GLsizeiptr ii = 0; ii < kSize; ++ii) {
120     data[ii] = static_cast<int8_t>(ii % 255);
121   }
122 
123   {  // MapBufferRange
124     EXPECT_CALL(*gl_,
125                 MapBufferRange(kTarget, kOffset, kSize, kAccess))
126         .WillOnce(Return(&data[0]))
127         .RetiresOnSaturation();
128 
129     auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
130 
131     cmds::MapBufferRange cmd;
132     cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
133              result_shm_id, result_shm_offset);
134     *result = 0;
135     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
136     int8_t* mem = reinterpret_cast<int8_t*>(&result[1]);
137     EXPECT_EQ(0, memcmp(&data[0], mem, kSize));
138     EXPECT_EQ(1u, *result);
139   }
140 
141   {  // UnmapBuffer
142     EXPECT_CALL(*gl_, UnmapBuffer(kTarget))
143         .WillOnce(Return(GL_TRUE))
144         .RetiresOnSaturation();
145 
146     cmds::UnmapBuffer cmd;
147     cmd.Init(kTarget);
148     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
149   }
150 
151   EXPECT_EQ(GL_NO_ERROR, GetGLError());
152 }
153 
TEST_P(GLES3DecoderTest,MapBufferRangeUnmapBufferWriteSucceeds)154 TEST_P(GLES3DecoderTest, MapBufferRangeUnmapBufferWriteSucceeds) {
155   const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
156   const GLintptr kOffset = 10;
157   const GLsizeiptr kSize = 64;
158   const GLsizeiptr kTotalSize = kOffset + kSize;
159   const GLbitfield kAccess = GL_MAP_WRITE_BIT;
160   const GLbitfield kMappedAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT;
161 
162   uint32_t result_shm_id = shared_memory_id_;
163   uint32_t result_shm_offset = kSharedMemoryOffset;
164   uint32_t data_shm_id = shared_memory_id_;
165   // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
166   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t);
167 
168   auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
169   int8_t* client_data = GetSharedMemoryAs<int8_t*>() + sizeof(uint32_t);
170 
171   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
172   Buffer* buffer = GetBuffer(client_buffer_id_);
173   EXPECT_TRUE(buffer != nullptr);
174   DoBufferData(kTarget, kTotalSize);
175   std::vector<int8_t> gpu_data(kTotalSize);
176   for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
177     gpu_data[ii] = static_cast<int8_t>(ii % 128);
178   }
179   DoBufferSubData(kTarget, 0, kTotalSize, &gpu_data[0]);
180 
181   EXPECT_EQ(GL_NO_ERROR, GetGLError());
182   EXPECT_TRUE(buffer->shadowed());
183   const int8_t* shadow_data = reinterpret_cast<const int8_t*>(
184       buffer->GetRange(0, kTotalSize));
185   EXPECT_TRUE(shadow_data);
186   // Verify the shadow data is initialized.
187   for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
188     EXPECT_EQ(static_cast<int8_t>(ii % 128), shadow_data[ii]);
189   }
190 
191   {  // MapBufferRange succeeds
192     EXPECT_CALL(*gl_,
193                 MapBufferRange(kTarget, kOffset, kSize, kMappedAccess))
194         .WillOnce(Return(&gpu_data[kOffset]))
195         .RetiresOnSaturation();
196 
197     cmds::MapBufferRange cmd;
198     cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
199              result_shm_id, result_shm_offset);
200     *result = 0;
201     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
202     EXPECT_EQ(1u, *result);
203     // Verify the buffer range from GPU is copied to client mem.
204     EXPECT_EQ(0, memcmp(&gpu_data[kOffset], client_data, kSize));
205   }
206 
207   // Update the client mem.
208   const int8_t kValue0 = 21;
209   memset(client_data, kValue0, kSize);
210 
211   {  // UnmapBuffer succeeds
212     EXPECT_CALL(*gl_, UnmapBuffer(kTarget))
213         .WillOnce(Return(GL_TRUE))
214         .RetiresOnSaturation();
215 
216     cmds::UnmapBuffer cmd;
217     cmd.Init(kTarget);
218     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
219 
220     // Verify the GPU mem and shadow data are both updated
221     for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
222       if (ii < kOffset) {
223         EXPECT_EQ(static_cast<int8_t>(ii % 128), gpu_data[ii]);
224         EXPECT_EQ(static_cast<int8_t>(ii % 128), shadow_data[ii]);
225       } else {
226         EXPECT_EQ(kValue0, gpu_data[ii]);
227         EXPECT_EQ(kValue0, shadow_data[ii]);
228       }
229     }
230   }
231 
232   EXPECT_EQ(GL_NO_ERROR, GetGLError());
233 }
234 
235 
TEST_P(GLES3DecoderTest,FlushMappedBufferRangeSucceeds)236 TEST_P(GLES3DecoderTest, FlushMappedBufferRangeSucceeds) {
237   const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
238   const GLintptr kMappedOffset = 10;
239   const GLsizeiptr kMappedSize = 64;
240   const GLintptr kFlushRangeOffset = 5;
241   const GLsizeiptr kFlushRangeSize = 32;
242   const GLsizeiptr kTotalSize = kMappedOffset + kMappedSize;
243   const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
244   const GLbitfield kMappedAccess = kAccess | GL_MAP_READ_BIT;
245 
246   uint32_t result_shm_id = shared_memory_id_;
247   uint32_t result_shm_offset = kSharedMemoryOffset;
248   uint32_t data_shm_id = shared_memory_id_;
249   // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
250   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t);
251 
252   auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
253   int8_t* client_data = GetSharedMemoryAs<int8_t*>() + sizeof(uint32_t);
254 
255   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
256   Buffer* buffer = GetBuffer(client_buffer_id_);
257   EXPECT_TRUE(buffer != nullptr);
258   DoBufferData(kTarget, kTotalSize);
259   std::vector<int8_t> gpu_data(kTotalSize);
260   for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
261     gpu_data[ii] = static_cast<int8_t>(ii % 128);
262   }
263   DoBufferSubData(kTarget, 0, kTotalSize, &gpu_data[0]);
264 
265   EXPECT_EQ(GL_NO_ERROR, GetGLError());
266   EXPECT_TRUE(buffer->shadowed());
267   const int8_t* shadow_data = reinterpret_cast<const int8_t*>(
268       buffer->GetRange(0, kTotalSize));
269   EXPECT_TRUE(shadow_data);
270   // Verify the shadow data is initialized.
271   for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
272     EXPECT_EQ(static_cast<int8_t>(ii % 128), shadow_data[ii]);
273   }
274 
275   {  // MapBufferRange succeeds
276     EXPECT_CALL(*gl_, MapBufferRange(kTarget, kMappedOffset, kMappedSize,
277                                      kMappedAccess))
278         .WillOnce(Return(&gpu_data[kMappedOffset]))
279         .RetiresOnSaturation();
280 
281     cmds::MapBufferRange cmd;
282     cmd.Init(kTarget, kMappedOffset, kMappedSize, kAccess,
283              data_shm_id, data_shm_offset,
284              result_shm_id, result_shm_offset);
285     *result = 0;
286     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
287     EXPECT_EQ(1u, *result);
288     // Verify the buffer range from GPU is copied to client mem.
289     EXPECT_EQ(0, memcmp(&gpu_data[kMappedOffset], client_data, kMappedSize));
290   }
291 
292   // Update the client mem, including data within and outside the flush range.
293   const int8_t kValue0 = 21;
294   memset(client_data, kValue0, kTotalSize);
295 
296   {  // FlushMappedBufferRange succeeds
297     EXPECT_CALL(*gl_, FlushMappedBufferRange(kTarget, kFlushRangeOffset,
298                                              kFlushRangeSize))
299         .Times(1)
300         .RetiresOnSaturation();
301 
302     cmds::FlushMappedBufferRange cmd;
303     cmd.Init(kTarget, kFlushRangeOffset, kFlushRangeSize);
304     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
305 
306     // Verify the GPU mem and shadow data are both updated, but only within
307     // the flushed range.
308     for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
309       if (ii >= kMappedOffset + kFlushRangeOffset &&
310           ii < kMappedOffset + kFlushRangeOffset + kFlushRangeSize) {
311         EXPECT_EQ(kValue0, gpu_data[ii]);
312         EXPECT_EQ(kValue0, shadow_data[ii]);
313       } else {
314         EXPECT_EQ(static_cast<int8_t>(ii % 128), gpu_data[ii]);
315         EXPECT_EQ(static_cast<int8_t>(ii % 128), shadow_data[ii]);
316       }
317     }
318   }
319 
320   {  // UnmapBuffer succeeds
321     EXPECT_CALL(*gl_, UnmapBuffer(kTarget))
322         .WillOnce(Return(GL_TRUE))
323         .RetiresOnSaturation();
324 
325     cmds::UnmapBuffer cmd;
326     cmd.Init(kTarget);
327     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
328 
329     // Verify no further update to the GPU mem and shadow data.
330     for (GLsizeiptr ii = 0; ii < kTotalSize; ++ii) {
331       if (ii >= kMappedOffset + kFlushRangeOffset &&
332           ii < kMappedOffset + kFlushRangeOffset + kFlushRangeSize) {
333         EXPECT_EQ(kValue0, gpu_data[ii]);
334         EXPECT_EQ(kValue0, shadow_data[ii]);
335       } else {
336         EXPECT_EQ(static_cast<int8_t>(ii % 128), gpu_data[ii]);
337         EXPECT_EQ(static_cast<int8_t>(ii % 128), shadow_data[ii]);
338       }
339     }
340   }
341 
342   EXPECT_EQ(GL_NO_ERROR, GetGLError());
343 }
344 
TEST_P(GLES3DecoderTest,MapBufferRangeNotInitFails)345 TEST_P(GLES3DecoderTest, MapBufferRangeNotInitFails) {
346   const GLenum kTarget = GL_ARRAY_BUFFER;
347   const GLintptr kOffset = 10;
348   const GLsizeiptr kSize = 64;
349   const GLbitfield kAccess = GL_MAP_READ_BIT;
350   std::vector<int8_t> data(kSize);
351 
352   auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
353   *result = 1;  // Any value other than 0.
354   uint32_t result_shm_id = shared_memory_id_;
355   uint32_t result_shm_offset = kSharedMemoryOffset;
356   uint32_t data_shm_id = shared_memory_id_;
357   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result);
358 
359   cmds::MapBufferRange cmd;
360   cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
361            result_shm_id, result_shm_offset);
362   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
363 }
364 
TEST_P(GLES3DecoderTest,MapBufferRangeWriteInvalidateRangeSucceeds)365 TEST_P(GLES3DecoderTest, MapBufferRangeWriteInvalidateRangeSucceeds) {
366   const GLenum kTarget = GL_ARRAY_BUFFER;
367   const GLintptr kOffset = 10;
368   const GLsizeiptr kSize = 64;
369   // With MAP_INVALIDATE_RANGE_BIT, no need to append MAP_READ_BIT.
370   const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
371 
372   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
373   DoBufferData(kTarget, kSize + kOffset);
374 
375   std::vector<int8_t> data(kSize);
376   for (GLsizeiptr ii = 0; ii < kSize; ++ii) {
377     data[ii] = static_cast<int8_t>(ii % 255);
378   }
379   EXPECT_CALL(*gl_,
380               MapBufferRange(kTarget, kOffset, kSize, kAccess))
381       .WillOnce(Return(&data[0]))
382       .RetiresOnSaturation();
383 
384   auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
385   *result = 0;
386   uint32_t result_shm_id = shared_memory_id_;
387   uint32_t result_shm_offset = kSharedMemoryOffset;
388   uint32_t data_shm_id = shared_memory_id_;
389   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result);
390 
391   int8_t* mem = reinterpret_cast<int8_t*>(&result[1]);
392   memset(mem, 72, kSize);  // Init to a random value other than 0.
393 
394   cmds::MapBufferRange cmd;
395   cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
396            result_shm_id, result_shm_offset);
397   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
398 }
399 
TEST_P(GLES3DecoderTest,MapBufferRangeWriteInvalidateBufferSucceeds)400 TEST_P(GLES3DecoderTest, MapBufferRangeWriteInvalidateBufferSucceeds) {
401   // Test INVALIDATE_BUFFER_BIT is mapped to INVALIDATE_RANGE_BIT.
402   const GLenum kTarget = GL_ARRAY_BUFFER;
403   const GLintptr kOffset = 10;
404   const GLsizeiptr kSize = 64;
405   const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
406   // With MAP_INVALIDATE_BUFFER_BIT, no need to append MAP_READ_BIT.
407   const GLbitfield kFilteredAccess =
408       GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
409 
410   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
411   DoBufferData(kTarget, kSize + kOffset);
412 
413   std::vector<int8_t> data(kSize);
414   for (GLsizeiptr ii = 0; ii < kSize; ++ii) {
415     data[ii] = static_cast<int8_t>(ii % 255);
416   }
417   EXPECT_CALL(*gl_,
418               MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess))
419       .WillOnce(Return(&data[0]))
420       .RetiresOnSaturation();
421 
422   auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
423   *result = 0;
424   uint32_t result_shm_id = shared_memory_id_;
425   uint32_t result_shm_offset = kSharedMemoryOffset;
426   uint32_t data_shm_id = shared_memory_id_;
427   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result);
428 
429   int8_t* mem = reinterpret_cast<int8_t*>(&result[1]);
430   memset(mem, 72, kSize);  // Init to a random value other than 0.
431 
432   cmds::MapBufferRange cmd;
433   cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
434            result_shm_id, result_shm_offset);
435   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
436 }
437 
TEST_P(GLES3DecoderTest,MapBufferRangeWriteUnsynchronizedBit)438 TEST_P(GLES3DecoderTest, MapBufferRangeWriteUnsynchronizedBit) {
439   // Test UNSYNCHRONIZED_BIT is filtered out.
440   const GLenum kTarget = GL_ARRAY_BUFFER;
441   const GLintptr kOffset = 10;
442   const GLsizeiptr kSize = 64;
443   const GLbitfield kAccess = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
444   const GLbitfield kFilteredAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT;
445 
446   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
447   DoBufferData(kTarget, kSize + kOffset);
448 
449   std::vector<int8_t> data(kSize);
450   for (GLsizeiptr ii = 0; ii < kSize; ++ii) {
451     data[ii] = static_cast<int8_t>(ii % 255);
452   }
453   EXPECT_CALL(*gl_,
454               MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess))
455       .WillOnce(Return(&data[0]))
456       .RetiresOnSaturation();
457 
458   auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
459   *result = 0;
460   uint32_t result_shm_id = shared_memory_id_;
461   uint32_t result_shm_offset = kSharedMemoryOffset;
462   uint32_t data_shm_id = shared_memory_id_;
463   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result);
464 
465   int8_t* mem = reinterpret_cast<int8_t*>(&result[1]);
466   memset(mem, 72, kSize);  // Init to a random value other than 0.
467 
468   cmds::MapBufferRange cmd;
469   cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
470            result_shm_id, result_shm_offset);
471   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
472   EXPECT_EQ(0, memcmp(&data[0], mem, kSize));
473 }
474 
TEST_P(GLES3DecoderTest,MapBufferRangeWithError)475 TEST_P(GLES3DecoderTest, MapBufferRangeWithError) {
476   const GLenum kTarget = GL_ARRAY_BUFFER;
477   const GLintptr kOffset = 10;
478   const GLsizeiptr kSize = 64;
479   const GLbitfield kAccess = GL_MAP_READ_BIT;
480   std::vector<int8_t> data(kSize);
481   for (GLsizeiptr ii = 0; ii < kSize; ++ii) {
482     data[ii] = static_cast<int8_t>(ii % 255);
483   }
484 
485   auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
486   *result = 0;
487   uint32_t result_shm_id = shared_memory_id_;
488   uint32_t result_shm_offset = kSharedMemoryOffset;
489   uint32_t data_shm_id = shared_memory_id_;
490   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result);
491 
492   int8_t* mem = reinterpret_cast<int8_t*>(&result[1]);
493   memset(mem, 72, kSize);  // Init to a random value other than 0.
494 
495   cmds::MapBufferRange cmd;
496   cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
497            result_shm_id, result_shm_offset);
498   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
499   memset(&data[0], 72, kSize);
500   // Mem is untouched.
501   EXPECT_EQ(0, memcmp(&data[0], mem, kSize));
502   EXPECT_EQ(0u, *result);
503   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
504 }
505 
TEST_P(GLES3DecoderTest,MapBufferRangeBadSharedMemoryFails)506 TEST_P(GLES3DecoderTest, MapBufferRangeBadSharedMemoryFails) {
507   const GLenum kTarget = GL_ARRAY_BUFFER;
508   const GLintptr kOffset = 10;
509   const GLsizeiptr kSize = 64;
510   const GLbitfield kAccess = GL_MAP_READ_BIT;
511   std::vector<int8_t> data(kSize);
512   for (GLsizeiptr ii = 0; ii < kSize; ++ii) {
513     data[ii] = static_cast<int8_t>(ii % 255);
514   }
515 
516   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
517   DoBufferData(kTarget, kOffset + kSize);
518 
519   auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
520   *result = 0;
521   uint32_t result_shm_id = shared_memory_id_;
522   uint32_t result_shm_offset = kSharedMemoryOffset;
523   uint32_t data_shm_id = shared_memory_id_;
524   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(*result);
525 
526   cmds::MapBufferRange cmd;
527   cmd.Init(kTarget, kOffset, kSize, kAccess,
528            kInvalidSharedMemoryId, data_shm_offset,
529            result_shm_id, result_shm_offset);
530   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
531   cmd.Init(kTarget, kOffset, kSize, kAccess,
532            data_shm_id, data_shm_offset,
533            kInvalidSharedMemoryId, result_shm_offset);
534   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
535   cmd.Init(kTarget, kOffset, kSize, kAccess,
536            data_shm_id, kInvalidSharedMemoryOffset,
537            result_shm_id, result_shm_offset);
538   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
539   cmd.Init(kTarget, kOffset, kSize, kAccess,
540            data_shm_id, data_shm_offset,
541            result_shm_id, kInvalidSharedMemoryOffset);
542   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
543 }
544 
TEST_P(GLES3DecoderTest,UnmapBufferWriteNotMappedFails)545 TEST_P(GLES3DecoderTest, UnmapBufferWriteNotMappedFails) {
546   const GLenum kTarget = GL_ARRAY_BUFFER;
547 
548   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
549 
550   cmds::UnmapBuffer cmd;
551   cmd.Init(kTarget);
552   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
553   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
554 }
555 
TEST_P(GLES3DecoderTest,UnmapBufferWriteNoBoundBufferFails)556 TEST_P(GLES3DecoderTest, UnmapBufferWriteNoBoundBufferFails) {
557   const GLenum kTarget = GL_ARRAY_BUFFER;
558 
559   cmds::UnmapBuffer cmd;
560   cmd.Init(kTarget);
561   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
562   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
563 }
564 
TEST_P(GLES3DecoderTest,BufferDataDestroysDataStore)565 TEST_P(GLES3DecoderTest, BufferDataDestroysDataStore) {
566   const GLenum kTarget = GL_ARRAY_BUFFER;
567   const GLintptr kOffset = 10;
568   const GLsizeiptr kSize = 64;
569   const GLbitfield kAccess = GL_MAP_WRITE_BIT;
570   const GLbitfield kFilteredAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT;
571 
572   uint32_t result_shm_id = shared_memory_id_;
573   uint32_t result_shm_offset = kSharedMemoryOffset;
574   uint32_t data_shm_id = shared_memory_id_;
575   // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
576   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t);
577 
578   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
579   DoBufferData(kTarget, kSize + kOffset);
580 
581   std::vector<int8_t> data(kSize);
582 
583   {  // MapBufferRange succeeds
584     EXPECT_CALL(*gl_,
585                 MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess))
586         .WillOnce(Return(&data[0]))
587         .RetiresOnSaturation();
588 
589     auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
590 
591     cmds::MapBufferRange cmd;
592     cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
593              result_shm_id, result_shm_offset);
594     *result = 0;
595     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
596     EXPECT_EQ(1u, *result);
597   }
598 
599   {  // BufferData unmaps the data store.
600     DoBufferData(kTarget, kSize * 2);
601     EXPECT_EQ(GL_NO_ERROR, GetGLError());
602   }
603 
604   {  // UnmapBuffer fails.
605     cmds::UnmapBuffer cmd;
606     cmd.Init(kTarget);
607     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
608     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
609   }
610 }
611 
TEST_P(GLES3DecoderTest,DeleteBuffersDestroysDataStore)612 TEST_P(GLES3DecoderTest, DeleteBuffersDestroysDataStore) {
613   const GLenum kTarget = GL_ARRAY_BUFFER;
614   const GLintptr kOffset = 10;
615   const GLsizeiptr kSize = 64;
616   const GLbitfield kAccess = GL_MAP_WRITE_BIT;
617   const GLbitfield kFilteredAccess = GL_MAP_WRITE_BIT | GL_MAP_READ_BIT;
618 
619   uint32_t result_shm_id = shared_memory_id_;
620   uint32_t result_shm_offset = kSharedMemoryOffset;
621   uint32_t data_shm_id = shared_memory_id_;
622   // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
623   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t);
624 
625   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
626   DoBufferData(kTarget, kSize + kOffset);
627 
628   std::vector<int8_t> data(kSize);
629 
630   {  // MapBufferRange succeeds
631     EXPECT_CALL(*gl_,
632                 MapBufferRange(kTarget, kOffset, kSize, kFilteredAccess))
633         .WillOnce(Return(&data[0]))
634         .RetiresOnSaturation();
635 
636     auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
637 
638     cmds::MapBufferRange cmd;
639     cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
640              result_shm_id, result_shm_offset);
641     *result = 0;
642     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
643     EXPECT_EQ(1u, *result);
644   }
645 
646   {  // DeleteBuffers unmaps the data store.
647     EXPECT_CALL(*gl_, BindBuffer(kTarget, 0)).Times(1).RetiresOnSaturation();
648     EXPECT_CALL(*gl_, UnmapBuffer(kTarget))
649         .WillOnce(Return(GL_TRUE))
650         .RetiresOnSaturation();
651     DoDeleteBuffer(client_buffer_id_, kServiceBufferId);
652     EXPECT_EQ(GL_NO_ERROR, GetGLError());
653   }
654 
655   {  // UnmapBuffer fails.
656     cmds::UnmapBuffer cmd;
657     cmd.Init(kTarget);
658     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
659     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
660   }
661 }
662 
TEST_P(GLES3DecoderTest,MapUnmapBufferInvalidTarget)663 TEST_P(GLES3DecoderTest, MapUnmapBufferInvalidTarget) {
664   const GLenum kTarget = GL_TEXTURE_2D;
665   const GLintptr kOffset = 10;
666   const GLsizeiptr kSize = 64;
667   const GLbitfield kAccess = GL_MAP_WRITE_BIT;
668 
669   uint32_t result_shm_id = shared_memory_id_;
670   uint32_t result_shm_offset = kSharedMemoryOffset;
671   uint32_t data_shm_id = shared_memory_id_;
672   // uint32_t is Result for both MapBufferRange and UnmapBuffer commands.
673   uint32_t data_shm_offset = kSharedMemoryOffset + sizeof(uint32_t);
674 
675   auto* result = GetSharedMemoryAs<cmds::MapBufferRange::Result*>();
676 
677   {
678     cmds::MapBufferRange cmd;
679     cmd.Init(kTarget, kOffset, kSize, kAccess, data_shm_id, data_shm_offset,
680              result_shm_id, result_shm_offset);
681     *result = 0;
682     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
683     EXPECT_EQ(0u, *result);
684     EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
685   }
686 
687   {
688     cmds::UnmapBuffer cmd;
689     cmd.Init(kTarget);
690     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
691     EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
692   }
693 }
694 
TEST_P(GLES3DecoderTest,CopyBufferSubDataValidArgs)695 TEST_P(GLES3DecoderTest, CopyBufferSubDataValidArgs) {
696   const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
697   const GLsizeiptr kSize = 64;
698   const GLsizeiptr kHalfSize = kSize / 2;
699   const GLintptr kReadOffset = 0;
700   const GLintptr kWriteOffset = kHalfSize;
701   const GLsizeiptr kCopySize = 5;
702   const char kValue0 = 3;
703   const char kValue1 = 21;
704 
705   // Set up the buffer so first half is kValue0 and second half is kValue1.
706   DoBindBuffer(kTarget, client_buffer_id_, kServiceBufferId);
707   DoBufferData(kTarget, kSize);
708   std::unique_ptr<char[]> data(new char[kHalfSize]);
709   memset(data.get(), kValue0, kHalfSize);
710   DoBufferSubData(kTarget, 0, kHalfSize, data.get());
711   memset(data.get(), kValue1, kHalfSize);
712   DoBufferSubData(kTarget, kHalfSize, kHalfSize, data.get());
713   EXPECT_EQ(GL_NO_ERROR, GetGLError());
714   Buffer* buffer = GetBuffer(client_buffer_id_);
715   EXPECT_TRUE(buffer);
716   const char* shadow_data = reinterpret_cast<const char*>(
717       buffer->GetRange(0, kSize));
718   EXPECT_TRUE(shadow_data);
719   // Verify the shadow data is initialized.
720   for (GLsizeiptr ii = 0; ii < kHalfSize; ++ii) {
721     EXPECT_EQ(kValue0, shadow_data[ii]);
722   }
723   for (GLsizeiptr ii = kHalfSize; ii < kSize; ++ii) {
724     EXPECT_EQ(kValue1, shadow_data[ii]);
725   }
726 
727   EXPECT_CALL(*gl_, CopyBufferSubData(kTarget, kTarget,
728                                       kReadOffset, kWriteOffset, kCopySize));
729   cmds::CopyBufferSubData cmd;
730   cmd.Init(kTarget, kTarget, kReadOffset, kWriteOffset, kCopySize);
731   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
732   EXPECT_EQ(GL_NO_ERROR, GetGLError());
733   // Verify the shadow data is updated.
734   for (GLsizeiptr ii = 0; ii < kHalfSize; ++ii) {
735     EXPECT_EQ(kValue0, shadow_data[ii]);
736   }
737   for (GLsizeiptr ii = kHalfSize; ii < kSize; ++ii) {
738     if (ii >= kWriteOffset && ii < kWriteOffset + kCopySize) {
739       EXPECT_EQ(kValue0, shadow_data[ii]);
740     } else {
741       EXPECT_EQ(kValue1, shadow_data[ii]);
742     }
743   }
744 }
745 
746 }  // namespace gles2
747 }  // namespace gpu
748