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/cmd_buffer_engine.h"
12 #include "gpu/command_buffer/service/context_group.h"
13 #include "gpu/command_buffer/service/context_state.h"
14 #include "gpu/command_buffer/service/gl_surface_mock.h"
15 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
17 #include "gpu/command_buffer/service/gpu_switches.h"
18 #include "gpu/command_buffer/service/image_manager.h"
19 #include "gpu/command_buffer/service/mailbox_manager.h"
20 #include "gpu/command_buffer/service/mocks.h"
21 #include "gpu/command_buffer/service/program_manager.h"
22 #include "gpu/command_buffer/service/test_helper.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/gl/gl_implementation.h"
25 #include "ui/gl/gl_mock.h"
26 #include "ui/gl/gl_surface_stub.h"
28 #if !defined(GL_DEPTH24_STENCIL8)
29 #define GL_DEPTH24_STENCIL8 0x88F0
32 using ::gfx::MockGLInterface
;
34 using ::testing::DoAll
;
35 using ::testing::InSequence
;
36 using ::testing::Invoke
;
37 using ::testing::MatcherCast
;
38 using ::testing::Mock
;
39 using ::testing::Pointee
;
40 using ::testing::Return
;
41 using ::testing::SaveArg
;
42 using ::testing::SetArrayArgument
;
43 using ::testing::SetArgumentPointee
;
44 using ::testing::SetArgPointee
;
45 using ::testing::StrEq
;
46 using ::testing::StrictMock
;
53 TEST_P(GLES2DecoderWithShaderTest
, GetVertexAttribPointervSucceeds
) {
54 const GLuint kOffsetToTestFor
= sizeof(float) * 4;
55 const GLuint kIndexToTest
= 1;
56 GetVertexAttribPointerv::Result
* result
=
57 static_cast<GetVertexAttribPointerv::Result
*>(shared_memory_address_
);
59 const GLuint
* result_value
= result
->GetData();
60 // Test that initial value is 0.
61 GetVertexAttribPointerv cmd
;
62 cmd
.Init(kIndexToTest
,
63 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
65 shared_memory_offset_
);
66 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
67 EXPECT_EQ(sizeof(*result_value
), result
->size
);
68 EXPECT_EQ(0u, *result_value
);
69 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
71 // Set the value and see that we get it.
73 DoVertexAttribPointer(kIndexToTest
, 2, GL_FLOAT
, 0, kOffsetToTestFor
);
75 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
76 EXPECT_EQ(sizeof(*result_value
), result
->size
);
77 EXPECT_EQ(kOffsetToTestFor
, *result_value
);
78 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
81 TEST_P(GLES2DecoderWithShaderTest
, GetVertexAttribPointervBadArgsFails
) {
82 const GLuint kIndexToTest
= 1;
83 GetVertexAttribPointerv::Result
* result
=
84 static_cast<GetVertexAttribPointerv::Result
*>(shared_memory_address_
);
86 const GLuint
* result_value
= result
->GetData();
87 // Test pname invalid fails.
88 GetVertexAttribPointerv cmd
;
89 cmd
.Init(kIndexToTest
,
90 GL_VERTEX_ATTRIB_ARRAY_POINTER
+ 1,
92 shared_memory_offset_
);
93 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
94 EXPECT_EQ(0u, result
->size
);
95 EXPECT_EQ(kInitialResult
, *result_value
);
96 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
98 // Test index out of range fails.
100 cmd
.Init(kNumVertexAttribs
,
101 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
103 shared_memory_offset_
);
104 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
105 EXPECT_EQ(0u, result
->size
);
106 EXPECT_EQ(kInitialResult
, *result_value
);
107 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
109 // Test memory id bad fails.
110 cmd
.Init(kIndexToTest
,
111 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
112 kInvalidSharedMemoryId
,
113 shared_memory_offset_
);
114 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
116 // Test memory offset bad fails.
117 cmd
.Init(kIndexToTest
,
118 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
120 kInvalidSharedMemoryOffset
);
121 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
124 TEST_P(GLES2DecoderWithShaderTest
, BindBufferToDifferentTargetFails
) {
125 // Bind the buffer to GL_ARRAY_BUFFER
126 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
127 // Attempt to rebind to GL_ELEMENT_ARRAY_BUFFER
128 // NOTE: Real GLES2 does not have this restriction but WebGL and we do.
129 // This can be restriction can be removed at runtime.
130 EXPECT_CALL(*gl_
, BindBuffer(_
, _
)).Times(0);
132 cmd
.Init(GL_ELEMENT_ARRAY_BUFFER
, client_buffer_id_
);
133 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
134 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
137 TEST_P(GLES2DecoderWithShaderTest
, VertexAttribPointer
) {
139 static const GLenum types
[] = {
140 GL_BYTE
, GL_UNSIGNED_BYTE
, GL_SHORT
, GL_UNSIGNED_SHORT
,
141 GL_FLOAT
, GL_FIXED
, GL_INT
, GL_UNSIGNED_INT
,
143 static const GLsizei sizes
[] = {
144 1, 1, 2, 2, 4, 4, 4, 4,
146 static const GLuint indices
[] = {
147 0, 1, kNumVertexAttribs
- 1, kNumVertexAttribs
,
149 static const GLsizei offset_mult
[] = {
152 static const GLsizei offset_offset
[] = {
155 static const GLsizei stride_mult
[] = {
156 -1, 0, 0, 1, 1, 2, 1000,
158 static const GLsizei stride_offset
[] = {
161 for (size_t tt
= 0; tt
< arraysize(types
); ++tt
) {
162 GLenum type
= types
[tt
];
163 GLsizei num_bytes
= sizes
[tt
];
164 for (size_t ii
= 0; ii
< arraysize(indices
); ++ii
) {
165 GLuint index
= indices
[ii
];
166 for (GLint size
= 0; size
< 5; ++size
) {
167 for (size_t oo
= 0; oo
< arraysize(offset_mult
); ++oo
) {
168 GLuint offset
= num_bytes
* offset_mult
[oo
] + offset_offset
[oo
];
169 for (size_t ss
= 0; ss
< arraysize(stride_mult
); ++ss
) {
170 GLsizei stride
= num_bytes
* stride_mult
[ss
] + stride_offset
[ss
];
171 for (int normalize
= 0; normalize
< 2; ++normalize
) {
172 bool index_good
= index
< static_cast<GLuint
>(kNumVertexAttribs
);
173 bool size_good
= (size
> 0 && size
< 5);
174 bool offset_good
= (offset
% num_bytes
== 0);
176 (stride
% num_bytes
== 0) && stride
>= 0 && stride
<= 255;
177 bool type_good
= (type
!= GL_INT
&& type
!= GL_UNSIGNED_INT
&&
179 bool good
= size_good
&& offset_good
&& stride_good
&&
180 type_good
&& index_good
;
181 bool call
= good
&& (type
!= GL_FIXED
);
184 VertexAttribPointer(index
,
189 BufferOffset(offset
)));
191 VertexAttribPointer cmd
;
192 cmd
.Init(index
, size
, type
, normalize
, stride
, offset
);
193 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
195 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
196 } else if (size_good
&& offset_good
&& stride_good
&& type_good
&&
198 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
199 } else if (size_good
&& offset_good
&& stride_good
&&
200 !type_good
&& index_good
) {
201 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
202 } else if (size_good
&& offset_good
&& !stride_good
&&
203 type_good
&& index_good
) {
204 if (stride
< 0 || stride
> 255) {
205 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
207 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
209 } else if (size_good
&& !offset_good
&& stride_good
&&
210 type_good
&& index_good
) {
211 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_VALUE
, GetGLError());
216 EXPECT_NE(GL_NO_ERROR
, GetGLError());
226 class GLES2DecoderVertexArraysOESTest
: public GLES2DecoderWithShaderTest
{
228 GLES2DecoderVertexArraysOESTest() {}
230 bool vertex_array_deleted_manually_
;
232 void SetUp() override
{
234 init
.gl_version
= "opengl es 2.0";
235 init
.bind_generates_resource
= true;
237 SetupDefaultProgram();
239 AddExpectationsForGenVertexArraysOES();
240 GenHelper
<GenVertexArraysOESImmediate
>(client_vertexarray_id_
);
242 vertex_array_deleted_manually_
= false;
245 void TearDown() override
{
246 // This should only be set if the test handled deletion of the vertex array
247 // itself. Necessary because vertex_array_objects are not sharable, and thus
248 // not managed in the ContextGroup, meaning they will be destroyed during
250 if (!vertex_array_deleted_manually_
) {
251 AddExpectationsForDeleteVertexArraysOES();
254 GLES2DecoderWithShaderTest::TearDown();
257 void GenVertexArraysOESImmediateValidArgs() {
258 AddExpectationsForGenVertexArraysOES();
259 GenVertexArraysOESImmediate
* cmd
=
260 GetImmediateAs
<GenVertexArraysOESImmediate
>();
261 GLuint temp
= kNewClientId
;
263 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(*cmd
, sizeof(temp
)));
264 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
265 EXPECT_TRUE(GetVertexArrayInfo(kNewClientId
) != NULL
);
266 AddExpectationsForDeleteVertexArraysOES();
269 void GenVertexArraysOESImmediateInvalidArgs() {
270 EXPECT_CALL(*gl_
, GenVertexArraysOES(_
, _
)).Times(0);
271 GenVertexArraysOESImmediate
* cmd
=
272 GetImmediateAs
<GenVertexArraysOESImmediate
>();
273 cmd
->Init(1, &client_vertexarray_id_
);
274 EXPECT_EQ(error::kInvalidArguments
,
275 ExecuteImmediateCmd(*cmd
, sizeof(&client_vertexarray_id_
)));
278 void DeleteVertexArraysOESImmediateValidArgs() {
279 AddExpectationsForDeleteVertexArraysOES();
280 DeleteVertexArraysOESImmediate
& cmd
=
281 *GetImmediateAs
<DeleteVertexArraysOESImmediate
>();
282 cmd
.Init(1, &client_vertexarray_id_
);
283 EXPECT_EQ(error::kNoError
,
284 ExecuteImmediateCmd(cmd
, sizeof(client_vertexarray_id_
)));
285 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
286 EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_
) == NULL
);
287 vertex_array_deleted_manually_
= true;
290 void DeleteVertexArraysOESImmediateInvalidArgs() {
291 DeleteVertexArraysOESImmediate
& cmd
=
292 *GetImmediateAs
<DeleteVertexArraysOESImmediate
>();
293 GLuint temp
= kInvalidClientId
;
295 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(cmd
, sizeof(temp
)));
298 void DeleteBoundVertexArraysOESImmediateValidArgs() {
299 BindVertexArrayOESValidArgs();
301 AddExpectationsForDeleteBoundVertexArraysOES();
302 DeleteVertexArraysOESImmediate
& cmd
=
303 *GetImmediateAs
<DeleteVertexArraysOESImmediate
>();
304 cmd
.Init(1, &client_vertexarray_id_
);
305 EXPECT_EQ(error::kNoError
,
306 ExecuteImmediateCmd(cmd
, sizeof(client_vertexarray_id_
)));
307 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
308 EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_
) == NULL
);
309 vertex_array_deleted_manually_
= true;
312 void IsVertexArrayOESValidArgs() {
313 IsVertexArrayOES cmd
;
314 cmd
.Init(client_vertexarray_id_
, shared_memory_id_
, shared_memory_offset_
);
315 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
316 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
319 void IsVertexArrayOESInvalidArgsBadSharedMemoryId() {
320 IsVertexArrayOES cmd
;
322 client_vertexarray_id_
, kInvalidSharedMemoryId
, shared_memory_offset_
);
323 EXPECT_EQ(error::kOutOfBounds
, ExecuteCmd(cmd
));
325 client_vertexarray_id_
, shared_memory_id_
, kInvalidSharedMemoryOffset
);
326 EXPECT_EQ(error::kOutOfBounds
, ExecuteCmd(cmd
));
329 void BindVertexArrayOESValidArgs() {
330 AddExpectationsForBindVertexArrayOES();
331 BindVertexArrayOES cmd
;
332 cmd
.Init(client_vertexarray_id_
);
333 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
334 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
337 void BindVertexArrayOESValidArgsNewId() {
338 BindVertexArrayOES cmd
;
339 cmd
.Init(kNewClientId
);
340 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
341 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
345 INSTANTIATE_TEST_CASE_P(Service
,
346 GLES2DecoderVertexArraysOESTest
,
349 class GLES2DecoderEmulatedVertexArraysOESTest
350 : public GLES2DecoderVertexArraysOESTest
{
352 GLES2DecoderEmulatedVertexArraysOESTest() {}
354 void SetUp() override
{
356 init
.bind_generates_resource
= true;
357 init
.use_native_vao
= false;
359 SetupDefaultProgram();
361 AddExpectationsForGenVertexArraysOES();
362 GenHelper
<GenVertexArraysOESImmediate
>(client_vertexarray_id_
);
364 vertex_array_deleted_manually_
= false;
368 INSTANTIATE_TEST_CASE_P(Service
,
369 GLES2DecoderEmulatedVertexArraysOESTest
,
372 // Test vertex array objects with native support
373 TEST_P(GLES2DecoderVertexArraysOESTest
, GenVertexArraysOESImmediateValidArgs
) {
374 GenVertexArraysOESImmediateValidArgs();
376 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
377 GenVertexArraysOESImmediateValidArgs
) {
378 GenVertexArraysOESImmediateValidArgs();
381 TEST_P(GLES2DecoderVertexArraysOESTest
,
382 GenVertexArraysOESImmediateInvalidArgs
) {
383 GenVertexArraysOESImmediateInvalidArgs();
385 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
386 GenVertexArraysOESImmediateInvalidArgs
) {
387 GenVertexArraysOESImmediateInvalidArgs();
390 TEST_P(GLES2DecoderVertexArraysOESTest
,
391 DeleteVertexArraysOESImmediateValidArgs
) {
392 DeleteVertexArraysOESImmediateValidArgs();
394 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
395 DeleteVertexArraysOESImmediateValidArgs
) {
396 DeleteVertexArraysOESImmediateValidArgs();
399 TEST_P(GLES2DecoderVertexArraysOESTest
,
400 DeleteVertexArraysOESImmediateInvalidArgs
) {
401 DeleteVertexArraysOESImmediateInvalidArgs();
403 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
404 DeleteVertexArraysOESImmediateInvalidArgs
) {
405 DeleteVertexArraysOESImmediateInvalidArgs();
408 TEST_P(GLES2DecoderVertexArraysOESTest
,
409 DeleteBoundVertexArraysOESImmediateValidArgs
) {
410 DeleteBoundVertexArraysOESImmediateValidArgs();
412 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
413 DeleteBoundVertexArraysOESImmediateValidArgs
) {
414 DeleteBoundVertexArraysOESImmediateValidArgs();
417 TEST_P(GLES2DecoderVertexArraysOESTest
, IsVertexArrayOESValidArgs
) {
418 IsVertexArrayOESValidArgs();
420 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
, IsVertexArrayOESValidArgs
) {
421 IsVertexArrayOESValidArgs();
424 TEST_P(GLES2DecoderVertexArraysOESTest
,
425 IsVertexArrayOESInvalidArgsBadSharedMemoryId
) {
426 IsVertexArrayOESInvalidArgsBadSharedMemoryId();
428 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
429 IsVertexArrayOESInvalidArgsBadSharedMemoryId
) {
430 IsVertexArrayOESInvalidArgsBadSharedMemoryId();
433 TEST_P(GLES2DecoderVertexArraysOESTest
, BindVertexArrayOESValidArgs
) {
434 BindVertexArrayOESValidArgs();
436 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
, BindVertexArrayOESValidArgs
) {
437 BindVertexArrayOESValidArgs();
440 TEST_P(GLES2DecoderVertexArraysOESTest
, BindVertexArrayOESValidArgsNewId
) {
441 BindVertexArrayOESValidArgsNewId();
443 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
444 BindVertexArrayOESValidArgsNewId
) {
445 BindVertexArrayOESValidArgsNewId();
448 TEST_P(GLES2DecoderTest
, BufferDataGLError
) {
449 GLenum target
= GL_ARRAY_BUFFER
;
451 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
452 BufferManager
* manager
= group().buffer_manager();
453 Buffer
* buffer
= manager
->GetBuffer(client_buffer_id_
);
454 ASSERT_TRUE(buffer
!= NULL
);
455 EXPECT_EQ(0, buffer
->size());
456 EXPECT_CALL(*gl_
, GetError())
457 .WillOnce(Return(GL_NO_ERROR
))
458 .WillOnce(Return(GL_OUT_OF_MEMORY
))
459 .RetiresOnSaturation();
460 EXPECT_CALL(*gl_
, BufferData(target
, size
, _
, GL_STREAM_DRAW
))
462 .RetiresOnSaturation();
464 cmd
.Init(target
, size
, 0, 0, GL_STREAM_DRAW
);
465 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
466 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
467 EXPECT_EQ(0, buffer
->size());
470 // TODO(gman): BufferData
472 // TODO(gman): BufferDataImmediate
474 // TODO(gman): BufferSubData
476 // TODO(gman): BufferSubDataImmediate