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.
4
5#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6
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"
20
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"
31
32#if !defined(GL_DEPTH24_STENCIL8)
33#define GL_DEPTH24_STENCIL8 0x88F0
34#endif
35
36using ::gfx::MockGLInterface;
37using ::testing::_;
38using ::testing::DoAll;
39using ::testing::InSequence;
40using ::testing::Invoke;
41using ::testing::MatcherCast;
42using ::testing::Mock;
43using ::testing::Pointee;
44using ::testing::Return;
45using ::testing::SaveArg;
46using ::testing::SetArrayArgument;
47using ::testing::SetArgumentPointee;
48using ::testing::SetArgPointee;
49using ::testing::StrEq;
50using ::testing::StrictMock;
51
52namespace gpu {
53namespace gles2 {
54
55using namespace cmds;
56
57TEST_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);
64}
65
66TEST_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);
83}
84
85TEST_P(GLES2DecoderWithShaderTest, GetUniformivSucceeds) {
86  GetUniformiv::Result* result =
87      static_cast<GetUniformiv::Result*>(shared_memory_address_);
88  result->size = 0;
89  GetUniformiv cmd;
90  cmd.Init(client_program_id_,
91           kUniform2FakeLocation,
92           kSharedMemoryId,
93           kSharedMemoryOffset);
94  EXPECT_CALL(*gl_, GetUniformiv(kServiceProgramId, kUniform2RealLocation, _))
95      .Times(1);
96  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
97  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
98            result->size);
99}
100
101TEST_P(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) {
102  GetUniformiv::Result* result =
103      static_cast<GetUniformiv::Result*>(shared_memory_address_);
104  result->size = 0;
105  GetUniformiv cmd;
106  cmd.Init(client_program_id_,
107           kUniform2ElementFakeLocation,
108           kSharedMemoryId,
109           kSharedMemoryOffset);
110  EXPECT_CALL(*gl_,
111              GetUniformiv(kServiceProgramId, kUniform2ElementRealLocation, _))
112      .Times(1);
113  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
114  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
115            result->size);
116}
117
118TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) {
119  GetUniformiv::Result* result =
120      static_cast<GetUniformiv::Result*>(shared_memory_address_);
121  result->size = 0;
122  GetUniformiv cmd;
123  // non-existant program
124  cmd.Init(kInvalidClientId,
125           kUniform2FakeLocation,
126           kSharedMemoryId,
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
133// this case.
134#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
135  result->size = kInitialResult;
136  cmd.Init(client_shader_id_,
137           kUniform2FakeLocation,
138           kSharedMemoryId,
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
144  // Unlinked program
145  EXPECT_CALL(*gl_, CreateProgram())
146      .Times(1)
147      .WillOnce(Return(kNewServiceId))
148      .RetiresOnSaturation();
149  CreateProgram cmd2;
150  cmd2.Init(kNewClientId);
151  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
152  result->size = kInitialResult;
153  cmd.Init(kNewClientId,
154           kUniform2FakeLocation,
155           kSharedMemoryId,
156           kSharedMemoryOffset);
157  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
158  EXPECT_EQ(0U, result->size);
159  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
160}
161
162TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadLocationFails) {
163  GetUniformiv::Result* result =
164      static_cast<GetUniformiv::Result*>(shared_memory_address_);
165  result->size = 0;
166  GetUniformiv cmd;
167  // invalid location
168  cmd.Init(client_program_id_,
169           kInvalidUniformLocation,
170           kSharedMemoryId,
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());
176}
177
178TEST_P(GLES2DecoderWithShaderTest, GetUniformivBadSharedMemoryFails) {
179  GetUniformiv cmd;
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,
188           kSharedMemoryId,
189           kInvalidSharedMemoryOffset);
190  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
191};
192
193TEST_P(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) {
194  GetUniformfv::Result* result =
195      static_cast<GetUniformfv::Result*>(shared_memory_address_);
196  result->size = 0;
197  GetUniformfv cmd;
198  cmd.Init(client_program_id_,
199           kUniform2FakeLocation,
200           kSharedMemoryId,
201           kSharedMemoryOffset);
202  EXPECT_CALL(*gl_, GetUniformfv(kServiceProgramId, kUniform2RealLocation, _))
203      .Times(1);
204  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
205  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
206            result->size);
207}
208
209TEST_P(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) {
210  GetUniformfv::Result* result =
211      static_cast<GetUniformfv::Result*>(shared_memory_address_);
212  result->size = 0;
213  GetUniformfv cmd;
214  cmd.Init(client_program_id_,
215           kUniform2ElementFakeLocation,
216           kSharedMemoryId,
217           kSharedMemoryOffset);
218  EXPECT_CALL(*gl_,
219              GetUniformfv(kServiceProgramId, kUniform2ElementRealLocation, _))
220      .Times(1);
221  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
222  EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
223            result->size);
224}
225
226TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) {
227  GetUniformfv::Result* result =
228      static_cast<GetUniformfv::Result*>(shared_memory_address_);
229  result->size = 0;
230  GetUniformfv cmd;
231  // non-existant program
232  cmd.Init(kInvalidClientId,
233           kUniform2FakeLocation,
234           kSharedMemoryId,
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
241// this case.
242#if GLES2_TEST_SHADER_VS_PROGRAM_IDS
243  result->size = kInitialResult;
244  cmd.Init(client_shader_id_,
245           kUniform2FakeLocation,
246           kSharedMemoryId,
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
252  // Unlinked program
253  EXPECT_CALL(*gl_, CreateProgram())
254      .Times(1)
255      .WillOnce(Return(kNewServiceId))
256      .RetiresOnSaturation();
257  CreateProgram cmd2;
258  cmd2.Init(kNewClientId);
259  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
260  result->size = kInitialResult;
261  cmd.Init(kNewClientId,
262           kUniform2FakeLocation,
263           kSharedMemoryId,
264           kSharedMemoryOffset);
265  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
266  EXPECT_EQ(0U, result->size);
267  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
268}
269
270TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadLocationFails) {
271  GetUniformfv::Result* result =
272      static_cast<GetUniformfv::Result*>(shared_memory_address_);
273  result->size = 0;
274  GetUniformfv cmd;
275  // invalid location
276  cmd.Init(client_program_id_,
277           kInvalidUniformLocation,
278           kSharedMemoryId,
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());
284}
285
286TEST_P(GLES2DecoderWithShaderTest, GetUniformfvBadSharedMemoryFails) {
287  GetUniformfv cmd;
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,
296           kSharedMemoryId,
297           kInvalidSharedMemoryOffset);
298  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
299};
300
301TEST_P(GLES2DecoderWithShaderTest, GetAttachedShadersSucceeds) {
302  GetAttachedShaders cmd;
303  typedef GetAttachedShaders::Result Result;
304  Result* result = static_cast<Result*>(shared_memory_address_);
305  result->size = 0;
306  EXPECT_CALL(*gl_, GetAttachedShaders(kServiceProgramId, 1, _, _)).WillOnce(
307      DoAll(SetArgumentPointee<2>(1), SetArgumentPointee<3>(kServiceShaderId)));
308  cmd.Init(client_program_id_,
309           shared_memory_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());
316}
317
318TEST_P(GLES2DecoderWithShaderTest, GetAttachedShadersResultNotInitFail) {
319  GetAttachedShaders cmd;
320  typedef GetAttachedShaders::Result Result;
321  Result* result = static_cast<Result*>(shared_memory_address_);
322  result->size = 1;
323  EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _)).Times(0);
324  cmd.Init(client_program_id_,
325           shared_memory_id_,
326           shared_memory_offset_,
327           Result::ComputeSize(1));
328  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
329}
330
331TEST_P(GLES2DecoderWithShaderTest, GetAttachedShadersBadProgramFails) {
332  GetAttachedShaders cmd;
333  typedef GetAttachedShaders::Result Result;
334  Result* result = static_cast<Result*>(shared_memory_address_);
335  result->size = 0;
336  EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _)).Times(0);
337  cmd.Init(kInvalidClientId,
338           shared_memory_id_,
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());
344}
345
346TEST_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_,
356           shared_memory_id_,
357           kInvalidSharedMemoryOffset,
358           Result::ComputeSize(1));
359  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
360}
361
362TEST_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_);
367  result->success = 0;
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,
375           GL_HIGH_FLOAT,
376           shared_memory_id_,
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());
384}
385
386TEST_P(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatResultNotInitFails) {
387  GetShaderPrecisionFormat cmd;
388  typedef GetShaderPrecisionFormat::Result Result;
389  Result* result = static_cast<Result*>(shared_memory_address_);
390  result->success = 1;
391  // NOTE: GL might not be called. There is no Desktop OpenGL equivalent
392  cmd.Init(GL_VERTEX_SHADER,
393           GL_HIGH_FLOAT,
394           shared_memory_id_,
395           shared_memory_offset_);
396  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
397}
398
399TEST_P(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatBadArgsFails) {
400  typedef GetShaderPrecisionFormat::Result Result;
401  Result* result = static_cast<Result*>(shared_memory_address_);
402  result->success = 0;
403  GetShaderPrecisionFormat cmd;
404  cmd.Init(
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());
408  result->success = 0;
409  cmd.Init(GL_VERTEX_SHADER,
410           GL_TEXTURE_2D,
411           shared_memory_id_,
412           shared_memory_offset_);
413  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
414  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
415}
416
417TEST_P(GLES2DecoderWithShaderTest,
418       GetShaderPrecisionFormatBadSharedMemoryFails) {
419  GetShaderPrecisionFormat cmd;
420  cmd.Init(GL_VERTEX_SHADER,
421           GL_HIGH_FLOAT,
422           kInvalidSharedMemoryId,
423           shared_memory_offset_);
424  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
425  cmd.Init(GL_VERTEX_SHADER,
426           GL_TEXTURE_2D,
427           shared_memory_id_,
428           kInvalidSharedMemoryOffset);
429  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
430}
431
432TEST_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_);
438  result->success = 0;
439  cmd.Init(client_program_id_,
440           kUniformIndex,
441           kBucketId,
442           shared_memory_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);
451  EXPECT_EQ(
452      0,
453      memcmp(
454          bucket->GetData(0, bucket->size()), kUniform2Name, bucket->size()));
455}
456
457TEST_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_);
463  result->success = 1;
464  cmd.Init(client_program_id_,
465           kUniformIndex,
466           kBucketId,
467           shared_memory_id_,
468           shared_memory_offset_);
469  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
470}
471
472TEST_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_);
478  result->success = 0;
479  cmd.Init(kInvalidClientId,
480           kUniformIndex,
481           kBucketId,
482           shared_memory_id_,
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
488  result->success = 0;
489  cmd.Init(client_shader_id_,
490           kUniformIndex,
491           kBucketId,
492           shared_memory_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
498}
499
500TEST_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_);
505  result->success = 0;
506  cmd.Init(client_program_id_,
507           kBadUniformIndex,
508           kBucketId,
509           shared_memory_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());
514}
515
516TEST_P(GLES2DecoderWithShaderTest, GetActiveUniformBadSharedMemoryFails) {
517  const GLuint kUniformIndex = 1;
518  const uint32 kBucketId = 123;
519  GetActiveUniform cmd;
520  cmd.Init(client_program_id_,
521           kUniformIndex,
522           kBucketId,
523           kInvalidSharedMemoryId,
524           shared_memory_offset_);
525  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
526  cmd.Init(client_program_id_,
527           kUniformIndex,
528           kBucketId,
529           shared_memory_id_,
530           kInvalidSharedMemoryOffset);
531  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
532}
533
534TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribSucceeds) {
535  const GLuint kAttribIndex = 1;
536  const uint32 kBucketId = 123;
537  GetActiveAttrib cmd;
538  typedef GetActiveAttrib::Result Result;
539  Result* result = static_cast<Result*>(shared_memory_address_);
540  result->success = 0;
541  cmd.Init(client_program_id_,
542           kAttribIndex,
543           kBucketId,
544           shared_memory_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);
553  EXPECT_EQ(
554      0,
555      memcmp(bucket->GetData(0, bucket->size()), kAttrib2Name, bucket->size()));
556}
557
558TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribResultNotInitFails) {
559  const GLuint kAttribIndex = 1;
560  const uint32 kBucketId = 123;
561  GetActiveAttrib cmd;
562  typedef GetActiveAttrib::Result Result;
563  Result* result = static_cast<Result*>(shared_memory_address_);
564  result->success = 1;
565  cmd.Init(client_program_id_,
566           kAttribIndex,
567           kBucketId,
568           shared_memory_id_,
569           shared_memory_offset_);
570  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
571}
572
573TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribBadProgramFails) {
574  const GLuint kAttribIndex = 1;
575  const uint32 kBucketId = 123;
576  GetActiveAttrib cmd;
577  typedef GetActiveAttrib::Result Result;
578  Result* result = static_cast<Result*>(shared_memory_address_);
579  result->success = 0;
580  cmd.Init(kInvalidClientId,
581           kAttribIndex,
582           kBucketId,
583           shared_memory_id_,
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
589  result->success = 0;
590  cmd.Init(client_shader_id_,
591           kAttribIndex,
592           kBucketId,
593           shared_memory_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
599}
600
601TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribBadIndexFails) {
602  const uint32 kBucketId = 123;
603  GetActiveAttrib cmd;
604  typedef GetActiveAttrib::Result Result;
605  Result* result = static_cast<Result*>(shared_memory_address_);
606  result->success = 0;
607  cmd.Init(client_program_id_,
608           kBadAttribIndex,
609           kBucketId,
610           shared_memory_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());
615}
616
617TEST_P(GLES2DecoderWithShaderTest, GetActiveAttribBadSharedMemoryFails) {
618  const GLuint kAttribIndex = 1;
619  const uint32 kBucketId = 123;
620  GetActiveAttrib cmd;
621  cmd.Init(client_program_id_,
622           kAttribIndex,
623           kBucketId,
624           kInvalidSharedMemoryId,
625           shared_memory_offset_);
626  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
627  cmd.Init(client_program_id_,
628           kAttribIndex,
629           kBucketId,
630           shared_memory_id_,
631           kInvalidSharedMemoryOffset);
632  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
633}
634
635TEST_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());
658  EXPECT_EQ(0,
659            memcmp(bucket->GetData(0, bucket->size()), kInfo, bucket->size()));
660  EXPECT_EQ(GL_NO_ERROR, GetGLError());
661}
662
663TEST_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());
669}
670
671TEST_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();
677  CompileShader cmd;
678  cmd.Init(client_shader_id_);
679  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
680}
681
682TEST_P(GLES2DecoderTest, CompileShaderInvalidArgs) {
683  CompileShader cmd;
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
692}
693
694TEST_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));
703  ClearSharedMemory();
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());
710  EXPECT_EQ(
711      0, memcmp(bucket->GetData(0, bucket->size()), kSource, bucket->size()));
712}
713
714TEST_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;
720  // Test no bucket.
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);
730  cmd.Init(
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
735}
736
737TEST_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());
745}
746
747TEST_P(GLES2DecoderWithShaderTest, Uniform1iValidArgs) {
748  EXPECT_CALL(*gl_, Uniform1i(kUniform1RealLocation, 2));
749  Uniform1i cmd;
750  cmd.Init(kUniform1FakeLocation, 2);
751  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
752}
753
754TEST_P(GLES2DecoderWithShaderTest, Uniform1ivImmediateValidArgs) {
755  Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
756  EXPECT_CALL(*gl_,
757              Uniform1iv(kUniform1RealLocation,
758                         1,
759                         reinterpret_cast<GLint*>(ImmediateDataAddress(&cmd))));
760  GLint temp[1 * 2] = {
761      0,
762  };
763  cmd.Init(kUniform1FakeLocation, 1, &temp[0]);
764  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
765}
766
767TEST_P(GLES2DecoderWithShaderTest, Uniform1ivImmediateInvalidValidArgs) {
768  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
769  Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
770  GLint temp[1 * 2] = {
771      0,
772  };
773  cmd.Init(kUniform1FakeLocation, 2, &temp[0]);
774  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
775  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
776}
777
778TEST_P(GLES2DecoderWithShaderTest, Uniform1ivZeroCount) {
779  EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
780  Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
781  GLint temp = 0;
782  cmd.Init(kUniform1FakeLocation, 0, &temp);
783  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
784  EXPECT_EQ(GL_NO_ERROR, GetGLError());
785}
786
787TEST_P(GLES2DecoderWithShaderTest, Uniform1iSamplerIsLmited) {
788  EXPECT_CALL(*gl_, Uniform1i(_, _)).Times(0);
789  Uniform1i cmd;
790  cmd.Init(kUniform1FakeLocation, kNumTextureUnits);
791  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
792  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
793}
794
795TEST_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());
802}
803
804TEST_P(GLES2DecoderTest, BindAttribLocationBucket) {
805  const uint32 kBucketId = 123;
806  const GLint kLocation = 2;
807  const char* kName = "testing";
808  EXPECT_CALL(*gl_,
809              BindAttribLocation(kServiceProgramId, kLocation, StrEq(kName)))
810      .Times(1);
811  SetBucketAsCString(kBucketId, kName);
812  BindAttribLocationBucket cmd;
813  cmd.Init(client_program_id_, kLocation, kBucketId);
814  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
815}
816
817TEST_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());
835}
836
837TEST_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);
843  *result = -1;
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);
849  *result = -1;
850  cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
851  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
852  EXPECT_EQ(-1, *result);
853}
854
855TEST_P(GLES2DecoderWithShaderTest, GetAttribLocationInvalidArgs) {
856  const uint32 kBucketId = 123;
857  typedef GetAttribLocation::Result Result;
858  Result* result = GetSharedMemoryAs<Result*>();
859  *result = -1;
860  GetAttribLocation cmd;
861  // Check no bucket
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);
868  *result = -1;
869  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
870  EXPECT_EQ(-1, *result);
871  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
872  // Check bad memory
873  cmd.Init(client_program_id_,
874           kBucketId,
875           kInvalidSharedMemoryId,
876           kSharedMemoryOffset);
877  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
878  cmd.Init(client_program_id_,
879           kBucketId,
880           kSharedMemoryId,
881           kInvalidSharedMemoryOffset);
882  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
883}
884
885TEST_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);
891  *result = -1;
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);
897  *result = -1;
898  cmd.Init(client_program_id_, kBucketId, kSharedMemoryId, kSharedMemoryOffset);
899  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
900  EXPECT_EQ(-1, *result);
901}
902
903TEST_P(GLES2DecoderWithShaderTest, GetUniformLocationInvalidArgs) {
904  const uint32 kBucketId = 123;
905  typedef GetUniformLocation::Result Result;
906  Result* result = GetSharedMemoryAs<Result*>();
907  *result = -1;
908  GetUniformLocation cmd;
909  // Check no bucket
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);
916  *result = -1;
917  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
918  EXPECT_EQ(-1, *result);
919  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
920  // Check bad memory
921  cmd.Init(client_program_id_,
922           kBucketId,
923           kInvalidSharedMemoryId,
924           kSharedMemoryOffset);
925  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
926  cmd.Init(client_program_id_,
927           kBucketId,
928           kSharedMemoryId,
929           kInvalidSharedMemoryOffset);
930  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
931}
932
933TEST_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]";
939
940  SetBucketAsCString(kBucketId, kName);
941  BindUniformLocationCHROMIUMBucket cmd;
942  cmd.Init(client_program_id_,
943           kLocation,
944           kBucketId);
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);
954  GLint kMaxLocation =
955      (kMaxFragmentUniformVectors + kMaxVertexUniformVectors) * 4 - 1;
956  cmd.Init(client_program_id_,
957           kMaxLocation,
958           kBucketId);
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_,
964           kMaxLocation + 1,
965           kBucketId);
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_,
971           kLocation,
972           kBucketId);
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_,
978           kLocation,
979           kBucketId);
980  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
981  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
982}
983
984TEST_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));
989  InitState init;
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);
995  {
996    static AttribInfo attribs[] = {
997        {
998         kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location,
999        },
1000        {
1001         kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location,
1002        },
1003        {
1004         kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location,
1005        },
1006    };
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},
1014    };
1015    SetupShader(attribs,
1016                arraysize(attribs),
1017                uniforms,
1018                arraysize(uniforms),
1019                client_program_id_,
1020                kServiceProgramId,
1021                client_vertex_shader_id_,
1022                kServiceVertexShaderId,
1023                client_fragment_shader_id_,
1024                kServiceFragmentShaderId);
1025    TestHelper::SetupExpectationsForClearingUniforms(
1026        gl_.get(), uniforms, arraysize(uniforms));
1027  }
1028
1029  {
1030    EXPECT_CALL(*gl_, UseProgram(kServiceProgramId))
1031        .Times(1)
1032        .RetiresOnSaturation();
1033    cmds::UseProgram cmd;
1034    cmd.Init(client_program_id_);
1035    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1036  }
1037}
1038
1039// TODO(gman): DeleteProgram
1040
1041// TODO(gman): UseProgram
1042
1043// TODO(gman): DeleteShader
1044
1045}  // namespace gles2
1046}  // namespace gpu
1047