1 // Copyright 2014 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"
7 #include "base/command_line.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "gpu/command_buffer/common/gles2_cmd_format.h"
10 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
11 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
12 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
13 #include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
14 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
15 #include "gpu/command_buffer/service/context_group.h"
16 #include "gpu/command_buffer/service/context_state.h"
17 #include "gpu/command_buffer/service/gl_surface_mock.h"
18 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
20 #include "gpu/command_buffer/service/gpu_switches.h"
21 #include "gpu/command_buffer/service/image_manager.h"
22 #include "gpu/command_buffer/service/mailbox_manager.h"
23 #include "gpu/command_buffer/service/mocks.h"
24 #include "gpu/command_buffer/service/program_manager.h"
25 #include "gpu/command_buffer/service/test_helper.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "ui/gl/gl_implementation.h"
28 #include "ui/gl/gl_mock.h"
29 #include "ui/gl/gl_surface_stub.h"
31 #if !defined(GL_DEPTH24_STENCIL8)
32 #define GL_DEPTH24_STENCIL8 0x88F0
35 using ::gfx::MockGLInterface
;
37 using ::testing::DoAll
;
38 using ::testing::InSequence
;
39 using ::testing::Invoke
;
40 using ::testing::MatcherCast
;
41 using ::testing::Mock
;
42 using ::testing::Pointee
;
43 using ::testing::Return
;
44 using ::testing::SaveArg
;
45 using ::testing::SetArrayArgument
;
46 using ::testing::SetArgumentPointee
;
47 using ::testing::SetArgPointee
;
48 using ::testing::StrEq
;
49 using ::testing::StrictMock
;
56 TEST_P(GLES2DecoderWithShaderTest
, GetVertexAttribPointervSucceeds
) {
57 const GLuint kOffsetToTestFor
= sizeof(float) * 4;
58 const GLuint kIndexToTest
= 1;
59 GetVertexAttribPointerv::Result
* result
=
60 static_cast<GetVertexAttribPointerv::Result
*>(shared_memory_address_
);
62 const GLuint
* result_value
= result
->GetData();
63 // Test that initial value is 0.
64 GetVertexAttribPointerv cmd
;
65 cmd
.Init(kIndexToTest
,
66 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
68 shared_memory_offset_
);
69 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
70 EXPECT_EQ(sizeof(*result_value
), result
->size
);
71 EXPECT_EQ(0u, *result_value
);
72 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
74 // Set the value and see that we get it.
76 DoVertexAttribPointer(kIndexToTest
, 2, GL_FLOAT
, 0, kOffsetToTestFor
);
78 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
79 EXPECT_EQ(sizeof(*result_value
), result
->size
);
80 EXPECT_EQ(kOffsetToTestFor
, *result_value
);
81 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
84 TEST_P(GLES2DecoderWithShaderTest
, GetVertexAttribPointervBadArgsFails
) {
85 const GLuint kIndexToTest
= 1;
86 GetVertexAttribPointerv::Result
* result
=
87 static_cast<GetVertexAttribPointerv::Result
*>(shared_memory_address_
);
89 const GLuint
* result_value
= result
->GetData();
90 // Test pname invalid fails.
91 GetVertexAttribPointerv cmd
;
92 cmd
.Init(kIndexToTest
,
93 GL_VERTEX_ATTRIB_ARRAY_POINTER
+ 1,
95 shared_memory_offset_
);
96 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
97 EXPECT_EQ(0u, result
->size
);
98 EXPECT_EQ(kInitialResult
, *result_value
);
99 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
101 // Test index out of range fails.
103 cmd
.Init(kNumVertexAttribs
,
104 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
106 shared_memory_offset_
);
107 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
108 EXPECT_EQ(0u, result
->size
);
109 EXPECT_EQ(kInitialResult
, *result_value
);
110 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
112 // Test memory id bad fails.
113 cmd
.Init(kIndexToTest
,
114 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
115 kInvalidSharedMemoryId
,
116 shared_memory_offset_
);
117 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
119 // Test memory offset bad fails.
120 cmd
.Init(kIndexToTest
,
121 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
123 kInvalidSharedMemoryOffset
);
124 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
127 TEST_P(GLES2DecoderWithShaderTest
, BindBufferToDifferentTargetFails
) {
128 // Bind the buffer to GL_ARRAY_BUFFER
129 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
130 // Attempt to rebind to GL_ELEMENT_ARRAY_BUFFER
131 // NOTE: Real GLES2 does not have this restriction but WebGL and we do.
132 // This can be restriction can be removed at runtime.
133 EXPECT_CALL(*gl_
, BindBuffer(_
, _
)).Times(0);
135 cmd
.Init(GL_ELEMENT_ARRAY_BUFFER
, client_buffer_id_
);
136 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
137 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
140 TEST_P(GLES2DecoderWithShaderTest
, VertexAttribPointer
) {
142 static const GLenum types
[] = {
143 GL_BYTE
, GL_UNSIGNED_BYTE
, GL_SHORT
, GL_UNSIGNED_SHORT
,
144 GL_FLOAT
, GL_FIXED
, GL_INT
, GL_UNSIGNED_INT
,
146 static const GLsizei sizes
[] = {
147 1, 1, 2, 2, 4, 4, 4, 4,
149 static const GLuint indices
[] = {
150 0, 1, kNumVertexAttribs
- 1, kNumVertexAttribs
,
152 static const GLsizei offset_mult
[] = {
155 static const GLsizei offset_offset
[] = {
158 static const GLsizei stride_mult
[] = {
159 -1, 0, 0, 1, 1, 2, 1000,
161 static const GLsizei stride_offset
[] = {
164 for (size_t tt
= 0; tt
< arraysize(types
); ++tt
) {
165 GLenum type
= types
[tt
];
166 GLsizei num_bytes
= sizes
[tt
];
167 for (size_t ii
= 0; ii
< arraysize(indices
); ++ii
) {
168 GLuint index
= indices
[ii
];
169 for (GLint size
= 0; size
< 5; ++size
) {
170 for (size_t oo
= 0; oo
< arraysize(offset_mult
); ++oo
) {
171 GLuint offset
= num_bytes
* offset_mult
[oo
] + offset_offset
[oo
];
172 for (size_t ss
= 0; ss
< arraysize(stride_mult
); ++ss
) {
173 GLsizei stride
= num_bytes
* stride_mult
[ss
] + stride_offset
[ss
];
174 for (int normalize
= 0; normalize
< 2; ++normalize
) {
175 bool index_good
= index
< static_cast<GLuint
>(kNumVertexAttribs
);
176 bool size_good
= (size
> 0 && size
< 5);
177 bool offset_good
= (offset
% num_bytes
== 0);
179 (stride
% num_bytes
== 0) && stride
>= 0 && stride
<= 255;
180 bool type_good
= (type
!= GL_INT
&& type
!= GL_UNSIGNED_INT
&&
182 bool good
= size_good
&& offset_good
&& stride_good
&&
183 type_good
&& index_good
;
184 bool call
= good
&& (type
!= GL_FIXED
);
187 VertexAttribPointer(index
,
192 BufferOffset(offset
)));
194 VertexAttribPointer cmd
;
195 cmd
.Init(index
, size
, type
, normalize
, stride
, offset
);
196 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
198 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
199 } else if (size_good
&& offset_good
&& stride_good
&& type_good
&&
201 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
202 } else if (size_good
&& offset_good
&& stride_good
&&
203 !type_good
&& index_good
) {
204 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
205 } else if (size_good
&& offset_good
&& !stride_good
&&
206 type_good
&& index_good
) {
207 if (stride
< 0 || stride
> 255) {
208 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
210 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
212 } else if (size_good
&& !offset_good
&& stride_good
&&
213 type_good
&& index_good
) {
214 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
215 } else if (!size_good
&& offset_good
&& stride_good
&&
216 type_good
&& index_good
) {
217 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
219 EXPECT_NE(GL_NO_ERROR
, GetGLError());
229 class GLES2DecoderVertexArraysOESTest
: public GLES2DecoderWithShaderTest
{
231 GLES2DecoderVertexArraysOESTest() {}
233 bool vertex_array_deleted_manually_
;
235 void SetUp() override
{
237 init
.gl_version
= "opengl es 2.0";
238 init
.bind_generates_resource
= true;
240 SetupDefaultProgram();
242 AddExpectationsForGenVertexArraysOES();
243 GenHelper
<GenVertexArraysOESImmediate
>(client_vertexarray_id_
);
245 vertex_array_deleted_manually_
= false;
248 void TearDown() override
{
249 // This should only be set if the test handled deletion of the vertex array
250 // itself. Necessary because vertex_array_objects are not sharable, and thus
251 // not managed in the ContextGroup, meaning they will be destroyed during
253 if (!vertex_array_deleted_manually_
) {
254 AddExpectationsForDeleteVertexArraysOES();
257 GLES2DecoderWithShaderTest::TearDown();
260 void GenVertexArraysOESImmediateValidArgs() {
261 AddExpectationsForGenVertexArraysOES();
262 GenVertexArraysOESImmediate
* cmd
=
263 GetImmediateAs
<GenVertexArraysOESImmediate
>();
264 GLuint temp
= kNewClientId
;
266 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(*cmd
, sizeof(temp
)));
267 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
268 EXPECT_TRUE(GetVertexArrayInfo(kNewClientId
) != NULL
);
269 AddExpectationsForDeleteVertexArraysOES();
272 void GenVertexArraysOESImmediateInvalidArgs() {
273 EXPECT_CALL(*gl_
, GenVertexArraysOES(_
, _
)).Times(0);
274 GenVertexArraysOESImmediate
* cmd
=
275 GetImmediateAs
<GenVertexArraysOESImmediate
>();
276 cmd
->Init(1, &client_vertexarray_id_
);
277 EXPECT_EQ(error::kInvalidArguments
,
278 ExecuteImmediateCmd(*cmd
, sizeof(&client_vertexarray_id_
)));
281 void DeleteVertexArraysOESImmediateValidArgs() {
282 AddExpectationsForDeleteVertexArraysOES();
283 DeleteVertexArraysOESImmediate
& cmd
=
284 *GetImmediateAs
<DeleteVertexArraysOESImmediate
>();
285 cmd
.Init(1, &client_vertexarray_id_
);
286 EXPECT_EQ(error::kNoError
,
287 ExecuteImmediateCmd(cmd
, sizeof(client_vertexarray_id_
)));
288 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
289 EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_
) == NULL
);
290 vertex_array_deleted_manually_
= true;
293 void DeleteVertexArraysOESImmediateInvalidArgs() {
294 DeleteVertexArraysOESImmediate
& cmd
=
295 *GetImmediateAs
<DeleteVertexArraysOESImmediate
>();
296 GLuint temp
= kInvalidClientId
;
298 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(cmd
, sizeof(temp
)));
301 void DeleteBoundVertexArraysOESImmediateValidArgs() {
302 BindVertexArrayOESValidArgs();
304 AddExpectationsForDeleteBoundVertexArraysOES();
305 DeleteVertexArraysOESImmediate
& cmd
=
306 *GetImmediateAs
<DeleteVertexArraysOESImmediate
>();
307 cmd
.Init(1, &client_vertexarray_id_
);
308 EXPECT_EQ(error::kNoError
,
309 ExecuteImmediateCmd(cmd
, sizeof(client_vertexarray_id_
)));
310 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
311 EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_
) == NULL
);
312 vertex_array_deleted_manually_
= true;
315 void IsVertexArrayOESValidArgs() {
316 IsVertexArrayOES cmd
;
317 cmd
.Init(client_vertexarray_id_
, shared_memory_id_
, shared_memory_offset_
);
318 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
319 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
322 void IsVertexArrayOESInvalidArgsBadSharedMemoryId() {
323 IsVertexArrayOES cmd
;
325 client_vertexarray_id_
, kInvalidSharedMemoryId
, shared_memory_offset_
);
326 EXPECT_EQ(error::kOutOfBounds
, ExecuteCmd(cmd
));
328 client_vertexarray_id_
, shared_memory_id_
, kInvalidSharedMemoryOffset
);
329 EXPECT_EQ(error::kOutOfBounds
, ExecuteCmd(cmd
));
332 void BindVertexArrayOESValidArgs() {
333 AddExpectationsForBindVertexArrayOES();
334 BindVertexArrayOES cmd
;
335 cmd
.Init(client_vertexarray_id_
);
336 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
337 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
340 void BindVertexArrayOESValidArgsNewId() {
341 BindVertexArrayOES cmd
;
342 cmd
.Init(kNewClientId
);
343 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
344 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
348 INSTANTIATE_TEST_CASE_P(Service
,
349 GLES2DecoderVertexArraysOESTest
,
352 class GLES2DecoderEmulatedVertexArraysOESTest
353 : public GLES2DecoderVertexArraysOESTest
{
355 GLES2DecoderEmulatedVertexArraysOESTest() {}
357 void SetUp() override
{
359 init
.bind_generates_resource
= true;
360 init
.use_native_vao
= false;
362 SetupDefaultProgram();
364 AddExpectationsForGenVertexArraysOES();
365 GenHelper
<GenVertexArraysOESImmediate
>(client_vertexarray_id_
);
367 vertex_array_deleted_manually_
= false;
371 INSTANTIATE_TEST_CASE_P(Service
,
372 GLES2DecoderEmulatedVertexArraysOESTest
,
375 // Test vertex array objects with native support
376 TEST_P(GLES2DecoderVertexArraysOESTest
, GenVertexArraysOESImmediateValidArgs
) {
377 GenVertexArraysOESImmediateValidArgs();
379 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
380 GenVertexArraysOESImmediateValidArgs
) {
381 GenVertexArraysOESImmediateValidArgs();
384 TEST_P(GLES2DecoderVertexArraysOESTest
,
385 GenVertexArraysOESImmediateInvalidArgs
) {
386 GenVertexArraysOESImmediateInvalidArgs();
388 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
389 GenVertexArraysOESImmediateInvalidArgs
) {
390 GenVertexArraysOESImmediateInvalidArgs();
393 TEST_P(GLES2DecoderVertexArraysOESTest
,
394 DeleteVertexArraysOESImmediateValidArgs
) {
395 DeleteVertexArraysOESImmediateValidArgs();
397 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
398 DeleteVertexArraysOESImmediateValidArgs
) {
399 DeleteVertexArraysOESImmediateValidArgs();
402 TEST_P(GLES2DecoderVertexArraysOESTest
,
403 DeleteVertexArraysOESImmediateInvalidArgs
) {
404 DeleteVertexArraysOESImmediateInvalidArgs();
406 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
407 DeleteVertexArraysOESImmediateInvalidArgs
) {
408 DeleteVertexArraysOESImmediateInvalidArgs();
411 TEST_P(GLES2DecoderVertexArraysOESTest
,
412 DeleteBoundVertexArraysOESImmediateValidArgs
) {
413 DeleteBoundVertexArraysOESImmediateValidArgs();
415 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
416 DeleteBoundVertexArraysOESImmediateValidArgs
) {
417 DeleteBoundVertexArraysOESImmediateValidArgs();
420 TEST_P(GLES2DecoderVertexArraysOESTest
, IsVertexArrayOESValidArgs
) {
421 IsVertexArrayOESValidArgs();
423 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
, IsVertexArrayOESValidArgs
) {
424 IsVertexArrayOESValidArgs();
427 TEST_P(GLES2DecoderVertexArraysOESTest
,
428 IsVertexArrayOESInvalidArgsBadSharedMemoryId
) {
429 IsVertexArrayOESInvalidArgsBadSharedMemoryId();
431 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
432 IsVertexArrayOESInvalidArgsBadSharedMemoryId
) {
433 IsVertexArrayOESInvalidArgsBadSharedMemoryId();
436 TEST_P(GLES2DecoderVertexArraysOESTest
, BindVertexArrayOESValidArgs
) {
437 BindVertexArrayOESValidArgs();
439 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
, BindVertexArrayOESValidArgs
) {
440 BindVertexArrayOESValidArgs();
443 TEST_P(GLES2DecoderVertexArraysOESTest
, BindVertexArrayOESValidArgsNewId
) {
444 BindVertexArrayOESValidArgsNewId();
446 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
447 BindVertexArrayOESValidArgsNewId
) {
448 BindVertexArrayOESValidArgsNewId();
451 TEST_P(GLES2DecoderTest
, BufferDataGLError
) {
452 GLenum target
= GL_ARRAY_BUFFER
;
454 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
455 BufferManager
* manager
= group().buffer_manager();
456 Buffer
* buffer
= manager
->GetBuffer(client_buffer_id_
);
457 ASSERT_TRUE(buffer
!= NULL
);
458 EXPECT_EQ(0, buffer
->size());
459 EXPECT_CALL(*gl_
, GetError())
460 .WillOnce(Return(GL_NO_ERROR
))
461 .WillOnce(Return(GL_OUT_OF_MEMORY
))
462 .RetiresOnSaturation();
463 EXPECT_CALL(*gl_
, BufferData(target
, size
, _
, GL_STREAM_DRAW
))
465 .RetiresOnSaturation();
467 cmd
.Init(target
, size
, 0, 0, GL_STREAM_DRAW
);
468 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
469 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
470 EXPECT_EQ(0, buffer
->size());
473 // TODO(gman): BufferData
475 // TODO(gman): BufferDataImmediate
477 // TODO(gman): BufferSubData
479 // TODO(gman): BufferSubDataImmediate