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/common/id_allocator.h"
12 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
13 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
14 #include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
15 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
16 #include "gpu/command_buffer/service/context_group.h"
17 #include "gpu/command_buffer/service/context_state.h"
18 #include "gpu/command_buffer/service/gl_surface_mock.h"
19 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
21 #include "gpu/command_buffer/service/gpu_switches.h"
22 #include "gpu/command_buffer/service/image_manager.h"
23 #include "gpu/command_buffer/service/mailbox_manager.h"
24 #include "gpu/command_buffer/service/mocks.h"
25 #include "gpu/command_buffer/service/program_manager.h"
26 #include "gpu/command_buffer/service/test_helper.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "ui/gl/gl_implementation.h"
29 #include "ui/gl/gl_mock.h"
30 #include "ui/gl/gl_surface_stub.h"
32 #if !defined(GL_DEPTH24_STENCIL8)
33 #define GL_DEPTH24_STENCIL8 0x88F0
36 using ::gfx::MockGLInterface
;
38 using ::testing::DoAll
;
39 using ::testing::InSequence
;
40 using ::testing::Invoke
;
41 using ::testing::MatcherCast
;
42 using ::testing::Mock
;
43 using ::testing::Pointee
;
44 using ::testing::Return
;
45 using ::testing::SaveArg
;
46 using ::testing::SetArrayArgument
;
47 using ::testing::SetArgumentPointee
;
48 using ::testing::SetArgPointee
;
49 using ::testing::StrEq
;
50 using ::testing::StrictMock
;
57 TEST_P(GLES2DecoderWithShaderTest
, GetVertexAttribPointervSucceeds
) {
58 const float dummy
= 0;
59 const GLuint kOffsetToTestFor
= sizeof(dummy
) * 4;
60 const GLuint kIndexToTest
= 1;
61 GetVertexAttribPointerv::Result
* result
=
62 static_cast<GetVertexAttribPointerv::Result
*>(shared_memory_address_
);
64 const GLuint
* result_value
= result
->GetData();
65 // Test that initial value is 0.
66 GetVertexAttribPointerv cmd
;
67 cmd
.Init(kIndexToTest
,
68 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
70 shared_memory_offset_
);
71 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
72 EXPECT_EQ(sizeof(*result_value
), result
->size
);
73 EXPECT_EQ(0u, *result_value
);
74 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
76 // Set the value and see that we get it.
78 DoVertexAttribPointer(kIndexToTest
, 2, GL_FLOAT
, 0, kOffsetToTestFor
);
80 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
81 EXPECT_EQ(sizeof(*result_value
), result
->size
);
82 EXPECT_EQ(kOffsetToTestFor
, *result_value
);
83 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
86 TEST_P(GLES2DecoderWithShaderTest
, GetVertexAttribPointervBadArgsFails
) {
87 const GLuint kIndexToTest
= 1;
88 GetVertexAttribPointerv::Result
* result
=
89 static_cast<GetVertexAttribPointerv::Result
*>(shared_memory_address_
);
91 const GLuint
* result_value
= result
->GetData();
92 // Test pname invalid fails.
93 GetVertexAttribPointerv cmd
;
94 cmd
.Init(kIndexToTest
,
95 GL_VERTEX_ATTRIB_ARRAY_POINTER
+ 1,
97 shared_memory_offset_
);
98 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
99 EXPECT_EQ(0u, result
->size
);
100 EXPECT_EQ(kInitialResult
, *result_value
);
101 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
103 // Test index out of range fails.
105 cmd
.Init(kNumVertexAttribs
,
106 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
108 shared_memory_offset_
);
109 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
110 EXPECT_EQ(0u, result
->size
);
111 EXPECT_EQ(kInitialResult
, *result_value
);
112 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
114 // Test memory id bad fails.
115 cmd
.Init(kIndexToTest
,
116 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
117 kInvalidSharedMemoryId
,
118 shared_memory_offset_
);
119 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
121 // Test memory offset bad fails.
122 cmd
.Init(kIndexToTest
,
123 GL_VERTEX_ATTRIB_ARRAY_POINTER
,
125 kInvalidSharedMemoryOffset
);
126 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
129 TEST_P(GLES2DecoderWithShaderTest
, BindBufferToDifferentTargetFails
) {
130 // Bind the buffer to GL_ARRAY_BUFFER
131 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
132 // Attempt to rebind to GL_ELEMENT_ARRAY_BUFFER
133 // NOTE: Real GLES2 does not have this restriction but WebGL and we do.
134 // This can be restriction can be removed at runtime.
135 EXPECT_CALL(*gl_
, BindBuffer(_
, _
)).Times(0);
137 cmd
.Init(GL_ELEMENT_ARRAY_BUFFER
, client_buffer_id_
);
138 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
139 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
142 TEST_P(GLES2DecoderWithShaderTest
, VertexAttribPointer
) {
144 static const GLenum types
[] = {
145 GL_BYTE
, GL_UNSIGNED_BYTE
, GL_SHORT
, GL_UNSIGNED_SHORT
,
146 GL_FLOAT
, GL_FIXED
, GL_INT
, GL_UNSIGNED_INT
,
148 static const GLsizei sizes
[] = {
149 1, 1, 2, 2, 4, 4, 4, 4,
151 static const GLuint indices
[] = {
152 0, 1, kNumVertexAttribs
- 1, kNumVertexAttribs
,
154 static const GLsizei offset_mult
[] = {
157 static const GLsizei offset_offset
[] = {
160 static const GLsizei stride_mult
[] = {
161 -1, 0, 0, 1, 1, 2, 1000,
163 static const GLsizei stride_offset
[] = {
166 for (size_t tt
= 0; tt
< arraysize(types
); ++tt
) {
167 GLenum type
= types
[tt
];
168 GLsizei num_bytes
= sizes
[tt
];
169 for (size_t ii
= 0; ii
< arraysize(indices
); ++ii
) {
170 GLuint index
= indices
[ii
];
171 for (GLint size
= 0; size
< 5; ++size
) {
172 for (size_t oo
= 0; oo
< arraysize(offset_mult
); ++oo
) {
173 GLuint offset
= num_bytes
* offset_mult
[oo
] + offset_offset
[oo
];
174 for (size_t ss
= 0; ss
< arraysize(stride_mult
); ++ss
) {
175 GLsizei stride
= num_bytes
* stride_mult
[ss
] + stride_offset
[ss
];
176 for (int normalize
= 0; normalize
< 2; ++normalize
) {
177 bool index_good
= index
< static_cast<GLuint
>(kNumVertexAttribs
);
178 bool size_good
= (size
> 0 && size
< 5);
179 bool offset_good
= (offset
% num_bytes
== 0);
181 (stride
% num_bytes
== 0) && stride
>= 0 && stride
<= 255;
182 bool type_good
= (type
!= GL_INT
&& type
!= GL_UNSIGNED_INT
&&
184 bool good
= size_good
&& offset_good
&& stride_good
&&
185 type_good
&& index_good
;
186 bool call
= good
&& (type
!= GL_FIXED
);
189 VertexAttribPointer(index
,
194 BufferOffset(offset
)));
196 VertexAttribPointer cmd
;
197 cmd
.Init(index
, size
, type
, normalize
, stride
, offset
);
198 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
200 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
201 } else if (size_good
&& offset_good
&& stride_good
&& type_good
&&
203 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
204 } else if (size_good
&& offset_good
&& stride_good
&&
205 !type_good
&& index_good
) {
206 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
207 } else if (size_good
&& offset_good
&& !stride_good
&&
208 type_good
&& index_good
) {
209 if (stride
< 0 || stride
> 255) {
210 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
212 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
214 } else if (size_good
&& !offset_good
&& stride_good
&&
215 type_good
&& index_good
) {
216 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
217 } else if (!size_good
&& offset_good
&& stride_good
&&
218 type_good
&& index_good
) {
219 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
221 EXPECT_NE(GL_NO_ERROR
, GetGLError());
231 class GLES2DecoderVertexArraysOESTest
: public GLES2DecoderWithShaderTest
{
233 GLES2DecoderVertexArraysOESTest() {}
235 bool vertex_array_deleted_manually_
;
237 virtual void SetUp() {
239 init
.gl_version
= "opengl es 2.0";
240 init
.bind_generates_resource
= true;
242 SetupDefaultProgram();
244 AddExpectationsForGenVertexArraysOES();
245 GenHelper
<GenVertexArraysOESImmediate
>(client_vertexarray_id_
);
247 vertex_array_deleted_manually_
= false;
250 virtual void TearDown() {
251 // This should only be set if the test handled deletion of the vertex array
252 // itself. Necessary because vertex_array_objects are not sharable, and thus
253 // not managed in the ContextGroup, meaning they will be destroyed during
255 if (!vertex_array_deleted_manually_
) {
256 AddExpectationsForDeleteVertexArraysOES();
259 GLES2DecoderWithShaderTest::TearDown();
262 void GenVertexArraysOESImmediateValidArgs() {
263 AddExpectationsForGenVertexArraysOES();
264 GenVertexArraysOESImmediate
* cmd
=
265 GetImmediateAs
<GenVertexArraysOESImmediate
>();
266 GLuint temp
= kNewClientId
;
268 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(*cmd
, sizeof(temp
)));
269 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
270 EXPECT_TRUE(GetVertexArrayInfo(kNewClientId
) != NULL
);
271 AddExpectationsForDeleteVertexArraysOES();
274 void GenVertexArraysOESImmediateInvalidArgs() {
275 EXPECT_CALL(*gl_
, GenVertexArraysOES(_
, _
)).Times(0);
276 GenVertexArraysOESImmediate
* cmd
=
277 GetImmediateAs
<GenVertexArraysOESImmediate
>();
278 cmd
->Init(1, &client_vertexarray_id_
);
279 EXPECT_EQ(error::kInvalidArguments
,
280 ExecuteImmediateCmd(*cmd
, sizeof(&client_vertexarray_id_
)));
283 void DeleteVertexArraysOESImmediateValidArgs() {
284 AddExpectationsForDeleteVertexArraysOES();
285 DeleteVertexArraysOESImmediate
& cmd
=
286 *GetImmediateAs
<DeleteVertexArraysOESImmediate
>();
287 cmd
.Init(1, &client_vertexarray_id_
);
288 EXPECT_EQ(error::kNoError
,
289 ExecuteImmediateCmd(cmd
, sizeof(client_vertexarray_id_
)));
290 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
291 EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_
) == NULL
);
292 vertex_array_deleted_manually_
= true;
295 void DeleteVertexArraysOESImmediateInvalidArgs() {
296 DeleteVertexArraysOESImmediate
& cmd
=
297 *GetImmediateAs
<DeleteVertexArraysOESImmediate
>();
298 GLuint temp
= kInvalidClientId
;
300 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(cmd
, sizeof(temp
)));
303 void DeleteBoundVertexArraysOESImmediateValidArgs() {
304 BindVertexArrayOESValidArgs();
306 AddExpectationsForDeleteBoundVertexArraysOES();
307 DeleteVertexArraysOESImmediate
& cmd
=
308 *GetImmediateAs
<DeleteVertexArraysOESImmediate
>();
309 cmd
.Init(1, &client_vertexarray_id_
);
310 EXPECT_EQ(error::kNoError
,
311 ExecuteImmediateCmd(cmd
, sizeof(client_vertexarray_id_
)));
312 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
313 EXPECT_TRUE(GetVertexArrayInfo(client_vertexarray_id_
) == NULL
);
314 vertex_array_deleted_manually_
= true;
317 void IsVertexArrayOESValidArgs() {
318 IsVertexArrayOES cmd
;
319 cmd
.Init(client_vertexarray_id_
, shared_memory_id_
, shared_memory_offset_
);
320 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
321 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
324 void IsVertexArrayOESInvalidArgsBadSharedMemoryId() {
325 IsVertexArrayOES cmd
;
327 client_vertexarray_id_
, kInvalidSharedMemoryId
, shared_memory_offset_
);
328 EXPECT_EQ(error::kOutOfBounds
, ExecuteCmd(cmd
));
330 client_vertexarray_id_
, shared_memory_id_
, kInvalidSharedMemoryOffset
);
331 EXPECT_EQ(error::kOutOfBounds
, ExecuteCmd(cmd
));
334 void BindVertexArrayOESValidArgs() {
335 AddExpectationsForBindVertexArrayOES();
336 BindVertexArrayOES cmd
;
337 cmd
.Init(client_vertexarray_id_
);
338 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
339 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
342 void BindVertexArrayOESValidArgsNewId() {
343 BindVertexArrayOES cmd
;
344 cmd
.Init(kNewClientId
);
345 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
346 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
350 INSTANTIATE_TEST_CASE_P(Service
,
351 GLES2DecoderVertexArraysOESTest
,
354 class GLES2DecoderEmulatedVertexArraysOESTest
355 : public GLES2DecoderVertexArraysOESTest
{
357 GLES2DecoderEmulatedVertexArraysOESTest() {}
359 virtual void SetUp() {
361 init
.gl_version
= "3.0";
362 init
.bind_generates_resource
= true;
363 init
.use_native_vao
= false;
365 SetupDefaultProgram();
367 AddExpectationsForGenVertexArraysOES();
368 GenHelper
<GenVertexArraysOESImmediate
>(client_vertexarray_id_
);
370 vertex_array_deleted_manually_
= false;
374 INSTANTIATE_TEST_CASE_P(Service
,
375 GLES2DecoderEmulatedVertexArraysOESTest
,
378 // Test vertex array objects with native support
379 TEST_P(GLES2DecoderVertexArraysOESTest
, GenVertexArraysOESImmediateValidArgs
) {
380 GenVertexArraysOESImmediateValidArgs();
382 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
383 GenVertexArraysOESImmediateValidArgs
) {
384 GenVertexArraysOESImmediateValidArgs();
387 TEST_P(GLES2DecoderVertexArraysOESTest
,
388 GenVertexArraysOESImmediateInvalidArgs
) {
389 GenVertexArraysOESImmediateInvalidArgs();
391 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
392 GenVertexArraysOESImmediateInvalidArgs
) {
393 GenVertexArraysOESImmediateInvalidArgs();
396 TEST_P(GLES2DecoderVertexArraysOESTest
,
397 DeleteVertexArraysOESImmediateValidArgs
) {
398 DeleteVertexArraysOESImmediateValidArgs();
400 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
401 DeleteVertexArraysOESImmediateValidArgs
) {
402 DeleteVertexArraysOESImmediateValidArgs();
405 TEST_P(GLES2DecoderVertexArraysOESTest
,
406 DeleteVertexArraysOESImmediateInvalidArgs
) {
407 DeleteVertexArraysOESImmediateInvalidArgs();
409 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
410 DeleteVertexArraysOESImmediateInvalidArgs
) {
411 DeleteVertexArraysOESImmediateInvalidArgs();
414 TEST_P(GLES2DecoderVertexArraysOESTest
,
415 DeleteBoundVertexArraysOESImmediateValidArgs
) {
416 DeleteBoundVertexArraysOESImmediateValidArgs();
418 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
419 DeleteBoundVertexArraysOESImmediateValidArgs
) {
420 DeleteBoundVertexArraysOESImmediateValidArgs();
423 TEST_P(GLES2DecoderVertexArraysOESTest
, IsVertexArrayOESValidArgs
) {
424 IsVertexArrayOESValidArgs();
426 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
, IsVertexArrayOESValidArgs
) {
427 IsVertexArrayOESValidArgs();
430 TEST_P(GLES2DecoderVertexArraysOESTest
,
431 IsVertexArrayOESInvalidArgsBadSharedMemoryId
) {
432 IsVertexArrayOESInvalidArgsBadSharedMemoryId();
434 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
435 IsVertexArrayOESInvalidArgsBadSharedMemoryId
) {
436 IsVertexArrayOESInvalidArgsBadSharedMemoryId();
439 TEST_P(GLES2DecoderVertexArraysOESTest
, BindVertexArrayOESValidArgs
) {
440 BindVertexArrayOESValidArgs();
442 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
, BindVertexArrayOESValidArgs
) {
443 BindVertexArrayOESValidArgs();
446 TEST_P(GLES2DecoderVertexArraysOESTest
, BindVertexArrayOESValidArgsNewId
) {
447 BindVertexArrayOESValidArgsNewId();
449 TEST_P(GLES2DecoderEmulatedVertexArraysOESTest
,
450 BindVertexArrayOESValidArgsNewId
) {
451 BindVertexArrayOESValidArgsNewId();
454 TEST_P(GLES2DecoderTest
, BufferDataGLError
) {
455 GLenum target
= GL_ARRAY_BUFFER
;
457 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
458 BufferManager
* manager
= group().buffer_manager();
459 Buffer
* buffer
= manager
->GetBuffer(client_buffer_id_
);
460 ASSERT_TRUE(buffer
!= NULL
);
461 EXPECT_EQ(0, buffer
->size());
462 EXPECT_CALL(*gl_
, GetError())
463 .WillOnce(Return(GL_NO_ERROR
))
464 .WillOnce(Return(GL_OUT_OF_MEMORY
))
465 .RetiresOnSaturation();
466 EXPECT_CALL(*gl_
, BufferData(target
, size
, _
, GL_STREAM_DRAW
))
468 .RetiresOnSaturation();
470 cmd
.Init(target
, size
, 0, 0, GL_STREAM_DRAW
);
471 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
472 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
473 EXPECT_EQ(0, buffer
->size());
476 // TODO(gman): BufferData
478 // TODO(gman): BufferDataImmediate
480 // TODO(gman): BufferSubData
482 // TODO(gman): BufferSubDataImmediate