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
, GetProgramInfoCHROMIUMValidArgs
) {
58 const uint32 kBucketId
= 123;
59 GetProgramInfoCHROMIUM cmd
;
60 cmd
.Init(client_program_id_
, kBucketId
);
61 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
62 CommonDecoder::Bucket
* bucket
= decoder_
->GetBucket(kBucketId
);
63 EXPECT_GT(bucket
->size(), 0u);
66 TEST_P(GLES2DecoderWithShaderTest
, GetProgramInfoCHROMIUMInvalidArgs
) {
67 const uint32 kBucketId
= 123;
68 CommonDecoder::Bucket
* bucket
= decoder_
->GetBucket(kBucketId
);
69 EXPECT_TRUE(bucket
== NULL
);
70 GetProgramInfoCHROMIUM cmd
;
71 cmd
.Init(kInvalidClientId
, kBucketId
);
72 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
73 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
74 bucket
= decoder_
->GetBucket(kBucketId
);
75 ASSERT_TRUE(bucket
!= NULL
);
76 EXPECT_EQ(sizeof(ProgramInfoHeader
), bucket
->size());
77 ProgramInfoHeader
* info
=
78 bucket
->GetDataAs
<ProgramInfoHeader
*>(0, sizeof(ProgramInfoHeader
));
79 ASSERT_TRUE(info
!= 0);
80 EXPECT_EQ(0u, info
->link_status
);
81 EXPECT_EQ(0u, info
->num_attribs
);
82 EXPECT_EQ(0u, info
->num_uniforms
);
85 TEST_P(GLES2DecoderWithShaderTest
, GetUniformivSucceeds
) {
86 GetUniformiv::Result
* result
=
87 static_cast<GetUniformiv::Result
*>(shared_memory_address_
);
90 cmd
.Init(client_program_id_
,
91 kUniform2FakeLocation
,
94 EXPECT_CALL(*gl_
, GetUniformiv(kServiceProgramId
, kUniform2RealLocation
, _
))
96 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
97 EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type
),
101 TEST_P(GLES2DecoderWithShaderTest
, GetUniformivArrayElementSucceeds
) {
102 GetUniformiv::Result
* result
=
103 static_cast<GetUniformiv::Result
*>(shared_memory_address_
);
106 cmd
.Init(client_program_id_
,
107 kUniform2ElementFakeLocation
,
109 kSharedMemoryOffset
);
111 GetUniformiv(kServiceProgramId
, kUniform2ElementRealLocation
, _
))
113 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
114 EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type
),
118 TEST_P(GLES2DecoderWithShaderTest
, GetUniformivBadProgramFails
) {
119 GetUniformiv::Result
* result
=
120 static_cast<GetUniformiv::Result
*>(shared_memory_address_
);
123 // non-existant program
124 cmd
.Init(kInvalidClientId
,
125 kUniform2FakeLocation
,
127 kSharedMemoryOffset
);
128 EXPECT_CALL(*gl_
, GetUniformiv(_
, _
, _
)).Times(0);
129 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
130 EXPECT_EQ(0U, result
->size
);
131 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
132 // Valid id that is not a program. The GL spec requires a different error for
134 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
135 result
->size
= kInitialResult
;
136 cmd
.Init(client_shader_id_
,
137 kUniform2FakeLocation
,
139 kSharedMemoryOffset
);
140 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
141 EXPECT_EQ(0U, result
->size
);
142 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
143 #endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS
145 EXPECT_CALL(*gl_
, CreateProgram())
147 .WillOnce(Return(kNewServiceId
))
148 .RetiresOnSaturation();
150 cmd2
.Init(kNewClientId
);
151 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
152 result
->size
= kInitialResult
;
153 cmd
.Init(kNewClientId
,
154 kUniform2FakeLocation
,
156 kSharedMemoryOffset
);
157 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
158 EXPECT_EQ(0U, result
->size
);
159 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
162 TEST_P(GLES2DecoderWithShaderTest
, GetUniformivBadLocationFails
) {
163 GetUniformiv::Result
* result
=
164 static_cast<GetUniformiv::Result
*>(shared_memory_address_
);
168 cmd
.Init(client_program_id_
,
169 kInvalidUniformLocation
,
171 kSharedMemoryOffset
);
172 EXPECT_CALL(*gl_
, GetUniformiv(_
, _
, _
)).Times(0);
173 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
174 EXPECT_EQ(0U, result
->size
);
175 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
178 TEST_P(GLES2DecoderWithShaderTest
, GetUniformivBadSharedMemoryFails
) {
180 cmd
.Init(client_program_id_
,
181 kUniform2FakeLocation
,
182 kInvalidSharedMemoryId
,
183 kSharedMemoryOffset
);
184 EXPECT_CALL(*gl_
, GetUniformiv(_
, _
, _
)).Times(0);
185 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
186 cmd
.Init(client_program_id_
,
187 kUniform2FakeLocation
,
189 kInvalidSharedMemoryOffset
);
190 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
193 TEST_P(GLES2DecoderWithShaderTest
, GetUniformfvSucceeds
) {
194 GetUniformfv::Result
* result
=
195 static_cast<GetUniformfv::Result
*>(shared_memory_address_
);
198 cmd
.Init(client_program_id_
,
199 kUniform2FakeLocation
,
201 kSharedMemoryOffset
);
202 EXPECT_CALL(*gl_
, GetUniformfv(kServiceProgramId
, kUniform2RealLocation
, _
))
204 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
205 EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type
),
209 TEST_P(GLES2DecoderWithShaderTest
, GetUniformfvArrayElementSucceeds
) {
210 GetUniformfv::Result
* result
=
211 static_cast<GetUniformfv::Result
*>(shared_memory_address_
);
214 cmd
.Init(client_program_id_
,
215 kUniform2ElementFakeLocation
,
217 kSharedMemoryOffset
);
219 GetUniformfv(kServiceProgramId
, kUniform2ElementRealLocation
, _
))
221 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
222 EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type
),
226 TEST_P(GLES2DecoderWithShaderTest
, GetUniformfvBadProgramFails
) {
227 GetUniformfv::Result
* result
=
228 static_cast<GetUniformfv::Result
*>(shared_memory_address_
);
231 // non-existant program
232 cmd
.Init(kInvalidClientId
,
233 kUniform2FakeLocation
,
235 kSharedMemoryOffset
);
236 EXPECT_CALL(*gl_
, GetUniformfv(_
, _
, _
)).Times(0);
237 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
238 EXPECT_EQ(0U, result
->size
);
239 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
240 // Valid id that is not a program. The GL spec requires a different error for
242 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
243 result
->size
= kInitialResult
;
244 cmd
.Init(client_shader_id_
,
245 kUniform2FakeLocation
,
247 kSharedMemoryOffset
);
248 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
249 EXPECT_EQ(0U, result
->size
);
250 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
251 #endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS
253 EXPECT_CALL(*gl_
, CreateProgram())
255 .WillOnce(Return(kNewServiceId
))
256 .RetiresOnSaturation();
258 cmd2
.Init(kNewClientId
);
259 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
260 result
->size
= kInitialResult
;
261 cmd
.Init(kNewClientId
,
262 kUniform2FakeLocation
,
264 kSharedMemoryOffset
);
265 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
266 EXPECT_EQ(0U, result
->size
);
267 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
270 TEST_P(GLES2DecoderWithShaderTest
, GetUniformfvBadLocationFails
) {
271 GetUniformfv::Result
* result
=
272 static_cast<GetUniformfv::Result
*>(shared_memory_address_
);
276 cmd
.Init(client_program_id_
,
277 kInvalidUniformLocation
,
279 kSharedMemoryOffset
);
280 EXPECT_CALL(*gl_
, GetUniformfv(_
, _
, _
)).Times(0);
281 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
282 EXPECT_EQ(0U, result
->size
);
283 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
286 TEST_P(GLES2DecoderWithShaderTest
, GetUniformfvBadSharedMemoryFails
) {
288 cmd
.Init(client_program_id_
,
289 kUniform2FakeLocation
,
290 kInvalidSharedMemoryId
,
291 kSharedMemoryOffset
);
292 EXPECT_CALL(*gl_
, GetUniformfv(_
, _
, _
)).Times(0);
293 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
294 cmd
.Init(client_program_id_
,
295 kUniform2FakeLocation
,
297 kInvalidSharedMemoryOffset
);
298 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
301 TEST_P(GLES2DecoderWithShaderTest
, GetAttachedShadersSucceeds
) {
302 GetAttachedShaders cmd
;
303 typedef GetAttachedShaders::Result Result
;
304 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
306 EXPECT_CALL(*gl_
, GetAttachedShaders(kServiceProgramId
, 1, _
, _
)).WillOnce(
307 DoAll(SetArgumentPointee
<2>(1), SetArgumentPointee
<3>(kServiceShaderId
)));
308 cmd
.Init(client_program_id_
,
310 shared_memory_offset_
,
311 Result::ComputeSize(1));
312 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
313 EXPECT_EQ(1, result
->GetNumResults());
314 EXPECT_EQ(client_shader_id_
, result
->GetData()[0]);
315 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
318 TEST_P(GLES2DecoderWithShaderTest
, GetAttachedShadersResultNotInitFail
) {
319 GetAttachedShaders cmd
;
320 typedef GetAttachedShaders::Result Result
;
321 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
323 EXPECT_CALL(*gl_
, GetAttachedShaders(_
, _
, _
, _
)).Times(0);
324 cmd
.Init(client_program_id_
,
326 shared_memory_offset_
,
327 Result::ComputeSize(1));
328 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
331 TEST_P(GLES2DecoderWithShaderTest
, GetAttachedShadersBadProgramFails
) {
332 GetAttachedShaders cmd
;
333 typedef GetAttachedShaders::Result Result
;
334 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
336 EXPECT_CALL(*gl_
, GetAttachedShaders(_
, _
, _
, _
)).Times(0);
337 cmd
.Init(kInvalidClientId
,
339 shared_memory_offset_
,
340 Result::ComputeSize(1));
341 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
342 EXPECT_EQ(0U, result
->size
);
343 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
346 TEST_P(GLES2DecoderWithShaderTest
, GetAttachedShadersBadSharedMemoryFails
) {
347 GetAttachedShaders cmd
;
348 typedef GetAttachedShaders::Result Result
;
349 cmd
.Init(client_program_id_
,
350 kInvalidSharedMemoryId
,
351 shared_memory_offset_
,
352 Result::ComputeSize(1));
353 EXPECT_CALL(*gl_
, GetAttachedShaders(_
, _
, _
, _
)).Times(0);
354 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
355 cmd
.Init(client_program_id_
,
357 kInvalidSharedMemoryOffset
,
358 Result::ComputeSize(1));
359 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
362 TEST_P(GLES2DecoderWithShaderTest
, GetShaderPrecisionFormatSucceeds
) {
363 ScopedGLImplementationSetter
gl_impl(::gfx::kGLImplementationEGLGLES2
);
364 GetShaderPrecisionFormat cmd
;
365 typedef GetShaderPrecisionFormat::Result Result
;
366 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
368 const GLint range
[2] = {62, 62};
369 const GLint precision
= 16;
370 EXPECT_CALL(*gl_
, GetShaderPrecisionFormat(_
, _
, _
, _
))
371 .WillOnce(DoAll(SetArrayArgument
<2>(range
, range
+ 2),
372 SetArgumentPointee
<3>(precision
)))
373 .RetiresOnSaturation();
374 cmd
.Init(GL_VERTEX_SHADER
,
377 shared_memory_offset_
);
378 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
379 EXPECT_NE(0, result
->success
);
380 EXPECT_EQ(range
[0], result
->min_range
);
381 EXPECT_EQ(range
[1], result
->max_range
);
382 EXPECT_EQ(precision
, result
->precision
);
383 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
386 TEST_P(GLES2DecoderWithShaderTest
, GetShaderPrecisionFormatResultNotInitFails
) {
387 GetShaderPrecisionFormat cmd
;
388 typedef GetShaderPrecisionFormat::Result Result
;
389 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
391 // NOTE: GL might not be called. There is no Desktop OpenGL equivalent
392 cmd
.Init(GL_VERTEX_SHADER
,
395 shared_memory_offset_
);
396 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
399 TEST_P(GLES2DecoderWithShaderTest
, GetShaderPrecisionFormatBadArgsFails
) {
400 typedef GetShaderPrecisionFormat::Result Result
;
401 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
403 GetShaderPrecisionFormat cmd
;
405 GL_TEXTURE_2D
, GL_HIGH_FLOAT
, shared_memory_id_
, shared_memory_offset_
);
406 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
407 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
409 cmd
.Init(GL_VERTEX_SHADER
,
412 shared_memory_offset_
);
413 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
414 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
417 TEST_P(GLES2DecoderWithShaderTest
,
418 GetShaderPrecisionFormatBadSharedMemoryFails
) {
419 GetShaderPrecisionFormat cmd
;
420 cmd
.Init(GL_VERTEX_SHADER
,
422 kInvalidSharedMemoryId
,
423 shared_memory_offset_
);
424 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
425 cmd
.Init(GL_VERTEX_SHADER
,
428 kInvalidSharedMemoryOffset
);
429 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
432 TEST_P(GLES2DecoderWithShaderTest
, GetActiveUniformSucceeds
) {
433 const GLuint kUniformIndex
= 1;
434 const uint32 kBucketId
= 123;
435 GetActiveUniform cmd
;
436 typedef GetActiveUniform::Result Result
;
437 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
439 cmd
.Init(client_program_id_
,
443 shared_memory_offset_
);
444 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
445 EXPECT_NE(0, result
->success
);
446 EXPECT_EQ(kUniform2Size
, result
->size
);
447 EXPECT_EQ(kUniform2Type
, result
->type
);
448 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
449 CommonDecoder::Bucket
* bucket
= decoder_
->GetBucket(kBucketId
);
450 ASSERT_TRUE(bucket
!= NULL
);
454 bucket
->GetData(0, bucket
->size()), kUniform2Name
, bucket
->size()));
457 TEST_P(GLES2DecoderWithShaderTest
, GetActiveUniformResultNotInitFails
) {
458 const GLuint kUniformIndex
= 1;
459 const uint32 kBucketId
= 123;
460 GetActiveUniform cmd
;
461 typedef GetActiveUniform::Result Result
;
462 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
464 cmd
.Init(client_program_id_
,
468 shared_memory_offset_
);
469 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
472 TEST_P(GLES2DecoderWithShaderTest
, GetActiveUniformBadProgramFails
) {
473 const GLuint kUniformIndex
= 1;
474 const uint32 kBucketId
= 123;
475 GetActiveUniform cmd
;
476 typedef GetActiveUniform::Result Result
;
477 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
479 cmd
.Init(kInvalidClientId
,
483 shared_memory_offset_
);
484 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
485 EXPECT_EQ(0, result
->success
);
486 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
487 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
489 cmd
.Init(client_shader_id_
,
493 shared_memory_offset_
);
494 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
495 EXPECT_EQ(0, result
->success
);
496 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
497 #endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS
500 TEST_P(GLES2DecoderWithShaderTest
, GetActiveUniformBadIndexFails
) {
501 const uint32 kBucketId
= 123;
502 GetActiveUniform cmd
;
503 typedef GetActiveUniform::Result Result
;
504 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
506 cmd
.Init(client_program_id_
,
510 shared_memory_offset_
);
511 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
512 EXPECT_EQ(0, result
->success
);
513 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
516 TEST_P(GLES2DecoderWithShaderTest
, GetActiveUniformBadSharedMemoryFails
) {
517 const GLuint kUniformIndex
= 1;
518 const uint32 kBucketId
= 123;
519 GetActiveUniform cmd
;
520 cmd
.Init(client_program_id_
,
523 kInvalidSharedMemoryId
,
524 shared_memory_offset_
);
525 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
526 cmd
.Init(client_program_id_
,
530 kInvalidSharedMemoryOffset
);
531 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
534 TEST_P(GLES2DecoderWithShaderTest
, GetActiveAttribSucceeds
) {
535 const GLuint kAttribIndex
= 1;
536 const uint32 kBucketId
= 123;
538 typedef GetActiveAttrib::Result Result
;
539 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
541 cmd
.Init(client_program_id_
,
545 shared_memory_offset_
);
546 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
547 EXPECT_NE(0, result
->success
);
548 EXPECT_EQ(kAttrib2Size
, result
->size
);
549 EXPECT_EQ(kAttrib2Type
, result
->type
);
550 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
551 CommonDecoder::Bucket
* bucket
= decoder_
->GetBucket(kBucketId
);
552 ASSERT_TRUE(bucket
!= NULL
);
555 memcmp(bucket
->GetData(0, bucket
->size()), kAttrib2Name
, bucket
->size()));
558 TEST_P(GLES2DecoderWithShaderTest
, GetActiveAttribResultNotInitFails
) {
559 const GLuint kAttribIndex
= 1;
560 const uint32 kBucketId
= 123;
562 typedef GetActiveAttrib::Result Result
;
563 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
565 cmd
.Init(client_program_id_
,
569 shared_memory_offset_
);
570 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
573 TEST_P(GLES2DecoderWithShaderTest
, GetActiveAttribBadProgramFails
) {
574 const GLuint kAttribIndex
= 1;
575 const uint32 kBucketId
= 123;
577 typedef GetActiveAttrib::Result Result
;
578 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
580 cmd
.Init(kInvalidClientId
,
584 shared_memory_offset_
);
585 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
586 EXPECT_EQ(0, result
->success
);
587 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
588 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
590 cmd
.Init(client_shader_id_
,
594 shared_memory_offset_
);
595 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
596 EXPECT_EQ(0, result
->success
);
597 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
598 #endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS
601 TEST_P(GLES2DecoderWithShaderTest
, GetActiveAttribBadIndexFails
) {
602 const uint32 kBucketId
= 123;
604 typedef GetActiveAttrib::Result Result
;
605 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
607 cmd
.Init(client_program_id_
,
611 shared_memory_offset_
);
612 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
613 EXPECT_EQ(0, result
->success
);
614 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
617 TEST_P(GLES2DecoderWithShaderTest
, GetActiveAttribBadSharedMemoryFails
) {
618 const GLuint kAttribIndex
= 1;
619 const uint32 kBucketId
= 123;
621 cmd
.Init(client_program_id_
,
624 kInvalidSharedMemoryId
,
625 shared_memory_offset_
);
626 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
627 cmd
.Init(client_program_id_
,
631 kInvalidSharedMemoryOffset
);
632 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
635 TEST_P(GLES2DecoderWithShaderTest
, GetShaderInfoLogValidArgs
) {
636 const char* kInfo
= "hello";
637 const uint32 kBucketId
= 123;
638 CompileShader compile_cmd
;
639 GetShaderInfoLog cmd
;
640 EXPECT_CALL(*gl_
, ShaderSource(kServiceShaderId
, 1, _
, _
));
641 EXPECT_CALL(*gl_
, CompileShader(kServiceShaderId
));
642 EXPECT_CALL(*gl_
, GetShaderiv(kServiceShaderId
, GL_COMPILE_STATUS
, _
))
643 .WillOnce(SetArgumentPointee
<2>(GL_FALSE
))
644 .RetiresOnSaturation();
645 EXPECT_CALL(*gl_
, GetShaderiv(kServiceShaderId
, GL_INFO_LOG_LENGTH
, _
))
646 .WillOnce(SetArgumentPointee
<2>(strlen(kInfo
) + 1))
647 .RetiresOnSaturation();
648 EXPECT_CALL(*gl_
, GetShaderInfoLog(kServiceShaderId
, strlen(kInfo
) + 1, _
, _
))
649 .WillOnce(DoAll(SetArgumentPointee
<2>(strlen(kInfo
)),
650 SetArrayArgument
<3>(kInfo
, kInfo
+ strlen(kInfo
) + 1)));
651 compile_cmd
.Init(client_shader_id_
);
652 cmd
.Init(client_shader_id_
, kBucketId
);
653 EXPECT_EQ(error::kNoError
, ExecuteCmd(compile_cmd
));
654 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
655 CommonDecoder::Bucket
* bucket
= decoder_
->GetBucket(kBucketId
);
656 ASSERT_TRUE(bucket
!= NULL
);
657 EXPECT_EQ(strlen(kInfo
) + 1, bucket
->size());
659 memcmp(bucket
->GetData(0, bucket
->size()), kInfo
, bucket
->size()));
660 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
663 TEST_P(GLES2DecoderWithShaderTest
, GetShaderInfoLogInvalidArgs
) {
664 const uint32 kBucketId
= 123;
665 GetShaderInfoLog cmd
;
666 cmd
.Init(kInvalidClientId
, kBucketId
);
667 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
668 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
671 TEST_P(GLES2DecoderTest
, CompileShaderValidArgs
) {
672 EXPECT_CALL(*gl_
, ShaderSource(kServiceShaderId
, 1, _
, _
));
673 EXPECT_CALL(*gl_
, CompileShader(kServiceShaderId
));
674 EXPECT_CALL(*gl_
, GetShaderiv(kServiceShaderId
, GL_COMPILE_STATUS
, _
))
675 .WillOnce(SetArgumentPointee
<2>(GL_TRUE
))
676 .RetiresOnSaturation();
678 cmd
.Init(client_shader_id_
);
679 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
682 TEST_P(GLES2DecoderTest
, CompileShaderInvalidArgs
) {
684 cmd
.Init(kInvalidClientId
);
685 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
686 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
687 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
688 cmd
.Init(client_program_id_
);
689 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
690 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
691 #endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS
694 TEST_P(GLES2DecoderTest
, ShaderSourceBucketAndGetShaderSourceValidArgs
) {
695 const uint32 kInBucketId
= 123;
696 const uint32 kOutBucketId
= 125;
697 const char kSource
[] = "hello";
698 const uint32 kSourceSize
= sizeof(kSource
) - 1;
699 SetBucketAsCString(kInBucketId
, kSource
);
700 ShaderSourceBucket cmd
;
701 cmd
.Init(client_shader_id_
, kInBucketId
);
702 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
704 GetShaderSource get_cmd
;
705 get_cmd
.Init(client_shader_id_
, kOutBucketId
);
706 EXPECT_EQ(error::kNoError
, ExecuteCmd(get_cmd
));
707 CommonDecoder::Bucket
* bucket
= decoder_
->GetBucket(kOutBucketId
);
708 ASSERT_TRUE(bucket
!= NULL
);
709 EXPECT_EQ(kSourceSize
+ 1, bucket
->size());
711 0, memcmp(bucket
->GetData(0, bucket
->size()), kSource
, bucket
->size()));
714 TEST_P(GLES2DecoderTest
, ShaderSourceBucketInvalidArgs
) {
715 const uint32 kBucketId
= 123;
716 const char kSource
[] = "hello";
717 const uint32 kSourceSize
= sizeof(kSource
) - 1;
718 memcpy(shared_memory_address_
, kSource
, kSourceSize
);
719 ShaderSourceBucket cmd
;
721 cmd
.Init(client_texture_id_
, kBucketId
);
722 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
723 // Test invalid client.
724 SetBucketAsCString(kBucketId
, kSource
);
725 cmd
.Init(kInvalidClientId
, kBucketId
);
726 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
727 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
728 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
729 SetBucketAsCString(kBucketId
, kSource
);
731 client_program_id_
, kBucketId
);
732 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
733 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
734 #endif // GLES2_TEST_SHADER_VS_PROGRAM_IDS
737 TEST_P(GLES2DecoderTest
, ShaderSourceStripComments
) {
738 const uint32 kInBucketId
= 123;
739 const char kSource
[] = "hello/*te\ast*/world//a\ab";
740 SetBucketAsCString(kInBucketId
, kSource
);
741 ShaderSourceBucket cmd
;
742 cmd
.Init(client_shader_id_
, kInBucketId
);
743 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
744 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
747 TEST_P(GLES2DecoderWithShaderTest
, Uniform1iValidArgs
) {
748 EXPECT_CALL(*gl_
, Uniform1i(kUniform1RealLocation
, 2));
750 cmd
.Init(kUniform1FakeLocation
, 2);
751 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
754 TEST_P(GLES2DecoderWithShaderTest
, Uniform1ivImmediateValidArgs
) {
755 Uniform1ivImmediate
& cmd
= *GetImmediateAs
<Uniform1ivImmediate
>();
757 Uniform1iv(kUniform1RealLocation
,
759 reinterpret_cast<GLint
*>(ImmediateDataAddress(&cmd
))));
760 GLint temp
[1 * 2] = {
763 cmd
.Init(kUniform1FakeLocation
, 1, &temp
[0]);
764 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(cmd
, sizeof(temp
)));
767 TEST_P(GLES2DecoderWithShaderTest
, Uniform1ivImmediateInvalidValidArgs
) {
768 EXPECT_CALL(*gl_
, Uniform1iv(_
, _
, _
)).Times(0);
769 Uniform1ivImmediate
& cmd
= *GetImmediateAs
<Uniform1ivImmediate
>();
770 GLint temp
[1 * 2] = {
773 cmd
.Init(kUniform1FakeLocation
, 2, &temp
[0]);
774 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(cmd
, sizeof(temp
)));
775 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
778 TEST_P(GLES2DecoderWithShaderTest
, Uniform1ivZeroCount
) {
779 EXPECT_CALL(*gl_
, Uniform1iv(_
, _
, _
)).Times(0);
780 Uniform1ivImmediate
& cmd
= *GetImmediateAs
<Uniform1ivImmediate
>();
782 cmd
.Init(kUniform1FakeLocation
, 0, &temp
);
783 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(cmd
, sizeof(temp
)));
784 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
787 TEST_P(GLES2DecoderWithShaderTest
, Uniform1iSamplerIsLmited
) {
788 EXPECT_CALL(*gl_
, Uniform1i(_
, _
)).Times(0);
790 cmd
.Init(kUniform1FakeLocation
, kNumTextureUnits
);
791 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
792 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
795 TEST_P(GLES2DecoderWithShaderTest
, Uniform1ivSamplerIsLimited
) {
796 EXPECT_CALL(*gl_
, Uniform1iv(_
, _
, _
)).Times(0);
797 Uniform1ivImmediate
& cmd
= *GetImmediateAs
<Uniform1ivImmediate
>();
798 GLint temp
[] = {kNumTextureUnits
};
799 cmd
.Init(kUniform1FakeLocation
, 1, &temp
[0]);
800 EXPECT_EQ(error::kNoError
, ExecuteImmediateCmd(cmd
, sizeof(temp
)));
801 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
804 TEST_P(GLES2DecoderTest
, BindAttribLocationBucket
) {
805 const uint32 kBucketId
= 123;
806 const GLint kLocation
= 2;
807 const char* kName
= "testing";
809 BindAttribLocation(kServiceProgramId
, kLocation
, StrEq(kName
)))
811 SetBucketAsCString(kBucketId
, kName
);
812 BindAttribLocationBucket cmd
;
813 cmd
.Init(client_program_id_
, kLocation
, kBucketId
);
814 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
817 TEST_P(GLES2DecoderTest
, BindAttribLocationBucketInvalidArgs
) {
818 const uint32 kBucketId
= 123;
819 const GLint kLocation
= 2;
820 const char* kName
= "testing";
821 EXPECT_CALL(*gl_
, BindAttribLocation(_
, _
, _
)).Times(0);
822 BindAttribLocationBucket cmd
;
823 // check bucket does not exist.
824 cmd
.Init(client_program_id_
, kLocation
, kBucketId
);
825 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
826 // check bucket is empty.
827 SetBucketAsCString(kBucketId
, NULL
);
828 cmd
.Init(client_program_id_
, kLocation
, kBucketId
);
829 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
830 // Check bad program id
831 SetBucketAsCString(kBucketId
, kName
);
832 cmd
.Init(kInvalidClientId
, kLocation
, kBucketId
);
833 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
834 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
837 TEST_P(GLES2DecoderWithShaderTest
, GetAttribLocation
) {
838 const uint32 kBucketId
= 123;
839 const char* kNonExistentName
= "foobar";
840 typedef GetAttribLocation::Result Result
;
841 Result
* result
= GetSharedMemoryAs
<Result
*>();
842 SetBucketAsCString(kBucketId
, kAttrib2Name
);
844 GetAttribLocation cmd
;
845 cmd
.Init(client_program_id_
, kBucketId
, kSharedMemoryId
, kSharedMemoryOffset
);
846 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
847 EXPECT_EQ(kAttrib2Location
, *result
);
848 SetBucketAsCString(kBucketId
, kNonExistentName
);
850 cmd
.Init(client_program_id_
, kBucketId
, kSharedMemoryId
, kSharedMemoryOffset
);
851 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
852 EXPECT_EQ(-1, *result
);
855 TEST_P(GLES2DecoderWithShaderTest
, GetAttribLocationInvalidArgs
) {
856 const uint32 kBucketId
= 123;
857 typedef GetAttribLocation::Result Result
;
858 Result
* result
= GetSharedMemoryAs
<Result
*>();
860 GetAttribLocation cmd
;
862 cmd
.Init(client_program_id_
, kBucketId
, kSharedMemoryId
, kSharedMemoryOffset
);
863 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
864 EXPECT_EQ(-1, *result
);
865 // Check bad program id.
866 SetBucketAsCString(kBucketId
, kAttrib2Name
);
867 cmd
.Init(kInvalidClientId
, kBucketId
, kSharedMemoryId
, kSharedMemoryOffset
);
869 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
870 EXPECT_EQ(-1, *result
);
871 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
873 cmd
.Init(client_program_id_
,
875 kInvalidSharedMemoryId
,
876 kSharedMemoryOffset
);
877 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
878 cmd
.Init(client_program_id_
,
881 kInvalidSharedMemoryOffset
);
882 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
885 TEST_P(GLES2DecoderWithShaderTest
, GetUniformLocation
) {
886 const uint32 kBucketId
= 123;
887 const char* kNonExistentName
= "foobar";
888 typedef GetUniformLocation::Result Result
;
889 Result
* result
= GetSharedMemoryAs
<Result
*>();
890 SetBucketAsCString(kBucketId
, kUniform2Name
);
892 GetUniformLocation cmd
;
893 cmd
.Init(client_program_id_
, kBucketId
, kSharedMemoryId
, kSharedMemoryOffset
);
894 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
895 EXPECT_EQ(kUniform2FakeLocation
, *result
);
896 SetBucketAsCString(kBucketId
, kNonExistentName
);
898 cmd
.Init(client_program_id_
, kBucketId
, kSharedMemoryId
, kSharedMemoryOffset
);
899 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
900 EXPECT_EQ(-1, *result
);
903 TEST_P(GLES2DecoderWithShaderTest
, GetUniformLocationInvalidArgs
) {
904 const uint32 kBucketId
= 123;
905 typedef GetUniformLocation::Result Result
;
906 Result
* result
= GetSharedMemoryAs
<Result
*>();
908 GetUniformLocation cmd
;
910 cmd
.Init(client_program_id_
, kBucketId
, kSharedMemoryId
, kSharedMemoryOffset
);
911 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
912 EXPECT_EQ(-1, *result
);
913 // Check bad program id.
914 SetBucketAsCString(kBucketId
, kUniform2Name
);
915 cmd
.Init(kInvalidClientId
, kBucketId
, kSharedMemoryId
, kSharedMemoryOffset
);
917 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
918 EXPECT_EQ(-1, *result
);
919 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
921 cmd
.Init(client_program_id_
,
923 kInvalidSharedMemoryId
,
924 kSharedMemoryOffset
);
925 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
926 cmd
.Init(client_program_id_
,
929 kInvalidSharedMemoryOffset
);
930 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
933 TEST_P(GLES2DecoderWithShaderTest
, BindUniformLocationCHROMIUMBucket
) {
934 const uint32 kBucketId
= 123;
935 const GLint kLocation
= 2;
936 const char* kName
= "testing";
937 const char* kBadName1
= "gl_testing";
938 const char* kBadName2
= "testing[1]";
940 SetBucketAsCString(kBucketId
, kName
);
941 BindUniformLocationCHROMIUMBucket cmd
;
942 cmd
.Init(client_program_id_
,
945 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
946 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
947 // check negative location
948 SetBucketAsCString(kBucketId
, kName
);
949 cmd
.Init(client_program_id_
, -1, kBucketId
);
950 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
951 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
952 // check highest location
953 SetBucketAsCString(kBucketId
, kName
);
955 (kMaxFragmentUniformVectors
+ kMaxVertexUniformVectors
) * 4 - 1;
956 cmd
.Init(client_program_id_
,
959 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
960 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
961 // check too high location
962 SetBucketAsCString(kBucketId
, kName
);
963 cmd
.Init(client_program_id_
,
966 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
967 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
968 // check bad name "gl_..."
969 SetBucketAsCString(kBucketId
, kBadName1
);
970 cmd
.Init(client_program_id_
,
973 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
974 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
975 // check bad name "name[1]" non zero
976 SetBucketAsCString(kBucketId
, kBadName2
);
977 cmd
.Init(client_program_id_
,
980 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
981 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
984 TEST_P(GLES2DecoderManualInitTest
, ClearUniformsBeforeFirstProgramUse
) {
985 CommandLine
command_line(0, NULL
);
986 command_line
.AppendSwitchASCII(
987 switches::kGpuDriverBugWorkarounds
,
988 base::IntToString(gpu::CLEAR_UNIFORMS_BEFORE_FIRST_PROGRAM_USE
));
990 init
.gl_version
= "3.0";
991 init
.has_alpha
= true;
992 init
.request_alpha
= true;
993 init
.bind_generates_resource
= true;
994 InitDecoderWithCommandLine(init
, &command_line
);
996 static AttribInfo attribs
[] = {
998 kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
,
1001 kAttrib2Name
, kAttrib2Size
, kAttrib2Type
, kAttrib2Location
,
1004 kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
,
1007 static UniformInfo uniforms
[] = {
1008 {kUniform1Name
, kUniform1Size
, kUniform1Type
, kUniform1FakeLocation
,
1009 kUniform1RealLocation
, kUniform1DesiredLocation
},
1010 {kUniform2Name
, kUniform2Size
, kUniform2Type
, kUniform2FakeLocation
,
1011 kUniform2RealLocation
, kUniform2DesiredLocation
},
1012 {kUniform3Name
, kUniform3Size
, kUniform3Type
, kUniform3FakeLocation
,
1013 kUniform3RealLocation
, kUniform3DesiredLocation
},
1015 SetupShader(attribs
,
1018 arraysize(uniforms
),
1021 client_vertex_shader_id_
,
1022 kServiceVertexShaderId
,
1023 client_fragment_shader_id_
,
1024 kServiceFragmentShaderId
);
1025 TestHelper::SetupExpectationsForClearingUniforms(
1026 gl_
.get(), uniforms
, arraysize(uniforms
));
1030 EXPECT_CALL(*gl_
, UseProgram(kServiceProgramId
))
1032 .RetiresOnSaturation();
1033 cmds::UseProgram cmd
;
1034 cmd
.Init(client_program_id_
);
1035 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1039 // TODO(gman): DeleteProgram
1041 // TODO(gman): UseProgram
1043 // TODO(gman): DeleteShader
1045 } // namespace gles2