- add sources.
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / service / gles2_cmd_decoder_unittest.cc
1 // Copyright (c) 2012 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/atomicops.h"
8 #include "gpu/command_buffer/common/gles2_cmd_format.h"
9 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
10 #include "gpu/command_buffer/common/id_allocator.h"
11 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
12 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
13 #include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
14 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
15 #include "gpu/command_buffer/service/context_group.h"
16 #include "gpu/command_buffer/service/gl_surface_mock.h"
17 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.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/stream_texture_manager_mock.h"
23 #include "gpu/command_buffer/service/stream_texture_mock.h"
24 #include "gpu/command_buffer/service/test_helper.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gl/gl_implementation.h"
27 #include "ui/gl/gl_mock.h"
28 #include "ui/gl/gl_surface_stub.h"
29
30
31 #if !defined(GL_DEPTH24_STENCIL8)
32 #define GL_DEPTH24_STENCIL8 0x88F0
33 #endif
34
35 using ::gfx::MockGLInterface;
36 using ::testing::_;
37 using ::testing::DoAll;
38 using ::testing::InSequence;
39 using ::testing::Invoke;
40 using ::testing::MatcherCast;
41 using ::testing::Pointee;
42 using ::testing::Return;
43 using ::testing::SaveArg;
44 using ::testing::SetArrayArgument;
45 using ::testing::SetArgumentPointee;
46 using ::testing::SetArgPointee;
47 using ::testing::StrEq;
48 using ::testing::StrictMock;
49
50 namespace gpu {
51 namespace gles2 {
52
53 using namespace cmds;
54
55 class GLES2DecoderTest : public GLES2DecoderTestBase {
56  public:
57   GLES2DecoderTest() { }
58
59  protected:
60   void CheckReadPixelsOutOfRange(
61       GLint in_read_x, GLint in_read_y,
62       GLsizei in_read_width, GLsizei in_read_height,
63       bool init);
64 };
65
66 class GLES2DecoderANGLETest : public GLES2DecoderTestBase {
67  public:
68   GLES2DecoderANGLETest()
69       : GLES2DecoderTestBase() {
70     GLES2Decoder::set_testing_force_is_angle(true);
71   }
72
73   virtual ~GLES2DecoderANGLETest() {
74     GLES2Decoder::set_testing_force_is_angle(false);
75   }
76 };
77
78 class GLES2DecoderWithShaderTest : public GLES2DecoderWithShaderTestBase {
79  public:
80   GLES2DecoderWithShaderTest()
81       : GLES2DecoderWithShaderTestBase() {
82   }
83
84   void CheckTextureChangesMarkFBOAsNotComplete(bool bound_fbo);
85   void CheckRenderbufferChangesMarkFBOAsNotComplete(bool bound_fbo);
86 };
87
88 class GLES2DecoderGeometryInstancingTest : public GLES2DecoderWithShaderTest {
89  public:
90   GLES2DecoderGeometryInstancingTest()
91       : GLES2DecoderWithShaderTest() {
92   }
93
94   virtual void SetUp() {
95     InitDecoder(
96         "GL_ANGLE_instanced_arrays", // extensions
97         true,                        // has alpha
98         true,                        // has depth
99         false,                       // has stencil
100         true,                        // request alpha
101         true,                        // request depth
102         false,                       // request stencil
103         true);                       // bind generates resource
104     SetupDefaultProgram();
105   }
106 };
107
108 class GLES2DecoderRGBBackbufferTest : public GLES2DecoderWithShaderTest {
109  public:
110   GLES2DecoderRGBBackbufferTest() { }
111
112   virtual void SetUp() {
113     InitDecoder(
114         "",     // extensions
115         false,  // has alpha
116         false,  // has depth
117         false,  // has stencil
118         false,  // request alpha
119         false,  // request depth
120         false,  // request stencil
121         true);   // bind generates resource
122     SetupDefaultProgram();
123   }
124 };
125
126 class GLES2DecoderManualInitTest : public GLES2DecoderWithShaderTest {
127  public:
128   GLES2DecoderManualInitTest() { }
129
130   // Override default setup so nothing gets setup.
131   virtual void SetUp() {
132   }
133 };
134
135 class GLES2DecoderANGLEManualInitTest : public GLES2DecoderANGLETest {
136  public:
137   // Override default setup so nothing gets setup.
138   virtual void SetUp() {
139   }
140 };
141
142 TEST_F(GLES2DecoderWithShaderTest, DrawArraysNoAttributesSucceeds) {
143   SetupTexture();
144   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
145   SetupExpectationsForApplyingDefaultDirtyState();
146
147   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
148       .Times(1)
149       .RetiresOnSaturation();
150   DrawArrays cmd;
151   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
152   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
153   EXPECT_EQ(GL_NO_ERROR, GetGLError());
154 }
155
156 // Tests when the math overflows (0x40000000 * sizeof GLfloat)
157 TEST_F(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0OverflowFails) {
158   const GLsizei kLargeCount = 0x40000000;
159   SetupTexture();
160   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
161       .Times(0)
162       .RetiresOnSaturation();
163   DrawArrays cmd;
164   cmd.Init(GL_TRIANGLES, 0, kLargeCount);
165   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
166   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
167 }
168
169 // Tests when the math overflows (0x7FFFFFFF + 1 = 0x8000000 verts)
170 TEST_F(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0PosToNegFails) {
171   const GLsizei kLargeCount = 0x7FFFFFFF;
172   SetupTexture();
173   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
174       .Times(0)
175       .RetiresOnSaturation();
176   DrawArrays cmd;
177   cmd.Init(GL_TRIANGLES, 0, kLargeCount);
178   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
179   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
180 }
181
182 // Tests when the driver returns an error
183 TEST_F(GLES2DecoderWithShaderTest, DrawArraysSimulatedAttrib0OOMFails) {
184   const GLsizei kFakeLargeCount = 0x1234;
185   SetupTexture();
186   AddExpectationsForSimulatedAttrib0WithError(
187       kFakeLargeCount, 0, GL_OUT_OF_MEMORY);
188   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
189       .Times(0)
190       .RetiresOnSaturation();
191   DrawArrays cmd;
192   cmd.Init(GL_TRIANGLES, 0, kFakeLargeCount);
193   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
194   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
195 }
196
197 TEST_F(GLES2DecoderWithShaderTest, DrawArraysBadTextureUsesBlack) {
198   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
199   // This is an NPOT texture. As the default filtering requires mips
200   // this should trigger replacing with black textures before rendering.
201   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
202                kSharedMemoryId, kSharedMemoryOffset);
203   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
204   {
205     InSequence sequence;
206     EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
207         .Times(1)
208         .RetiresOnSaturation();
209     EXPECT_CALL(*gl_, BindTexture(
210         GL_TEXTURE_2D, TestHelper::kServiceBlackTexture2dId))
211         .Times(1)
212         .RetiresOnSaturation();
213     EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
214         .Times(1)
215         .RetiresOnSaturation();
216     EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
217         .Times(1)
218         .RetiresOnSaturation();
219     EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
220         .Times(1)
221         .RetiresOnSaturation();
222     EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
223         .Times(1)
224         .RetiresOnSaturation();
225   }
226   SetupExpectationsForApplyingDefaultDirtyState();
227   DrawArrays cmd;
228   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
229   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
230   EXPECT_EQ(GL_NO_ERROR, GetGLError());
231 }
232
233 TEST_F(GLES2DecoderWithShaderTest, DrawArraysMissingAttributesFails) {
234   DoEnableVertexAttribArray(1);
235
236   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
237       .Times(0);
238   DrawArrays cmd;
239   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
240   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
241   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
242 }
243
244 TEST_F(GLES2DecoderWithShaderTest,
245        DrawArraysMissingAttributesZeroCountSucceeds) {
246   DoEnableVertexAttribArray(1);
247
248   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
249       .Times(0);
250   DrawArrays cmd;
251   cmd.Init(GL_TRIANGLES, 0, 0);
252   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
253   EXPECT_EQ(GL_NO_ERROR, GetGLError());
254 }
255
256 TEST_F(GLES2DecoderWithShaderTest, DrawArraysValidAttributesSucceeds) {
257   SetupTexture();
258   SetupVertexBuffer();
259   DoEnableVertexAttribArray(1);
260   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
261   AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
262   SetupExpectationsForApplyingDefaultDirtyState();
263
264   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
265       .Times(1)
266       .RetiresOnSaturation();
267   DrawArrays cmd;
268   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
269   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
270   EXPECT_EQ(GL_NO_ERROR, GetGLError());
271 }
272
273 TEST_F(GLES2DecoderWithShaderTest, DrawArraysDeletedBufferFails) {
274   SetupVertexBuffer();
275   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
276   DeleteVertexBuffer();
277
278   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
279       .Times(0);
280   DrawArrays cmd;
281   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
282   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
283   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
284 }
285
286 TEST_F(GLES2DecoderWithShaderTest, DrawArraysDeletedProgramSucceeds) {
287   SetupTexture();
288   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
289   SetupExpectationsForApplyingDefaultDirtyState();
290   DoDeleteProgram(client_program_id_, kServiceProgramId);
291
292   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
293       .Times(1)
294       .RetiresOnSaturation();
295   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
296       .Times(1);
297   DrawArrays cmd;
298   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
299   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
300   EXPECT_EQ(GL_NO_ERROR, GetGLError());
301 }
302
303 TEST_F(GLES2DecoderWithShaderTest, DrawArraysWithInvalidModeFails) {
304   SetupVertexBuffer();
305   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
306
307   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
308       .Times(0);
309   DrawArrays cmd;
310   cmd.Init(GL_QUADS, 0, 1);
311   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
312   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
313   cmd.Init(GL_POLYGON, 0, 1);
314   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
315   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
316 }
317
318 TEST_F(GLES2DecoderWithShaderTest, DrawArraysInvalidCountFails) {
319   SetupVertexBuffer();
320   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
321
322   // Try start > 0
323   EXPECT_CALL(*gl_, DrawArrays(_, _, _)).Times(0);
324   DrawArrays cmd;
325   cmd.Init(GL_TRIANGLES, 1, kNumVertices);
326   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
327   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
328   EXPECT_EQ(GL_NO_ERROR, GetGLError());
329
330   // Try with count > size
331   cmd.Init(GL_TRIANGLES, 0, kNumVertices + 1);
332   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
333   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
334   EXPECT_EQ(GL_NO_ERROR, GetGLError());
335
336   // Try with attrib offset > 0
337   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
338   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 4);
339   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
340   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
341   EXPECT_EQ(GL_NO_ERROR, GetGLError());
342
343   // Try with size > 2 (ie, vec3 instead of vec2)
344   DoVertexAttribPointer(1, 3, GL_FLOAT, 0, 0);
345   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
346   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
347   EXPECT_EQ(GL_NO_ERROR, GetGLError());
348
349   // Try with stride > 8 (vec2 + vec2 byte)
350   DoVertexAttribPointer(1, 2, GL_FLOAT, sizeof(GLfloat) * 3, 0);
351   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
352   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
353   EXPECT_EQ(GL_NO_ERROR, GetGLError());
354 }
355
356 TEST_F(GLES2DecoderWithShaderTest, DrawArraysInstancedANGLEFails) {
357   SetupTexture();
358   SetupVertexBuffer();
359   DoEnableVertexAttribArray(1);
360   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
361
362   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
363       .Times(0)
364       .RetiresOnSaturation();
365   DrawArraysInstancedANGLE cmd;
366   cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
367   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
368   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
369 }
370
371 TEST_F(GLES2DecoderGeometryInstancingTest,
372        DrawArraysInstancedANGLENoAttributesFails) {
373   SetupTexture();
374
375   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
376       .Times(0)
377       .RetiresOnSaturation();
378   DrawArraysInstancedANGLE cmd;
379   cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
380   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
381   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
382 }
383
384 TEST_F(GLES2DecoderGeometryInstancingTest,
385        DrawArraysInstancedANGLESimulatedAttrib0) {
386   SetupTexture();
387   SetupVertexBuffer();
388   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
389
390   AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
391   SetupExpectationsForApplyingDefaultDirtyState();
392
393   DoVertexAttribDivisorANGLE(0, 1);
394   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices, 3))
395       .Times(1)
396       .RetiresOnSaturation();
397   EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 0))
398       .Times(1)
399       .RetiresOnSaturation();
400   EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 1))
401       .Times(1)
402       .RetiresOnSaturation();
403   DrawArraysInstancedANGLE cmd;
404   cmd.Init(GL_TRIANGLES, 0, kNumVertices, 3);
405   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
406   EXPECT_EQ(GL_NO_ERROR, GetGLError());
407 }
408
409 TEST_F(GLES2DecoderGeometryInstancingTest,
410        DrawArraysInstancedANGLEMissingAttributesFails) {
411   DoEnableVertexAttribArray(1);
412
413   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
414       .Times(0);
415   DrawArraysInstancedANGLE cmd;
416   cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
417   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
418   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
419 }
420
421 TEST_F(GLES2DecoderGeometryInstancingTest,
422        DrawArraysInstancedANGLEMissingAttributesZeroCountSucceeds) {
423   DoEnableVertexAttribArray(1);
424
425   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
426       .Times(0);
427   DrawArraysInstancedANGLE cmd;
428   cmd.Init(GL_TRIANGLES, 0, 0, 1);
429   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
430   EXPECT_EQ(GL_NO_ERROR, GetGLError());
431 }
432
433 TEST_F(GLES2DecoderGeometryInstancingTest,
434        DrawArraysInstancedANGLEValidAttributesSucceeds) {
435   SetupTexture();
436   SetupVertexBuffer();
437   DoEnableVertexAttribArray(1);
438   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
439   AddExpectationsForSimulatedAttrib0(kNumVertices, kServiceBufferId);
440   SetupExpectationsForApplyingDefaultDirtyState();
441
442   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices, 1))
443       .Times(1)
444       .RetiresOnSaturation();
445   DrawArraysInstancedANGLE cmd;
446   cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
447   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
448   EXPECT_EQ(GL_NO_ERROR, GetGLError());
449 }
450
451 TEST_F(GLES2DecoderGeometryInstancingTest,
452        DrawArraysInstancedANGLEWithInvalidModeFails) {
453   SetupVertexBuffer();
454   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
455
456   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
457       .Times(0);
458   DrawArraysInstancedANGLE cmd;
459   cmd.Init(GL_QUADS, 0, 1, 1);
460   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
461   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
462   cmd.Init(GL_POLYGON, 0, 1, 1);
463   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
464   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
465 }
466
467 TEST_F(GLES2DecoderGeometryInstancingTest,
468        DrawArraysInstancedANGLEInvalidPrimcountFails) {
469   SetupVertexBuffer();
470   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
471
472   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
473       .Times(0);
474   DrawArraysInstancedANGLE cmd;
475   cmd.Init(GL_TRIANGLES, 0, 1, -1);
476   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
477   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
478 }
479
480 // Per-instance data is twice as large, but number of instances is half
481 TEST_F(GLES2DecoderGeometryInstancingTest,
482        DrawArraysInstancedANGLELargeInstanceSucceeds) {
483   SetupTexture();
484   SetupVertexBuffer();
485   SetupExpectationsForApplyingDefaultDirtyState();
486   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
487
488   DoEnableVertexAttribArray(0);
489   DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
490   DoVertexAttribDivisorANGLE(0, 1);
491   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices,
492                                              kNumVertices / 2))
493       .Times(1)
494       .RetiresOnSaturation();
495   DrawArraysInstancedANGLE cmd;
496   cmd.Init(GL_TRIANGLES, 0, kNumVertices, kNumVertices / 2);
497   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
498   EXPECT_EQ(GL_NO_ERROR, GetGLError());
499 }
500
501 // Per-instance data is twice as large, but divisor is twice
502 TEST_F(GLES2DecoderGeometryInstancingTest,
503        DrawArraysInstancedANGLELargeDivisorSucceeds) {
504   SetupTexture();
505   SetupVertexBuffer();
506   SetupExpectationsForApplyingDefaultDirtyState();
507   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
508
509   DoEnableVertexAttribArray(0);
510   DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
511   DoVertexAttribDivisorANGLE(0, 2);
512   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices,
513                                              kNumVertices))
514       .Times(1)
515       .RetiresOnSaturation();
516   DrawArraysInstancedANGLE cmd;
517   cmd.Init(GL_TRIANGLES, 0, kNumVertices, kNumVertices);
518   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
519   EXPECT_EQ(GL_NO_ERROR, GetGLError());
520 }
521
522 TEST_F(GLES2DecoderGeometryInstancingTest, DrawArraysInstancedANGLELargeFails) {
523   SetupTexture();
524   SetupVertexBuffer();
525   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
526
527   DoEnableVertexAttribArray(0);
528   DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
529   DoVertexAttribDivisorANGLE(0, 1);
530   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
531       .Times(0)
532       .RetiresOnSaturation();
533   DrawArraysInstancedANGLE cmd;
534   cmd.Init(GL_TRIANGLES, 0, kNumVertices, kNumVertices + 1);
535   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
536   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
537   EXPECT_EQ(GL_NO_ERROR, GetGLError());
538
539   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
540       .Times(0)
541       .RetiresOnSaturation();
542   cmd.Init(GL_TRIANGLES, 0, kNumVertices + 1, kNumVertices);
543   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
544   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
545   EXPECT_EQ(GL_NO_ERROR, GetGLError());
546 }
547
548 // Per-index data is twice as large, but number of indices is half
549 TEST_F(GLES2DecoderGeometryInstancingTest,
550        DrawArraysInstancedANGLELargeIndexSucceeds) {
551   SetupTexture();
552   SetupVertexBuffer();
553   SetupExpectationsForApplyingDefaultDirtyState();
554   DoVertexAttribPointer(1, 4, GL_FLOAT, 0, 0);
555
556   DoEnableVertexAttribArray(0);
557   DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
558   DoVertexAttribDivisorANGLE(0, 1);
559   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(GL_TRIANGLES, 0, kNumVertices / 2,
560                                              kNumVertices))
561       .Times(1)
562       .RetiresOnSaturation();
563   DrawArraysInstancedANGLE cmd;
564   cmd.Init(GL_TRIANGLES, 0, kNumVertices / 2, kNumVertices);
565   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
566   EXPECT_EQ(GL_NO_ERROR, GetGLError());
567 }
568
569 TEST_F(GLES2DecoderGeometryInstancingTest,
570        DrawArraysInstancedANGLENoDivisor0Fails) {
571   SetupTexture();
572   SetupVertexBuffer();
573   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
574
575   DoEnableVertexAttribArray(0);
576   DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
577   DoVertexAttribDivisorANGLE(0, 1);
578   DoVertexAttribDivisorANGLE(1, 1);
579   EXPECT_CALL(*gl_, DrawArraysInstancedANGLE(_, _, _, _))
580       .Times(0)
581       .RetiresOnSaturation();
582   DrawArraysInstancedANGLE cmd;
583   cmd.Init(GL_TRIANGLES, 0, kNumVertices, 1);
584   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
585   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
586   EXPECT_EQ(GL_NO_ERROR, GetGLError());
587 }
588
589 TEST_F(GLES2DecoderWithShaderTest, DrawElementsNoAttributesSucceeds) {
590   SetupTexture();
591   SetupIndexBuffer();
592   AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
593   SetupExpectationsForApplyingDefaultDirtyState();
594   EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
595                                  GL_UNSIGNED_SHORT,
596                                  BufferOffset(kValidIndexRangeStart * 2)))
597       .Times(1)
598       .RetiresOnSaturation();
599   DrawElements cmd;
600   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
601            kValidIndexRangeStart * 2);
602   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
603   EXPECT_EQ(GL_NO_ERROR, GetGLError());
604 }
605
606 TEST_F(GLES2DecoderWithShaderTest, DrawElementsMissingAttributesFails) {
607   SetupIndexBuffer();
608   DoEnableVertexAttribArray(1);
609
610   EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
611       .Times(0);
612   DrawElements cmd;
613   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
614            kValidIndexRangeStart * 2);
615   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
616   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
617 }
618
619 TEST_F(GLES2DecoderWithShaderTest,
620        DrawElementsMissingAttributesZeroCountSucceeds) {
621   SetupIndexBuffer();
622   DoEnableVertexAttribArray(1);
623
624   EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
625       .Times(0);
626   DrawElements cmd;
627   cmd.Init(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT,
628            kValidIndexRangeStart * 2);
629   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
630   EXPECT_EQ(GL_NO_ERROR, GetGLError());
631 }
632
633 TEST_F(GLES2DecoderWithShaderTest, DrawElementsExtraAttributesFails) {
634   SetupIndexBuffer();
635   DoEnableVertexAttribArray(6);
636
637   EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
638       .Times(0);
639   DrawElements cmd;
640   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
641            kValidIndexRangeStart * 2);
642   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
643   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
644 }
645
646 TEST_F(GLES2DecoderWithShaderTest, DrawElementsValidAttributesSucceeds) {
647   SetupTexture();
648   SetupVertexBuffer();
649   SetupIndexBuffer();
650   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
651   AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, kServiceBufferId);
652   SetupExpectationsForApplyingDefaultDirtyState();
653
654   EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
655                                  GL_UNSIGNED_SHORT,
656                                  BufferOffset(kValidIndexRangeStart * 2)))
657       .Times(1)
658       .RetiresOnSaturation();
659   DrawElements cmd;
660   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
661            kValidIndexRangeStart * 2);
662   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
663   EXPECT_EQ(GL_NO_ERROR, GetGLError());
664 }
665
666 TEST_F(GLES2DecoderWithShaderTest, DrawElementsDeletedBufferFails) {
667   SetupVertexBuffer();
668   SetupIndexBuffer();
669   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
670   DeleteIndexBuffer();
671
672   EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
673       .Times(0);
674   DrawElements cmd;
675   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
676            kValidIndexRangeStart * 2);
677   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
678   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
679 }
680
681 TEST_F(GLES2DecoderWithShaderTest, DrawElementsDeletedProgramSucceeds) {
682   SetupTexture();
683   SetupIndexBuffer();
684   AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
685   SetupExpectationsForApplyingDefaultDirtyState();
686   DoDeleteProgram(client_program_id_, kServiceProgramId);
687
688   EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
689       .Times(1);
690   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
691       .Times(1);
692   DrawElements cmd;
693   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
694            kValidIndexRangeStart * 2);
695   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
696   EXPECT_EQ(GL_NO_ERROR, GetGLError());
697 }
698
699 TEST_F(GLES2DecoderWithShaderTest, DrawElementsWithInvalidModeFails) {
700   SetupVertexBuffer();
701   SetupIndexBuffer();
702   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
703
704   EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
705       .Times(0);
706   DrawElements cmd;
707   cmd.Init(GL_QUADS, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
708            kValidIndexRangeStart * 2);
709   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
710   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
711   cmd.Init(GL_POLYGON, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
712            kValidIndexRangeStart);
713   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
714   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
715 }
716
717 TEST_F(GLES2DecoderWithShaderTest, DrawElementsInvalidCountFails) {
718   SetupVertexBuffer();
719   SetupIndexBuffer();
720   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
721
722   // Try start > 0
723   EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
724   DrawElements cmd;
725   cmd.Init(GL_TRIANGLES, kNumIndices, GL_UNSIGNED_SHORT, 2);
726   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
727   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
728   EXPECT_EQ(GL_NO_ERROR, GetGLError());
729
730   // Try with count > size
731   cmd.Init(GL_TRIANGLES, kNumIndices + 1, GL_UNSIGNED_SHORT, 0);
732   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
733   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
734   EXPECT_EQ(GL_NO_ERROR, GetGLError());
735 }
736
737 TEST_F(GLES2DecoderWithShaderTest, DrawElementsOutOfRangeIndicesFails) {
738   SetupVertexBuffer();
739   SetupIndexBuffer();
740   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
741
742   EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
743   DrawElements cmd;
744   cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT,
745            kInvalidIndexRangeStart * 2);
746   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
747   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
748   EXPECT_EQ(GL_NO_ERROR, GetGLError());
749 }
750
751 TEST_F(GLES2DecoderWithShaderTest, DrawElementsOddOffsetForUint16Fails) {
752   SetupVertexBuffer();
753   SetupIndexBuffer();
754   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
755
756   EXPECT_CALL(*gl_, DrawElements(_, _, _, _)).Times(0);
757   DrawElements cmd;
758   cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT, 1);
759   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
760   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
761   EXPECT_EQ(GL_NO_ERROR, GetGLError());
762 }
763
764 TEST_F(GLES2DecoderWithShaderTest, DrawElementsInstancedANGLEFails) {
765   SetupTexture();
766   SetupVertexBuffer();
767   SetupIndexBuffer();
768   DoEnableVertexAttribArray(1);
769   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
770
771   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
772       .Times(0)
773       .RetiresOnSaturation();
774   DrawElementsInstancedANGLE cmd;
775   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
776            kValidIndexRangeStart * 2, 1);
777   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
778   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
779 }
780
781 TEST_F(GLES2DecoderGeometryInstancingTest,
782        DrawElementsInstancedANGLENoAttributesFails) {
783   SetupTexture();
784   SetupIndexBuffer();
785
786   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
787       .Times(0)
788       .RetiresOnSaturation();
789   DrawElementsInstancedANGLE cmd;
790   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
791            kValidIndexRangeStart * 2, 1);
792   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
793   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
794 }
795
796 TEST_F(GLES2DecoderGeometryInstancingTest,
797        DrawElementsInstancedANGLESimulatedAttrib0) {
798   SetupTexture();
799   SetupVertexBuffer();
800   SetupIndexBuffer();
801   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
802
803   AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, kServiceBufferId);
804   SetupExpectationsForApplyingDefaultDirtyState();
805
806   DoVertexAttribDivisorANGLE(0, 1);
807   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
808                         GL_TRIANGLES,
809                         kValidIndexRangeCount,
810                         GL_UNSIGNED_SHORT,
811                         BufferOffset(kValidIndexRangeStart * 2),
812                         3))
813       .Times(1)
814       .RetiresOnSaturation();
815   EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 0))
816       .Times(1)
817       .RetiresOnSaturation();
818   EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(0, 1))
819       .Times(1)
820       .RetiresOnSaturation();
821   DrawElementsInstancedANGLE cmd;
822   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
823            kValidIndexRangeStart * 2, 3);
824   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
825   EXPECT_EQ(GL_NO_ERROR, GetGLError());
826 }
827
828 TEST_F(GLES2DecoderGeometryInstancingTest,
829        DrawElementsInstancedANGLEMissingAttributesFails) {
830   SetupIndexBuffer();
831   DoEnableVertexAttribArray(1);
832
833   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
834       .Times(0);
835   DrawElementsInstancedANGLE cmd;
836   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
837            kValidIndexRangeStart * 2, 1);
838   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
839   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
840 }
841
842 TEST_F(GLES2DecoderGeometryInstancingTest,
843        DrawElementsInstancedANGLEMissingAttributesZeroCountSucceeds) {
844   SetupIndexBuffer();
845   DoEnableVertexAttribArray(1);
846
847   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
848       .Times(0);
849   DrawElementsInstancedANGLE cmd;
850   cmd.Init(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT,
851            kValidIndexRangeStart * 2, 1);
852   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
853   EXPECT_EQ(GL_NO_ERROR, GetGLError());
854 }
855
856 TEST_F(GLES2DecoderGeometryInstancingTest,
857        DrawElementsInstancedANGLEValidAttributesSucceeds) {
858   SetupIndexBuffer();
859   SetupTexture();
860   SetupVertexBuffer();
861   DoEnableVertexAttribArray(1);
862   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
863   AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, kServiceBufferId);
864   SetupExpectationsForApplyingDefaultDirtyState();
865
866   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
867                         GL_TRIANGLES,
868                         kValidIndexRangeCount,
869                         GL_UNSIGNED_SHORT,
870                         BufferOffset(kValidIndexRangeStart * 2),
871                         1))
872       .Times(1)
873       .RetiresOnSaturation();
874   DrawElementsInstancedANGLE cmd;
875   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
876            kValidIndexRangeStart * 2, 1);
877   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
878   EXPECT_EQ(GL_NO_ERROR, GetGLError());
879 }
880
881 TEST_F(GLES2DecoderGeometryInstancingTest,
882        DrawElementsInstancedANGLEWithInvalidModeFails) {
883   SetupIndexBuffer();
884   SetupVertexBuffer();
885   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
886
887   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
888       .Times(0);
889   DrawElementsInstancedANGLE cmd;
890   cmd.Init(GL_QUADS, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
891            kValidIndexRangeStart * 2, 1);
892   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
893   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
894   cmd.Init(GL_INVALID_ENUM, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
895            kValidIndexRangeStart * 2, 1);
896   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
897   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
898 }
899
900 // Per-instance data is twice as large, but number of instances is half
901 TEST_F(GLES2DecoderGeometryInstancingTest,
902        DrawElementsInstancedANGLELargeInstanceSucceeds) {
903   SetupTexture();
904   SetupIndexBuffer();
905   SetupVertexBuffer();
906   SetupExpectationsForApplyingDefaultDirtyState();
907   //Add offset so we're sure we're accessing data near the end of the buffer.
908   DoVertexAttribPointer(1, 2, GL_FLOAT, 0,
909                         (kNumVertices - kMaxValidIndex - 1) * 2 *
910                             sizeof(GLfloat));
911
912   DoEnableVertexAttribArray(0);
913   DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
914   DoVertexAttribDivisorANGLE(0, 1);
915   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
916                         GL_TRIANGLES,
917                         kValidIndexRangeCount,
918                         GL_UNSIGNED_SHORT,
919                         BufferOffset(kValidIndexRangeStart * 2),
920                         kNumVertices / 2))
921       .Times(1)
922       .RetiresOnSaturation();
923   DrawElementsInstancedANGLE cmd;
924   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
925            kValidIndexRangeStart * 2, kNumVertices / 2);
926   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
927   EXPECT_EQ(GL_NO_ERROR, GetGLError());
928 }
929
930 // Per-instance data is twice as large, but divisor is twice
931 TEST_F(GLES2DecoderGeometryInstancingTest,
932        DrawElementsInstancedANGLELargeDivisorSucceeds) {
933   SetupTexture();
934   SetupIndexBuffer();
935   SetupVertexBuffer();
936   SetupExpectationsForApplyingDefaultDirtyState();
937   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
938
939   DoEnableVertexAttribArray(0);
940   DoVertexAttribPointer(0, 4, GL_FLOAT, 0, 0);
941   DoVertexAttribDivisorANGLE(0, 2);
942   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
943                         GL_TRIANGLES,
944                         kValidIndexRangeCount,
945                         GL_UNSIGNED_SHORT,
946                         BufferOffset(kValidIndexRangeStart * 2),
947                         kNumVertices))
948       .Times(1)
949       .RetiresOnSaturation();
950   DrawElementsInstancedANGLE cmd;
951   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
952            kValidIndexRangeStart * 2, kNumVertices);
953   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
954   EXPECT_EQ(GL_NO_ERROR, GetGLError());
955 }
956
957 TEST_F(GLES2DecoderGeometryInstancingTest,
958        DrawElementsInstancedANGLELargeFails) {
959   SetupTexture();
960   SetupIndexBuffer();
961   SetupVertexBuffer();
962   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
963
964   DoEnableVertexAttribArray(0);
965   DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
966   DoVertexAttribDivisorANGLE(0, 1);
967   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
968       .Times(0)
969       .RetiresOnSaturation();
970   DrawElementsInstancedANGLE cmd;
971   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
972            kValidIndexRangeStart * 2, kNumVertices + 1);
973   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
974   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
975   EXPECT_EQ(GL_NO_ERROR, GetGLError());
976
977   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
978       .Times(0)
979       .RetiresOnSaturation();
980   cmd.Init(GL_TRIANGLES, kInvalidIndexRangeCount, GL_UNSIGNED_SHORT,
981            kInvalidIndexRangeStart * 2, kNumVertices);
982   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
983   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
984   EXPECT_EQ(GL_NO_ERROR, GetGLError());
985 }
986
987 TEST_F(GLES2DecoderGeometryInstancingTest,
988        DrawElementsInstancedANGLEInvalidPrimcountFails) {
989   SetupTexture();
990   SetupIndexBuffer();
991   SetupVertexBuffer();
992   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
993
994   DoEnableVertexAttribArray(0);
995   DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
996   DoVertexAttribDivisorANGLE(0, 1);
997   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
998       .Times(0)
999       .RetiresOnSaturation();
1000   DrawElementsInstancedANGLE cmd;
1001   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
1002            kValidIndexRangeStart * 2, -1);
1003   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1004   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1005   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1006 }
1007
1008 // Per-index data is twice as large, but values of indices are smaller
1009 TEST_F(GLES2DecoderGeometryInstancingTest,
1010        DrawElementsInstancedANGLELargeIndexSucceeds) {
1011   SetupTexture();
1012   SetupIndexBuffer();
1013   SetupVertexBuffer();
1014   SetupExpectationsForApplyingDefaultDirtyState();
1015   DoVertexAttribPointer(1, 4, GL_FLOAT, 0, 0);
1016
1017   DoEnableVertexAttribArray(0);
1018   DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
1019   DoVertexAttribDivisorANGLE(0, 1);
1020   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(
1021                         GL_TRIANGLES,
1022                         kValidIndexRangeCount,
1023                         GL_UNSIGNED_SHORT,
1024                         BufferOffset(kValidIndexRangeStart * 2),
1025                         kNumVertices))
1026       .Times(1)
1027       .RetiresOnSaturation();
1028   DrawElementsInstancedANGLE cmd;
1029   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
1030            kValidIndexRangeStart * 2, kNumVertices);
1031   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1032   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1033 }
1034
1035 TEST_F(GLES2DecoderGeometryInstancingTest,
1036        DrawElementsInstancedANGLENoDivisor0Fails) {
1037   SetupTexture();
1038   SetupIndexBuffer();
1039   SetupVertexBuffer();
1040   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
1041
1042   DoEnableVertexAttribArray(0);
1043   DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
1044   DoVertexAttribDivisorANGLE(0, 1);
1045   DoVertexAttribDivisorANGLE(1, 1);
1046   EXPECT_CALL(*gl_, DrawElementsInstancedANGLE(_, _, _, _, _))
1047       .Times(0)
1048       .RetiresOnSaturation();
1049   DrawElementsInstancedANGLE cmd;
1050   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
1051            kValidIndexRangeStart * 2, kNumVertices);
1052   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1053   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1054   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1055 }
1056
1057 TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervSucceeds) {
1058   const float dummy = 0;
1059   const GLuint kOffsetToTestFor = sizeof(dummy) * 4;
1060   const GLuint kIndexToTest = 1;
1061   GetVertexAttribPointerv::Result* result =
1062       static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_);
1063   result->size = 0;
1064   const GLuint* result_value = result->GetData();
1065   // Test that initial value is 0.
1066   GetVertexAttribPointerv cmd;
1067   cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER,
1068            shared_memory_id_, shared_memory_offset_);
1069   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1070   EXPECT_EQ(sizeof(*result_value), result->size);
1071   EXPECT_EQ(0u, *result_value);
1072   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1073
1074   // Set the value and see that we get it.
1075   SetupVertexBuffer();
1076   DoVertexAttribPointer(kIndexToTest, 2, GL_FLOAT, 0, kOffsetToTestFor);
1077   result->size = 0;
1078   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1079   EXPECT_EQ(sizeof(*result_value), result->size);
1080   EXPECT_EQ(kOffsetToTestFor, *result_value);
1081   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1082 }
1083
1084 TEST_F(GLES2DecoderWithShaderTest, GetVertexAttribPointervBadArgsFails) {
1085   const GLuint kIndexToTest = 1;
1086   GetVertexAttribPointerv::Result* result =
1087       static_cast<GetVertexAttribPointerv::Result*>(shared_memory_address_);
1088   result->size = 0;
1089   const GLuint* result_value = result->GetData();
1090   // Test pname invalid fails.
1091   GetVertexAttribPointerv cmd;
1092   cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER + 1,
1093            shared_memory_id_, shared_memory_offset_);
1094   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1095   EXPECT_EQ(0u, result->size);
1096   EXPECT_EQ(kInitialResult, *result_value);
1097   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1098
1099   // Test index out of range fails.
1100   result->size = 0;
1101   cmd.Init(kNumVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_POINTER,
1102            shared_memory_id_, shared_memory_offset_);
1103   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1104   EXPECT_EQ(0u, result->size);
1105   EXPECT_EQ(kInitialResult, *result_value);
1106   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1107
1108   // Test memory id bad fails.
1109   cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER,
1110            kInvalidSharedMemoryId, shared_memory_offset_);
1111   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1112
1113   // Test memory offset bad fails.
1114   cmd.Init(kIndexToTest, GL_VERTEX_ATTRIB_ARRAY_POINTER,
1115            shared_memory_id_, kInvalidSharedMemoryOffset);
1116   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1117 }
1118
1119 TEST_F(GLES2DecoderWithShaderTest, GetUniformivSucceeds) {
1120   GetUniformiv::Result* result =
1121       static_cast<GetUniformiv::Result*>(shared_memory_address_);
1122   result->size = 0;
1123   GetUniformiv cmd;
1124   cmd.Init(client_program_id_,
1125            kUniform2FakeLocation,
1126            kSharedMemoryId, kSharedMemoryOffset);
1127   EXPECT_CALL(*gl_, GetUniformiv(kServiceProgramId, kUniform2RealLocation, _))
1128       .Times(1);
1129   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1130   EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
1131             result->size);
1132 }
1133
1134 TEST_F(GLES2DecoderWithShaderTest, GetUniformivArrayElementSucceeds) {
1135   GetUniformiv::Result* result =
1136       static_cast<GetUniformiv::Result*>(shared_memory_address_);
1137   result->size = 0;
1138   GetUniformiv cmd;
1139   cmd.Init(client_program_id_,
1140            kUniform2ElementFakeLocation,
1141            kSharedMemoryId, kSharedMemoryOffset);
1142   EXPECT_CALL(*gl_,
1143               GetUniformiv(kServiceProgramId, kUniform2ElementRealLocation, _))
1144       .Times(1);
1145   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1146   EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
1147             result->size);
1148 }
1149
1150 TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadProgramFails) {
1151   GetUniformiv::Result* result =
1152       static_cast<GetUniformiv::Result*>(shared_memory_address_);
1153   result->size = 0;
1154   GetUniformiv cmd;
1155   // non-existant program
1156   cmd.Init(kInvalidClientId,
1157            kUniform2FakeLocation,
1158            kSharedMemoryId, kSharedMemoryOffset);
1159   EXPECT_CALL(*gl_, GetUniformiv(_, _, _))
1160       .Times(0);
1161   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1162   EXPECT_EQ(0U, result->size);
1163   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1164   // Valid id that is not a program. The GL spec requires a different error for
1165   // this case.
1166 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
1167   result->size = kInitialResult;
1168   cmd.Init(client_shader_id_,
1169            kUniform2FakeLocation,
1170            kSharedMemoryId, kSharedMemoryOffset);
1171   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1172   EXPECT_EQ(0U, result->size);
1173   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1174 #endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
1175   // Unlinked program
1176   EXPECT_CALL(*gl_, CreateProgram())
1177       .Times(1)
1178       .WillOnce(Return(kNewServiceId))
1179       .RetiresOnSaturation();
1180   CreateProgram cmd2;
1181   cmd2.Init(kNewClientId);
1182   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1183   result->size = kInitialResult;
1184   cmd.Init(kNewClientId,
1185            kUniform2FakeLocation,
1186            kSharedMemoryId, kSharedMemoryOffset);
1187   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1188   EXPECT_EQ(0U, result->size);
1189   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1190 }
1191
1192 TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadLocationFails) {
1193   GetUniformiv::Result* result =
1194       static_cast<GetUniformiv::Result*>(shared_memory_address_);
1195   result->size = 0;
1196   GetUniformiv cmd;
1197   // invalid location
1198   cmd.Init(client_program_id_, kInvalidUniformLocation,
1199            kSharedMemoryId, kSharedMemoryOffset);
1200   EXPECT_CALL(*gl_, GetUniformiv(_, _, _))
1201       .Times(0);
1202   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1203   EXPECT_EQ(0U, result->size);
1204   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1205 }
1206
1207 TEST_F(GLES2DecoderWithShaderTest, GetUniformivBadSharedMemoryFails) {
1208   GetUniformiv cmd;
1209   cmd.Init(client_program_id_,
1210            kUniform2FakeLocation,
1211            kInvalidSharedMemoryId, kSharedMemoryOffset);
1212   EXPECT_CALL(*gl_, GetUniformiv(_, _, _))
1213       .Times(0);
1214   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1215   cmd.Init(client_program_id_, kUniform2FakeLocation,
1216            kSharedMemoryId, kInvalidSharedMemoryOffset);
1217   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1218 };
1219
1220 TEST_F(GLES2DecoderWithShaderTest, GetUniformfvSucceeds) {
1221   GetUniformfv::Result* result =
1222       static_cast<GetUniformfv::Result*>(shared_memory_address_);
1223   result->size = 0;
1224   GetUniformfv cmd;
1225   cmd.Init(client_program_id_,
1226            kUniform2FakeLocation,
1227            kSharedMemoryId, kSharedMemoryOffset);
1228   EXPECT_CALL(*gl_, GetUniformfv(kServiceProgramId, kUniform2RealLocation, _))
1229       .Times(1);
1230   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1231   EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
1232             result->size);
1233 }
1234
1235 TEST_F(GLES2DecoderWithShaderTest, GetUniformfvArrayElementSucceeds) {
1236   GetUniformfv::Result* result =
1237       static_cast<GetUniformfv::Result*>(shared_memory_address_);
1238   result->size = 0;
1239   GetUniformfv cmd;
1240   cmd.Init(client_program_id_,
1241            kUniform2ElementFakeLocation,
1242            kSharedMemoryId, kSharedMemoryOffset);
1243   EXPECT_CALL(*gl_,
1244               GetUniformfv(kServiceProgramId, kUniform2ElementRealLocation, _))
1245       .Times(1);
1246   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1247   EXPECT_EQ(GLES2Util::GetGLDataTypeSizeForUniforms(kUniform2Type),
1248             result->size);
1249 }
1250
1251 TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadProgramFails) {
1252   GetUniformfv::Result* result =
1253       static_cast<GetUniformfv::Result*>(shared_memory_address_);
1254   result->size = 0;
1255   GetUniformfv cmd;
1256   // non-existant program
1257   cmd.Init(kInvalidClientId,
1258            kUniform2FakeLocation,
1259            kSharedMemoryId, kSharedMemoryOffset);
1260   EXPECT_CALL(*gl_, GetUniformfv(_, _, _))
1261       .Times(0);
1262   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1263   EXPECT_EQ(0U, result->size);
1264   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1265   // Valid id that is not a program. The GL spec requires a different error for
1266   // this case.
1267 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
1268   result->size = kInitialResult;
1269   cmd.Init(client_shader_id_,
1270            kUniform2FakeLocation,
1271            kSharedMemoryId, kSharedMemoryOffset);
1272   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1273   EXPECT_EQ(0U, result->size);
1274   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1275 #endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
1276   // Unlinked program
1277   EXPECT_CALL(*gl_, CreateProgram())
1278       .Times(1)
1279       .WillOnce(Return(kNewServiceId))
1280       .RetiresOnSaturation();
1281   CreateProgram cmd2;
1282   cmd2.Init(kNewClientId);
1283   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1284   result->size = kInitialResult;
1285   cmd.Init(kNewClientId,
1286            kUniform2FakeLocation,
1287            kSharedMemoryId, kSharedMemoryOffset);
1288   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1289   EXPECT_EQ(0U, result->size);
1290   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1291 }
1292
1293 TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadLocationFails) {
1294   GetUniformfv::Result* result =
1295       static_cast<GetUniformfv::Result*>(shared_memory_address_);
1296   result->size = 0;
1297   GetUniformfv cmd;
1298   // invalid location
1299   cmd.Init(client_program_id_, kInvalidUniformLocation,
1300            kSharedMemoryId, kSharedMemoryOffset);
1301   EXPECT_CALL(*gl_, GetUniformfv(_, _, _))
1302       .Times(0);
1303   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1304   EXPECT_EQ(0U, result->size);
1305   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1306 }
1307
1308 TEST_F(GLES2DecoderWithShaderTest, GetUniformfvBadSharedMemoryFails) {
1309   GetUniformfv cmd;
1310   cmd.Init(client_program_id_,
1311            kUniform2FakeLocation,
1312            kInvalidSharedMemoryId, kSharedMemoryOffset);
1313   EXPECT_CALL(*gl_, GetUniformfv(_, _, _))
1314       .Times(0);
1315   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1316   cmd.Init(client_program_id_, kUniform2FakeLocation,
1317            kSharedMemoryId, kInvalidSharedMemoryOffset);
1318   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1319 };
1320
1321 TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersSucceeds) {
1322   GetAttachedShaders cmd;
1323   typedef GetAttachedShaders::Result Result;
1324   Result* result = static_cast<Result*>(shared_memory_address_);
1325   result->size = 0;
1326   EXPECT_CALL(*gl_, GetAttachedShaders(kServiceProgramId, 1, _, _))
1327       .WillOnce(DoAll(SetArgumentPointee<2>(1),
1328                       SetArgumentPointee<3>(kServiceShaderId)));
1329   cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_,
1330            Result::ComputeSize(1));
1331   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1332   EXPECT_EQ(1, result->GetNumResults());
1333   EXPECT_EQ(client_shader_id_, result->GetData()[0]);
1334   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1335 }
1336
1337 TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersResultNotInitFail) {
1338   GetAttachedShaders cmd;
1339   typedef GetAttachedShaders::Result Result;
1340   Result* result = static_cast<Result*>(shared_memory_address_);
1341   result->size = 1;
1342   EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _))
1343       .Times(0);
1344   cmd.Init(client_program_id_, shared_memory_id_, shared_memory_offset_,
1345            Result::ComputeSize(1));
1346   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1347 }
1348
1349 TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersBadProgramFails) {
1350   GetAttachedShaders cmd;
1351   typedef GetAttachedShaders::Result Result;
1352   Result* result = static_cast<Result*>(shared_memory_address_);
1353   result->size = 0;
1354   EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _))
1355       .Times(0);
1356   cmd.Init(kInvalidClientId, shared_memory_id_, shared_memory_offset_,
1357            Result::ComputeSize(1));
1358   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1359   EXPECT_EQ(0U, result->size);
1360   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1361 }
1362
1363 TEST_F(GLES2DecoderWithShaderTest, GetAttachedShadersBadSharedMemoryFails) {
1364   GetAttachedShaders cmd;
1365   typedef GetAttachedShaders::Result Result;
1366   cmd.Init(client_program_id_, kInvalidSharedMemoryId, shared_memory_offset_,
1367            Result::ComputeSize(1));
1368   EXPECT_CALL(*gl_, GetAttachedShaders(_, _, _, _))
1369       .Times(0);
1370   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1371   cmd.Init(client_program_id_, shared_memory_id_, kInvalidSharedMemoryOffset,
1372            Result::ComputeSize(1));
1373   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1374 }
1375
1376 TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatSucceeds) {
1377   ScopedGLImplementationSetter gl_impl(::gfx::kGLImplementationEGLGLES2);
1378   GetShaderPrecisionFormat cmd;
1379   typedef GetShaderPrecisionFormat::Result Result;
1380   Result* result = static_cast<Result*>(shared_memory_address_);
1381   result->success = 0;
1382   const GLint range[2] = { 62, 62 };
1383   const GLint precision = 16;
1384   EXPECT_CALL(*gl_,GetShaderPrecisionFormat(_, _, _, _))
1385       .WillOnce(DoAll(SetArrayArgument<2>(range,range+2),
1386                       SetArgumentPointee<3>(precision)))
1387       .RetiresOnSaturation();
1388   cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT,
1389            shared_memory_id_, shared_memory_offset_);
1390   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1391   EXPECT_NE(0, result->success);
1392   EXPECT_EQ(range[0], result->min_range);
1393   EXPECT_EQ(range[1], result->max_range);
1394   EXPECT_EQ(precision, result->precision);
1395   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1396 }
1397
1398 TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatResultNotInitFails) {
1399   GetShaderPrecisionFormat cmd;
1400   typedef GetShaderPrecisionFormat::Result Result;
1401   Result* result = static_cast<Result*>(shared_memory_address_);
1402   result->success = 1;
1403   // NOTE: GL might not be called. There is no Desktop OpenGL equivalent
1404   cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT,
1405            shared_memory_id_, shared_memory_offset_);
1406   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1407 }
1408
1409 TEST_F(GLES2DecoderWithShaderTest, GetShaderPrecisionFormatBadArgsFails) {
1410   typedef GetShaderPrecisionFormat::Result Result;
1411   Result* result = static_cast<Result*>(shared_memory_address_);
1412   result->success = 0;
1413   GetShaderPrecisionFormat cmd;
1414   cmd.Init(GL_TEXTURE_2D, GL_HIGH_FLOAT,
1415            shared_memory_id_, shared_memory_offset_);
1416   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1417   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1418   result->success = 0;
1419   cmd.Init(GL_VERTEX_SHADER, GL_TEXTURE_2D,
1420            shared_memory_id_, shared_memory_offset_);
1421   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1422   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1423 }
1424
1425 TEST_F(GLES2DecoderWithShaderTest,
1426        GetShaderPrecisionFormatBadSharedMemoryFails) {
1427   GetShaderPrecisionFormat cmd;
1428   cmd.Init(GL_VERTEX_SHADER, GL_HIGH_FLOAT,
1429            kInvalidSharedMemoryId, shared_memory_offset_);
1430   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1431   cmd.Init(GL_VERTEX_SHADER, GL_TEXTURE_2D,
1432            shared_memory_id_, kInvalidSharedMemoryOffset);
1433   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1434 }
1435
1436 TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformSucceeds) {
1437   const GLuint kUniformIndex = 1;
1438   const uint32 kBucketId = 123;
1439   GetActiveUniform cmd;
1440   typedef GetActiveUniform::Result Result;
1441   Result* result = static_cast<Result*>(shared_memory_address_);
1442   result->success = 0;
1443   cmd.Init(client_program_id_, kUniformIndex, kBucketId,
1444            shared_memory_id_, shared_memory_offset_);
1445   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1446   EXPECT_NE(0, result->success);
1447   EXPECT_EQ(kUniform2Size, result->size);
1448   EXPECT_EQ(kUniform2Type, result->type);
1449   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1450   CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
1451   ASSERT_TRUE(bucket != NULL);
1452   EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kUniform2Name,
1453                       bucket->size()));
1454 }
1455
1456 TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformResultNotInitFails) {
1457   const GLuint kUniformIndex = 1;
1458   const uint32 kBucketId = 123;
1459   GetActiveUniform cmd;
1460   typedef GetActiveUniform::Result Result;
1461   Result* result = static_cast<Result*>(shared_memory_address_);
1462   result->success = 1;
1463   cmd.Init(client_program_id_, kUniformIndex, kBucketId,
1464            shared_memory_id_, shared_memory_offset_);
1465   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1466 }
1467
1468 TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadProgramFails) {
1469   const GLuint kUniformIndex = 1;
1470   const uint32 kBucketId = 123;
1471   GetActiveUniform cmd;
1472   typedef GetActiveUniform::Result Result;
1473   Result* result = static_cast<Result*>(shared_memory_address_);
1474   result->success = 0;
1475   cmd.Init(kInvalidClientId, kUniformIndex, kBucketId,
1476            shared_memory_id_, shared_memory_offset_);
1477   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1478   EXPECT_EQ(0, result->success);
1479   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1480 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
1481   result->success = 0;
1482   cmd.Init(client_shader_id_, kUniformIndex, kBucketId,
1483            shared_memory_id_, shared_memory_offset_);
1484   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1485   EXPECT_EQ(0, result->success);
1486   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1487 #endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
1488 }
1489
1490 TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadIndexFails) {
1491   const uint32 kBucketId = 123;
1492   GetActiveUniform cmd;
1493   typedef GetActiveUniform::Result Result;
1494   Result* result = static_cast<Result*>(shared_memory_address_);
1495   result->success = 0;
1496   cmd.Init(client_program_id_, kBadUniformIndex, kBucketId,
1497            shared_memory_id_, shared_memory_offset_);
1498   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1499   EXPECT_EQ(0, result->success);
1500   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1501 }
1502
1503 TEST_F(GLES2DecoderWithShaderTest, GetActiveUniformBadSharedMemoryFails) {
1504   const GLuint kUniformIndex = 1;
1505   const uint32 kBucketId = 123;
1506   GetActiveUniform cmd;
1507   typedef GetActiveUniform::Result Result;
1508   cmd.Init(client_program_id_, kUniformIndex, kBucketId,
1509            kInvalidSharedMemoryId, shared_memory_offset_);
1510   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1511   cmd.Init(client_program_id_, kUniformIndex, kBucketId,
1512            shared_memory_id_, kInvalidSharedMemoryOffset);
1513   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1514 }
1515
1516 TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribSucceeds) {
1517   const GLuint kAttribIndex = 1;
1518   const uint32 kBucketId = 123;
1519   GetActiveAttrib cmd;
1520   typedef GetActiveAttrib::Result Result;
1521   Result* result = static_cast<Result*>(shared_memory_address_);
1522   result->success = 0;
1523   cmd.Init(client_program_id_, kAttribIndex, kBucketId,
1524            shared_memory_id_, shared_memory_offset_);
1525   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1526   EXPECT_NE(0, result->success);
1527   EXPECT_EQ(kAttrib2Size, result->size);
1528   EXPECT_EQ(kAttrib2Type, result->type);
1529   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1530   CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
1531   ASSERT_TRUE(bucket != NULL);
1532   EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kAttrib2Name,
1533                       bucket->size()));
1534 }
1535
1536 TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribResultNotInitFails) {
1537   const GLuint kAttribIndex = 1;
1538   const uint32 kBucketId = 123;
1539   GetActiveAttrib cmd;
1540   typedef GetActiveAttrib::Result Result;
1541   Result* result = static_cast<Result*>(shared_memory_address_);
1542   result->success = 1;
1543   cmd.Init(client_program_id_, kAttribIndex, kBucketId,
1544            shared_memory_id_, shared_memory_offset_);
1545   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1546 }
1547
1548 TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadProgramFails) {
1549   const GLuint kAttribIndex = 1;
1550   const uint32 kBucketId = 123;
1551   GetActiveAttrib cmd;
1552   typedef GetActiveAttrib::Result Result;
1553   Result* result = static_cast<Result*>(shared_memory_address_);
1554   result->success = 0;
1555   cmd.Init(kInvalidClientId, kAttribIndex, kBucketId,
1556            shared_memory_id_, shared_memory_offset_);
1557   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1558   EXPECT_EQ(0, result->success);
1559   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1560 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
1561   result->success = 0;
1562   cmd.Init(client_shader_id_, kAttribIndex, kBucketId,
1563            shared_memory_id_, shared_memory_offset_);
1564   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1565   EXPECT_EQ(0, result->success);
1566   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1567 #endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
1568 }
1569
1570 TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadIndexFails) {
1571   const uint32 kBucketId = 123;
1572   GetActiveAttrib cmd;
1573   typedef GetActiveAttrib::Result Result;
1574   Result* result = static_cast<Result*>(shared_memory_address_);
1575   result->success = 0;
1576   cmd.Init(client_program_id_, kBadAttribIndex, kBucketId,
1577            shared_memory_id_, shared_memory_offset_);
1578   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1579   EXPECT_EQ(0, result->success);
1580   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1581 }
1582
1583 TEST_F(GLES2DecoderWithShaderTest, GetActiveAttribBadSharedMemoryFails) {
1584   const GLuint kAttribIndex = 1;
1585   const uint32 kBucketId = 123;
1586   GetActiveAttrib cmd;
1587   typedef GetActiveAttrib::Result Result;
1588   cmd.Init(client_program_id_, kAttribIndex, kBucketId,
1589            kInvalidSharedMemoryId, shared_memory_offset_);
1590   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1591   cmd.Init(client_program_id_, kAttribIndex, kBucketId,
1592            shared_memory_id_, kInvalidSharedMemoryOffset);
1593   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1594 }
1595
1596 TEST_F(GLES2DecoderWithShaderTest, GetShaderInfoLogValidArgs) {
1597   const char* kInfo = "hello";
1598   const uint32 kBucketId = 123;
1599   CompileShader compile_cmd;
1600   GetShaderInfoLog cmd;
1601   EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _));
1602   EXPECT_CALL(*gl_, CompileShader(kServiceShaderId));
1603   EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_COMPILE_STATUS, _))
1604       .WillOnce(SetArgumentPointee<2>(GL_FALSE))
1605       .RetiresOnSaturation();
1606   EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_INFO_LOG_LENGTH, _))
1607       .WillOnce(SetArgumentPointee<2>(strlen(kInfo) + 1))
1608       .RetiresOnSaturation();
1609   EXPECT_CALL(
1610       *gl_, GetShaderInfoLog(kServiceShaderId, strlen(kInfo) + 1, _, _))
1611       .WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)),
1612                       SetArrayArgument<3>(kInfo, kInfo + strlen(kInfo) + 1)));
1613   compile_cmd.Init(client_shader_id_);
1614   cmd.Init(client_shader_id_, kBucketId);
1615   EXPECT_EQ(error::kNoError, ExecuteCmd(compile_cmd));
1616   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1617   CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
1618   ASSERT_TRUE(bucket != NULL);
1619   EXPECT_EQ(strlen(kInfo) + 1, bucket->size());
1620   EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kInfo,
1621                       bucket->size()));
1622   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1623 }
1624
1625 TEST_F(GLES2DecoderWithShaderTest, GetShaderInfoLogInvalidArgs) {
1626   const uint32 kBucketId = 123;
1627   GetShaderInfoLog cmd;
1628   cmd.Init(kInvalidClientId, kBucketId);
1629   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1630   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1631 }
1632
1633 TEST_F(GLES2DecoderTest, GetIntegervCached) {
1634   struct TestInfo {
1635     GLenum pname;
1636     GLint expected;
1637   };
1638   TestInfo tests[] = {
1639     { GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize, },
1640     { GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize, },
1641     { GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize, },
1642   };
1643   typedef GetIntegerv::Result Result;
1644   for (size_t ii = 0; ii < sizeof(tests) / sizeof(tests[0]); ++ii) {
1645     const TestInfo& test = tests[ii];
1646     Result* result = static_cast<Result*>(shared_memory_address_);
1647     EXPECT_CALL(*gl_, GetError())
1648         .WillOnce(Return(GL_NO_ERROR))
1649         .WillOnce(Return(GL_NO_ERROR))
1650         .RetiresOnSaturation();
1651     EXPECT_CALL(*gl_, GetIntegerv(test.pname, _))
1652         .Times(0);
1653     result->size = 0;
1654     GetIntegerv cmd2;
1655     cmd2.Init(test.pname, shared_memory_id_, shared_memory_offset_);
1656     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1657     EXPECT_EQ(
1658         decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname),
1659         result->GetNumResults());
1660     EXPECT_EQ(GL_NO_ERROR, GetGLError());
1661     EXPECT_EQ(test.expected, result->GetData()[0]);
1662   }
1663 }
1664
1665 TEST_F(GLES2DecoderTest, CompileShaderValidArgs) {
1666   EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _));
1667   EXPECT_CALL(*gl_, CompileShader(kServiceShaderId));
1668   EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_COMPILE_STATUS, _))
1669       .WillOnce(SetArgumentPointee<2>(GL_TRUE))
1670       .RetiresOnSaturation();
1671   CompileShader cmd;
1672   cmd.Init(client_shader_id_);
1673   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1674 }
1675
1676 TEST_F(GLES2DecoderTest, CompileShaderInvalidArgs) {
1677   CompileShader cmd;
1678   cmd.Init(kInvalidClientId);
1679   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1680   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1681 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
1682   cmd.Init(client_program_id_);
1683   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1684   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1685 #endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
1686 }
1687
1688 TEST_F(GLES2DecoderTest, ShaderSourceAndGetShaderSourceValidArgs) {
1689   const uint32 kBucketId = 123;
1690   const char kSource[] = "hello";
1691   const uint32 kSourceSize = sizeof(kSource) - 1;
1692   memcpy(shared_memory_address_, kSource, kSourceSize);
1693   ShaderSource cmd;
1694   cmd.Init(client_shader_id_,
1695            kSharedMemoryId, kSharedMemoryOffset, kSourceSize);
1696   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1697   memset(shared_memory_address_, 0, kSourceSize);
1698   GetShaderSource get_cmd;
1699   get_cmd.Init(client_shader_id_, kBucketId);
1700   EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd));
1701   CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
1702   ASSERT_TRUE(bucket != NULL);
1703   EXPECT_EQ(kSourceSize + 1, bucket->size());
1704   EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kSource,
1705                       bucket->size()));
1706 }
1707
1708 TEST_F(GLES2DecoderTest, ShaderSourceInvalidArgs) {
1709   const char kSource[] = "hello";
1710   const uint32 kSourceSize = sizeof(kSource) - 1;
1711   memcpy(shared_memory_address_, kSource, kSourceSize);
1712   ShaderSource cmd;
1713   cmd.Init(kInvalidClientId,
1714            kSharedMemoryId, kSharedMemoryOffset, kSourceSize);
1715   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1716   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1717 #if GLES2_TEST_SHADER_VS_PROGRAM_IDS
1718   cmd.Init(client_program_id_,
1719            kSharedMemoryId, kSharedMemoryOffset, kSourceSize);
1720   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1721   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1722 #endif  // GLES2_TEST_SHADER_VS_PROGRAM_IDS
1723   cmd.Init(client_shader_id_,
1724            kInvalidSharedMemoryId, kSharedMemoryOffset, kSourceSize);
1725   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1726   cmd.Init(client_shader_id_,
1727            kSharedMemoryId, kInvalidSharedMemoryOffset, kSourceSize);
1728   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1729   cmd.Init(client_shader_id_,
1730            kSharedMemoryId, kSharedMemoryOffset, kSharedBufferSize);
1731   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1732 }
1733
1734 TEST_F(GLES2DecoderTest, ShaderSourceBucketAndGetShaderSourceValidArgs) {
1735   const uint32 kInBucketId = 123;
1736   const uint32 kOutBucketId = 125;
1737   const char kSource[] = "hello";
1738   const uint32 kSourceSize = sizeof(kSource) - 1;
1739   SetBucketAsCString(kInBucketId, kSource);
1740   ShaderSourceBucket cmd;
1741   cmd.Init(client_shader_id_, kInBucketId);
1742   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1743   ClearSharedMemory();
1744   GetShaderSource get_cmd;
1745   get_cmd.Init(client_shader_id_, kOutBucketId);
1746   EXPECT_EQ(error::kNoError, ExecuteCmd(get_cmd));
1747   CommonDecoder::Bucket* bucket = decoder_->GetBucket(kOutBucketId);
1748   ASSERT_TRUE(bucket != NULL);
1749   EXPECT_EQ(kSourceSize + 1, bucket->size());
1750   EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kSource,
1751                       bucket->size()));
1752 }
1753
1754 TEST_F(GLES2DecoderTest, ShaderSourceBucketInvalidArgs) {
1755   const uint32 kBucketId = 123;
1756   const char kSource[] = "hello";
1757   const uint32 kSourceSize = sizeof(kSource) - 1;
1758   memcpy(shared_memory_address_, kSource, kSourceSize);
1759   ShaderSourceBucket cmd;
1760   // Test no bucket.
1761   cmd.Init(client_texture_id_, kBucketId);
1762   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
1763   // Test invalid client.
1764   SetBucketAsCString(kBucketId, kSource);
1765   cmd.Init(kInvalidClientId, kBucketId);
1766   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1767   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1768 }
1769
1770 TEST_F(GLES2DecoderTest, ShaderSourceStripComments) {
1771   const uint32 kInBucketId = 123;
1772   const char kSource[] = "hello/*te\ast*/world//a\ab";
1773   SetBucketAsCString(kInBucketId, kSource);
1774   ShaderSourceBucket cmd;
1775   cmd.Init(client_shader_id_, kInBucketId);
1776   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1777   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1778 }
1779
1780 TEST_F(GLES2DecoderTest, GenerateMipmapWrongFormatsFails) {
1781   EXPECT_CALL(*gl_, GenerateMipmapEXT(_))
1782        .Times(0);
1783   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1784   DoTexImage2D(
1785       GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1786       0, 0);
1787   GenerateMipmap cmd;
1788   cmd.Init(GL_TEXTURE_2D);
1789   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1790   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1791 }
1792
1793 TEST_F(GLES2DecoderTest, GenerateMipmapHandlesOutOfMemory) {
1794   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1795   TextureManager* manager = group().texture_manager();
1796   TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
1797   ASSERT_TRUE(texture_ref != NULL);
1798   Texture* texture = texture_ref->texture();
1799   GLint width = 0;
1800   GLint height = 0;
1801   EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height));
1802   DoTexImage2D(
1803       GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1804       kSharedMemoryId, kSharedMemoryOffset);
1805   EXPECT_CALL(*gl_, TexParameteri(
1806       GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST))
1807       .Times(1)
1808       .RetiresOnSaturation();
1809   EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D))
1810       .Times(1);
1811   EXPECT_CALL(*gl_, TexParameteri(
1812       GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR))
1813       .Times(1)
1814       .RetiresOnSaturation();
1815   EXPECT_CALL(*gl_, GetError())
1816       .WillOnce(Return(GL_NO_ERROR))
1817       .WillOnce(Return(GL_OUT_OF_MEMORY))
1818       .RetiresOnSaturation();
1819   GenerateMipmap cmd;
1820   cmd.Init(GL_TEXTURE_2D);
1821   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1822   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1823   EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 2, &width, &height));
1824 }
1825
1826 TEST_F(GLES2DecoderTest, GenerateMipmapClearsUnclearedTexture) {
1827   EXPECT_CALL(*gl_, GenerateMipmapEXT(_))
1828        .Times(0);
1829   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1830   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1831                0, 0);
1832   SetupClearTextureExpections(
1833       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
1834       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
1835   EXPECT_CALL(*gl_, TexParameteri(
1836       GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST))
1837       .Times(1)
1838       .RetiresOnSaturation();
1839   EXPECT_CALL(*gl_, GenerateMipmapEXT(GL_TEXTURE_2D));
1840   EXPECT_CALL(*gl_, TexParameteri(
1841       GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR))
1842       .Times(1)
1843       .RetiresOnSaturation();
1844   EXPECT_CALL(*gl_, GetError())
1845       .WillOnce(Return(GL_NO_ERROR))
1846       .WillOnce(Return(GL_NO_ERROR))
1847       .RetiresOnSaturation();
1848   GenerateMipmap cmd;
1849   cmd.Init(GL_TEXTURE_2D);
1850   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1851   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1852 }
1853
1854 TEST_F(GLES2DecoderWithShaderTest, Uniform1iValidArgs) {
1855   EXPECT_CALL(*gl_, Uniform1i(kUniform1RealLocation, 2));
1856   Uniform1i cmd;
1857   cmd.Init(kUniform1FakeLocation, 2);
1858   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1859 }
1860
1861 TEST_F(GLES2DecoderWithShaderTest, Uniform1ivValidArgs) {
1862   EXPECT_CALL(
1863       *gl_, Uniform1iv(kUniform1RealLocation, 1,
1864           reinterpret_cast<const GLint*>(shared_memory_address_)));
1865   Uniform1iv cmd;
1866   cmd.Init(kUniform1FakeLocation,
1867            1, shared_memory_id_, shared_memory_offset_);
1868   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1869 }
1870
1871 TEST_F(GLES2DecoderWithShaderTest, Uniform1ivInvalidArgs2_0) {
1872   EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
1873   Uniform1iv cmd;
1874   cmd.Init(kUniform1FakeLocation,
1875            1, kInvalidSharedMemoryId, 0);
1876   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
1877 }
1878
1879 TEST_F(GLES2DecoderWithShaderTest, Uniform1ivInvalidArgs2_1) {
1880   EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
1881   Uniform1iv cmd;
1882   cmd.Init(kUniform1FakeLocation,
1883            1, shared_memory_id_, kInvalidSharedMemoryOffset);
1884   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
1885 }
1886
1887 TEST_F(GLES2DecoderWithShaderTest, Uniform1ivImmediateValidArgs) {
1888   Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
1889   EXPECT_CALL(
1890       *gl_,
1891       Uniform1iv(kUniform1RealLocation, 1,
1892           reinterpret_cast<GLint*>(ImmediateDataAddress(&cmd))));
1893   GLint temp[1 * 2] = { 0, };
1894   cmd.Init(kUniform1FakeLocation, 1,
1895            &temp[0]);
1896   EXPECT_EQ(error::kNoError,
1897             ExecuteImmediateCmd(cmd, sizeof(temp)));
1898 }
1899
1900 TEST_F(GLES2DecoderWithShaderTest, Uniform1ivInvalidValidArgs) {
1901   EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
1902   Uniform1iv cmd;
1903   cmd.Init(kUniform1FakeLocation,
1904            2, shared_memory_id_, shared_memory_offset_);
1905   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1906   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1907 }
1908
1909 TEST_F(GLES2DecoderWithShaderTest, Uniform1ivZeroCount) {
1910   EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
1911   Uniform1iv cmd;
1912   cmd.Init(kUniform1FakeLocation,
1913            0, shared_memory_id_, shared_memory_offset_);
1914   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1915   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1916 }
1917
1918 TEST_F(GLES2DecoderWithShaderTest, Uniform1iSamplerIsLmited) {
1919   EXPECT_CALL(*gl_, Uniform1i(_, _)).Times(0);
1920   Uniform1i cmd;
1921   cmd.Init(
1922       kUniform1FakeLocation,
1923       kNumTextureUnits);
1924   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1925   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1926 }
1927
1928 TEST_F(GLES2DecoderWithShaderTest, Uniform1ivSamplerIsLimited) {
1929   EXPECT_CALL(*gl_, Uniform1iv(_, _, _)).Times(0);
1930   Uniform1ivImmediate& cmd = *GetImmediateAs<Uniform1ivImmediate>();
1931   GLint temp[] = { kNumTextureUnits };
1932   cmd.Init(kUniform1FakeLocation, 1,
1933            &temp[0]);
1934   EXPECT_EQ(error::kNoError,
1935             ExecuteImmediateCmd(cmd, sizeof(temp)));
1936   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1937 }
1938
1939 TEST_F(GLES2DecoderWithShaderTest, BindBufferToDifferentTargetFails) {
1940   // Bind the buffer to GL_ARRAY_BUFFER
1941   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
1942   // Attempt to rebind to GL_ELEMENT_ARRAY_BUFFER
1943   // NOTE: Real GLES2 does not have this restriction but WebGL and we do.
1944   // This can be restriction can be removed at runtime.
1945   EXPECT_CALL(*gl_, BindBuffer(_, _))
1946       .Times(0);
1947   BindBuffer cmd;
1948   cmd.Init(GL_ELEMENT_ARRAY_BUFFER, client_buffer_id_);
1949   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1950   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1951 }
1952
1953 TEST_F(GLES2DecoderTest, ActiveTextureValidArgs) {
1954   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
1955   SpecializedSetup<ActiveTexture, 0>(true);
1956   ActiveTexture cmd;
1957   cmd.Init(GL_TEXTURE1);
1958   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1959   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1960 }
1961
1962 TEST_F(GLES2DecoderTest, ActiveTextureInvalidArgs) {
1963   EXPECT_CALL(*gl_, ActiveTexture(_)).Times(0);
1964   SpecializedSetup<ActiveTexture, 0>(false);
1965   ActiveTexture cmd;
1966   cmd.Init(GL_TEXTURE0 - 1);
1967   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1968   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1969   cmd.Init(kNumTextureUnits);
1970   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1971   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1972 }
1973
1974 TEST_F(GLES2DecoderTest, CheckFramebufferStatusWithNoBoundTarget) {
1975   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_))
1976       .Times(0);
1977   CheckFramebufferStatus::Result* result =
1978       static_cast<CheckFramebufferStatus::Result*>(shared_memory_address_);
1979   *result = 0;
1980   CheckFramebufferStatus cmd;
1981   cmd.Init(GL_FRAMEBUFFER, shared_memory_id_, shared_memory_offset_);
1982   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1983   EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), *result);
1984 }
1985
1986 TEST_F(GLES2DecoderWithShaderTest, BindAndDeleteFramebuffer) {
1987   SetupTexture();
1988   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
1989   SetupExpectationsForApplyingDefaultDirtyState();
1990   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
1991                     kServiceFramebufferId);
1992   DoDeleteFramebuffer(
1993       client_framebuffer_id_, kServiceFramebufferId,
1994       true, GL_FRAMEBUFFER, 0,
1995       true, GL_FRAMEBUFFER, 0);
1996   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
1997       .Times(1)
1998       .RetiresOnSaturation();
1999   DrawArrays cmd;
2000   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
2001   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2002   EXPECT_EQ(GL_NO_ERROR, GetGLError());
2003 }
2004
2005 TEST_F(GLES2DecoderTest, FramebufferRenderbufferWithNoBoundTarget) {
2006   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _))
2007       .Times(0);
2008   FramebufferRenderbuffer cmd;
2009   cmd.Init(
2010       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2011       client_renderbuffer_id_);
2012   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2013   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2014 }
2015
2016 TEST_F(GLES2DecoderTest, FramebufferTexture2DWithNoBoundTarget) {
2017   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _))
2018       .Times(0);
2019   FramebufferTexture2D cmd;
2020   cmd.Init(
2021       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
2022       0);
2023   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2024   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2025 }
2026
2027 TEST_F(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithNoBoundTarget) {
2028   EXPECT_CALL(*gl_, GetError())
2029       .WillOnce(Return(GL_NO_ERROR))
2030       .WillOnce(Return(GL_NO_ERROR))
2031       .RetiresOnSaturation();
2032   EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
2033       .Times(0);
2034   GetFramebufferAttachmentParameteriv cmd;
2035   cmd.Init(
2036       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2037       GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, shared_memory_id_,
2038       shared_memory_offset_);
2039   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2040   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2041 }
2042
2043 TEST_F(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithRenderbuffer) {
2044   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
2045                     kServiceFramebufferId);
2046   EXPECT_CALL(*gl_, GetError())
2047       .WillOnce(Return(GL_NO_ERROR))
2048       .RetiresOnSaturation();
2049   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
2050       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2051       kServiceRenderbufferId))
2052       .Times(1)
2053       .RetiresOnSaturation();
2054   EXPECT_CALL(*gl_, GetError())
2055       .WillOnce(Return(GL_NO_ERROR))
2056       .RetiresOnSaturation();
2057   EXPECT_CALL(*gl_, GetError())
2058       .WillOnce(Return(GL_NO_ERROR))
2059       .WillOnce(Return(GL_NO_ERROR))
2060       .RetiresOnSaturation();
2061   GetFramebufferAttachmentParameteriv::Result* result =
2062       static_cast<GetFramebufferAttachmentParameteriv::Result*>(
2063           shared_memory_address_);
2064   result->size = 0;
2065   const GLint* result_value = result->GetData();
2066   FramebufferRenderbuffer fbrb_cmd;
2067   GetFramebufferAttachmentParameteriv cmd;
2068   fbrb_cmd.Init(
2069       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2070       client_renderbuffer_id_);
2071   cmd.Init(
2072       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2073       GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, shared_memory_id_,
2074       shared_memory_offset_);
2075   EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
2076   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2077   EXPECT_EQ(GL_NO_ERROR, GetGLError());
2078   EXPECT_EQ(static_cast<GLuint>(*result_value), client_renderbuffer_id_);
2079 }
2080
2081 TEST_F(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithTexture) {
2082   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
2083                     kServiceFramebufferId);
2084   EXPECT_CALL(*gl_, GetError())
2085       .WillOnce(Return(GL_NO_ERROR))
2086       .RetiresOnSaturation();
2087   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
2088       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
2089       kServiceTextureId, 0))
2090       .Times(1)
2091       .RetiresOnSaturation();
2092   EXPECT_CALL(*gl_, GetError())
2093       .WillOnce(Return(GL_NO_ERROR))
2094       .RetiresOnSaturation();
2095   EXPECT_CALL(*gl_, GetError())
2096       .WillOnce(Return(GL_NO_ERROR))
2097       .WillOnce(Return(GL_NO_ERROR))
2098       .RetiresOnSaturation();
2099   GetFramebufferAttachmentParameteriv::Result* result =
2100       static_cast<GetFramebufferAttachmentParameteriv::Result*>(
2101           shared_memory_address_);
2102   result->SetNumResults(0);
2103   const GLint* result_value = result->GetData();
2104   FramebufferTexture2D fbtex_cmd;
2105   GetFramebufferAttachmentParameteriv cmd;
2106   fbtex_cmd.Init(
2107       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
2108       0);
2109   cmd.Init(
2110       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2111       GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, shared_memory_id_,
2112       shared_memory_offset_);
2113   EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
2114   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2115   EXPECT_EQ(GL_NO_ERROR, GetGLError());
2116   EXPECT_EQ(static_cast<GLuint>(*result_value), client_texture_id_);
2117 }
2118
2119 TEST_F(GLES2DecoderTest, GetRenderbufferParameterivWithNoBoundTarget) {
2120   EXPECT_CALL(*gl_, GetError())
2121       .WillOnce(Return(GL_NO_ERROR))
2122       .WillOnce(Return(GL_NO_ERROR))
2123       .RetiresOnSaturation();
2124   EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _))
2125       .Times(0);
2126   GetRenderbufferParameteriv cmd;
2127   cmd.Init(
2128       GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, shared_memory_id_,
2129       shared_memory_offset_);
2130   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2131   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2132 }
2133
2134 TEST_F(GLES2DecoderTest, RenderbufferStorageWithNoBoundTarget) {
2135   EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _))
2136       .Times(0);
2137   RenderbufferStorage cmd;
2138   cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, 4);
2139   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2140   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2141 }
2142
2143 namespace {
2144
2145 // A class to emulate glReadPixels
2146 class ReadPixelsEmulator {
2147  public:
2148   // pack_alignment is the alignment you want ReadPixels to use
2149   // when copying. The actual data passed in pixels should be contiguous.
2150   ReadPixelsEmulator(GLsizei width, GLsizei height, GLint bytes_per_pixel,
2151                      const void* src_pixels, const void* expected_pixels,
2152                      GLint pack_alignment)
2153       : width_(width),
2154         height_(height),
2155         pack_alignment_(pack_alignment),
2156         bytes_per_pixel_(bytes_per_pixel),
2157         src_pixels_(reinterpret_cast<const int8*>(src_pixels)),
2158         expected_pixels_(reinterpret_cast<const int8*>(expected_pixels)) {
2159   }
2160
2161   void ReadPixels(
2162       GLint x, GLint y, GLsizei width, GLsizei height,
2163       GLenum format, GLenum type, void* pixels) const {
2164     DCHECK_GE(x, 0);
2165     DCHECK_GE(y, 0);
2166     DCHECK_LE(x + width, width_);
2167     DCHECK_LE(y + height, height_);
2168     for (GLint yy = 0; yy < height; ++yy) {
2169       const int8* src = GetPixelAddress(src_pixels_, x, y + yy);
2170       const void* dst = ComputePackAlignmentAddress(0, yy, width, pixels);
2171       memcpy(const_cast<void*>(dst), src, width * bytes_per_pixel_);
2172     }
2173   }
2174
2175   bool CompareRowSegment(
2176       GLint x, GLint y, GLsizei width, const void* data) const {
2177     DCHECK(x + width <= width_ || width == 0);
2178     return memcmp(data, GetPixelAddress(expected_pixels_, x, y),
2179                   width * bytes_per_pixel_) == 0;
2180   }
2181
2182   // Helper to compute address of pixel in pack aligned data.
2183   const void* ComputePackAlignmentAddress(
2184       GLint x, GLint y, GLsizei width, const void* address) const {
2185     GLint unpadded_row_size = ComputeImageDataSize(width, 1);
2186     GLint two_rows_size = ComputeImageDataSize(width, 2);
2187     GLsizei padded_row_size = two_rows_size - unpadded_row_size;
2188     GLint offset = y * padded_row_size + x * bytes_per_pixel_;
2189     return static_cast<const int8*>(address) + offset;
2190   }
2191
2192   GLint ComputeImageDataSize(GLint width, GLint height) const {
2193     GLint row_size = width * bytes_per_pixel_;
2194     if (height > 1) {
2195       GLint temp = row_size + pack_alignment_ - 1;
2196       GLint padded_row_size = (temp / pack_alignment_) * pack_alignment_;
2197       GLint size_of_all_but_last_row = (height - 1) * padded_row_size;
2198       return size_of_all_but_last_row + row_size;
2199     } else {
2200       return height * row_size;
2201     }
2202   }
2203
2204  private:
2205   const int8* GetPixelAddress(const int8* base, GLint x, GLint y) const {
2206     return base + (width_ * y + x) * bytes_per_pixel_;
2207   }
2208
2209   GLsizei width_;
2210   GLsizei height_;
2211   GLint pack_alignment_;
2212   GLint bytes_per_pixel_;
2213   const int8* src_pixels_;
2214   const int8* expected_pixels_;
2215 };
2216
2217 }  // anonymous namespace
2218
2219 void GLES2DecoderTest::CheckReadPixelsOutOfRange(
2220     GLint in_read_x, GLint in_read_y,
2221     GLsizei in_read_width, GLsizei in_read_height,
2222     bool init) {
2223   const GLsizei kWidth = 5;
2224   const GLsizei kHeight = 3;
2225   const GLint kBytesPerPixel = 3;
2226   const GLint kPackAlignment = 4;
2227   const GLenum kFormat = GL_RGB;
2228   static const int8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
2229     12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 18, 19, 13,
2230     29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21, 22, 21, 28,
2231     31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32, 37, 32, 34,
2232   };
2233
2234   ClearSharedMemory();
2235
2236   // We need to setup an FBO so we can know the max size that ReadPixels will
2237   // access
2238   if (init) {
2239     DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
2240     DoTexImage2D(
2241         GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0,
2242         kFormat, GL_UNSIGNED_BYTE, kSharedMemoryId,
2243         kSharedMemoryOffset);
2244     DoBindFramebuffer(
2245         GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2246     DoFramebufferTexture2D(
2247         GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
2248         client_texture_id_, kServiceTextureId, 0, GL_NO_ERROR);
2249     EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
2250         .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
2251         .RetiresOnSaturation();
2252   }
2253
2254   ReadPixelsEmulator emu(
2255       kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
2256   typedef ReadPixels::Result Result;
2257   Result* result = GetSharedMemoryAs<Result*>();
2258   uint32 result_shm_id = kSharedMemoryId;
2259   uint32 result_shm_offset = kSharedMemoryOffset;
2260   uint32 pixels_shm_id = kSharedMemoryId;
2261   uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
2262   void* dest = &result[1];
2263   EXPECT_CALL(*gl_, GetError())
2264      .WillOnce(Return(GL_NO_ERROR))
2265      .WillOnce(Return(GL_NO_ERROR))
2266      .RetiresOnSaturation();
2267   // ReadPixels will be called for valid size only even though the command
2268   // is requesting a larger size.
2269   GLint read_x = std::max(0, in_read_x);
2270   GLint read_y = std::max(0, in_read_y);
2271   GLint read_end_x = std::max(0, std::min(kWidth, in_read_x + in_read_width));
2272   GLint read_end_y = std::max(0, std::min(kHeight, in_read_y + in_read_height));
2273   GLint read_width = read_end_x - read_x;
2274   GLint read_height = read_end_y - read_y;
2275   if (read_width > 0 && read_height > 0) {
2276     for (GLint yy = read_y; yy < read_end_y; ++yy) {
2277       EXPECT_CALL(
2278           *gl_, ReadPixels(read_x, yy, read_width, 1,
2279                            kFormat, GL_UNSIGNED_BYTE, _))
2280           .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels))
2281           .RetiresOnSaturation();
2282     }
2283   }
2284   ReadPixels cmd;
2285   cmd.Init(in_read_x, in_read_y, in_read_width, in_read_height,
2286            kFormat, GL_UNSIGNED_BYTE,
2287            pixels_shm_id, pixels_shm_offset,
2288            result_shm_id, result_shm_offset,
2289            false);
2290   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2291
2292   GLint unpadded_row_size = emu.ComputeImageDataSize(in_read_width, 1);
2293   scoped_ptr<int8[]> zero(new int8[unpadded_row_size]);
2294   scoped_ptr<int8[]> pack(new int8[kPackAlignment]);
2295   memset(zero.get(), 0, unpadded_row_size);
2296   memset(pack.get(), kInitialMemoryValue, kPackAlignment);
2297   for (GLint yy = 0; yy < in_read_height; ++yy) {
2298     const int8* row = static_cast<const int8*>(
2299         emu.ComputePackAlignmentAddress(0, yy, in_read_width, dest));
2300     GLint y = in_read_y + yy;
2301     if (y < 0 || y >= kHeight) {
2302       EXPECT_EQ(0, memcmp(zero.get(), row, unpadded_row_size));
2303     } else {
2304       // check off left.
2305       GLint num_left_pixels = std::max(-in_read_x, 0);
2306       GLint num_left_bytes = num_left_pixels * kBytesPerPixel;
2307       EXPECT_EQ(0, memcmp(zero.get(), row, num_left_bytes));
2308
2309       // check off right.
2310       GLint num_right_pixels = std::max(in_read_x + in_read_width - kWidth, 0);
2311       GLint num_right_bytes = num_right_pixels * kBytesPerPixel;
2312       EXPECT_EQ(0, memcmp(zero.get(),
2313                             row + unpadded_row_size - num_right_bytes,
2314                             num_right_bytes));
2315
2316       // check middle.
2317       GLint x = std::max(in_read_x, 0);
2318       GLint num_middle_pixels =
2319           std::max(in_read_width - num_left_pixels - num_right_pixels, 0);
2320       EXPECT_TRUE(emu.CompareRowSegment(
2321           x, y, num_middle_pixels, row + num_left_bytes));
2322     }
2323
2324     // check padding
2325     if (yy != in_read_height - 1) {
2326       GLint num_padding_bytes =
2327           (kPackAlignment - 1) - (unpadded_row_size % kPackAlignment);
2328       EXPECT_EQ(0,
2329                 memcmp(pack.get(), row + unpadded_row_size, num_padding_bytes));
2330     }
2331   }
2332 }
2333
2334 TEST_F(GLES2DecoderTest, ReadPixels) {
2335   const GLsizei kWidth = 5;
2336   const GLsizei kHeight = 3;
2337   const GLint kBytesPerPixel = 3;
2338   const GLint kPackAlignment = 4;
2339   static const int8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
2340     12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 18, 19, 13,
2341     29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21, 22, 21, 28,
2342     31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32, 37, 32, 34,
2343   };
2344
2345   surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
2346
2347   ReadPixelsEmulator emu(
2348       kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
2349   typedef ReadPixels::Result Result;
2350   Result* result = GetSharedMemoryAs<Result*>();
2351   uint32 result_shm_id = kSharedMemoryId;
2352   uint32 result_shm_offset = kSharedMemoryOffset;
2353   uint32 pixels_shm_id = kSharedMemoryId;
2354   uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
2355   void* dest = &result[1];
2356   EXPECT_CALL(*gl_, GetError())
2357      .WillOnce(Return(GL_NO_ERROR))
2358      .WillOnce(Return(GL_NO_ERROR))
2359      .RetiresOnSaturation();
2360   EXPECT_CALL(
2361       *gl_, ReadPixels(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, _))
2362       .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
2363   ReadPixels cmd;
2364   cmd.Init(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE,
2365            pixels_shm_id, pixels_shm_offset,
2366            result_shm_id, result_shm_offset,
2367            false);
2368   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2369   for (GLint yy = 0; yy < kHeight; ++yy) {
2370     EXPECT_TRUE(emu.CompareRowSegment(
2371         0, yy, kWidth,
2372         emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
2373   }
2374 }
2375
2376 TEST_F(GLES2DecoderRGBBackbufferTest, ReadPixelsNoAlphaBackbuffer) {
2377   const GLsizei kWidth = 3;
2378   const GLsizei kHeight = 3;
2379   const GLint kBytesPerPixel = 4;
2380   const GLint kPackAlignment = 4;
2381   static const uint8 kExpectedPixels[kWidth * kHeight * kBytesPerPixel] = {
2382     12, 13, 14, 255, 19, 18, 19, 255, 13, 14, 18, 255,
2383     29, 28, 23, 255, 21, 22, 21, 255, 28, 23, 22, 255,
2384     31, 34, 39, 255, 32, 37, 32, 255, 34, 39, 37, 255,
2385   };
2386   static const uint8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
2387     12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19,
2388     29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21,
2389     31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32,
2390   };
2391
2392   surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
2393
2394   ReadPixelsEmulator emu(
2395       kWidth, kHeight, kBytesPerPixel, kSrcPixels, kExpectedPixels,
2396       kPackAlignment);
2397   typedef ReadPixels::Result Result;
2398   Result* result = GetSharedMemoryAs<Result*>();
2399   uint32 result_shm_id = kSharedMemoryId;
2400   uint32 result_shm_offset = kSharedMemoryOffset;
2401   uint32 pixels_shm_id = kSharedMemoryId;
2402   uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
2403   void* dest = &result[1];
2404   EXPECT_CALL(*gl_, GetError())
2405      .WillOnce(Return(GL_NO_ERROR))
2406      .WillOnce(Return(GL_NO_ERROR))
2407      .RetiresOnSaturation();
2408   EXPECT_CALL(
2409       *gl_, ReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, _))
2410       .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
2411   ReadPixels cmd;
2412   cmd.Init(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
2413            pixels_shm_id, pixels_shm_offset,
2414            result_shm_id, result_shm_offset,
2415            false);
2416   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2417   for (GLint yy = 0; yy < kHeight; ++yy) {
2418     EXPECT_TRUE(emu.CompareRowSegment(
2419         0, yy, kWidth,
2420         emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
2421   }
2422 }
2423
2424 TEST_F(GLES2DecoderTest, ReadPixelsOutOfRange) {
2425   static GLint tests[][4] = {
2426     { -2, -1, 9, 5, },  // out of range on all sides
2427     { 2, 1, 9, 5, },  // out of range on right, bottom
2428     { -7, -4, 9, 5, },  // out of range on left, top
2429     { 0, -5, 9, 5, },  // completely off top
2430     { 0, 3, 9, 5, },  // completely off bottom
2431     { -9, 0, 9, 5, },  // completely off left
2432     { 5, 0, 9, 5, },  // completely off right
2433   };
2434
2435   for (size_t tt = 0; tt < arraysize(tests); ++tt) {
2436     CheckReadPixelsOutOfRange(
2437         tests[tt][0], tests[tt][1], tests[tt][2], tests[tt][3], tt == 0);
2438   }
2439 }
2440
2441 TEST_F(GLES2DecoderTest, ReadPixelsInvalidArgs) {
2442   typedef ReadPixels::Result Result;
2443   Result* result = GetSharedMemoryAs<Result*>();
2444   uint32 result_shm_id = kSharedMemoryId;
2445   uint32 result_shm_offset = kSharedMemoryOffset;
2446   uint32 pixels_shm_id = kSharedMemoryId;
2447   uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
2448   EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0);
2449   ReadPixels cmd;
2450   cmd.Init(0, 0, -1, 1, GL_RGB, GL_UNSIGNED_BYTE,
2451            pixels_shm_id, pixels_shm_offset,
2452            result_shm_id, result_shm_offset,
2453            false);
2454   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2455   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2456   cmd.Init(0, 0, 1, -1, GL_RGB, GL_UNSIGNED_BYTE,
2457            pixels_shm_id, pixels_shm_offset,
2458            result_shm_id, result_shm_offset,
2459            false);
2460   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2461   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2462   cmd.Init(0, 0, 1, 1, GL_RGB, GL_INT,
2463            pixels_shm_id, pixels_shm_offset,
2464            result_shm_id, result_shm_offset,
2465            false);
2466   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2467   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
2468   cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
2469            kInvalidSharedMemoryId, pixels_shm_offset,
2470            result_shm_id, result_shm_offset,
2471            false);
2472   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2473   cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
2474            pixels_shm_id, kInvalidSharedMemoryOffset,
2475            result_shm_id, result_shm_offset,
2476            false);
2477   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2478   cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
2479            pixels_shm_id, pixels_shm_offset,
2480            kInvalidSharedMemoryId, result_shm_offset,
2481            false);
2482   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2483   cmd.Init(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE,
2484            pixels_shm_id, pixels_shm_offset,
2485            result_shm_id, kInvalidSharedMemoryOffset,
2486            false);
2487   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2488 }
2489
2490 TEST_F(GLES2DecoderTest, BindAttribLocation) {
2491   const GLint kLocation = 2;
2492   const char* kName = "testing";
2493   const uint32 kNameSize = strlen(kName);
2494   EXPECT_CALL(
2495       *gl_, BindAttribLocation(kServiceProgramId, kLocation, StrEq(kName)))
2496       .Times(1);
2497   memcpy(shared_memory_address_, kName, kNameSize);
2498   BindAttribLocation cmd;
2499   cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
2500            kNameSize);
2501   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2502 }
2503
2504 TEST_F(GLES2DecoderTest, BindAttribLocationInvalidArgs) {
2505   const GLint kLocation = 2;
2506   const char* kName = "testing";
2507   const char* kBadName = "test\aing";
2508   const uint32 kNameSize = strlen(kName);
2509   const uint32 kBadNameSize = strlen(kBadName);
2510   EXPECT_CALL(*gl_, BindAttribLocation(_, _, _)).Times(0);
2511   memcpy(shared_memory_address_, kName, kNameSize);
2512   BindAttribLocation cmd;
2513   cmd.Init(kInvalidClientId, kLocation,
2514            kSharedMemoryId, kSharedMemoryOffset, kNameSize);
2515   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2516   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2517   cmd.Init(client_program_id_, kLocation,
2518            kInvalidSharedMemoryId, kSharedMemoryOffset, kNameSize);
2519   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2520   cmd.Init(client_program_id_, kLocation,
2521            kSharedMemoryId, kInvalidSharedMemoryOffset, kNameSize);
2522   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2523   cmd.Init(client_program_id_, kLocation,
2524            kSharedMemoryId, kSharedMemoryOffset, kSharedBufferSize);
2525   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2526   memcpy(shared_memory_address_, kBadName, kBadNameSize);
2527   cmd.Init(client_program_id_, kLocation,
2528            kSharedMemoryId, kSharedMemoryOffset, kBadNameSize);
2529   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2530   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2531 }
2532
2533 TEST_F(GLES2DecoderTest, BindAttribLocationBucket) {
2534   const uint32 kBucketId = 123;
2535   const GLint kLocation = 2;
2536   const char* kName = "testing";
2537   EXPECT_CALL(
2538       *gl_, BindAttribLocation(kServiceProgramId, kLocation, StrEq(kName)))
2539       .Times(1);
2540   SetBucketAsCString(kBucketId, kName);
2541   BindAttribLocationBucket cmd;
2542   cmd.Init(client_program_id_, kLocation, kBucketId);
2543   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2544 }
2545
2546 TEST_F(GLES2DecoderTest, BindAttribLocationBucketInvalidArgs) {
2547   const uint32 kBucketId = 123;
2548   const GLint kLocation = 2;
2549   const char* kName = "testing";
2550   EXPECT_CALL(*gl_, BindAttribLocation(_, _, _)).Times(0);
2551   BindAttribLocationBucket cmd;
2552   // check bucket does not exist.
2553   cmd.Init(client_program_id_, kLocation, kBucketId);
2554   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2555   // check bucket is empty.
2556   SetBucketAsCString(kBucketId, NULL);
2557   cmd.Init(client_program_id_, kLocation, kBucketId);
2558   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2559   // Check bad program id
2560   SetBucketAsCString(kBucketId, kName);
2561   cmd.Init(kInvalidClientId, kLocation, kBucketId);
2562   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2563   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2564 }
2565
2566 TEST_F(GLES2DecoderWithShaderTest, GetAttribLocation) {
2567   const uint32 kNameSize = strlen(kAttrib2Name);
2568   const char* kNonExistentName = "foobar";
2569   const uint32 kNonExistentNameSize = strlen(kNonExistentName);
2570   typedef GetAttribLocation::Result Result;
2571   Result* result = GetSharedMemoryAs<Result*>();
2572   *result = -1;
2573   char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
2574   const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
2575   memcpy(name, kAttrib2Name, kNameSize);
2576   GetAttribLocation cmd;
2577   cmd.Init(client_program_id_,
2578            kSharedMemoryId, kNameOffset,
2579            kSharedMemoryId, kSharedMemoryOffset,
2580            kNameSize);
2581   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2582   EXPECT_EQ(kAttrib2Location, *result);
2583   *result = -1;
2584   memcpy(name, kNonExistentName, kNonExistentNameSize);
2585   cmd.Init(client_program_id_,
2586            kSharedMemoryId, kNameOffset,
2587            kSharedMemoryId, kSharedMemoryOffset,
2588            kNonExistentNameSize);
2589   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2590   EXPECT_EQ(-1, *result);
2591 }
2592
2593 TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationInvalidArgs) {
2594   const uint32 kNameSize = strlen(kAttrib2Name);
2595   const char* kBadName = "foo\abar";
2596   const uint32 kBadNameSize = strlen(kBadName);
2597   typedef GetAttribLocation::Result Result;
2598   Result* result = GetSharedMemoryAs<Result*>();
2599   *result = -1;
2600   char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
2601   const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
2602   memcpy(name, kAttrib2Name, kNameSize);
2603   GetAttribLocation cmd;
2604   cmd.Init(kInvalidClientId,
2605            kSharedMemoryId, kNameOffset,
2606            kSharedMemoryId, kSharedMemoryOffset,
2607            kNameSize);
2608   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2609   EXPECT_EQ(-1, *result);
2610   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2611   *result = -1;
2612   cmd.Init(client_program_id_,
2613            kInvalidSharedMemoryId, kNameOffset,
2614            kSharedMemoryId, kSharedMemoryOffset,
2615            kNameSize);
2616   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2617   EXPECT_EQ(-1, *result);
2618   cmd.Init(client_program_id_,
2619            kSharedMemoryId, kInvalidSharedMemoryOffset,
2620            kSharedMemoryId, kSharedMemoryOffset,
2621            kNameSize);
2622   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2623   EXPECT_EQ(-1, *result);
2624   cmd.Init(client_program_id_,
2625            kSharedMemoryId, kNameOffset,
2626            kInvalidSharedMemoryId, kSharedMemoryOffset,
2627            kNameSize);
2628   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2629   EXPECT_EQ(-1, *result);
2630   cmd.Init(client_program_id_,
2631            kSharedMemoryId, kNameOffset,
2632            kSharedMemoryId, kInvalidSharedMemoryOffset,
2633            kNameSize);
2634   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2635   EXPECT_EQ(-1, *result);
2636   cmd.Init(client_program_id_,
2637            kSharedMemoryId, kNameOffset,
2638            kSharedMemoryId, kSharedMemoryOffset,
2639            kSharedBufferSize);
2640   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2641   EXPECT_EQ(-1, *result);
2642   memcpy(name, kBadName, kBadNameSize);
2643   cmd.Init(client_program_id_,
2644            kSharedMemoryId, kNameOffset,
2645            kSharedMemoryId, kSharedMemoryOffset,
2646            kBadNameSize);
2647   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2648   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2649 }
2650
2651 TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationBucket) {
2652   const uint32 kBucketId = 123;
2653   const char* kNonExistentName = "foobar";
2654   typedef GetAttribLocationBucket::Result Result;
2655   Result* result = GetSharedMemoryAs<Result*>();
2656   SetBucketAsCString(kBucketId, kAttrib2Name);
2657   *result = -1;
2658   GetAttribLocationBucket cmd;
2659   cmd.Init(client_program_id_, kBucketId,
2660            kSharedMemoryId, kSharedMemoryOffset);
2661   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2662   EXPECT_EQ(kAttrib2Location, *result);
2663   SetBucketAsCString(kBucketId, kNonExistentName);
2664   *result = -1;
2665   cmd.Init(client_program_id_, kBucketId,
2666            kSharedMemoryId, kSharedMemoryOffset);
2667   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2668   EXPECT_EQ(-1, *result);
2669 }
2670
2671 TEST_F(GLES2DecoderWithShaderTest, GetAttribLocationBucketInvalidArgs) {
2672   const uint32 kBucketId = 123;
2673   typedef GetAttribLocationBucket::Result Result;
2674   Result* result = GetSharedMemoryAs<Result*>();
2675   *result = -1;
2676   GetAttribLocationBucket cmd;
2677   // Check no bucket
2678   cmd.Init(client_program_id_, kBucketId,
2679            kSharedMemoryId, kSharedMemoryOffset);
2680   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2681   EXPECT_EQ(-1, *result);
2682   // Check bad program id.
2683   SetBucketAsCString(kBucketId, kAttrib2Name);
2684   cmd.Init(kInvalidClientId, kBucketId,
2685            kSharedMemoryId, kSharedMemoryOffset);
2686   *result = -1;
2687   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2688   EXPECT_EQ(-1, *result);
2689   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2690   // Check bad memory
2691   cmd.Init(client_program_id_, kBucketId,
2692            kInvalidSharedMemoryId, kSharedMemoryOffset);
2693   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2694   cmd.Init(client_program_id_, kBucketId,
2695            kSharedMemoryId, kInvalidSharedMemoryOffset);
2696   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2697 }
2698
2699 TEST_F(GLES2DecoderWithShaderTest, GetUniformLocation) {
2700   const uint32 kNameSize = strlen(kUniform2Name);
2701   const char* kNonExistentName = "foobar";
2702   const uint32 kNonExistentNameSize = strlen(kNonExistentName);
2703   typedef GetUniformLocation::Result Result;
2704   Result* result = GetSharedMemoryAs<Result*>();
2705   *result = -1;
2706   char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
2707   const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
2708   memcpy(name, kUniform2Name, kNameSize);
2709   GetUniformLocation cmd;
2710   cmd.Init(client_program_id_,
2711            kSharedMemoryId, kNameOffset,
2712            kSharedMemoryId, kSharedMemoryOffset,
2713            kNameSize);
2714   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2715   EXPECT_EQ(kUniform2FakeLocation, *result);
2716   memcpy(name, kNonExistentName, kNonExistentNameSize);
2717   *result = -1;
2718   cmd.Init(client_program_id_,
2719            kSharedMemoryId, kNameOffset,
2720            kSharedMemoryId, kSharedMemoryOffset,
2721            kNonExistentNameSize);
2722   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2723   EXPECT_EQ(-1, *result);
2724 }
2725
2726 TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationInvalidArgs) {
2727   const uint32 kNameSize = strlen(kUniform2Name);
2728   const char* kBadName = "foo\abar";
2729   const uint32 kBadNameSize = strlen(kBadName);
2730   typedef GetUniformLocation::Result Result;
2731   Result* result = GetSharedMemoryAs<Result*>();
2732   *result = -1;
2733   char* name = GetSharedMemoryAsWithOffset<char*>(sizeof(*result));
2734   const uint32 kNameOffset = kSharedMemoryOffset + sizeof(*result);
2735   memcpy(name, kUniform2Name, kNameSize);
2736   GetUniformLocation cmd;
2737   cmd.Init(kInvalidClientId,
2738            kSharedMemoryId, kNameOffset,
2739            kSharedMemoryId, kSharedMemoryOffset,
2740            kNameSize);
2741   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2742   EXPECT_EQ(-1, *result);
2743   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2744   *result = -1;
2745   cmd.Init(client_program_id_,
2746            kInvalidSharedMemoryId, kNameOffset,
2747            kSharedMemoryId, kSharedMemoryOffset,
2748            kNameSize);
2749   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2750   EXPECT_EQ(-1, *result);
2751   cmd.Init(client_program_id_,
2752            kSharedMemoryId, kInvalidSharedMemoryOffset,
2753            kSharedMemoryId, kSharedMemoryOffset,
2754            kNameSize);
2755   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2756   EXPECT_EQ(-1, *result);
2757   cmd.Init(client_program_id_,
2758            kSharedMemoryId, kNameOffset,
2759            kInvalidSharedMemoryId, kSharedMemoryOffset,
2760            kNameSize);
2761   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2762   EXPECT_EQ(-1, *result);
2763   cmd.Init(client_program_id_,
2764            kSharedMemoryId, kNameOffset,
2765            kSharedMemoryId, kInvalidSharedMemoryOffset,
2766            kNameSize);
2767   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2768   EXPECT_EQ(-1, *result);
2769   cmd.Init(client_program_id_,
2770            kSharedMemoryId, kNameOffset,
2771            kSharedMemoryId, kSharedMemoryOffset,
2772            kSharedBufferSize);
2773   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2774   EXPECT_EQ(-1, *result);
2775   memcpy(name, kBadName, kBadNameSize);
2776   cmd.Init(client_program_id_,
2777            kSharedMemoryId, kNameOffset,
2778            kSharedMemoryId, kSharedMemoryOffset,
2779            kBadNameSize);
2780   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2781   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2782 }
2783
2784 TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationBucket) {
2785   const uint32 kBucketId = 123;
2786   const char* kNonExistentName = "foobar";
2787   typedef GetUniformLocationBucket::Result Result;
2788   Result* result = GetSharedMemoryAs<Result*>();
2789   SetBucketAsCString(kBucketId, kUniform2Name);
2790   *result = -1;
2791   GetUniformLocationBucket cmd;
2792   cmd.Init(client_program_id_, kBucketId,
2793            kSharedMemoryId, kSharedMemoryOffset);
2794   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2795   EXPECT_EQ(kUniform2FakeLocation, *result);
2796   SetBucketAsCString(kBucketId, kNonExistentName);
2797   *result = -1;
2798   cmd.Init(client_program_id_, kBucketId,
2799            kSharedMemoryId, kSharedMemoryOffset);
2800   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2801   EXPECT_EQ(-1, *result);
2802 }
2803
2804 TEST_F(GLES2DecoderWithShaderTest, GetUniformLocationBucketInvalidArgs) {
2805   const uint32 kBucketId = 123;
2806   typedef GetUniformLocationBucket::Result Result;
2807   Result* result = GetSharedMemoryAs<Result*>();
2808   *result = -1;
2809   GetUniformLocationBucket cmd;
2810   // Check no bucket
2811   cmd.Init(client_program_id_, kBucketId,
2812            kSharedMemoryId, kSharedMemoryOffset);
2813   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2814   EXPECT_EQ(-1, *result);
2815   // Check bad program id.
2816   SetBucketAsCString(kBucketId, kUniform2Name);
2817   cmd.Init(kInvalidClientId, kBucketId,
2818            kSharedMemoryId, kSharedMemoryOffset);
2819   *result = -1;
2820   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2821   EXPECT_EQ(-1, *result);
2822   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2823   // Check bad memory
2824   cmd.Init(client_program_id_, kBucketId,
2825            kInvalidSharedMemoryId, kSharedMemoryOffset);
2826   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2827   cmd.Init(client_program_id_, kBucketId,
2828            kSharedMemoryId, kInvalidSharedMemoryOffset);
2829   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2830 }
2831
2832 TEST_F(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) {
2833   SetupIndexBuffer();
2834   GetMaxValueInBufferCHROMIUM::Result* result =
2835       static_cast<GetMaxValueInBufferCHROMIUM::Result*>(shared_memory_address_);
2836   *result = 0;
2837
2838   GetMaxValueInBufferCHROMIUM cmd;
2839   cmd.Init(client_element_buffer_id_, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
2840            kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
2841   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2842   EXPECT_EQ(7u, *result);
2843   EXPECT_EQ(GL_NO_ERROR, GetGLError());
2844   cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
2845            GL_UNSIGNED_SHORT,
2846            kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
2847   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2848   EXPECT_EQ(100u, *result);
2849   EXPECT_EQ(GL_NO_ERROR, GetGLError());
2850
2851   cmd.Init(kInvalidClientId, kValidIndexRangeCount,
2852            GL_UNSIGNED_SHORT,
2853            kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
2854   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2855   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2856   cmd.Init(client_element_buffer_id_, kOutOfRangeIndexRangeEnd,
2857            GL_UNSIGNED_SHORT,
2858            kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
2859   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2860   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2861   cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
2862            GL_UNSIGNED_SHORT,
2863            kOutOfRangeIndexRangeEnd * 2, kSharedMemoryId, kSharedMemoryOffset);
2864   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2865   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2866   cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
2867            GL_UNSIGNED_SHORT,
2868            kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
2869   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2870   cmd.Init(client_buffer_id_, kValidIndexRangeCount + 1,
2871            GL_UNSIGNED_SHORT,
2872            kValidIndexRangeStart * 2, kSharedMemoryId, kSharedMemoryOffset);
2873   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2874   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2875   cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
2876            GL_UNSIGNED_SHORT,
2877            kValidIndexRangeStart * 2,
2878            kInvalidSharedMemoryId, kSharedMemoryOffset);
2879   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2880   cmd.Init(client_element_buffer_id_, kValidIndexRangeCount + 1,
2881            GL_UNSIGNED_SHORT,
2882            kValidIndexRangeStart * 2,
2883            kSharedMemoryId, kInvalidSharedMemoryOffset);
2884   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2885 }
2886
2887 TEST_F(GLES2DecoderTest, SharedIds) {
2888   GenSharedIdsCHROMIUM gen_cmd;
2889   RegisterSharedIdsCHROMIUM reg_cmd;
2890   DeleteSharedIdsCHROMIUM del_cmd;
2891
2892   const GLuint kNamespaceId = id_namespaces::kTextures;
2893   const GLuint kExpectedId1 = 1;
2894   const GLuint kExpectedId2 = 2;
2895   const GLuint kExpectedId3 = 4;
2896   const GLuint kRegisterId = 3;
2897   GLuint* ids = GetSharedMemoryAs<GLuint*>();
2898   gen_cmd.Init(kNamespaceId, 0, 2, kSharedMemoryId, kSharedMemoryOffset);
2899   EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
2900   IdAllocatorInterface* id_allocator = GetIdAllocator(kNamespaceId);
2901   ASSERT_TRUE(id_allocator != NULL);
2902   // This check is implementation dependant but it's kind of hard to check
2903   // otherwise.
2904   EXPECT_EQ(kExpectedId1, ids[0]);
2905   EXPECT_EQ(kExpectedId2, ids[1]);
2906   EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
2907   EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
2908   EXPECT_FALSE(id_allocator->InUse(kRegisterId));
2909   EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
2910
2911   ClearSharedMemory();
2912   ids[0] = kRegisterId;
2913   reg_cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
2914   EXPECT_EQ(error::kNoError, ExecuteCmd(reg_cmd));
2915   EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
2916   EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
2917   EXPECT_TRUE(id_allocator->InUse(kRegisterId));
2918   EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
2919
2920   ClearSharedMemory();
2921   gen_cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kSharedMemoryOffset);
2922   EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
2923   EXPECT_EQ(kExpectedId3, ids[0]);
2924   EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
2925   EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
2926   EXPECT_TRUE(id_allocator->InUse(kRegisterId));
2927   EXPECT_TRUE(id_allocator->InUse(kExpectedId3));
2928
2929   ClearSharedMemory();
2930   ids[0] = kExpectedId1;
2931   ids[1] = kRegisterId;
2932   del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset);
2933   EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd));
2934   EXPECT_FALSE(id_allocator->InUse(kExpectedId1));
2935   EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
2936   EXPECT_FALSE(id_allocator->InUse(kRegisterId));
2937   EXPECT_TRUE(id_allocator->InUse(kExpectedId3));
2938
2939   ClearSharedMemory();
2940   ids[0] = kExpectedId3;
2941   ids[1] = kExpectedId2;
2942   del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset);
2943   EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd));
2944   EXPECT_FALSE(id_allocator->InUse(kExpectedId1));
2945   EXPECT_FALSE(id_allocator->InUse(kExpectedId2));
2946   EXPECT_FALSE(id_allocator->InUse(kRegisterId));
2947   EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
2948
2949   // Check passing in an id_offset.
2950   ClearSharedMemory();
2951   const GLuint kOffset = 0xABCDEF;
2952   gen_cmd.Init(kNamespaceId, kOffset, 2, kSharedMemoryId, kSharedMemoryOffset);
2953   EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
2954   EXPECT_EQ(kOffset, ids[0]);
2955   EXPECT_EQ(kOffset + 1, ids[1]);
2956 }
2957
2958 TEST_F(GLES2DecoderTest, GenSharedIdsCHROMIUMBadArgs) {
2959   const GLuint kNamespaceId = id_namespaces::kTextures;
2960   GenSharedIdsCHROMIUM cmd;
2961   cmd.Init(kNamespaceId, 0, -1, kSharedMemoryId, kSharedMemoryOffset);
2962   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2963   cmd.Init(kNamespaceId, 0, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
2964   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2965   cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
2966   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2967 }
2968
2969 TEST_F(GLES2DecoderTest, RegisterSharedIdsCHROMIUMBadArgs) {
2970   const GLuint kNamespaceId = id_namespaces::kTextures;
2971   RegisterSharedIdsCHROMIUM cmd;
2972   cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
2973   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2974   cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
2975   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2976   cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
2977   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2978 }
2979
2980 TEST_F(GLES2DecoderTest, RegisterSharedIdsCHROMIUMDuplicateIds) {
2981   const GLuint kNamespaceId = id_namespaces::kTextures;
2982   const GLuint kRegisterId = 3;
2983   RegisterSharedIdsCHROMIUM cmd;
2984   GLuint* ids = GetSharedMemoryAs<GLuint*>();
2985   ids[0] = kRegisterId;
2986   cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
2987   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2988   cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
2989   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2990   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
2991 }
2992
2993 TEST_F(GLES2DecoderTest, DeleteSharedIdsCHROMIUMBadArgs) {
2994   const GLuint kNamespaceId = id_namespaces::kTextures;
2995   DeleteSharedIdsCHROMIUM cmd;
2996   cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
2997   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
2998   cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
2999   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
3000   cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
3001   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
3002 }
3003
3004 TEST_F(GLES2DecoderTest, TexSubImage2DValidArgs) {
3005   const int kWidth = 16;
3006   const int kHeight = 8;
3007   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
3008   DoTexImage2D(
3009       GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3010       kSharedMemoryId, kSharedMemoryOffset);
3011   EXPECT_CALL(*gl_, TexSubImage2D(
3012       GL_TEXTURE_2D, 1, 1, 0, kWidth - 1, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
3013       shared_memory_address_))
3014       .Times(1)
3015       .RetiresOnSaturation();
3016   TexSubImage2D cmd;
3017   cmd.Init(
3018       GL_TEXTURE_2D, 1, 1, 0, kWidth - 1, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
3019       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3020   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3021   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3022 }
3023
3024 TEST_F(GLES2DecoderTest, TexSubImage2DBadArgs) {
3025   const int kWidth = 16;
3026   const int kHeight = 8;
3027   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
3028   DoTexImage2D(
3029       GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3030       0, 0);
3031   TexSubImage2D cmd;
3032   cmd.Init(GL_TEXTURE0, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
3033            kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3034   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3035   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
3036   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_TRUE, GL_UNSIGNED_BYTE,
3037            kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3038   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3039   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
3040   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_INT,
3041            kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3042   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3043   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
3044   cmd.Init(GL_TEXTURE_2D, 1, -1, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
3045            kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3046   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3047   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3048   cmd.Init(GL_TEXTURE_2D, 1, 1, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
3049            kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3050   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3051   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3052   cmd.Init(GL_TEXTURE_2D, 1, 0, -1, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
3053            kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3054   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3055   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3056   cmd.Init(GL_TEXTURE_2D, 1, 0, 1, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
3057            kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3058   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3059   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3060   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth + 1, kHeight, GL_RGBA,
3061            GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3062   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3063   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3064   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight + 1, GL_RGBA,
3065            GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3066   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3067   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3068   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE,
3069            kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3070   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3071   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3072   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA,
3073            GL_UNSIGNED_SHORT_4_4_4_4, kSharedMemoryId, kSharedMemoryOffset,
3074            GL_FALSE);
3075   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3076   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3077   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
3078            kInvalidSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
3079   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
3080   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
3081            kSharedMemoryId, kInvalidSharedMemoryOffset, GL_FALSE);
3082   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
3083 }
3084
3085 TEST_F(GLES2DecoderTest, CopyTexSubImage2DValidArgs) {
3086   const int kWidth = 16;
3087   const int kHeight = 8;
3088   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
3089   DoTexImage2D(
3090       GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3091       kSharedMemoryId, kSharedMemoryOffset);
3092   EXPECT_CALL(*gl_, CopyTexSubImage2D(
3093       GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight))
3094       .Times(1)
3095       .RetiresOnSaturation();
3096   CopyTexSubImage2D cmd;
3097   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight);
3098   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3099   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3100 }
3101
3102 TEST_F(GLES2DecoderTest, CopyTexSubImage2DBadArgs) {
3103   const int kWidth = 16;
3104   const int kHeight = 8;
3105   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
3106   DoTexImage2D(
3107       GL_TEXTURE_2D, 1, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3108       0, 0);
3109   CopyTexSubImage2D cmd;
3110   cmd.Init(GL_TEXTURE0, 1, 0, 0, 0, 0, kWidth, kHeight);
3111   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3112   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
3113   cmd.Init(GL_TEXTURE_2D, 1, -1, 0, 0, 0, kWidth, kHeight);
3114   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3115   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3116   cmd.Init(GL_TEXTURE_2D, 1, 1, 0, 0, 0, kWidth, kHeight);
3117   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3118   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3119   cmd.Init(GL_TEXTURE_2D, 1, 0, -1, 0, 0, kWidth, kHeight);
3120   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3121   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3122   cmd.Init(GL_TEXTURE_2D, 1, 0, 1, 0, 0, kWidth, kHeight);
3123   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3124   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3125   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth + 1, kHeight);
3126   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3127   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3128   cmd.Init(GL_TEXTURE_2D, 1, 0, 0, 0, 0, kWidth, kHeight + 1);
3129   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3130   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3131 }
3132
3133 // Check that if a renderbuffer is attached and GL returns
3134 // GL_FRAMEBUFFER_COMPLETE that the buffer is cleared and state is restored.
3135 TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearColor) {
3136   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
3137                     kServiceFramebufferId);
3138   ClearColor color_cmd;
3139   ColorMask color_mask_cmd;
3140   Enable enable_cmd;
3141   FramebufferRenderbuffer cmd;
3142   color_cmd.Init(0.1f, 0.2f, 0.3f, 0.4f);
3143   color_mask_cmd.Init(0, 1, 0, 1);
3144   enable_cmd.Init(GL_SCISSOR_TEST);
3145   cmd.Init(
3146       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3147       client_renderbuffer_id_);
3148   InSequence sequence;
3149   EXPECT_CALL(*gl_, ClearColor(0.1f, 0.2f, 0.3f, 0.4f))
3150       .Times(1)
3151       .RetiresOnSaturation();
3152   EXPECT_CALL(*gl_, GetError())
3153       .WillOnce(Return(GL_NO_ERROR))
3154       .RetiresOnSaturation();
3155   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
3156       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3157       kServiceRenderbufferId))
3158       .Times(1)
3159       .RetiresOnSaturation();
3160   EXPECT_CALL(*gl_, GetError())
3161       .WillOnce(Return(GL_NO_ERROR))
3162       .RetiresOnSaturation();
3163   EXPECT_EQ(error::kNoError, ExecuteCmd(color_cmd));
3164   EXPECT_EQ(error::kNoError, ExecuteCmd(color_mask_cmd));
3165   EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
3166   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3167 }
3168
3169 TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearDepth) {
3170   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
3171                     kServiceFramebufferId);
3172   ClearDepthf depth_cmd;
3173   DepthMask depth_mask_cmd;
3174   FramebufferRenderbuffer cmd;
3175   depth_cmd.Init(0.5f);
3176   depth_mask_cmd.Init(false);
3177   cmd.Init(
3178       GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
3179       client_renderbuffer_id_);
3180   InSequence sequence;
3181   EXPECT_CALL(*gl_, ClearDepth(0.5f))
3182       .Times(1)
3183       .RetiresOnSaturation();
3184   EXPECT_CALL(*gl_, GetError())
3185       .WillOnce(Return(GL_NO_ERROR))
3186       .RetiresOnSaturation();
3187   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
3188       GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
3189       kServiceRenderbufferId))
3190       .Times(1)
3191       .RetiresOnSaturation();
3192   EXPECT_CALL(*gl_, GetError())
3193       .WillOnce(Return(GL_NO_ERROR))
3194       .RetiresOnSaturation();
3195   EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
3196   EXPECT_EQ(error::kNoError, ExecuteCmd(depth_mask_cmd));
3197   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3198 }
3199
3200 TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearStencil) {
3201   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
3202                     kServiceFramebufferId);
3203   ClearStencil stencil_cmd;
3204   StencilMaskSeparate stencil_mask_separate_cmd;
3205   FramebufferRenderbuffer cmd;
3206   stencil_cmd.Init(123);
3207   stencil_mask_separate_cmd.Init(GL_BACK, 0x1234u);
3208   cmd.Init(
3209       GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3210       client_renderbuffer_id_);
3211   InSequence sequence;
3212   EXPECT_CALL(*gl_, ClearStencil(123))
3213       .Times(1)
3214       .RetiresOnSaturation();
3215   EXPECT_CALL(*gl_, GetError())
3216       .WillOnce(Return(GL_NO_ERROR))
3217       .RetiresOnSaturation();
3218   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
3219       GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3220       kServiceRenderbufferId))
3221       .Times(1)
3222       .RetiresOnSaturation();
3223   EXPECT_CALL(*gl_, GetError())
3224       .WillOnce(Return(GL_NO_ERROR))
3225       .RetiresOnSaturation();
3226   EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
3227   EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_mask_separate_cmd));
3228   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3229 }
3230
3231 TEST_F(GLES2DecoderTest, IsBuffer) {
3232   EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
3233   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
3234   EXPECT_TRUE(DoIsBuffer(client_buffer_id_));
3235   DoDeleteBuffer(client_buffer_id_, kServiceBufferId);
3236   EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
3237 }
3238
3239 TEST_F(GLES2DecoderTest, IsFramebuffer) {
3240   EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
3241   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
3242                     kServiceFramebufferId);
3243   EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_));
3244   DoDeleteFramebuffer(
3245       client_framebuffer_id_, kServiceFramebufferId,
3246       true, GL_FRAMEBUFFER, 0,
3247       true, GL_FRAMEBUFFER, 0);
3248   EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
3249 }
3250
3251 TEST_F(GLES2DecoderTest, IsProgram) {
3252   // IsProgram is true as soon as the program is created.
3253   EXPECT_TRUE(DoIsProgram(client_program_id_));
3254   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
3255       .Times(1)
3256       .RetiresOnSaturation();
3257   DoDeleteProgram(client_program_id_, kServiceProgramId);
3258   EXPECT_FALSE(DoIsProgram(client_program_id_));
3259
3260 }
3261
3262 TEST_F(GLES2DecoderTest, IsRenderbuffer) {
3263   EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
3264   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
3265                     kServiceRenderbufferId);
3266   EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_));
3267   DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
3268   EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
3269 }
3270
3271 TEST_F(GLES2DecoderTest, IsShader) {
3272   // IsShader is true as soon as the program is created.
3273   EXPECT_TRUE(DoIsShader(client_shader_id_));
3274   DoDeleteShader(client_shader_id_, kServiceShaderId);
3275   EXPECT_FALSE(DoIsShader(client_shader_id_));
3276 }
3277
3278 TEST_F(GLES2DecoderTest, IsTexture) {
3279   EXPECT_FALSE(DoIsTexture(client_texture_id_));
3280   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
3281   EXPECT_TRUE(DoIsTexture(client_texture_id_));
3282   DoDeleteTexture(client_texture_id_, kServiceTextureId);
3283   EXPECT_FALSE(DoIsTexture(client_texture_id_));
3284 }
3285
3286 #if 0  // Turn this test on once we allow GL_DEPTH_STENCIL_ATTACHMENT
3287 TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearDepthStencil) {
3288   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
3289                     kServiceFramebufferId);
3290   ClearDepthf depth_cmd;
3291   ClearStencil stencil_cmd;
3292   FramebufferRenderbuffer cmd;
3293   depth_cmd.Init(0.5f);
3294   stencil_cmd.Init(123);
3295   cmd.Init(
3296       GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3297       client_renderbuffer_id_);
3298   InSequence sequence;
3299   EXPECT_CALL(*gl_, ClearDepth(0.5f))
3300       .Times(1)
3301       .RetiresOnSaturation();
3302   EXPECT_CALL(*gl_, ClearStencil(123))
3303       .Times(1)
3304       .RetiresOnSaturation();
3305   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
3306       GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3307       kServiceRenderbufferId))
3308       .Times(1)
3309       .RetiresOnSaturation();
3310   EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
3311   EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
3312   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3313 }
3314 #endif
3315
3316 TEST_F(GLES2DecoderWithShaderTest, VertexAttribPointer) {
3317   SetupVertexBuffer();
3318   static const GLenum types[] = {
3319     GL_BYTE,
3320     GL_UNSIGNED_BYTE,
3321     GL_SHORT,
3322     GL_UNSIGNED_SHORT,
3323     GL_FLOAT,
3324     GL_FIXED,
3325     GL_INT,
3326     GL_UNSIGNED_INT,
3327   };
3328   static const GLsizei sizes[] = {
3329     1,
3330     1,
3331     2,
3332     2,
3333     4,
3334     4,
3335     4,
3336     4,
3337   };
3338   static const GLuint indices[] = {
3339     0,
3340     1,
3341     kNumVertexAttribs - 1,
3342     kNumVertexAttribs,
3343   };
3344   static const GLsizei offset_mult[] = {
3345     0,
3346     0,
3347     1,
3348     1,
3349     2,
3350     1000,
3351   };
3352   static const GLsizei offset_offset[] = {
3353     0,
3354     1,
3355     0,
3356     1,
3357     0,
3358     0,
3359   };
3360   static const GLsizei stride_mult[] = {
3361     -1,
3362     0,
3363     0,
3364     1,
3365     1,
3366     2,
3367     1000,
3368   };
3369   static const GLsizei stride_offset[] = {
3370     0,
3371     0,
3372     1,
3373     0,
3374     1,
3375     0,
3376     0,
3377   };
3378   for (size_t tt = 0; tt < arraysize(types); ++tt) {
3379     GLenum type = types[tt];
3380     GLsizei num_bytes = sizes[tt];
3381     for (size_t ii = 0; ii < arraysize(indices); ++ii) {
3382       GLuint index = indices[ii];
3383       for (GLint size = 0; size < 5; ++size) {
3384         for (size_t oo = 0; oo < arraysize(offset_mult); ++oo) {
3385           GLuint offset = num_bytes * offset_mult[oo] + offset_offset[oo];
3386           for (size_t ss = 0; ss < arraysize(stride_mult); ++ss) {
3387             GLsizei stride = num_bytes * stride_mult[ss] + stride_offset[ss];
3388             for (int normalize = 0; normalize < 2; ++normalize) {
3389               bool index_good = index < static_cast<GLuint>(kNumVertexAttribs);
3390               bool size_good = (size > 0 && size < 5);
3391               bool offset_good = (offset % num_bytes == 0);
3392               bool stride_good = (stride % num_bytes == 0) && stride >= 0 &&
3393                                  stride <= 255;
3394               bool type_good = (type != GL_INT && type != GL_UNSIGNED_INT &&
3395                                 type != GL_FIXED);
3396               bool good = size_good && offset_good && stride_good &&
3397                           type_good && index_good;
3398               bool call = good && (type != GL_FIXED);
3399               if (call) {
3400                 EXPECT_CALL(*gl_, VertexAttribPointer(
3401                     index, size, type, normalize, stride,
3402                     BufferOffset(offset)));
3403               }
3404               VertexAttribPointer cmd;
3405               cmd.Init(index, size, type, normalize, stride, offset);
3406               EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3407               if (good) {
3408                 EXPECT_EQ(GL_NO_ERROR, GetGLError());
3409               } else if (size_good &&
3410                          offset_good &&
3411                          stride_good &&
3412                          type_good &&
3413                          !index_good) {
3414                 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3415               } else if (size_good &&
3416                          offset_good &&
3417                          stride_good &&
3418                          !type_good &&
3419                          index_good) {
3420                 EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
3421               } else if (size_good &&
3422                          offset_good &&
3423                          !stride_good &&
3424                          type_good &&
3425                          index_good) {
3426                 if (stride < 0 || stride > 255) {
3427                   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3428                 } else {
3429                   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3430                 }
3431               } else if (size_good &&
3432                          !offset_good &&
3433                          stride_good &&
3434                          type_good &&
3435                          index_good) {
3436                 EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
3437               } else if (!size_good &&
3438                          offset_good &&
3439                          stride_good &&
3440                          type_good &&
3441                          index_good) {
3442                 EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
3443               } else {
3444                 EXPECT_NE(GL_NO_ERROR, GetGLError());
3445               }
3446             }
3447           }
3448         }
3449       }
3450     }
3451   }
3452 }
3453
3454 // Test that with an RGB backbuffer if we set the color mask to 1,1,1,1 it is
3455 // set to 1,1,1,0 at Draw time but is 1,1,1,1 at query time.
3456 TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMask) {
3457   ColorMask cmd;
3458   cmd.Init(true, true, true, true);
3459   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3460   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3461
3462   SetupTexture();
3463   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
3464   SetupExpectationsForApplyingDirtyState(
3465       true,    // Framebuffer is RGB
3466       false,   // Framebuffer has depth
3467       false,   // Framebuffer has stencil
3468       0x1110,  // color bits
3469       false,   // depth mask
3470       false,   // depth enabled
3471       0,       // front stencil mask
3472       0,       // back stencil mask
3473       false,   // stencil enabled
3474       false,   // cull_face_enabled
3475       false,   // scissor_test_enabled
3476       false);  // blend_enabled
3477
3478   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
3479       .Times(1)
3480       .RetiresOnSaturation();
3481   DrawArrays draw_cmd;
3482   draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
3483   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
3484   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3485
3486   EXPECT_CALL(*gl_, GetError())
3487       .WillOnce(Return(GL_NO_ERROR))
3488       .WillOnce(Return(GL_NO_ERROR))
3489       .RetiresOnSaturation();
3490   typedef GetIntegerv::Result Result;
3491   Result* result = static_cast<Result*>(shared_memory_address_);
3492   EXPECT_CALL(*gl_, GetIntegerv(GL_COLOR_WRITEMASK, result->GetData()))
3493       .Times(0);
3494   result->size = 0;
3495   GetIntegerv cmd2;
3496   cmd2.Init(GL_COLOR_WRITEMASK, shared_memory_id_, shared_memory_offset_);
3497   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3498   EXPECT_EQ(
3499       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_COLOR_WRITEMASK),
3500       result->GetNumResults());
3501   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3502   EXPECT_EQ(1, result->GetData()[0]);
3503   EXPECT_EQ(1, result->GetData()[1]);
3504   EXPECT_EQ(1, result->GetData()[2]);
3505   EXPECT_EQ(1, result->GetData()[3]);
3506 }
3507
3508 // Test that with no depth if we set DepthMask true that it's set to false at
3509 // draw time but querying it returns true.
3510 TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferDepthMask) {
3511   EXPECT_CALL(*gl_, DepthMask(true))
3512       .Times(0)
3513       .RetiresOnSaturation();
3514   DepthMask cmd;
3515   cmd.Init(true);
3516   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3517   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3518
3519   SetupTexture();
3520   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
3521   SetupExpectationsForApplyingDirtyState(
3522       true,    // Framebuffer is RGB
3523       false,   // Framebuffer has depth
3524       false,   // Framebuffer has stencil
3525       0x1110,  // color bits
3526       false,   // depth mask
3527       false,   // depth enabled
3528       0,       // front stencil mask
3529       0,       // back stencil mask
3530       false,   // stencil enabled
3531       false,   // cull_face_enabled
3532       false,   // scissor_test_enabled
3533       false);  // blend_enabled
3534
3535   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
3536       .Times(1)
3537       .RetiresOnSaturation();
3538   DrawArrays draw_cmd;
3539   draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
3540   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
3541   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3542
3543   EXPECT_CALL(*gl_, GetError())
3544       .WillOnce(Return(GL_NO_ERROR))
3545       .WillOnce(Return(GL_NO_ERROR))
3546       .RetiresOnSaturation();
3547   typedef GetIntegerv::Result Result;
3548   Result* result = static_cast<Result*>(shared_memory_address_);
3549   EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_WRITEMASK, result->GetData()))
3550       .Times(0);
3551   result->size = 0;
3552   GetIntegerv cmd2;
3553   cmd2.Init(GL_DEPTH_WRITEMASK, shared_memory_id_, shared_memory_offset_);
3554   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3555   EXPECT_EQ(
3556       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_WRITEMASK),
3557       result->GetNumResults());
3558   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3559   EXPECT_EQ(1, result->GetData()[0]);
3560 }
3561
3562 // Test that with no stencil if we set the stencil mask it's still set to 0 at
3563 // draw time but gets our value if we query.
3564 TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferStencilMask) {
3565   const GLint kMask = 123;
3566   EXPECT_CALL(*gl_, StencilMask(kMask))
3567       .Times(0)
3568       .RetiresOnSaturation();
3569   StencilMask cmd;
3570   cmd.Init(kMask);
3571   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3572   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3573
3574   SetupTexture();
3575   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
3576   SetupExpectationsForApplyingDirtyState(
3577       true,    // Framebuffer is RGB
3578       false,   // Framebuffer has depth
3579       false,   // Framebuffer has stencil
3580       0x1110,  // color bits
3581       false,   // depth mask
3582       false,   // depth enabled
3583       0,       // front stencil mask
3584       0,       // back stencil mask
3585       false,   // stencil enabled
3586       false,   // cull_face_enabled
3587       false,   // scissor_test_enabled
3588       false);  // blend_enabled
3589
3590   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
3591       .Times(1)
3592       .RetiresOnSaturation();
3593   DrawArrays draw_cmd;
3594   draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
3595   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
3596   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3597
3598   EXPECT_CALL(*gl_, GetError())
3599       .WillOnce(Return(GL_NO_ERROR))
3600       .WillOnce(Return(GL_NO_ERROR))
3601       .RetiresOnSaturation();
3602   typedef GetIntegerv::Result Result;
3603   Result* result = static_cast<Result*>(shared_memory_address_);
3604   EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_WRITEMASK, result->GetData()))
3605       .Times(0);
3606   result->size = 0;
3607   GetIntegerv cmd2;
3608   cmd2.Init(GL_STENCIL_WRITEMASK, shared_memory_id_, shared_memory_offset_);
3609   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3610   EXPECT_EQ(
3611       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_WRITEMASK),
3612       result->GetNumResults());
3613   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3614   EXPECT_EQ(kMask, result->GetData()[0]);
3615 }
3616
3617 // Test that if an FBO is bound we get the correct masks.
3618 TEST_F(GLES2DecoderRGBBackbufferTest, RGBBackbufferColorMaskFBO) {
3619   ColorMask cmd;
3620   cmd.Init(true, true, true, true);
3621   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3622   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3623
3624   SetupTexture();
3625   SetupVertexBuffer();
3626   DoEnableVertexAttribArray(0);
3627   DoVertexAttribPointer(0, 2, GL_FLOAT, 0, 0);
3628   DoEnableVertexAttribArray(1);
3629   DoVertexAttribPointer(1, 2, GL_FLOAT, 0, 0);
3630   DoEnableVertexAttribArray(2);
3631   DoVertexAttribPointer(2, 2, GL_FLOAT, 0, 0);
3632   SetupExpectationsForApplyingDirtyState(
3633       true,    // Framebuffer is RGB
3634       false,   // Framebuffer has depth
3635       false,   // Framebuffer has stencil
3636       0x1110,  // color bits
3637       false,   // depth mask
3638       false,   // depth enabled
3639       0,       // front stencil mask
3640       0,       // back stencil mask
3641       false,   // stencil enabled
3642       false,   // cull_face_enabled
3643       false,   // scissor_test_enabled
3644       false);  // blend_enabled
3645
3646   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
3647       .Times(1)
3648       .RetiresOnSaturation();
3649   DrawArrays draw_cmd;
3650   draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
3651   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
3652   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3653
3654   // Check that no extra calls are made on the next draw.
3655   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
3656       .Times(1)
3657       .RetiresOnSaturation();
3658   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
3659   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3660
3661   // Setup Frame buffer.
3662   // needs to be 1x1 or else it's not renderable.
3663   const GLsizei kWidth = 1;
3664   const GLsizei kHeight = 1;
3665   const GLenum kFormat = GL_RGB;
3666   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
3667   // Pass some data so the texture will be marked as cleared.
3668   DoTexImage2D(
3669       GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0,
3670       kFormat, GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
3671   DoBindFramebuffer(
3672       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
3673   DoFramebufferTexture2D(
3674       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3675       client_texture_id_, kServiceTextureId, 0, GL_NO_ERROR);
3676   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
3677       .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
3678       .RetiresOnSaturation();
3679
3680   // This time state needs to be set.
3681   SetupExpectationsForApplyingDirtyState(
3682       false,    // Framebuffer is RGB
3683       false,   // Framebuffer has depth
3684       false,   // Framebuffer has stencil
3685       0x1110,  // color bits
3686       false,   // depth mask
3687       false,   // depth enabled
3688       0,       // front stencil mask
3689       0,       // back stencil mask
3690       false,   // stencil enabled
3691       false,   // cull_face_enabled
3692       false,   // scissor_test_enabled
3693       false);  // blend_enabled
3694
3695   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
3696       .Times(1)
3697       .RetiresOnSaturation();
3698   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
3699   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3700
3701   // Check that no extra calls are made on the next draw.
3702   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
3703       .Times(1)
3704       .RetiresOnSaturation();
3705   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
3706   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3707
3708   // Unbind
3709   DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
3710
3711   SetupExpectationsForApplyingDirtyState(
3712       true,    // Framebuffer is RGB
3713       false,   // Framebuffer has depth
3714       false,   // Framebuffer has stencil
3715       0x1110,  // color bits
3716       false,   // depth mask
3717       false,   // depth enabled
3718       0,       // front stencil mask
3719       0,       // back stencil mask
3720       false,   // stencil enabled
3721       false,   // cull_face_enabled
3722       false,   // scissor_test_enabled
3723       false);  // blend_enabled
3724
3725   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
3726       .Times(1)
3727       .RetiresOnSaturation();
3728   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
3729   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3730 }
3731
3732 TEST_F(GLES2DecoderManualInitTest, ActualAlphaMatchesRequestedAlpha) {
3733   InitDecoder(
3734       "",      // extensions
3735       true,    // has alpha
3736       false,   // has depth
3737       false,   // has stencil
3738       true,    // request alpha
3739       false,   // request depth
3740       false,   // request stencil
3741       true);   // bind generates resource
3742
3743   EXPECT_CALL(*gl_, GetError())
3744       .WillOnce(Return(GL_NO_ERROR))
3745       .WillOnce(Return(GL_NO_ERROR))
3746       .RetiresOnSaturation();
3747   typedef GetIntegerv::Result Result;
3748   Result* result = static_cast<Result*>(shared_memory_address_);
3749   EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
3750       .WillOnce(SetArgumentPointee<1>(8))
3751       .RetiresOnSaturation();
3752   result->size = 0;
3753   GetIntegerv cmd2;
3754   cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
3755   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3756   EXPECT_EQ(
3757       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
3758       result->GetNumResults());
3759   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3760   EXPECT_EQ(8, result->GetData()[0]);
3761 }
3762
3763 TEST_F(GLES2DecoderManualInitTest, ActualAlphaDoesNotMatchRequestedAlpha) {
3764   InitDecoder(
3765       "",      // extensions
3766       true,    // has alpha
3767       false,   // has depth
3768       false,   // has stencil
3769       false,   // request alpha
3770       false,   // request depth
3771       false,   // request stencil
3772       true);   // bind generates resource
3773
3774   EXPECT_CALL(*gl_, GetError())
3775       .WillOnce(Return(GL_NO_ERROR))
3776       .WillOnce(Return(GL_NO_ERROR))
3777       .RetiresOnSaturation();
3778   typedef GetIntegerv::Result Result;
3779   Result* result = static_cast<Result*>(shared_memory_address_);
3780   EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
3781       .WillOnce(SetArgumentPointee<1>(8))
3782       .RetiresOnSaturation();
3783   result->size = 0;
3784   GetIntegerv cmd2;
3785   cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
3786   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3787   EXPECT_EQ(
3788       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
3789       result->GetNumResults());
3790   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3791   EXPECT_EQ(0, result->GetData()[0]);
3792 }
3793
3794 TEST_F(GLES2DecoderManualInitTest, ActualDepthMatchesRequestedDepth) {
3795   InitDecoder(
3796       "",      // extensions
3797       false,   // has alpha
3798       true,    // has depth
3799       false,   // has stencil
3800       false,   // request alpha
3801       true,    // request depth
3802       false,   // request stencil
3803       true);   // bind generates resource
3804
3805   EXPECT_CALL(*gl_, GetError())
3806       .WillOnce(Return(GL_NO_ERROR))
3807       .WillOnce(Return(GL_NO_ERROR))
3808       .RetiresOnSaturation();
3809   typedef GetIntegerv::Result Result;
3810   Result* result = static_cast<Result*>(shared_memory_address_);
3811   EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
3812       .WillOnce(SetArgumentPointee<1>(24))
3813       .RetiresOnSaturation();
3814   result->size = 0;
3815   GetIntegerv cmd2;
3816   cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
3817   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3818   EXPECT_EQ(
3819       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
3820       result->GetNumResults());
3821   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3822   EXPECT_EQ(24, result->GetData()[0]);
3823 }
3824
3825 TEST_F(GLES2DecoderManualInitTest, ActualDepthDoesNotMatchRequestedDepth) {
3826   InitDecoder(
3827       "",      // extensions
3828       false,   // has alpha
3829       true,    // has depth
3830       false,   // has stencil
3831       false,   // request alpha
3832       false,   // request depth
3833       false,   // request stencil
3834       true);   // bind generates resource
3835
3836   EXPECT_CALL(*gl_, GetError())
3837       .WillOnce(Return(GL_NO_ERROR))
3838       .WillOnce(Return(GL_NO_ERROR))
3839       .RetiresOnSaturation();
3840   typedef GetIntegerv::Result Result;
3841   Result* result = static_cast<Result*>(shared_memory_address_);
3842   EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
3843       .WillOnce(SetArgumentPointee<1>(24))
3844       .RetiresOnSaturation();
3845   result->size = 0;
3846   GetIntegerv cmd2;
3847   cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
3848   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3849   EXPECT_EQ(
3850       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
3851       result->GetNumResults());
3852   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3853   EXPECT_EQ(0, result->GetData()[0]);
3854 }
3855
3856 TEST_F(GLES2DecoderManualInitTest, ActualStencilMatchesRequestedStencil) {
3857   InitDecoder(
3858       "",      // extensions
3859       false,   // has alpha
3860       false,   // has depth
3861       true,    // has stencil
3862       false,   // request alpha
3863       false,   // request depth
3864       true,    // request stencil
3865       true);   // bind generates resource
3866
3867   EXPECT_CALL(*gl_, GetError())
3868       .WillOnce(Return(GL_NO_ERROR))
3869       .WillOnce(Return(GL_NO_ERROR))
3870       .RetiresOnSaturation();
3871   typedef GetIntegerv::Result Result;
3872   Result* result = static_cast<Result*>(shared_memory_address_);
3873   EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
3874       .WillOnce(SetArgumentPointee<1>(8))
3875       .RetiresOnSaturation();
3876   result->size = 0;
3877   GetIntegerv cmd2;
3878   cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
3879   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3880   EXPECT_EQ(
3881       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
3882       result->GetNumResults());
3883   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3884   EXPECT_EQ(8, result->GetData()[0]);
3885 }
3886
3887 TEST_F(GLES2DecoderManualInitTest, ActualStencilDoesNotMatchRequestedStencil) {
3888   InitDecoder(
3889       "",      // extensions
3890       false,   // has alpha
3891       false,   // has depth
3892       true,    // has stencil
3893       false,   // request alpha
3894       false,   // request depth
3895       false,   // request stencil
3896       true);   // bind generates resource
3897
3898   EXPECT_CALL(*gl_, GetError())
3899       .WillOnce(Return(GL_NO_ERROR))
3900       .WillOnce(Return(GL_NO_ERROR))
3901       .RetiresOnSaturation();
3902   typedef GetIntegerv::Result Result;
3903   Result* result = static_cast<Result*>(shared_memory_address_);
3904   EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
3905       .WillOnce(SetArgumentPointee<1>(8))
3906       .RetiresOnSaturation();
3907   result->size = 0;
3908   GetIntegerv cmd2;
3909   cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
3910   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3911   EXPECT_EQ(
3912       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
3913       result->GetNumResults());
3914   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3915   EXPECT_EQ(0, result->GetData()[0]);
3916 }
3917
3918 TEST_F(GLES2DecoderManualInitTest, DepthEnableWithDepth) {
3919   InitDecoder(
3920       "",      // extensions
3921       false,   // has alpha
3922       true,    // has depth
3923       false,   // has stencil
3924       false,   // request alpha
3925       true,    // request depth
3926       false,   // request stencil
3927       true);   // bind generates resource
3928
3929   Enable cmd;
3930   cmd.Init(GL_DEPTH_TEST);
3931   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3932   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3933
3934   SetupDefaultProgram();
3935   SetupTexture();
3936   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
3937   SetupExpectationsForApplyingDirtyState(
3938       true,    // Framebuffer is RGB
3939       true,    // Framebuffer has depth
3940       false,   // Framebuffer has stencil
3941       0x1110,  // color bits
3942       true,    // depth mask
3943       true,    // depth enabled
3944       0,       // front stencil mask
3945       0,       // back stencil mask
3946       false,   // stencil enabled
3947       false,   // cull_face_enabled
3948       false,   // scissor_test_enabled
3949       false);  // blend_enabled
3950
3951
3952   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
3953       .Times(1)
3954       .RetiresOnSaturation();
3955   DrawArrays draw_cmd;
3956   draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
3957   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
3958   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3959
3960   EXPECT_CALL(*gl_, GetError())
3961       .WillOnce(Return(GL_NO_ERROR))
3962       .WillOnce(Return(GL_NO_ERROR))
3963       .RetiresOnSaturation();
3964   typedef GetIntegerv::Result Result;
3965   Result* result = static_cast<Result*>(shared_memory_address_);
3966   EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_TEST, _))
3967       .Times(0)
3968       .RetiresOnSaturation();
3969   result->size = 0;
3970   GetIntegerv cmd2;
3971   cmd2.Init(GL_DEPTH_TEST, shared_memory_id_, shared_memory_offset_);
3972   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
3973   EXPECT_EQ(
3974       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_TEST),
3975       result->GetNumResults());
3976   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3977   EXPECT_EQ(1, result->GetData()[0]);
3978 }
3979
3980 TEST_F(GLES2DecoderManualInitTest, DepthEnableWithoutRequestedDepth) {
3981   InitDecoder(
3982       "",      // extensions
3983       false,   // has alpha
3984       true,    // has depth
3985       false,   // has stencil
3986       false,   // request alpha
3987       false,   // request depth
3988       false,   // request stencil
3989       true);   // bind generates resource
3990
3991   Enable cmd;
3992   cmd.Init(GL_DEPTH_TEST);
3993   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
3994   EXPECT_EQ(GL_NO_ERROR, GetGLError());
3995
3996   SetupDefaultProgram();
3997   SetupTexture();
3998   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
3999   SetupExpectationsForApplyingDirtyState(
4000       true,    // Framebuffer is RGB
4001       false,   // Framebuffer has depth
4002       false,   // Framebuffer has stencil
4003       0x1110,  // color bits
4004       false,   // depth mask
4005       false,   // depth enabled
4006       0,       // front stencil mask
4007       0,       // back stencil mask
4008       false,   // stencil enabled
4009       false,   // cull_face_enabled
4010       false,   // scissor_test_enabled
4011       false);  // blend_enabled
4012
4013   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
4014       .Times(1)
4015       .RetiresOnSaturation();
4016   DrawArrays draw_cmd;
4017   draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
4018   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
4019   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4020
4021   EXPECT_CALL(*gl_, GetError())
4022       .WillOnce(Return(GL_NO_ERROR))
4023       .WillOnce(Return(GL_NO_ERROR))
4024       .RetiresOnSaturation();
4025   typedef GetIntegerv::Result Result;
4026   Result* result = static_cast<Result*>(shared_memory_address_);
4027   EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_TEST, _))
4028       .Times(0)
4029       .RetiresOnSaturation();
4030   result->size = 0;
4031   GetIntegerv cmd2;
4032   cmd2.Init(GL_DEPTH_TEST, shared_memory_id_, shared_memory_offset_);
4033   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4034   EXPECT_EQ(
4035       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_TEST),
4036       result->GetNumResults());
4037   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4038   EXPECT_EQ(1, result->GetData()[0]);
4039 }
4040
4041 TEST_F(GLES2DecoderManualInitTest, StencilEnableWithStencil) {
4042   InitDecoder(
4043       "",      // extensions
4044       false,   // has alpha
4045       false,   // has depth
4046       true,    // has stencil
4047       false,   // request alpha
4048       false,   // request depth
4049       true,    // request stencil
4050       true);   // bind generates resource
4051
4052   Enable cmd;
4053   cmd.Init(GL_STENCIL_TEST);
4054   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4055   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4056
4057   SetupDefaultProgram();
4058   SetupTexture();
4059   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
4060   SetupExpectationsForApplyingDirtyState(
4061       true,    // Framebuffer is RGB
4062       false,   // Framebuffer has depth
4063       true,    // Framebuffer has stencil
4064       0x1110,  // color bits
4065       false,   // depth mask
4066       false,   // depth enabled
4067       -1,      // front stencil mask
4068       -1,      // back stencil mask
4069       true,    // stencil enabled
4070       false,   // cull_face_enabled
4071       false,   // scissor_test_enabled
4072       false);  // blend_enabled
4073
4074   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
4075       .Times(1)
4076       .RetiresOnSaturation();
4077   DrawArrays draw_cmd;
4078   draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
4079   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
4080   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4081
4082   EXPECT_CALL(*gl_, GetError())
4083       .WillOnce(Return(GL_NO_ERROR))
4084       .WillOnce(Return(GL_NO_ERROR))
4085       .RetiresOnSaturation();
4086   typedef GetIntegerv::Result Result;
4087   Result* result = static_cast<Result*>(shared_memory_address_);
4088   EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_TEST, _))
4089       .Times(0)
4090       .RetiresOnSaturation();
4091   result->size = 0;
4092   GetIntegerv cmd2;
4093   cmd2.Init(GL_STENCIL_TEST, shared_memory_id_, shared_memory_offset_);
4094   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4095   EXPECT_EQ(
4096       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_TEST),
4097       result->GetNumResults());
4098   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4099   EXPECT_EQ(1, result->GetData()[0]);
4100 }
4101
4102 TEST_F(GLES2DecoderManualInitTest, StencilEnableWithoutRequestedStencil) {
4103   InitDecoder(
4104       "",      // extensions
4105       false,   // has alpha
4106       false,   // has depth
4107       true,    // has stencil
4108       false,   // request alpha
4109       false,   // request depth
4110       false,   // request stencil
4111       true);   // bind generates resource
4112
4113   Enable cmd;
4114   cmd.Init(GL_STENCIL_TEST);
4115   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4116   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4117
4118   SetupDefaultProgram();
4119   SetupTexture();
4120   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
4121   SetupExpectationsForApplyingDirtyState(
4122       true,    // Framebuffer is RGB
4123       false,   // Framebuffer has depth
4124       false,   // Framebuffer has stencil
4125       0x1110,  // color bits
4126       false,   // depth mask
4127       false,   // depth enabled
4128       0,       // front stencil mask
4129       0,       // back stencil mask
4130       false,   // stencil enabled
4131       false,   // cull_face_enabled
4132       false,   // scissor_test_enabled
4133       false);  // blend_enabled
4134
4135   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
4136       .Times(1)
4137       .RetiresOnSaturation();
4138   DrawArrays draw_cmd;
4139   draw_cmd.Init(GL_TRIANGLES, 0, kNumVertices);
4140   EXPECT_EQ(error::kNoError, ExecuteCmd(draw_cmd));
4141   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4142
4143   EXPECT_CALL(*gl_, GetError())
4144       .WillOnce(Return(GL_NO_ERROR))
4145       .WillOnce(Return(GL_NO_ERROR))
4146       .RetiresOnSaturation();
4147   typedef GetIntegerv::Result Result;
4148   Result* result = static_cast<Result*>(shared_memory_address_);
4149   EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_TEST, _))
4150       .Times(0)
4151       .RetiresOnSaturation();
4152   result->size = 0;
4153   GetIntegerv cmd2;
4154   cmd2.Init(GL_STENCIL_TEST, shared_memory_id_, shared_memory_offset_);
4155   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4156   EXPECT_EQ(
4157       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_TEST),
4158       result->GetNumResults());
4159   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4160   EXPECT_EQ(1, result->GetData()[0]);
4161 }
4162
4163 TEST_F(GLES2DecoderManualInitTest, PackedDepthStencilReportsCorrectValues) {
4164   InitDecoder(
4165       "GL_OES_packed_depth_stencil",      // extensions
4166       false,   // has alpha
4167       true,    // has depth
4168       true,    // has stencil
4169       false,   // request alpha
4170       true,    // request depth
4171       true,    // request stencil
4172       true);   // bind generates resource
4173
4174   EXPECT_CALL(*gl_, GetError())
4175       .WillOnce(Return(GL_NO_ERROR))
4176       .WillOnce(Return(GL_NO_ERROR))
4177       .WillOnce(Return(GL_NO_ERROR))
4178       .WillOnce(Return(GL_NO_ERROR))
4179       .RetiresOnSaturation();
4180   typedef GetIntegerv::Result Result;
4181   Result* result = static_cast<Result*>(shared_memory_address_);
4182   result->size = 0;
4183   GetIntegerv cmd2;
4184   cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
4185   EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
4186       .WillOnce(SetArgumentPointee<1>(8))
4187       .RetiresOnSaturation();
4188   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4189   EXPECT_EQ(
4190       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
4191       result->GetNumResults());
4192   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4193   EXPECT_EQ(8, result->GetData()[0]);
4194   result->size = 0;
4195   cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
4196   EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
4197       .WillOnce(SetArgumentPointee<1>(24))
4198       .RetiresOnSaturation();
4199   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4200   EXPECT_EQ(
4201       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
4202       result->GetNumResults());
4203   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4204   EXPECT_EQ(24, result->GetData()[0]);
4205 }
4206
4207 TEST_F(GLES2DecoderManualInitTest, PackedDepthStencilNoRequestedStencil) {
4208   InitDecoder(
4209       "GL_OES_packed_depth_stencil",      // extensions
4210       false,   // has alpha
4211       true,    // has depth
4212       true,    // has stencil
4213       false,   // request alpha
4214       true,    // request depth
4215       false,   // request stencil
4216       true);   // bind generates resource
4217
4218   EXPECT_CALL(*gl_, GetError())
4219       .WillOnce(Return(GL_NO_ERROR))
4220       .WillOnce(Return(GL_NO_ERROR))
4221       .WillOnce(Return(GL_NO_ERROR))
4222       .WillOnce(Return(GL_NO_ERROR))
4223       .RetiresOnSaturation();
4224   typedef GetIntegerv::Result Result;
4225   Result* result = static_cast<Result*>(shared_memory_address_);
4226   result->size = 0;
4227   GetIntegerv cmd2;
4228   cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
4229   EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
4230       .WillOnce(SetArgumentPointee<1>(8))
4231       .RetiresOnSaturation();
4232   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4233   EXPECT_EQ(
4234       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
4235       result->GetNumResults());
4236   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4237   EXPECT_EQ(0, result->GetData()[0]);
4238   result->size = 0;
4239   cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
4240   EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
4241       .WillOnce(SetArgumentPointee<1>(24))
4242       .RetiresOnSaturation();
4243   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4244   EXPECT_EQ(
4245       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
4246       result->GetNumResults());
4247   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4248   EXPECT_EQ(24, result->GetData()[0]);
4249 }
4250
4251 TEST_F(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferDepth) {
4252   InitDecoder(
4253       "GL_OES_packed_depth_stencil",      // extensions
4254       false,   // has alpha
4255       false,   // has depth
4256       false,   // has stencil
4257       false,   // request alpha
4258       false,   // request depth
4259       false,   // request stencil
4260       true);   // bind generates resource
4261   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
4262                     kServiceRenderbufferId);
4263   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
4264                     kServiceFramebufferId);
4265
4266   EXPECT_CALL(*gl_, GetError())
4267       .WillOnce(Return(GL_NO_ERROR))  // for RenderbufferStoage
4268       .WillOnce(Return(GL_NO_ERROR))
4269       .WillOnce(Return(GL_NO_ERROR))  // for FramebufferRenderbuffer
4270       .WillOnce(Return(GL_NO_ERROR))
4271       .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
4272       .WillOnce(Return(GL_NO_ERROR))
4273       .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
4274       .WillOnce(Return(GL_NO_ERROR))
4275       .RetiresOnSaturation();
4276
4277   EXPECT_CALL(*gl_, RenderbufferStorageEXT(
4278       GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
4279       .Times(1)
4280       .RetiresOnSaturation();
4281   RenderbufferStorage cmd;
4282   cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
4283   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4284   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
4285       GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
4286       kServiceRenderbufferId))
4287       .Times(1)
4288       .RetiresOnSaturation();
4289   FramebufferRenderbuffer fbrb_cmd;
4290   fbrb_cmd.Init(
4291       GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
4292       client_renderbuffer_id_);
4293   EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
4294
4295   typedef GetIntegerv::Result Result;
4296   Result* result = static_cast<Result*>(shared_memory_address_);
4297   result->size = 0;
4298   GetIntegerv cmd2;
4299   cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
4300   EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
4301       .WillOnce(SetArgumentPointee<1>(8))
4302       .RetiresOnSaturation();
4303   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4304   EXPECT_EQ(
4305       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
4306       result->GetNumResults());
4307   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4308   EXPECT_EQ(0, result->GetData()[0]);
4309   result->size = 0;
4310   cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
4311   EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
4312       .WillOnce(SetArgumentPointee<1>(24))
4313       .RetiresOnSaturation();
4314   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4315   EXPECT_EQ(
4316       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
4317       result->GetNumResults());
4318   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4319   EXPECT_EQ(24, result->GetData()[0]);
4320 }
4321
4322 TEST_F(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferStencil) {
4323   InitDecoder(
4324       "GL_OES_packed_depth_stencil",      // extensions
4325       false,   // has alpha
4326       false,   // has depth
4327       false,   // has stencil
4328       false,   // request alpha
4329       false,   // request depth
4330       false,   // request stencil
4331       true);   // bind generates resource
4332   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
4333                     kServiceRenderbufferId);
4334   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
4335                     kServiceFramebufferId);
4336
4337   EXPECT_CALL(*gl_, GetError())
4338       .WillOnce(Return(GL_NO_ERROR))  // for RenderbufferStoage
4339       .WillOnce(Return(GL_NO_ERROR))
4340       .WillOnce(Return(GL_NO_ERROR))  // for FramebufferRenderbuffer
4341       .WillOnce(Return(GL_NO_ERROR))
4342       .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
4343       .WillOnce(Return(GL_NO_ERROR))
4344       .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
4345       .WillOnce(Return(GL_NO_ERROR))
4346       .RetiresOnSaturation();
4347
4348   EXPECT_CALL(*gl_, RenderbufferStorageEXT(
4349       GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
4350       .Times(1)
4351       .RetiresOnSaturation();
4352   RenderbufferStorage cmd;
4353   cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
4354   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4355   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
4356       GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
4357       kServiceRenderbufferId))
4358       .Times(1)
4359       .RetiresOnSaturation();
4360   FramebufferRenderbuffer fbrb_cmd;
4361   fbrb_cmd.Init(
4362       GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
4363       client_renderbuffer_id_);
4364   EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
4365
4366   typedef GetIntegerv::Result Result;
4367   Result* result = static_cast<Result*>(shared_memory_address_);
4368   result->size = 0;
4369   GetIntegerv cmd2;
4370   cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
4371   EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
4372       .WillOnce(SetArgumentPointee<1>(8))
4373       .RetiresOnSaturation();
4374   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4375   EXPECT_EQ(
4376       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
4377       result->GetNumResults());
4378   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4379   EXPECT_EQ(8, result->GetData()[0]);
4380   result->size = 0;
4381   cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
4382   EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
4383       .WillOnce(SetArgumentPointee<1>(24))
4384       .RetiresOnSaturation();
4385   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4386   EXPECT_EQ(
4387       decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
4388       result->GetNumResults());
4389   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4390   EXPECT_EQ(0, result->GetData()[0]);
4391 }
4392
4393 TEST_F(GLES2DecoderTest, GetMultipleIntegervCHROMIUMValidArgs) {
4394   const GLsizei kCount = 3;
4395   GLenum* pnames = GetSharedMemoryAs<GLenum*>();
4396   pnames[0] = GL_DEPTH_WRITEMASK;
4397   pnames[1] = GL_COLOR_WRITEMASK;
4398   pnames[2] = GL_STENCIL_WRITEMASK;
4399   GLint* results =
4400       GetSharedMemoryAsWithOffset<GLint*>(sizeof(*pnames) * kCount);
4401
4402   GLsizei num_results = 0;
4403   for (GLsizei ii = 0; ii < kCount; ++ii) {
4404     num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
4405   }
4406   const GLsizei result_size = num_results * sizeof(*results);
4407   memset(results,  0, result_size);
4408
4409   const GLint kSentinel = 0x12345678;
4410   results[num_results] = kSentinel;
4411
4412   GetMultipleIntegervCHROMIUM cmd;
4413   cmd.Init(
4414       kSharedMemoryId, kSharedMemoryOffset, kCount,
4415       kSharedMemoryId, kSharedMemoryOffset + sizeof(*pnames) * kCount,
4416       result_size);
4417
4418   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4419   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4420   EXPECT_EQ(1, results[0]);  // Depth writemask
4421   EXPECT_EQ(1, results[1]);  // color writemask red
4422   EXPECT_EQ(1, results[2]);  // color writemask green
4423   EXPECT_EQ(1, results[3]);  // color writemask blue
4424   EXPECT_EQ(1, results[4]);  // color writemask alpha
4425   EXPECT_EQ(-1, results[5]);  // stencil writemask alpha
4426   EXPECT_EQ(kSentinel, results[num_results]);  // End of results
4427 }
4428
4429 TEST_F(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) {
4430   const GLsizei kCount = 3;
4431   // Offset the pnames because GLGetError will use the first uint32.
4432   const uint32 kPnameOffset = sizeof(uint32);
4433   const uint32 kResultsOffset = kPnameOffset + sizeof(GLint) * kCount;
4434   GLenum* pnames = GetSharedMemoryAsWithOffset<GLenum*>(kPnameOffset);
4435   pnames[0] = GL_DEPTH_WRITEMASK;
4436   pnames[1] = GL_COLOR_WRITEMASK;
4437   pnames[2] = GL_STENCIL_WRITEMASK;
4438   GLint* results = GetSharedMemoryAsWithOffset<GLint*>(kResultsOffset);
4439
4440   GLsizei num_results = 0;
4441   for (GLsizei ii = 0; ii < kCount; ++ii) {
4442     num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
4443   }
4444   const GLsizei result_size = num_results * sizeof(*results);
4445   memset(results,  0, result_size);
4446
4447   const GLint kSentinel = 0x12345678;
4448   results[num_results] = kSentinel;
4449
4450   GetMultipleIntegervCHROMIUM cmd;
4451   // Check bad pnames pointer.
4452   cmd.Init(
4453       kInvalidSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
4454       kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
4455       result_size);
4456   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
4457   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4458   // Check bad pnames pointer.
4459   cmd.Init(
4460       kSharedMemoryId, kInvalidSharedMemoryOffset, kCount,
4461       kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
4462       result_size);
4463   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
4464   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4465   // Check bad count.
4466   cmd.Init(
4467       kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, -1,
4468       kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
4469       result_size);
4470   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
4471   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4472   // Check bad results pointer.
4473   cmd.Init(
4474       kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
4475       kInvalidSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
4476       result_size);
4477   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
4478   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4479   // Check bad results pointer.
4480   cmd.Init(
4481       kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
4482       kSharedMemoryId, kInvalidSharedMemoryOffset,
4483       result_size);
4484   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
4485   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4486   // Check bad size.
4487   cmd.Init(
4488       kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
4489       kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
4490       result_size + 1);
4491   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4492   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
4493   // Check bad size.
4494   cmd.Init(
4495       kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
4496       kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
4497       result_size - 1);
4498   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4499   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
4500   // Check bad enum.
4501   cmd.Init(
4502       kSharedMemoryId, kSharedMemoryOffset + kPnameOffset, kCount,
4503       kSharedMemoryId, kSharedMemoryOffset + kResultsOffset,
4504       result_size);
4505   GLenum temp = pnames[2];
4506   pnames[2] = GL_TRUE;
4507   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4508   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
4509   pnames[2] = temp;
4510   // Check results area has not been cleared by client.
4511   results[1] = 1;
4512   EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
4513   // Check buffer is what we expect
4514   EXPECT_EQ(0, results[0]);
4515   EXPECT_EQ(1, results[1]);
4516   EXPECT_EQ(0, results[2]);
4517   EXPECT_EQ(0, results[3]);
4518   EXPECT_EQ(0, results[4]);
4519   EXPECT_EQ(0, results[5]);
4520   EXPECT_EQ(kSentinel, results[num_results]);  // End of results
4521 }
4522
4523 TEST_F(GLES2DecoderTest, TexImage2DRedefinitionSucceeds) {
4524   const int kWidth = 16;
4525   const int kHeight = 8;
4526   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
4527   EXPECT_CALL(*gl_, GetError())
4528       .WillRepeatedly(Return(GL_NO_ERROR));
4529   for (int ii = 0; ii < 2; ++ii) {
4530     TexImage2D cmd;
4531     if (ii == 0) {
4532       EXPECT_CALL(*gl_, TexImage2D(
4533           GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
4534           GL_UNSIGNED_BYTE, _))
4535           .Times(1)
4536           .RetiresOnSaturation();
4537       cmd.Init(
4538           GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
4539           GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
4540     } else {
4541       SetupClearTextureExpections(
4542           kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
4543           0, GL_RGBA, GL_UNSIGNED_BYTE, kWidth, kHeight);
4544       cmd.Init(
4545           GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
4546           GL_UNSIGNED_BYTE, 0, 0);
4547     }
4548     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4549     EXPECT_CALL(*gl_, TexSubImage2D(
4550         GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight - 1, GL_RGBA, GL_UNSIGNED_BYTE,
4551         shared_memory_address_))
4552         .Times(1)
4553         .RetiresOnSaturation();
4554     // Consider this TexSubImage2D command part of the previous TexImage2D
4555     // (last GL_TRUE argument). It will be skipped if there are bugs in the
4556     // redefinition case.
4557     TexSubImage2D cmd2;
4558     cmd2.Init(
4559         GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight - 1, GL_RGBA, GL_UNSIGNED_BYTE,
4560         kSharedMemoryId, kSharedMemoryOffset, GL_TRUE);
4561     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
4562   }
4563 }
4564
4565 TEST_F(GLES2DecoderTest, TexImage2DGLError) {
4566   GLenum target = GL_TEXTURE_2D;
4567   GLint level = 0;
4568   GLenum internal_format = GL_RGBA;
4569   GLsizei width = 2;
4570   GLsizei height = 4;
4571   GLint border = 0;
4572   GLenum format = GL_RGBA;
4573   GLenum type = GL_UNSIGNED_BYTE;
4574   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
4575   TextureManager* manager = group().texture_manager();
4576   TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
4577   ASSERT_TRUE(texture_ref != NULL);
4578   Texture* texture = texture_ref->texture();
4579   EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
4580   EXPECT_CALL(*gl_, GetError())
4581       .WillOnce(Return(GL_NO_ERROR))
4582       .WillOnce(Return(GL_OUT_OF_MEMORY))
4583       .RetiresOnSaturation();
4584   EXPECT_CALL(*gl_, TexImage2D(target, level, internal_format,
4585                                width, height, border, format, type, _))
4586       .Times(1)
4587       .RetiresOnSaturation();
4588   TexImage2D cmd;
4589   cmd.Init(target, level, internal_format, width, height, border, format,
4590            type, kSharedMemoryId, kSharedMemoryOffset);
4591   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4592   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
4593   EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
4594 }
4595
4596 TEST_F(GLES2DecoderTest, BufferDataGLError) {
4597   GLenum target = GL_ARRAY_BUFFER;
4598   GLsizeiptr size = 4;
4599   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
4600   BufferManager* manager = group().buffer_manager();
4601   Buffer* buffer = manager->GetBuffer(client_buffer_id_);
4602   ASSERT_TRUE(buffer != NULL);
4603   EXPECT_EQ(0, buffer->size());
4604   EXPECT_CALL(*gl_, GetError())
4605       .WillOnce(Return(GL_NO_ERROR))
4606       .WillOnce(Return(GL_OUT_OF_MEMORY))
4607       .RetiresOnSaturation();
4608   EXPECT_CALL(*gl_, BufferData(target, size, _, GL_STREAM_DRAW))
4609       .Times(1)
4610       .RetiresOnSaturation();
4611   BufferData cmd;
4612   cmd.Init(target, size, 0, 0, GL_STREAM_DRAW);
4613   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4614   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
4615   EXPECT_EQ(0, buffer->size());
4616 }
4617
4618 TEST_F(GLES2DecoderTest, CopyTexImage2DGLError) {
4619   GLenum target = GL_TEXTURE_2D;
4620   GLint level = 0;
4621   GLenum internal_format = GL_RGBA;
4622   GLsizei width = 2;
4623   GLsizei height = 4;
4624   GLint border = 0;
4625   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
4626   TextureManager* manager = group().texture_manager();
4627   TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
4628   ASSERT_TRUE(texture_ref != NULL);
4629   Texture* texture = texture_ref->texture();
4630   EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
4631   EXPECT_CALL(*gl_, GetError())
4632       .WillOnce(Return(GL_NO_ERROR))
4633       .WillOnce(Return(GL_OUT_OF_MEMORY))
4634       .RetiresOnSaturation();
4635   EXPECT_CALL(*gl_, CopyTexImage2D(
4636       target, level, internal_format, 0, 0, width, height, border))
4637       .Times(1)
4638       .RetiresOnSaturation();
4639   CopyTexImage2D cmd;
4640   cmd.Init(target, level, internal_format, 0, 0, width, height, border);
4641   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4642   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
4643   EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
4644 }
4645
4646 TEST_F(GLES2DecoderTest, FramebufferRenderbufferGLError) {
4647   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
4648                     kServiceFramebufferId);
4649   EXPECT_CALL(*gl_, GetError())
4650       .WillOnce(Return(GL_NO_ERROR))
4651       .WillOnce(Return(GL_OUT_OF_MEMORY))
4652       .RetiresOnSaturation();
4653   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
4654       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4655       kServiceRenderbufferId))
4656       .Times(1)
4657       .RetiresOnSaturation();
4658   FramebufferRenderbuffer cmd;
4659   cmd.Init(
4660       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4661       client_renderbuffer_id_);
4662   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4663   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
4664 }
4665
4666 TEST_F(GLES2DecoderTest, FramebufferTexture2DGLError) {
4667   const GLsizei kWidth = 5;
4668   const GLsizei kHeight = 3;
4669   const GLenum kFormat = GL_RGB;
4670   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
4671   DoTexImage2D(GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0,
4672                kFormat, GL_UNSIGNED_BYTE, 0, 0);
4673   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
4674                     kServiceFramebufferId);
4675   EXPECT_CALL(*gl_, GetError())
4676       .WillOnce(Return(GL_NO_ERROR))
4677       .WillOnce(Return(GL_OUT_OF_MEMORY))
4678       .RetiresOnSaturation();
4679   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
4680       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
4681       kServiceTextureId, 0))
4682       .Times(1)
4683       .RetiresOnSaturation();
4684   FramebufferTexture2D fbtex_cmd;
4685   fbtex_cmd.Init(
4686       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
4687       0);
4688   EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
4689   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
4690 }
4691
4692 TEST_F(GLES2DecoderTest, RenderbufferStorageGLError) {
4693   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
4694                     kServiceRenderbufferId);
4695   EXPECT_CALL(*gl_, GetError())
4696       .WillOnce(Return(GL_NO_ERROR))
4697       .WillOnce(Return(GL_OUT_OF_MEMORY))
4698       .RetiresOnSaturation();
4699   EXPECT_CALL(*gl_, RenderbufferStorageEXT(
4700       GL_RENDERBUFFER, GL_RGBA, 100, 50))
4701       .Times(1)
4702       .RetiresOnSaturation();
4703   RenderbufferStorage cmd;
4704   cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 100, 50);
4705   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4706   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
4707 }
4708
4709 TEST_F(GLES2DecoderTest, RenderbufferStorageBadArgs) {
4710   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
4711                     kServiceRenderbufferId);
4712   EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _))
4713       .Times(0)
4714       .RetiresOnSaturation();
4715   RenderbufferStorage cmd;
4716   cmd.Init(GL_RENDERBUFFER, GL_RGBA4, TestHelper::kMaxRenderbufferSize + 1, 1);
4717   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4718   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
4719   cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 1, TestHelper::kMaxRenderbufferSize + 1);
4720   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4721   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
4722 }
4723
4724 TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleGLError) {
4725   InitDecoder(
4726       "GL_EXT_framebuffer_multisample",  // extensions
4727       false,   // has alpha
4728       false,   // has depth
4729       false,   // has stencil
4730       false,   // request alpha
4731       false,   // request depth
4732       false,   // request stencil
4733       true);   // bind generates resource
4734   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
4735                     kServiceRenderbufferId);
4736   EXPECT_CALL(*gl_, GetError())
4737       .WillOnce(Return(GL_NO_ERROR))
4738       .WillOnce(Return(GL_OUT_OF_MEMORY))
4739       .RetiresOnSaturation();
4740   EXPECT_CALL(*gl_, RenderbufferStorageMultisampleEXT(
4741       GL_RENDERBUFFER, 1, GL_RGBA, 100, 50))
4742       .Times(1)
4743       .RetiresOnSaturation();
4744   RenderbufferStorageMultisampleEXT cmd;
4745   cmd.Init(GL_RENDERBUFFER, 1, GL_RGBA4, 100, 50);
4746   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4747   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
4748 }
4749
4750 TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleBadArgs) {
4751   InitDecoder(
4752       "GL_EXT_framebuffer_multisample",  // extensions
4753       false,   // has alpha
4754       false,   // has depth
4755       false,   // has stencil
4756       false,   // request alpha
4757       false,   // request depth
4758       false,   // request stencil
4759       true);   // bind generates resource
4760   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
4761                     kServiceRenderbufferId);
4762   EXPECT_CALL(*gl_, RenderbufferStorageMultisampleEXT(_, _, _, _, _))
4763       .Times(0)
4764       .RetiresOnSaturation();
4765   RenderbufferStorageMultisampleEXT cmd;
4766   cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples + 1,
4767            GL_RGBA4, TestHelper::kMaxRenderbufferSize, 1);
4768   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4769   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
4770   cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples,
4771            GL_RGBA4, TestHelper::kMaxRenderbufferSize + 1, 1);
4772   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4773   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
4774   cmd.Init(GL_RENDERBUFFER, TestHelper::kMaxSamples,
4775            GL_RGBA4, 1, TestHelper::kMaxRenderbufferSize + 1);
4776   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4777   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
4778 }
4779
4780 TEST_F(GLES2DecoderTest, ReadPixelsGLError) {
4781   GLenum kFormat = GL_RGBA;
4782   GLint x = 0;
4783   GLint y = 0;
4784   GLsizei width = 2;
4785   GLsizei height = 4;
4786   typedef ReadPixels::Result Result;
4787   Result* result = GetSharedMemoryAs<Result*>();
4788   uint32 result_shm_id = kSharedMemoryId;
4789   uint32 result_shm_offset = kSharedMemoryOffset;
4790   uint32 pixels_shm_id = kSharedMemoryId;
4791   uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
4792   EXPECT_CALL(*gl_, GetError())
4793       .WillOnce(Return(GL_NO_ERROR))
4794       .WillOnce(Return(GL_OUT_OF_MEMORY))
4795       .RetiresOnSaturation();
4796   EXPECT_CALL(
4797       *gl_, ReadPixels(x, y, width, height, kFormat, GL_UNSIGNED_BYTE, _))
4798       .Times(1)
4799       .RetiresOnSaturation();
4800   ReadPixels cmd;
4801   cmd.Init(x, y, width, height, kFormat, GL_UNSIGNED_BYTE,
4802            pixels_shm_id, pixels_shm_offset,
4803            result_shm_id, result_shm_offset,
4804            false);
4805   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4806   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
4807 }
4808
4809 static bool ValueInArray(GLint value, GLint* array, GLint count) {
4810   for (GLint ii = 0; ii < count; ++ii) {
4811     if (array[ii] == value) {
4812       return true;
4813     }
4814   }
4815   return false;
4816 }
4817
4818 TEST_F(GLES2DecoderManualInitTest, GetCompressedTextureFormats) {
4819   InitDecoder(
4820       "GL_EXT_texture_compression_s3tc",  // extensions
4821       false,   // has alpha
4822       false,   // has depth
4823       false,   // has stencil
4824       false,   // request alpha
4825       false,   // request depth
4826       false,   // request stencil
4827       true);   // bind generates resource
4828
4829   EXPECT_CALL(*gl_, GetError())
4830       .WillOnce(Return(GL_NO_ERROR))
4831       .WillOnce(Return(GL_NO_ERROR))
4832       .WillOnce(Return(GL_NO_ERROR))
4833       .WillOnce(Return(GL_NO_ERROR))
4834       .RetiresOnSaturation();
4835
4836   typedef GetIntegerv::Result Result;
4837   Result* result = static_cast<Result*>(shared_memory_address_);
4838   GetIntegerv cmd;
4839   result->size = 0;
4840   EXPECT_CALL(*gl_, GetIntegerv(_, _))
4841       .Times(0)
4842       .RetiresOnSaturation();
4843   cmd.Init(
4844       GL_NUM_COMPRESSED_TEXTURE_FORMATS,
4845       shared_memory_id_, shared_memory_offset_);
4846   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4847   EXPECT_EQ(1, result->GetNumResults());
4848   GLint num_formats = result->GetData()[0];
4849   EXPECT_EQ(4, num_formats);
4850   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4851
4852   result->size = 0;
4853   cmd.Init(
4854       GL_COMPRESSED_TEXTURE_FORMATS,
4855       shared_memory_id_, shared_memory_offset_);
4856   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4857   EXPECT_EQ(num_formats, result->GetNumResults());
4858
4859   EXPECT_TRUE(ValueInArray(
4860       GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
4861       result->GetData(), result->GetNumResults()));
4862   EXPECT_TRUE(ValueInArray(
4863       GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
4864       result->GetData(), result->GetNumResults()));
4865   EXPECT_TRUE(ValueInArray(
4866       GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
4867       result->GetData(), result->GetNumResults()));
4868   EXPECT_TRUE(ValueInArray(
4869       GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
4870       result->GetData(), result->GetNumResults()));
4871
4872   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4873 }
4874
4875 TEST_F(GLES2DecoderManualInitTest, GetNoCompressedTextureFormats) {
4876   InitDecoder(
4877       "",  // extensions
4878       false,   // has alpha
4879       false,   // has depth
4880       false,   // has stencil
4881       false,   // request alpha
4882       false,   // request depth
4883       false,   // request stencil
4884       true);   // bind generates resource
4885
4886   EXPECT_CALL(*gl_, GetError())
4887       .WillOnce(Return(GL_NO_ERROR))
4888       .WillOnce(Return(GL_NO_ERROR))
4889       .WillOnce(Return(GL_NO_ERROR))
4890       .WillOnce(Return(GL_NO_ERROR))
4891       .RetiresOnSaturation();
4892
4893   typedef GetIntegerv::Result Result;
4894   Result* result = static_cast<Result*>(shared_memory_address_);
4895   GetIntegerv cmd;
4896   result->size = 0;
4897   EXPECT_CALL(*gl_, GetIntegerv(_, _))
4898       .Times(0)
4899       .RetiresOnSaturation();
4900   cmd.Init(
4901       GL_NUM_COMPRESSED_TEXTURE_FORMATS,
4902       shared_memory_id_, shared_memory_offset_);
4903   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4904   EXPECT_EQ(1, result->GetNumResults());
4905   GLint num_formats = result->GetData()[0];
4906   EXPECT_EQ(0, num_formats);
4907   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4908
4909   result->size = 0;
4910   cmd.Init(
4911       GL_COMPRESSED_TEXTURE_FORMATS,
4912       shared_memory_id_, shared_memory_offset_);
4913   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4914   EXPECT_EQ(num_formats, result->GetNumResults());
4915
4916   EXPECT_EQ(GL_NO_ERROR, GetGLError());
4917 }
4918
4919 TEST_F(GLES2DecoderManualInitTest, CompressedTexImage2DBucketBadBucket) {
4920   InitDecoder(
4921       "GL_EXT_texture_compression_s3tc",  // extensions
4922       false,   // has alpha
4923       false,   // has depth
4924       false,   // has stencil
4925       false,   // request alpha
4926       false,   // request depth
4927       false,   // request stencil
4928       true);   // bind generates resource
4929
4930   const uint32 kBadBucketId = 123;
4931   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
4932   CompressedTexImage2DBucket cmd;
4933   cmd.Init(
4934       GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 4, 4, 0,
4935       kBadBucketId);
4936   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
4937   CompressedTexSubImage2DBucket cmd2;
4938   cmd2.Init(
4939       GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
4940       kBadBucketId);
4941   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
4942 }
4943
4944 namespace {
4945
4946 struct S3TCTestData {
4947   GLenum format;
4948   size_t block_size;
4949 };
4950
4951 }  // anonymous namespace.
4952
4953 TEST_F(GLES2DecoderManualInitTest, CompressedTexImage2DS3TC) {
4954   InitDecoder(
4955       "GL_EXT_texture_compression_s3tc",  // extensions
4956       false,   // has alpha
4957       false,   // has depth
4958       false,   // has stencil
4959       false,   // request alpha
4960       false,   // request depth
4961       false,   // request stencil
4962       true);   // bind generates resource
4963   const uint32 kBucketId = 123;
4964   CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId);
4965   ASSERT_TRUE(bucket != NULL);
4966
4967   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
4968
4969   static const S3TCTestData test_data[] = {
4970     { GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, },
4971     { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, },
4972     { GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 16, },
4973     { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 16, },
4974   };
4975
4976   for (size_t ii = 0; ii < arraysize(test_data); ++ii) {
4977     const S3TCTestData& test = test_data[ii];
4978     CompressedTexImage2DBucket cmd;
4979     // test small width.
4980     DoCompressedTexImage2D(
4981         GL_TEXTURE_2D, 0, test.format, 2, 4, 0, test.block_size,
4982         kBucketId);
4983     EXPECT_EQ(GL_NO_ERROR, GetGLError());
4984
4985     // test bad width.
4986     cmd.Init(
4987         GL_TEXTURE_2D, 0, test.format, 5, 4, 0,
4988         kBucketId);
4989     bucket->SetSize(test.block_size * 2);
4990     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
4991     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
4992
4993     // test small height.
4994     DoCompressedTexImage2D(
4995         GL_TEXTURE_2D, 0, test.format, 4, 2, 0, test.block_size,
4996         kBucketId);
4997     EXPECT_EQ(GL_NO_ERROR, GetGLError());
4998
4999     // test too bad height.
5000     cmd.Init(
5001         GL_TEXTURE_2D, 0, test.format, 4, 5, 0,
5002         kBucketId);
5003     bucket->SetSize(test.block_size * 2);
5004     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5005     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5006
5007     // test small for level 0.
5008     DoCompressedTexImage2D(
5009         GL_TEXTURE_2D, 0, test.format, 1, 1, 0, test.block_size,
5010         kBucketId);
5011     EXPECT_EQ(GL_NO_ERROR, GetGLError());
5012
5013     // test small for level 0.
5014     DoCompressedTexImage2D(
5015         GL_TEXTURE_2D, 0, test.format, 2, 2, 0, test.block_size,
5016         kBucketId);
5017     EXPECT_EQ(GL_NO_ERROR, GetGLError());
5018
5019     // test size too large.
5020     cmd.Init(
5021         GL_TEXTURE_2D, 0, test.format, 4, 4, 0,
5022         kBucketId);
5023     bucket->SetSize(test.block_size * 2);
5024     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5025     EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5026
5027     // test size too small.
5028     cmd.Init(
5029         GL_TEXTURE_2D, 0, test.format, 4, 4, 0,
5030         kBucketId);
5031     bucket->SetSize(test.block_size / 2);
5032     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5033     EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5034
5035     // test with 3 mips.
5036     DoCompressedTexImage2D(
5037         GL_TEXTURE_2D, 0, test.format, 4, 4, 0, test.block_size, kBucketId);
5038     DoCompressedTexImage2D(
5039         GL_TEXTURE_2D, 1, test.format, 2, 2, 0, test.block_size, kBucketId);
5040     DoCompressedTexImage2D(
5041         GL_TEXTURE_2D, 2, test.format, 1, 1, 0, test.block_size, kBucketId);
5042     EXPECT_EQ(GL_NO_ERROR, GetGLError());
5043
5044     // Test a 16x16
5045     DoCompressedTexImage2D(
5046         GL_TEXTURE_2D, 0, test.format, 16, 16, 0, test.block_size * 4 * 4,
5047         kBucketId);
5048     EXPECT_EQ(GL_NO_ERROR, GetGLError());
5049
5050     CompressedTexSubImage2DBucket sub_cmd;
5051     bucket->SetSize(test.block_size);
5052     // Test sub image bad xoffset
5053     sub_cmd.Init(
5054         GL_TEXTURE_2D, 0, 1, 0, 4, 4, test.format, kBucketId);
5055     EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
5056     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5057
5058     // Test sub image bad yoffset
5059     sub_cmd.Init(
5060         GL_TEXTURE_2D, 0, 0, 2, 4, 4, test.format, kBucketId);
5061     EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
5062     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5063
5064     // Test sub image bad width
5065     bucket->SetSize(test.block_size * 2);
5066     sub_cmd.Init(
5067         GL_TEXTURE_2D, 0, 0, 0, 5, 4, test.format, kBucketId);
5068     EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
5069     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5070
5071     // Test sub image bad height
5072     sub_cmd.Init(
5073         GL_TEXTURE_2D, 0, 0, 0, 4, 5, test.format, kBucketId);
5074     EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
5075     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5076
5077     // Test sub image bad size
5078     bucket->SetSize(test.block_size + 1);
5079     sub_cmd.Init(
5080         GL_TEXTURE_2D, 0, 0, 0, 4, 4, test.format, kBucketId);
5081     EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
5082     EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5083
5084     for (GLint yoffset = 0; yoffset <= 8; yoffset += 4) {
5085       for (GLint xoffset = 0; xoffset <= 8; xoffset += 4) {
5086         for (GLsizei height = 4; height <= 8; height +=4 ) {
5087           for (GLsizei width = 4; width <= 8; width += 4) {
5088             GLsizei size = test.block_size * (width / 4) * (height / 4);
5089             bucket->SetSize(size);
5090             EXPECT_CALL(*gl_, CompressedTexSubImage2D(
5091                 GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, test.format,
5092                 size, _))
5093                 .Times(1)
5094                 .RetiresOnSaturation();
5095             sub_cmd.Init(
5096                 GL_TEXTURE_2D, 0, xoffset, yoffset, width, height, test.format,
5097                 kBucketId);
5098             EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
5099             EXPECT_EQ(GL_NO_ERROR, GetGLError());
5100           }
5101         }
5102       }
5103     }
5104   }
5105 }
5106
5107 TEST_F(GLES2DecoderManualInitTest, CompressedTexImage2DETC1) {
5108   InitDecoder(
5109       "GL_OES_compressed_ETC1_RGB8_texture",  // extensions
5110       false,   // has alpha
5111       false,   // has depth
5112       false,   // has stencil
5113       false,   // request alpha
5114       false,   // request depth
5115       false,   // request stencil
5116       true);   // bind generates resource
5117   const uint32 kBucketId = 123;
5118   CommonDecoder::Bucket* bucket = decoder_->CreateBucket(kBucketId);
5119   ASSERT_TRUE(bucket != NULL);
5120
5121   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
5122
5123   const GLenum kFormat = GL_ETC1_RGB8_OES;
5124   const size_t kBlockSize = 8;
5125
5126   CompressedTexImage2DBucket cmd;
5127   // test small width.
5128   DoCompressedTexImage2D(GL_TEXTURE_2D, 0, kFormat, 4, 8, 0, 16, kBucketId);
5129   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5130
5131   // test small height.
5132   DoCompressedTexImage2D(GL_TEXTURE_2D, 0, kFormat, 8, 4, 0, 16, kBucketId);
5133   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5134
5135   // test size too large.
5136   cmd.Init(GL_TEXTURE_2D, 0, kFormat, 4, 4, 0, kBucketId);
5137   bucket->SetSize(kBlockSize * 2);
5138   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5139   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5140
5141   // test size too small.
5142   cmd.Init(GL_TEXTURE_2D, 0, kFormat, 4, 4, 0, kBucketId);
5143   bucket->SetSize(kBlockSize / 2);
5144   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5145   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5146
5147   // Test a 16x16
5148   DoCompressedTexImage2D(
5149       GL_TEXTURE_2D, 0, kFormat, 16, 16, 0, kBlockSize * 16, kBucketId);
5150   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5151
5152   // Test CompressedTexSubImage not allowed
5153   CompressedTexSubImage2DBucket sub_cmd;
5154   bucket->SetSize(kBlockSize);
5155   sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 4, kFormat, kBucketId);
5156   EXPECT_EQ(error::kNoError, ExecuteCmd(sub_cmd));
5157   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5158
5159   // Test TexSubImage not allowed for ETC1 compressed texture
5160   TextureRef* texture_ref = GetTexture(client_texture_id_);
5161   ASSERT_TRUE(texture_ref != NULL);
5162   Texture* texture = texture_ref->texture();
5163   GLenum type, internal_format;
5164   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
5165   EXPECT_EQ(kFormat, internal_format);
5166   TexSubImage2D texsub_cmd;
5167   texsub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE,
5168            kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
5169   EXPECT_EQ(error::kNoError, ExecuteCmd(texsub_cmd));
5170   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5171
5172   // Test CopyTexSubImage not allowed for ETC1 compressed texture
5173   CopyTexSubImage2D copy_cmd;
5174   copy_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
5175   EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
5176   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5177 }
5178
5179 TEST_F(GLES2DecoderManualInitTest, GetCompressedTextureFormatsETC1) {
5180   InitDecoder(
5181       "GL_OES_compressed_ETC1_RGB8_texture",  // extensions
5182       false,   // has alpha
5183       false,   // has depth
5184       false,   // has stencil
5185       false,   // request alpha
5186       false,   // request depth
5187       false,   // request stencil
5188       true);   // bind generates resource
5189
5190   EXPECT_CALL(*gl_, GetError())
5191       .WillOnce(Return(GL_NO_ERROR))
5192       .WillOnce(Return(GL_NO_ERROR))
5193       .WillOnce(Return(GL_NO_ERROR))
5194       .WillOnce(Return(GL_NO_ERROR))
5195       .RetiresOnSaturation();
5196
5197   typedef GetIntegerv::Result Result;
5198   Result* result = static_cast<Result*>(shared_memory_address_);
5199   GetIntegerv cmd;
5200   result->size = 0;
5201   EXPECT_CALL(*gl_, GetIntegerv(_, _))
5202       .Times(0)
5203       .RetiresOnSaturation();
5204   cmd.Init(
5205       GL_NUM_COMPRESSED_TEXTURE_FORMATS,
5206       shared_memory_id_, shared_memory_offset_);
5207   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5208   EXPECT_EQ(1, result->GetNumResults());
5209   GLint num_formats = result->GetData()[0];
5210   EXPECT_EQ(1, num_formats);
5211   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5212
5213   result->size = 0;
5214   cmd.Init(
5215       GL_COMPRESSED_TEXTURE_FORMATS,
5216       shared_memory_id_, shared_memory_offset_);
5217   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5218   EXPECT_EQ(num_formats, result->GetNumResults());
5219
5220   EXPECT_TRUE(ValueInArray(
5221       GL_ETC1_RGB8_OES,
5222       result->GetData(), result->GetNumResults()));
5223   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5224 }
5225
5226 TEST_F(GLES2DecoderWithShaderTest, GetProgramInfoCHROMIUMValidArgs) {
5227   const uint32 kBucketId = 123;
5228   GetProgramInfoCHROMIUM cmd;
5229   cmd.Init(client_program_id_, kBucketId);
5230   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5231   CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
5232   EXPECT_GT(bucket->size(), 0u);
5233 }
5234
5235 TEST_F(GLES2DecoderWithShaderTest, GetProgramInfoCHROMIUMInvalidArgs) {
5236   const uint32 kBucketId = 123;
5237   CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
5238   EXPECT_TRUE(bucket == NULL);
5239   GetProgramInfoCHROMIUM cmd;
5240   cmd.Init(kInvalidClientId, kBucketId);
5241   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5242   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5243   bucket = decoder_->GetBucket(kBucketId);
5244   ASSERT_TRUE(bucket != NULL);
5245   EXPECT_EQ(sizeof(ProgramInfoHeader), bucket->size());
5246   ProgramInfoHeader* info = bucket->GetDataAs<ProgramInfoHeader*>(
5247       0, sizeof(ProgramInfoHeader));
5248   ASSERT_TRUE(info != 0);
5249   EXPECT_EQ(0u, info->link_status);
5250   EXPECT_EQ(0u, info->num_attribs);
5251   EXPECT_EQ(0u, info->num_uniforms);
5252 }
5253
5254 TEST_F(GLES2DecoderManualInitTest, EGLImageExternalBindTexture) {
5255   InitDecoder(
5256       "GL_OES_EGL_image_external",  // extensions
5257       false,   // has alpha
5258       false,   // has depth
5259       false,   // has stencil
5260       false,   // request alpha
5261       false,   // request depth
5262       false,   // request stencil
5263       true);   // bind generates resource
5264   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kNewServiceId));
5265   EXPECT_CALL(*gl_, GenTextures(1, _))
5266       .WillOnce(SetArgumentPointee<1>(kNewServiceId));
5267   BindTexture cmd;
5268   cmd.Init(GL_TEXTURE_EXTERNAL_OES, kNewClientId);
5269   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5270   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5271   TextureRef* texture_ref = GetTexture(kNewClientId);
5272   EXPECT_TRUE(texture_ref != NULL);
5273   EXPECT_TRUE(texture_ref->texture()->target() == GL_TEXTURE_EXTERNAL_OES);
5274 }
5275
5276 TEST_F(GLES2DecoderManualInitTest, EGLImageExternalGetBinding) {
5277   InitDecoder(
5278       "GL_OES_EGL_image_external",  // extensions
5279       false,   // has alpha
5280       false,   // has depth
5281       false,   // has stencil
5282       false,   // request alpha
5283       false,   // request depth
5284       false,   // request stencil
5285       true);   // bind generates resource
5286   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
5287
5288   EXPECT_CALL(*gl_, GetError())
5289       .WillOnce(Return(GL_NO_ERROR))
5290       .WillOnce(Return(GL_NO_ERROR))
5291       .RetiresOnSaturation();
5292   typedef GetIntegerv::Result Result;
5293   Result* result = static_cast<Result*>(shared_memory_address_);
5294   EXPECT_CALL(*gl_, GetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES,
5295                                 result->GetData()))
5296       .Times(0);
5297   result->size = 0;
5298   GetIntegerv cmd;
5299   cmd.Init(GL_TEXTURE_BINDING_EXTERNAL_OES,
5300            shared_memory_id_,
5301            shared_memory_offset_);
5302   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5303   EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
5304       GL_TEXTURE_BINDING_EXTERNAL_OES), result->GetNumResults());
5305   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5306   EXPECT_EQ(client_texture_id_, (uint32)result->GetData()[0]);
5307 }
5308
5309 TEST_F(GLES2DecoderManualInitTest, EGLImageExternalTextureDefaults) {
5310   InitDecoder(
5311       "GL_OES_EGL_image_external",  // extensions
5312       false,   // has alpha
5313       false,   // has depth
5314       false,   // has stencil
5315       false,   // request alpha
5316       false,   // request depth
5317       false,   // request stencil
5318       true);   // bind generates resource
5319   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
5320
5321   TextureRef* texture_ref = GetTexture(client_texture_id_);
5322   EXPECT_TRUE(texture_ref != NULL);
5323   Texture* texture = texture_ref->texture();
5324   EXPECT_TRUE(texture->target() == GL_TEXTURE_EXTERNAL_OES);
5325   EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
5326   EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
5327   EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
5328 }
5329
5330 TEST_F(GLES2DecoderManualInitTest, EGLImageExternalTextureParam) {
5331   InitDecoder(
5332       "GL_OES_EGL_image_external",  // extensions
5333       false,   // has alpha
5334       false,   // has depth
5335       false,   // has stencil
5336       false,   // request alpha
5337       false,   // request depth
5338       false,   // request stencil
5339       true);   // bind generates resource
5340
5341   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
5342
5343   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_EXTERNAL_OES,
5344                                   GL_TEXTURE_MIN_FILTER,
5345                                   GL_NEAREST));
5346   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_EXTERNAL_OES,
5347                                   GL_TEXTURE_MIN_FILTER,
5348                                   GL_LINEAR));
5349   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_EXTERNAL_OES,
5350                                   GL_TEXTURE_WRAP_S,
5351                                   GL_CLAMP_TO_EDGE));
5352   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_EXTERNAL_OES,
5353                                   GL_TEXTURE_WRAP_T,
5354                                   GL_CLAMP_TO_EDGE));
5355   TexParameteri cmd;
5356   cmd.Init(GL_TEXTURE_EXTERNAL_OES,
5357            GL_TEXTURE_MIN_FILTER,
5358            GL_NEAREST);
5359   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5360   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5361
5362   cmd.Init(GL_TEXTURE_EXTERNAL_OES,
5363            GL_TEXTURE_MIN_FILTER,
5364            GL_LINEAR);
5365   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5366   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5367
5368   cmd.Init(GL_TEXTURE_EXTERNAL_OES,
5369            GL_TEXTURE_WRAP_S,
5370            GL_CLAMP_TO_EDGE);
5371   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5372   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5373
5374   cmd.Init(GL_TEXTURE_EXTERNAL_OES,
5375            GL_TEXTURE_WRAP_T,
5376            GL_CLAMP_TO_EDGE);
5377   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5378   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5379
5380   TextureRef* texture_ref = GetTexture(client_texture_id_);
5381   EXPECT_TRUE(texture_ref != NULL);
5382   Texture* texture = texture_ref->texture();
5383   EXPECT_TRUE(texture->target() == GL_TEXTURE_EXTERNAL_OES);
5384   EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
5385   EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
5386   EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
5387 }
5388
5389 TEST_F(GLES2DecoderManualInitTest, EGLImageExternalTextureParamInvalid) {
5390   InitDecoder(
5391       "GL_OES_EGL_image_external",  // extensions
5392       false,   // has alpha
5393       false,   // has depth
5394       false,   // has stencil
5395       false,   // request alpha
5396       false,   // request depth
5397       false,   // request stencil
5398       true);   // bind generates resource
5399
5400   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
5401
5402   TexParameteri cmd;
5403   cmd.Init(GL_TEXTURE_EXTERNAL_OES,
5404            GL_TEXTURE_MIN_FILTER,
5405            GL_NEAREST_MIPMAP_NEAREST);
5406   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5407   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
5408
5409   cmd.Init(GL_TEXTURE_EXTERNAL_OES,
5410            GL_TEXTURE_WRAP_S,
5411            GL_REPEAT);
5412   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5413   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
5414
5415   cmd.Init(GL_TEXTURE_EXTERNAL_OES,
5416            GL_TEXTURE_WRAP_T,
5417            GL_REPEAT);
5418   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5419   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
5420
5421   TextureRef* texture_ref = GetTexture(client_texture_id_);
5422   EXPECT_TRUE(texture_ref != NULL);
5423   Texture* texture = texture_ref->texture();
5424   EXPECT_TRUE(texture->target() == GL_TEXTURE_EXTERNAL_OES);
5425   EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
5426   EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
5427   EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
5428 }
5429
5430 TEST_F(GLES2DecoderManualInitTest, EGLImageExternalTexImage2DError) {
5431   InitDecoder(
5432       "GL_OES_EGL_image_external",  // extensions
5433       false,   // has alpha
5434       false,   // has depth
5435       false,   // has stencil
5436       false,   // request alpha
5437       false,   // request depth
5438       false,   // request stencil
5439       true);   // bind generates resource
5440
5441   GLenum target = GL_TEXTURE_EXTERNAL_OES;
5442   GLint level = 0;
5443   GLenum internal_format = GL_RGBA;
5444   GLsizei width = 2;
5445   GLsizei height = 4;
5446   GLint border = 0;
5447   GLenum format = GL_RGBA;
5448   GLenum type = GL_UNSIGNED_BYTE;
5449   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
5450   ASSERT_TRUE(GetTexture(client_texture_id_) != NULL);
5451   TexImage2D cmd;
5452   cmd.Init(target, level, internal_format, width, height, border, format,
5453            type, kSharedMemoryId, kSharedMemoryOffset);
5454   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5455
5456   // TexImage2D is not allowed with GL_TEXTURE_EXTERNAL_OES targets.
5457   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
5458 }
5459
5460 TEST_F(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
5461   InitDecoder(
5462       "",      // extensions
5463       false,   // has alpha
5464       false,   // has depth
5465       false,   // has stencil
5466       false,   // request alpha
5467       false,   // request depth
5468       false,   // request stencil
5469       false);  // bind generates resource
5470
5471   BindTexture cmd1;
5472   cmd1.Init(GL_TEXTURE_2D, kInvalidClientId);
5473   EXPECT_NE(error::kNoError, ExecuteCmd(cmd1));
5474
5475   BindBuffer cmd2;
5476   cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId);
5477   EXPECT_NE(error::kNoError, ExecuteCmd(cmd2));
5478
5479   BindFramebuffer cmd3;
5480   cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId);
5481   EXPECT_NE(error::kNoError, ExecuteCmd(cmd3));
5482
5483   BindRenderbuffer cmd4;
5484   cmd4.Init(GL_RENDERBUFFER, kInvalidClientId);
5485   EXPECT_NE(error::kNoError, ExecuteCmd(cmd4));
5486 }
5487
5488 TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUM) {
5489   const GLuint kObjectId = 123;
5490   InitDecoder(
5491       "GL_CHROMIUM_stream_texture",  // extensions
5492       false,   // has alpha
5493       false,   // has depth
5494       false,   // has stencil
5495       false,   // request alpha
5496       false,   // request depth
5497       false,   // request stencil
5498       true);   // bind generates resource
5499
5500   EXPECT_CALL(*stream_texture_manager(), CreateStreamTexture(
5501       kServiceTextureId, client_texture_id_))
5502       .WillOnce(Return(kObjectId))
5503       .RetiresOnSaturation();
5504
5505   CreateStreamTextureCHROMIUM cmd;
5506   CreateStreamTextureCHROMIUM::Result* result =
5507       static_cast<CreateStreamTextureCHROMIUM::Result*>(shared_memory_address_);
5508   cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_);
5509   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5510   EXPECT_EQ(kObjectId, *result);
5511   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5512   TextureRef* texture_ref = GetTexture(client_texture_id_);
5513   EXPECT_TRUE(texture_ref != NULL);
5514   EXPECT_TRUE(texture_ref->texture()->IsStreamTexture());
5515   EXPECT_CALL(*stream_texture_manager(),
5516               DestroyStreamTexture(kServiceTextureId))
5517       .Times(1)
5518       .RetiresOnSaturation();
5519 }
5520
5521 TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUMBadId) {
5522   InitDecoder(
5523       "GL_CHROMIUM_stream_texture",  // extensions
5524       false,   // has alpha
5525       false,   // has depth
5526       false,   // has stencil
5527       false,   // request alpha
5528       false,   // request depth
5529       false,   // request stencil
5530       true);   // bind generates resource
5531
5532   CreateStreamTextureCHROMIUM cmd;
5533   CreateStreamTextureCHROMIUM::Result* result =
5534       static_cast<CreateStreamTextureCHROMIUM::Result*>(shared_memory_address_);
5535   cmd.Init(kNewClientId, shared_memory_id_, shared_memory_offset_);
5536   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5537   EXPECT_EQ(static_cast<GLuint>(GL_ZERO), *result);
5538   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5539 }
5540
5541 TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUMAlreadyBound) {
5542   InitDecoder(
5543       "GL_CHROMIUM_stream_texture",  // extensions
5544       false,   // has alpha
5545       false,   // has depth
5546       false,   // has stencil
5547       false,   // request alpha
5548       false,   // request depth
5549       false,   // request stencil
5550       true);   // bind generates resource
5551   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
5552
5553   CreateStreamTextureCHROMIUM cmd;
5554   CreateStreamTextureCHROMIUM::Result* result =
5555       static_cast<CreateStreamTextureCHROMIUM::Result*>(shared_memory_address_);
5556   cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_);
5557   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5558   EXPECT_EQ(static_cast<GLuint>(GL_ZERO), *result);
5559   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5560 }
5561
5562 TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUMAlreadySet) {
5563   InitDecoder(
5564       "GL_CHROMIUM_stream_texture",  // extensions
5565       false,   // has alpha
5566       false,   // has depth
5567       false,   // has stencil
5568       false,   // request alpha
5569       false,   // request depth
5570       false,   // request stencil
5571       true);   // bind generates resource
5572
5573   TextureRef* texture_ref = GetTexture(client_texture_id_);
5574   group().texture_manager()->SetStreamTexture(texture_ref, true);
5575
5576   CreateStreamTextureCHROMIUM cmd;
5577   cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_);
5578   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5579   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5580
5581   EXPECT_CALL(*stream_texture_manager(),
5582               DestroyStreamTexture(kServiceTextureId))
5583       .Times(1)
5584       .RetiresOnSaturation();
5585 }
5586
5587 TEST_F(GLES2DecoderManualInitTest, DrawStreamTextureCHROMIUM) {
5588   InitDecoder(
5589       "GL_CHROMIUM_stream_texture GL_OES_EGL_image_external",  // extensions
5590       true,                                                    // has alpha
5591       true,                                                    // has depth
5592       false,                                                   // has stencil
5593       true,                                                    // request alpha
5594       true,                                                    // request depth
5595       false,  // request stencil
5596       true);  // bind generates resource
5597
5598   StrictMock<MockStreamTexture> stream_texture;
5599
5600   TextureRef* texture_ref = GetTexture(client_texture_id_);
5601   group().texture_manager()->SetStreamTexture(texture_ref, true);
5602
5603   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
5604   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5605
5606   SetupSamplerExternalProgram();
5607   SetupIndexBuffer();
5608   AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
5609   SetupExpectationsForApplyingDefaultDirtyState();
5610   EXPECT_TRUE(group().texture_manager()->CanRender(texture_ref));
5611
5612   InSequence s;
5613   EXPECT_CALL(*stream_texture_manager(), LookupStreamTexture(kServiceTextureId))
5614       .WillOnce(Return(&stream_texture))
5615       .RetiresOnSaturation();
5616   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
5617       .Times(1)
5618       .RetiresOnSaturation();
5619   EXPECT_CALL(stream_texture, Update())
5620       .Times(1)
5621       .RetiresOnSaturation();
5622   EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
5623       .Times(1);
5624   DrawElements cmd;
5625   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
5626            kValidIndexRangeStart * 2);
5627   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5628   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5629
5630   EXPECT_CALL(*stream_texture_manager(),
5631               DestroyStreamTexture(kServiceTextureId))
5632       .Times(1)
5633       .RetiresOnSaturation();
5634 }
5635
5636 TEST_F(GLES2DecoderManualInitTest, BindStreamTextureCHROMIUMInvalid) {
5637   InitDecoder(
5638       "GL_CHROMIUM_stream_texture",  // extensions
5639       false,   // has alpha
5640       false,   // has depth
5641       false,   // has stencil
5642       false,   // request alpha
5643       false,   // request depth
5644       false,   // request stencil
5645       true);   // bind generates resource
5646
5647   TextureRef* texture_ref = GetTexture(client_texture_id_);
5648   group().texture_manager()->SetStreamTexture(texture_ref, true);
5649
5650   BindTexture cmd;
5651   cmd.Init(GL_TEXTURE_2D, client_texture_id_);
5652   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5653   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5654
5655   BindTexture cmd2;
5656   cmd2.Init(GL_TEXTURE_CUBE_MAP, client_texture_id_);
5657   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
5658   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5659
5660   EXPECT_CALL(*stream_texture_manager(),
5661               DestroyStreamTexture(kServiceTextureId))
5662       .Times(1)
5663       .RetiresOnSaturation();
5664 }
5665
5666 TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUM) {
5667   InitDecoder(
5668       "GL_CHROMIUM_stream_texture",  // extensions
5669       false,   // has alpha
5670       false,   // has depth
5671       false,   // has stencil
5672       false,   // request alpha
5673       false,   // request depth
5674       false,   // request stencil
5675       true);   // bind generates resource
5676
5677   TextureRef* texture_ref = GetTexture(client_texture_id_);
5678   group().texture_manager()->SetStreamTexture(texture_ref, true);
5679
5680   EXPECT_CALL(*stream_texture_manager(),
5681               DestroyStreamTexture(kServiceTextureId))
5682       .Times(1)
5683       .RetiresOnSaturation();
5684
5685   DestroyStreamTextureCHROMIUM cmd;
5686   cmd.Init(client_texture_id_);
5687   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5688   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5689   EXPECT_FALSE(texture_ref->texture()->IsStreamTexture());
5690   EXPECT_EQ(0U, texture_ref->texture()->target());
5691 }
5692
5693 TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUMInvalid) {
5694   InitDecoder(
5695       "GL_CHROMIUM_stream_texture",  // extensions
5696       false,   // has alpha
5697       false,   // has depth
5698       false,   // has stencil
5699       false,   // request alpha
5700       false,   // request depth
5701       false,   // request stencil
5702       true);   // bind generates resource
5703
5704   DestroyStreamTextureCHROMIUM cmd;
5705   cmd.Init(client_texture_id_);
5706   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5707   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5708 }
5709
5710 TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUMBadId) {
5711   InitDecoder(
5712       "GL_CHROMIUM_stream_texture",  // extensions
5713       false,   // has alpha
5714       false,   // has depth
5715       false,   // has stencil
5716       false,   // request alpha
5717       false,   // request depth
5718       false,   // request stencil
5719       true);   // bind generates resource
5720
5721   DestroyStreamTextureCHROMIUM cmd;
5722   cmd.Init(GL_ZERO);
5723   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5724   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
5725 }
5726
5727 TEST_F(GLES2DecoderManualInitTest, StreamTextureCHROMIUMNullMgr) {
5728   InitDecoder(
5729       "",  // extensions
5730       false,   // has alpha
5731       false,   // has depth
5732       false,   // has stencil
5733       false,   // request alpha
5734       false,   // request depth
5735       false,   // request stencil
5736       true);   // bind generates resource
5737
5738   CreateStreamTextureCHROMIUM cmd;
5739   cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_);
5740   EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
5741   GetGLError(); // ignore internal error
5742
5743   TextureRef* texture_ref = GetTexture(client_texture_id_);
5744   group().texture_manager()->SetStreamTexture(texture_ref, true);
5745
5746   DestroyStreamTextureCHROMIUM cmd2;
5747   cmd2.Init(client_texture_id_);
5748   EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd2));
5749   GetGLError(); // ignore internal error
5750 }
5751
5752 TEST_F(GLES2DecoderManualInitTest, ReCreateStreamTextureCHROMIUM) {
5753   const GLuint kObjectId = 123;
5754   InitDecoder(
5755       "GL_CHROMIUM_stream_texture GL_OES_EGL_image_external",  // extensions
5756       false,   // has alpha
5757       false,   // has depth
5758       false,   // has stencil
5759       false,   // request alpha
5760       false,   // request depth
5761       false,   // request stencil
5762       true);   // bind generates resource
5763
5764   EXPECT_CALL(*stream_texture_manager(),
5765               DestroyStreamTexture(kServiceTextureId))
5766       .Times(1)
5767       .RetiresOnSaturation();
5768   EXPECT_CALL(*stream_texture_manager(),
5769               CreateStreamTexture(kServiceTextureId, client_texture_id_))
5770       .WillOnce(Return(kObjectId))
5771       .RetiresOnSaturation();
5772
5773   TextureRef* texture_ref = GetTexture(client_texture_id_);
5774   group().texture_manager()->SetStreamTexture(texture_ref, true);
5775
5776   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
5777   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5778
5779   DestroyStreamTextureCHROMIUM cmd;
5780   cmd.Init(client_texture_id_);
5781   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5782   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5783   EXPECT_FALSE(texture_ref->texture()->IsStreamTexture());
5784
5785   CreateStreamTextureCHROMIUM cmd2;
5786   cmd2.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_);
5787   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
5788   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5789   EXPECT_TRUE(texture_ref->texture()->IsStreamTexture());
5790
5791   EXPECT_CALL(*stream_texture_manager(),
5792               DestroyStreamTexture(kServiceTextureId))
5793       .Times(1)
5794       .RetiresOnSaturation();
5795 }
5796
5797 TEST_F(GLES2DecoderManualInitTest, ProduceAndConsumeStreamTextureCHROMIUM) {
5798   InitDecoder(
5799       "GL_CHROMIUM_stream_texture GL_OES_EGL_image_external",  // extensions
5800       false,   // has alpha
5801       false,   // has depth
5802       false,   // has stencil
5803       false,   // request alpha
5804       false,   // request depth
5805       false,   // request stencil
5806       true);   // bind generates resource
5807
5808   TextureRef* texture_ref = GetTexture(client_texture_id_);
5809   group().texture_manager()->SetStreamTexture(texture_ref, true);
5810
5811   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
5812
5813   GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
5814   group().mailbox_manager()->GenerateMailboxName(
5815       reinterpret_cast<MailboxName*>(mailbox));
5816
5817   memcpy(shared_memory_address_, mailbox, sizeof(mailbox));
5818
5819   EXPECT_EQ(kServiceTextureId, texture_ref->service_id());
5820
5821   ProduceTextureCHROMIUM produce_cmd;
5822   produce_cmd.Init(
5823       GL_TEXTURE_EXTERNAL_OES, kSharedMemoryId, kSharedMemoryOffset);
5824   EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
5825   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5826
5827   // Create new texture for consume.
5828   EXPECT_CALL(*gl_, GenTextures(_, _))
5829       .WillOnce(SetArgumentPointee<1>(kNewServiceId))
5830       .RetiresOnSaturation();
5831   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, kNewClientId, kNewServiceId);
5832
5833   // Assigns and binds original service size texture ID.
5834   EXPECT_CALL(*gl_, DeleteTextures(1, _))
5835       .Times(1)
5836       .RetiresOnSaturation();
5837   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kServiceTextureId))
5838       .Times(1)
5839       .RetiresOnSaturation();
5840
5841   // Shared mem got clobbered from GetError() above.
5842   memcpy(shared_memory_address_, mailbox, sizeof(mailbox));
5843   ConsumeTextureCHROMIUM consume_cmd;
5844   consume_cmd.Init(
5845       GL_TEXTURE_EXTERNAL_OES, kSharedMemoryId, kSharedMemoryOffset);
5846   EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
5847   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5848
5849   // Service ID is restored.
5850   EXPECT_EQ(kServiceTextureId, texture_ref->service_id());
5851
5852   EXPECT_CALL(*stream_texture_manager(),
5853               DestroyStreamTexture(kServiceTextureId))
5854       .Times(1)
5855       .RetiresOnSaturation();
5856 }
5857
5858 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleBindTexture) {
5859   InitDecoder(
5860       "GL_ARB_texture_rectangle",  // extensions
5861       false,   // has alpha
5862       false,   // has depth
5863       false,   // has stencil
5864       false,   // request alpha
5865       false,   // request depth
5866       false,   // request stencil
5867       true);   // bind generates resource
5868   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_RECTANGLE_ARB, kNewServiceId));
5869   EXPECT_CALL(*gl_, GenTextures(1, _))
5870      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
5871   BindTexture cmd;
5872   cmd.Init(GL_TEXTURE_RECTANGLE_ARB, kNewClientId);
5873   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5874   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5875   Texture* texture = GetTexture(kNewClientId)->texture();
5876   EXPECT_TRUE(texture != NULL);
5877   EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
5878 }
5879
5880 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleGetBinding) {
5881   InitDecoder(
5882       "GL_ARB_texture_rectangle",  // extensions
5883       false,   // has alpha
5884       false,   // has depth
5885       false,   // has stencil
5886       false,   // request alpha
5887       false,   // request depth
5888       false,   // request stencil
5889       true);   // bind generates resource
5890   DoBindTexture(
5891       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
5892
5893   EXPECT_CALL(*gl_, GetError())
5894       .WillOnce(Return(GL_NO_ERROR))
5895       .WillOnce(Return(GL_NO_ERROR))
5896       .RetiresOnSaturation();
5897   typedef GetIntegerv::Result Result;
5898   Result* result = static_cast<Result*>(shared_memory_address_);
5899   EXPECT_CALL(*gl_, GetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB,
5900                                 result->GetData()))
5901       .Times(0);
5902   result->size = 0;
5903   GetIntegerv cmd;
5904   cmd.Init(GL_TEXTURE_BINDING_RECTANGLE_ARB,
5905            shared_memory_id_,
5906            shared_memory_offset_);
5907   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5908   EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
5909       GL_TEXTURE_BINDING_RECTANGLE_ARB), result->GetNumResults());
5910   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5911   EXPECT_EQ(client_texture_id_, (uint32)result->GetData()[0]);
5912 }
5913
5914 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTextureDefaults) {
5915   InitDecoder(
5916       "GL_ARB_texture_rectangle",  // extensions
5917       false,   // has alpha
5918       false,   // has depth
5919       false,   // has stencil
5920       false,   // request alpha
5921       false,   // request depth
5922       false,   // request stencil
5923       true);   // bind generates resource
5924   DoBindTexture(
5925       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
5926
5927   Texture* texture = GetTexture(client_texture_id_)->texture();
5928   EXPECT_TRUE(texture != NULL);
5929   EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
5930   EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
5931   EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
5932   EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
5933 }
5934
5935 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParam) {
5936   InitDecoder(
5937       "GL_ARB_texture_rectangle",  // extensions
5938       false,   // has alpha
5939       false,   // has depth
5940       false,   // has stencil
5941       false,   // request alpha
5942       false,   // request depth
5943       false,   // request stencil
5944       true);   // bind generates resource
5945
5946   DoBindTexture(
5947       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
5948
5949   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
5950                                   GL_TEXTURE_MIN_FILTER,
5951                                   GL_NEAREST));
5952   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
5953                                   GL_TEXTURE_MIN_FILTER,
5954                                   GL_LINEAR));
5955   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
5956                                   GL_TEXTURE_WRAP_S,
5957                                   GL_CLAMP_TO_EDGE));
5958   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
5959                                   GL_TEXTURE_WRAP_T,
5960                                   GL_CLAMP_TO_EDGE));
5961   TexParameteri cmd;
5962   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5963            GL_TEXTURE_MIN_FILTER,
5964            GL_NEAREST);
5965   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5966   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5967
5968   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5969            GL_TEXTURE_MIN_FILTER,
5970            GL_LINEAR);
5971   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5972   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5973
5974   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5975            GL_TEXTURE_WRAP_S,
5976            GL_CLAMP_TO_EDGE);
5977   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5978   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5979
5980   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5981            GL_TEXTURE_WRAP_T,
5982            GL_CLAMP_TO_EDGE);
5983   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5984   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5985
5986   Texture* texture = GetTexture(client_texture_id_)->texture();
5987   EXPECT_TRUE(texture != NULL);
5988   EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
5989   EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
5990   EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
5991   EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
5992 }
5993
5994 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParamInvalid) {
5995   InitDecoder(
5996       "GL_ARB_texture_rectangle",  // extensions
5997       false,   // has alpha
5998       false,   // has depth
5999       false,   // has stencil
6000       false,   // request alpha
6001       false,   // request depth
6002       false,   // request stencil
6003       true);   // bind generates resource
6004
6005   DoBindTexture(
6006       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
6007
6008   TexParameteri cmd;
6009   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
6010            GL_TEXTURE_MIN_FILTER,
6011            GL_NEAREST_MIPMAP_NEAREST);
6012   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6013   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
6014
6015   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
6016            GL_TEXTURE_WRAP_S,
6017            GL_REPEAT);
6018   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6019   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
6020
6021   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
6022            GL_TEXTURE_WRAP_T,
6023            GL_REPEAT);
6024   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6025   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
6026
6027   Texture* texture = GetTexture(client_texture_id_)->texture();
6028   EXPECT_TRUE(texture != NULL);
6029   EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
6030   EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
6031   EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
6032   EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
6033 }
6034
6035 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTexImage2DError) {
6036   InitDecoder(
6037       "GL_ARB_texture_rectangle",  // extensions
6038       false,   // has alpha
6039       false,   // has depth
6040       false,   // has stencil
6041       false,   // request alpha
6042       false,   // request depth
6043       false,   // request stencil
6044       true);   // bind generates resource
6045
6046   GLenum target = GL_TEXTURE_RECTANGLE_ARB;
6047   GLint level = 0;
6048   GLenum internal_format = GL_RGBA;
6049   GLsizei width = 2;
6050   GLsizei height = 4;
6051   GLint border = 0;
6052   GLenum format = GL_RGBA;
6053   GLenum type = GL_UNSIGNED_BYTE;
6054   DoBindTexture(
6055       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
6056   ASSERT_TRUE(GetTexture(client_texture_id_) != NULL);
6057   TexImage2D cmd;
6058   cmd.Init(target, level, internal_format, width, height, border, format,
6059            type, kSharedMemoryId, kSharedMemoryOffset);
6060   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6061
6062   // TexImage2D is not allowed with GL_TEXTURE_RECTANGLE_ARB targets.
6063   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
6064 }
6065
6066 TEST_F(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
6067   const uint32 kBadBucketId = 123;
6068   EnableFeatureCHROMIUM cmd;
6069   cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_);
6070   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
6071 }
6072
6073 TEST_F(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
6074   const uint32 kBadBucketId = 123;
6075   RequestExtensionCHROMIUM cmd;
6076   cmd.Init(kBadBucketId);
6077   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
6078 }
6079
6080 TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DNULL) {
6081   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6082   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6083                0, 0);
6084   SetupClearTextureExpections(
6085       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6086       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6087   EXPECT_CALL(*gl_, TexSubImage2D(
6088       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6089       shared_memory_address_))
6090       .Times(1)
6091       .RetiresOnSaturation();
6092   TexSubImage2D cmd;
6093   cmd.Init(
6094       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6095       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
6096   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6097   // Test if we call it again it does not clear.
6098   EXPECT_CALL(*gl_, TexSubImage2D(
6099       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6100       shared_memory_address_))
6101       .Times(1)
6102       .RetiresOnSaturation();
6103   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6104 }
6105
6106 TEST_F(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) {
6107   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6108   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6109                0, 0);
6110   DoTexImage2DSameSize(
6111       GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6112       kSharedMemoryId, kSharedMemoryOffset);
6113   EXPECT_CALL(*gl_, TexSubImage2D(
6114       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6115       shared_memory_address_))
6116       .Times(1)
6117       .RetiresOnSaturation();
6118   TexSubImage2D cmd;
6119   cmd.Init(
6120       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6121       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
6122   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6123   // Test if we call it again it does not clear.
6124   EXPECT_CALL(*gl_, TexSubImage2D(
6125       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6126       shared_memory_address_))
6127       .Times(1)
6128       .RetiresOnSaturation();
6129   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6130 }
6131
6132 TEST_F(GLES2DecoderANGLETest,
6133        TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) {
6134   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6135   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6136                0, 0);
6137   DoTexImage2DSameSize(
6138       GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6139       kSharedMemoryId, kSharedMemoryOffset);
6140   EXPECT_CALL(*gl_, TexSubImage2D(
6141       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6142       shared_memory_address_))
6143       .Times(1)
6144       .RetiresOnSaturation();
6145   TexSubImage2D cmd;
6146   cmd.Init(
6147       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6148       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
6149   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6150   // Test if we call it again it does not clear.
6151   EXPECT_CALL(*gl_, TexSubImage2D(
6152       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6153       shared_memory_address_))
6154       .Times(1)
6155       .RetiresOnSaturation();
6156   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6157 }
6158
6159 TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DWithDataThenNULL) {
6160   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6161   // Put in data (so it should be marked as cleared)
6162   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6163                kSharedMemoryId, kSharedMemoryOffset);
6164   // Put in no data.
6165   TexImage2D tex_cmd;
6166   tex_cmd.Init(
6167       GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6168   // It won't actually call TexImage2D, just mark it as uncleared.
6169   EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
6170   // Next call to TexSubImage2d should clear.
6171   SetupClearTextureExpections(
6172       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6173       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6174   EXPECT_CALL(*gl_, TexSubImage2D(
6175       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6176       shared_memory_address_))
6177       .Times(1)
6178       .RetiresOnSaturation();
6179   TexSubImage2D cmd;
6180   cmd.Init(
6181       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6182       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
6183   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6184 }
6185
6186 TEST_F(GLES2DecoderWithShaderTest, DrawArraysClearsAfterTexImage2DNULL) {
6187   SetupAllNeededVertexBuffers();
6188   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6189   // Create an uncleared texture with 2 levels.
6190   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6191                0, 0);
6192   DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6193                0, 0);
6194   // Expect 2 levels will be cleared.
6195   SetupClearTextureExpections(
6196       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6197       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6198   SetupClearTextureExpections(
6199       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6200       1, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
6201   SetupExpectationsForApplyingDefaultDirtyState();
6202   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6203       .Times(1)
6204       .RetiresOnSaturation();
6205   DrawArrays cmd;
6206   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6207   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6208   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6209
6210   // But not again
6211   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6212       .Times(1)
6213       .RetiresOnSaturation();
6214   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6215   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6216 }
6217
6218 TEST_F(GLES2DecoderWithShaderTest, DrawElementsClearsAfterTexImage2DNULL) {
6219   SetupAllNeededVertexBuffers();
6220   SetupIndexBuffer();
6221   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6222   // Create an uncleared texture with 2 levels.
6223   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6224                0, 0);
6225   DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6226                0, 0);
6227   // Expect 2 levels will be cleared.
6228   SetupClearTextureExpections(
6229       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6230       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6231   SetupClearTextureExpections(
6232       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6233       1, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
6234   SetupExpectationsForApplyingDefaultDirtyState();
6235
6236   EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
6237                                  GL_UNSIGNED_SHORT,
6238                                  BufferOffset(kValidIndexRangeStart * 2)))
6239       .Times(1)
6240       .RetiresOnSaturation();
6241   DrawElements cmd;
6242   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
6243            kValidIndexRangeStart * 2);
6244   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6245   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6246
6247   // But not again
6248   EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
6249                                  GL_UNSIGNED_SHORT,
6250                                  BufferOffset(kValidIndexRangeStart * 2)))
6251       .Times(1)
6252       .RetiresOnSaturation();
6253   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6254   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6255 }
6256
6257 TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterTexImage2DNULLInFBO) {
6258   const GLuint kFBOClientTextureId = 4100;
6259   const GLuint kFBOServiceTextureId = 4101;
6260
6261   SetupAllNeededVertexBuffers();
6262   // Register a texture id.
6263   EXPECT_CALL(*gl_, GenTextures(_, _))
6264       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6265       .RetiresOnSaturation();
6266   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6267
6268   // Setup "render to" texture.
6269   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6270   DoTexImage2D(
6271       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6272   DoBindFramebuffer(
6273       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6274   DoFramebufferTexture2D(
6275       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6276       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6277
6278   // Setup "render from" texture.
6279   SetupTexture();
6280
6281   SetupExpectationsForFramebufferClearing(
6282       GL_FRAMEBUFFER,         // target
6283       GL_COLOR_BUFFER_BIT,    // clear bits
6284       0, 0, 0, 0,             // color
6285       0,                      // stencil
6286       1.0f,                   // depth
6287       false);                 // scissor test
6288
6289   SetupExpectationsForApplyingDirtyState(
6290       false,   // Framebuffer is RGB
6291       false,   // Framebuffer has depth
6292       false,   // Framebuffer has stencil
6293       0x1111,  // color bits
6294       false,   // depth mask
6295       false,   // depth enabled
6296       0,       // front stencil mask
6297       0,       // back stencil mask
6298       false,   // stencil enabled
6299       false,   // cull_face_enabled
6300       false,   // scissor_test_enabled
6301       false);  // blend_enabled
6302
6303   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6304       .Times(1)
6305       .RetiresOnSaturation();
6306   DrawArrays cmd;
6307   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6308   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6309   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6310
6311   // But not again.
6312   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6313       .Times(1)
6314       .RetiresOnSaturation();
6315   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6316   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6317 }
6318
6319 TEST_F(GLES2DecoderWithShaderTest, DrawWitFBOThatCantClearDoesNotDraw) {
6320   const GLuint kFBOClientTextureId = 4100;
6321   const GLuint kFBOServiceTextureId = 4101;
6322
6323   // Register a texture id.
6324   EXPECT_CALL(*gl_, GenTextures(_, _))
6325       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6326       .RetiresOnSaturation();
6327   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6328
6329   // Setup "render to" texture.
6330   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6331   DoTexImage2D(
6332       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6333   DoBindFramebuffer(
6334       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6335   DoFramebufferTexture2D(
6336       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6337       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6338
6339   // Setup "render from" texture.
6340   SetupTexture();
6341
6342   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
6343       .WillOnce(Return(GL_FRAMEBUFFER_UNSUPPORTED))
6344       .RetiresOnSaturation();
6345   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
6346       .Times(0)
6347       .RetiresOnSaturation();
6348   DrawArrays cmd;
6349   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6350   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6351   EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
6352 }
6353
6354 TEST_F(GLES2DecoderTest, CopyTexImage2DMarksTextureAsCleared) {
6355   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6356
6357   TextureManager* manager = group().texture_manager();
6358   TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
6359   ASSERT_TRUE(texture_ref != NULL);
6360   Texture* texture = texture_ref->texture();
6361
6362   EXPECT_CALL(*gl_, GetError())
6363       .WillOnce(Return(GL_NO_ERROR))
6364       .RetiresOnSaturation();
6365   EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0))
6366       .Times(1)
6367       .RetiresOnSaturation();
6368   EXPECT_CALL(*gl_, GetError())
6369       .WillOnce(Return(GL_NO_ERROR))
6370       .RetiresOnSaturation();
6371   CopyTexImage2D cmd;
6372   cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
6373   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6374
6375   EXPECT_TRUE(texture->SafeToRenderFrom());
6376 }
6377
6378 TEST_F(GLES2DecoderTest, CopyTexSubImage2DClearsUnclearedTexture) {
6379   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6380   DoTexImage2D(
6381       GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6382
6383   SetupClearTextureExpections(
6384       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6385       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6386   EXPECT_CALL(*gl_, CopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1))
6387       .Times(1)
6388       .RetiresOnSaturation();
6389   CopyTexSubImage2D cmd;
6390   cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
6391   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6392 }
6393
6394 TEST_F(GLES2DecoderManualInitTest, CompressedImage2DMarksTextureAsCleared) {
6395   InitDecoder(
6396       "GL_EXT_texture_compression_s3tc",  // extensions
6397       false,   // has alpha
6398       false,   // has depth
6399       false,   // has stencil
6400       false,   // request alpha
6401       false,   // request depth
6402       false,   // request stencil
6403       true);   // bind generates resource
6404
6405   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6406   EXPECT_CALL(*gl_, GetError())
6407       .WillOnce(Return(GL_NO_ERROR))
6408       .RetiresOnSaturation();
6409   EXPECT_CALL(*gl_, CompressedTexImage2D(
6410       GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, 8, _))
6411       .Times(1)
6412       .RetiresOnSaturation();
6413   EXPECT_CALL(*gl_, GetError())
6414       .WillOnce(Return(GL_NO_ERROR))
6415       .RetiresOnSaturation();
6416   CompressedTexImage2D cmd;
6417   cmd.Init(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
6418            8, kSharedMemoryId, kSharedMemoryOffset);
6419   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6420   TextureManager* manager = group().texture_manager();
6421   TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
6422   EXPECT_TRUE(texture_ref->texture()->SafeToRenderFrom());
6423 }
6424
6425 TEST_F(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnClear) {
6426   const GLuint kFBOClientTextureId = 4100;
6427   const GLuint kFBOServiceTextureId = 4101;
6428
6429   // Register a texture id.
6430   EXPECT_CALL(*gl_, GenTextures(_, _))
6431       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6432       .RetiresOnSaturation();
6433   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6434
6435   // Setup "render to" texture.
6436   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6437   DoTexImage2D(
6438       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6439   DoBindFramebuffer(
6440       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6441   DoFramebufferTexture2D(
6442       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6443       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6444
6445   // Setup "render from" texture.
6446   SetupTexture();
6447
6448   SetupExpectationsForFramebufferClearing(
6449       GL_FRAMEBUFFER,         // target
6450       GL_COLOR_BUFFER_BIT,    // clear bits
6451       0, 0, 0, 0,             // color
6452       0,                      // stencil
6453       1.0f,                   // depth
6454       false);                 // scissor test
6455   SetupExpectationsForApplyingDirtyState(
6456       false,   // Framebuffer is RGB
6457       false,   // Framebuffer has depth
6458       false,   // Framebuffer has stencil
6459       0x1111,  // color bits
6460       false,   // depth mask
6461       false,   // depth enabled
6462       0,       // front stencil mask
6463       0,       // back stencil mask
6464       false,   // stencil enabled
6465       false,   // cull_face_enabled
6466       false,   // scissor_test_enabled
6467       false);  // blend_enabled
6468
6469   EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT))
6470       .Times(1)
6471       .RetiresOnSaturation();
6472
6473   Clear cmd;
6474   cmd.Init(GL_COLOR_BUFFER_BIT);
6475   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6476   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6477 }
6478
6479 TEST_F(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnReadPixels) {
6480   const GLuint kFBOClientTextureId = 4100;
6481   const GLuint kFBOServiceTextureId = 4101;
6482
6483   // Register a texture id.
6484   EXPECT_CALL(*gl_, GenTextures(_, _))
6485       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6486       .RetiresOnSaturation();
6487   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6488
6489   // Setup "render to" texture.
6490   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6491   DoTexImage2D(
6492       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6493   DoBindFramebuffer(
6494       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6495   DoFramebufferTexture2D(
6496       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6497       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6498
6499   // Setup "render from" texture.
6500   SetupTexture();
6501
6502   SetupExpectationsForFramebufferClearing(
6503       GL_FRAMEBUFFER,         // target
6504       GL_COLOR_BUFFER_BIT,    // clear bits
6505       0, 0, 0, 0,             // color
6506       0,                      // stencil
6507       1.0f,                   // depth
6508       false);                 // scissor test
6509
6510   EXPECT_CALL(*gl_, GetError())
6511      .WillOnce(Return(GL_NO_ERROR))
6512      .WillOnce(Return(GL_NO_ERROR))
6513      .RetiresOnSaturation();
6514   EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
6515       .Times(1)
6516       .RetiresOnSaturation();
6517   typedef ReadPixels::Result Result;
6518   Result* result = GetSharedMemoryAs<Result*>();
6519   uint32 result_shm_id = kSharedMemoryId;
6520   uint32 result_shm_offset = kSharedMemoryOffset;
6521   uint32 pixels_shm_id = kSharedMemoryId;
6522   uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
6523   ReadPixels cmd;
6524   cmd.Init(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6525            pixels_shm_id, pixels_shm_offset,
6526            result_shm_id, result_shm_offset,
6527            false);
6528   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6529   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6530 }
6531
6532 TEST_F(GLES2DecoderManualInitTest,
6533        UnClearedAttachmentsGetClearedOnReadPixelsAndDrawBufferGetsRestored) {
6534   InitDecoder(
6535       "GL_EXT_framebuffer_multisample",  // extensions
6536       false,   // has alpha
6537       false,   // has depth
6538       false,   // has stencil
6539       false,   // request alpha
6540       false,   // request depth
6541       false,   // request stencil
6542       true);   // bind generates resource
6543   const GLuint kFBOClientTextureId = 4100;
6544   const GLuint kFBOServiceTextureId = 4101;
6545
6546   // Register a texture id.
6547   EXPECT_CALL(*gl_, GenTextures(_, _))
6548       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6549       .RetiresOnSaturation();
6550   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6551
6552   // Setup "render from" texture.
6553   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6554   DoTexImage2D(
6555       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6556   DoBindFramebuffer(
6557       GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6558   DoFramebufferTexture2D(
6559       GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6560       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6561
6562   SetupExpectationsForFramebufferClearingMulti(
6563       kServiceFramebufferId,  // read framebuffer service id
6564       0,                      // backbuffer service id
6565       GL_READ_FRAMEBUFFER,    // target
6566       GL_COLOR_BUFFER_BIT,    // clear bits
6567       0, 0, 0, 0,             // color
6568       0,                      // stencil
6569       1.0f,                   // depth
6570       false);                 // scissor test
6571
6572   EXPECT_CALL(*gl_, GetError())
6573      .WillOnce(Return(GL_NO_ERROR))
6574      .WillOnce(Return(GL_NO_ERROR))
6575      .RetiresOnSaturation();
6576   EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
6577       .Times(1)
6578       .RetiresOnSaturation();
6579   typedef ReadPixels::Result Result;
6580   uint32 result_shm_id = kSharedMemoryId;
6581   uint32 result_shm_offset = kSharedMemoryOffset;
6582   uint32 pixels_shm_id = kSharedMemoryId;
6583   uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
6584   ReadPixels cmd;
6585   cmd.Init(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6586            pixels_shm_id, pixels_shm_offset,
6587            result_shm_id, result_shm_offset,
6588            false);
6589   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6590   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6591 }
6592
6593 TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterRenderbufferStorageInFBO) {
6594   SetupTexture();
6595   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6596                     kServiceRenderbufferId);
6597   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6598                     kServiceFramebufferId);
6599   DoRenderbufferStorage(
6600       GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 100, 50, GL_NO_ERROR);
6601   DoFramebufferRenderbuffer(
6602       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
6603       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6604
6605   SetupExpectationsForFramebufferClearing(
6606       GL_FRAMEBUFFER,         // target
6607       GL_COLOR_BUFFER_BIT,    // clear bits
6608       0, 0, 0, 0,             // color
6609       0,                      // stencil
6610       1.0f,                   // depth
6611       false);                 // scissor test
6612
6613   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
6614   SetupExpectationsForApplyingDirtyState(
6615       false,   // Framebuffer is RGB
6616       false,   // Framebuffer has depth
6617       false,   // Framebuffer has stencil
6618       0x1111,  // color bits
6619       false,   // depth mask
6620       false,   // depth enabled
6621       0,       // front stencil mask
6622       0,       // back stencil mask
6623       false,   // stencil enabled
6624       false,   // cull_face_enabled
6625       false,   // scissor_test_enabled
6626       false);  // blend_enabled
6627
6628   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6629       .Times(1)
6630       .RetiresOnSaturation();
6631   DrawArrays cmd;
6632   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6633   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6634   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6635 }
6636
6637 TEST_F(GLES2DecoderTest, DrawArraysClearsAfterTexImage2DNULLCubemap) {
6638   static const GLenum faces[] = {
6639     GL_TEXTURE_CUBE_MAP_POSITIVE_X,
6640     GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
6641     GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
6642     GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
6643     GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
6644     GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
6645   };
6646   SetupCubemapProgram();
6647   DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
6648   // Fill out all the faces for 2 levels, leave 2 uncleared.
6649   for (int ii = 0; ii < 6; ++ii) {
6650     GLenum face = faces[ii];
6651     int32 shm_id =
6652         (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryId;
6653     uint32 shm_offset =
6654         (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryOffset;
6655     DoTexImage2D(face, 0, GL_RGBA, 2, 2, 0, GL_RGBA,
6656                  GL_UNSIGNED_BYTE, shm_id, shm_offset);
6657     DoTexImage2D(face, 1, GL_RGBA, 1, 1, 0, GL_RGBA,
6658                  GL_UNSIGNED_BYTE, shm_id, shm_offset);
6659   }
6660   // Expect 2 levels will be cleared.
6661   SetupClearTextureExpections(
6662       kServiceTextureId, kServiceTextureId, GL_TEXTURE_CUBE_MAP,
6663       GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6664   SetupClearTextureExpections(
6665       kServiceTextureId, kServiceTextureId, GL_TEXTURE_CUBE_MAP,
6666       GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
6667   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
6668   SetupExpectationsForApplyingDefaultDirtyState();
6669   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6670       .Times(1)
6671       .RetiresOnSaturation();
6672   DrawArrays cmd;
6673   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6674   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6675 }
6676
6677 TEST_F(GLES2DecoderTest, TextureUsageAngleExtNotEnabledByDefault) {
6678   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6679
6680   TexParameteri cmd;
6681   cmd.Init(GL_TEXTURE_2D,
6682            GL_TEXTURE_USAGE_ANGLE,
6683            GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
6684   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6685   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
6686 }
6687
6688 TEST_F(GLES2DecoderWithShaderTest,
6689        DrawClearsAfterRenderbuffersWithMultipleAttachments) {
6690   const GLuint kFBOClientTextureId = 4100;
6691   const GLuint kFBOServiceTextureId = 4101;
6692
6693   // Register a texture id.
6694   EXPECT_CALL(*gl_, GenTextures(_, _))
6695       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6696       .RetiresOnSaturation();
6697   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6698
6699   // Setup "render to" texture.
6700   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6701   DoTexImage2D(
6702       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6703   DoBindFramebuffer(
6704       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6705   DoFramebufferTexture2D(
6706       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6707       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6708
6709   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6710                     kServiceRenderbufferId);
6711   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6712                     kServiceFramebufferId);
6713   DoRenderbufferStorage(
6714       GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT,
6715       1, 1, GL_NO_ERROR);
6716   DoFramebufferRenderbuffer(
6717       GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
6718       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6719
6720   SetupTexture();
6721   SetupExpectationsForFramebufferClearing(
6722       GL_FRAMEBUFFER,         // target
6723       GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,    // clear bits
6724       0, 0, 0, 0,             // color
6725       0,                      // stencil
6726       1.0f,                   // depth
6727       false);                 // scissor test
6728
6729   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
6730   SetupExpectationsForApplyingDirtyState(
6731       false,   // Framebuffer is RGB
6732       true,    // Framebuffer has depth
6733       false,   // Framebuffer has stencil
6734       0x1111,  // color bits
6735       true,    // depth mask
6736       false,   // depth enabled
6737       0,       // front stencil mask
6738       0,       // back stencil mask
6739       false,   // stencil enabled
6740       false,   // cull_face_enabled
6741       false,   // scissor_test_enabled
6742       false);  // blend_enabled
6743
6744   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6745       .Times(1)
6746       .RetiresOnSaturation();
6747   DrawArrays cmd;
6748   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6749   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6750   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6751 }
6752
6753 TEST_F(GLES2DecoderWithShaderTest, CopyTexImageWithInCompleteFBOFails) {
6754   GLenum target = GL_TEXTURE_2D;
6755   GLint level = 0;
6756   GLenum internal_format = GL_RGBA;
6757   GLsizei width = 2;
6758   GLsizei height = 4;
6759   GLint border = 0;
6760   SetupTexture();
6761   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6762                     kServiceRenderbufferId);
6763   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6764                     kServiceFramebufferId);
6765   DoRenderbufferStorage(
6766       GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 0, 0, GL_NO_ERROR);
6767   DoFramebufferRenderbuffer(
6768       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
6769       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6770
6771   EXPECT_CALL(*gl_, CopyTexImage2D(_, _, _, _, _, _, _, _))
6772       .Times(0)
6773       .RetiresOnSaturation();
6774   CopyTexImage2D cmd;
6775   cmd.Init(target, level, internal_format, 0, 0, width, height, border);
6776   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6777   EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
6778 }
6779
6780 void GLES2DecoderWithShaderTest::CheckRenderbufferChangesMarkFBOAsNotComplete(
6781     bool bound_fbo) {
6782   FramebufferManager* framebuffer_manager = group().framebuffer_manager();
6783   SetupTexture();
6784   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6785                     kServiceRenderbufferId);
6786   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6787                     kServiceFramebufferId);
6788   DoRenderbufferStorage(
6789       GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
6790   DoFramebufferRenderbuffer(
6791       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
6792       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6793
6794
6795   if (!bound_fbo) {
6796     DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
6797   }
6798
6799   Framebuffer* framebuffer =
6800       framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
6801   ASSERT_TRUE(framebuffer != NULL);
6802   framebuffer_manager->MarkAsComplete(framebuffer);
6803   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6804
6805   // Test that renderbufferStorage marks fbo as not complete.
6806   DoRenderbufferStorage(
6807       GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
6808   EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6809   framebuffer_manager->MarkAsComplete(framebuffer);
6810   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6811
6812   // Test deleting renderbuffer marks fbo as not complete.
6813   DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
6814   if (bound_fbo) {
6815     EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6816   } else {
6817     EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6818   }
6819 }
6820
6821 TEST_F(GLES2DecoderWithShaderTest,
6822        RenderbufferChangesMarkFBOAsNotCompleteBoundFBO) {
6823   CheckRenderbufferChangesMarkFBOAsNotComplete(true);
6824 }
6825
6826 TEST_F(GLES2DecoderWithShaderTest,
6827        RenderbufferChangesMarkFBOAsNotCompleteUnboundFBO) {
6828   CheckRenderbufferChangesMarkFBOAsNotComplete(false);
6829 }
6830
6831 void GLES2DecoderWithShaderTest::CheckTextureChangesMarkFBOAsNotComplete(
6832     bool bound_fbo) {
6833   FramebufferManager* framebuffer_manager = group().framebuffer_manager();
6834   const GLuint kFBOClientTextureId = 4100;
6835   const GLuint kFBOServiceTextureId = 4101;
6836
6837   // Register a texture id.
6838   EXPECT_CALL(*gl_, GenTextures(_, _))
6839       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6840       .RetiresOnSaturation();
6841   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6842
6843   SetupTexture();
6844
6845   // Setup "render to" texture.
6846   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6847   DoTexImage2D(
6848       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6849   DoBindFramebuffer(
6850       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6851   DoFramebufferTexture2D(
6852       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6853       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6854
6855   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6856                     kServiceRenderbufferId);
6857   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6858                     kServiceFramebufferId);
6859   DoRenderbufferStorage(
6860       GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT,
6861       1, 1, GL_NO_ERROR);
6862   DoFramebufferRenderbuffer(
6863       GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
6864       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6865
6866   if (!bound_fbo) {
6867     DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
6868   }
6869
6870   Framebuffer* framebuffer =
6871       framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
6872   ASSERT_TRUE(framebuffer != NULL);
6873   framebuffer_manager->MarkAsComplete(framebuffer);
6874   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6875
6876   // Test TexImage2D marks fbo as not complete.
6877   DoTexImage2D(
6878       GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, 0, 0);
6879   EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6880   framebuffer_manager->MarkAsComplete(framebuffer);
6881   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6882
6883   // Test CopyImage2D marks fbo as not complete.
6884   EXPECT_CALL(*gl_, GetError())
6885       .WillOnce(Return(GL_NO_ERROR))
6886       .RetiresOnSaturation();
6887   EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0))
6888       .Times(1)
6889       .RetiresOnSaturation();
6890   EXPECT_CALL(*gl_, GetError())
6891       .WillOnce(Return(GL_NO_ERROR))
6892       .RetiresOnSaturation();
6893   CopyTexImage2D cmd;
6894   cmd.Init(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0);
6895   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6896   EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6897
6898   // Test deleting texture marks fbo as not complete.
6899   framebuffer_manager->MarkAsComplete(framebuffer);
6900   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6901   DoDeleteTexture(kFBOClientTextureId, kFBOServiceTextureId);
6902
6903   if (bound_fbo) {
6904     EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6905   } else {
6906     EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6907   }
6908 }
6909
6910 TEST_F(GLES2DecoderWithShaderTest, TextureChangesMarkFBOAsNotCompleteBoundFBO) {
6911   CheckTextureChangesMarkFBOAsNotComplete(true);
6912 }
6913
6914 TEST_F(GLES2DecoderWithShaderTest,
6915        TextureChangesMarkFBOAsNotCompleteUnboundFBO) {
6916   CheckTextureChangesMarkFBOAsNotComplete(false);
6917 }
6918
6919 TEST_F(GLES2DecoderWithShaderTest,
6920        DrawingWithFBOTwiceChecksForFBOCompleteOnce) {
6921   const GLuint kFBOClientTextureId = 4100;
6922   const GLuint kFBOServiceTextureId = 4101;
6923
6924   SetupAllNeededVertexBuffers();
6925
6926   // Register a texture id.
6927   EXPECT_CALL(*gl_, GenTextures(_, _))
6928       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6929       .RetiresOnSaturation();
6930   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6931
6932   // Setup "render to" texture that is cleared.
6933   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6934   DoTexImage2D(
6935       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6936       kSharedMemoryId, kSharedMemoryOffset);
6937   DoBindFramebuffer(
6938       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6939   DoFramebufferTexture2D(
6940       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6941       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6942
6943   // Setup "render from" texture.
6944   SetupTexture();
6945
6946   // Make sure we check for framebuffer complete.
6947   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
6948       .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
6949       .RetiresOnSaturation();
6950
6951   SetupExpectationsForApplyingDirtyState(
6952       false,   // Framebuffer is RGB
6953       false,   // Framebuffer has depth
6954       false,   // Framebuffer has stencil
6955       0x1111,  // color bits
6956       false,   // depth mask
6957       false,   // depth enabled
6958       0,       // front stencil mask
6959       0,       // back stencil mask
6960       false,   // stencil enabled
6961       false,   // cull_face_enabled
6962       false,   // scissor_test_enabled
6963       false);  // blend_enabled
6964
6965   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6966       .Times(1)
6967       .RetiresOnSaturation();
6968   DrawArrays cmd;
6969   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6970   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6971   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6972
6973   // But not again.
6974   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6975       .Times(1)
6976       .RetiresOnSaturation();
6977   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6978   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6979 }
6980
6981 TEST_F(GLES2DecoderTest, BeginQueryEXTDisabled) {
6982   // Test something fails if off.
6983 }
6984
6985 TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
6986   InitDecoder(
6987       "GL_EXT_occlusion_query_boolean",      // extensions
6988       true,    // has alpha
6989       false,   // has depth
6990       false,   // has stencil
6991       true,    // request alpha
6992       false,   // request depth
6993       false,   // request stencil
6994       true);   // bind generates resource
6995
6996   // Test end fails if no begin.
6997   EndQueryEXT end_cmd;
6998   end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
6999   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
7000   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7001
7002   BeginQueryEXT begin_cmd;
7003
7004   // Test id = 0 fails.
7005   begin_cmd.Init(
7006       GL_ANY_SAMPLES_PASSED_EXT, 0, kSharedMemoryId, kSharedMemoryOffset);
7007   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
7008   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7009
7010   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
7011
7012   // Test valid parameters work.
7013   EXPECT_CALL(*gl_, GenQueriesARB(1, _))
7014      .WillOnce(SetArgumentPointee<1>(kNewServiceId))
7015      .RetiresOnSaturation();
7016   EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
7017       .Times(1)
7018       .RetiresOnSaturation();
7019   begin_cmd.Init(
7020       GL_ANY_SAMPLES_PASSED_EXT, kNewClientId,
7021       kSharedMemoryId, kSharedMemoryOffset);
7022   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
7023   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7024
7025   QueryManager* query_manager = decoder_->GetQueryManager();
7026   ASSERT_TRUE(query_manager != NULL);
7027   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
7028   ASSERT_TRUE(query != NULL);
7029   EXPECT_FALSE(query->pending());
7030
7031   // Test trying begin again fails
7032   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
7033   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7034
7035   // Test end fails with different target
7036   end_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1);
7037   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
7038   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7039
7040   // Test end succeeds
7041   EXPECT_CALL(*gl_, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT))
7042       .Times(1)
7043       .RetiresOnSaturation();
7044   end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
7045   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
7046   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7047   EXPECT_TRUE(query->pending());
7048
7049   EXPECT_CALL(*gl_, DeleteQueriesARB(1, _))
7050       .Times(1)
7051       .RetiresOnSaturation();
7052 }
7053
7054 static void CheckBeginEndQueryBadMemoryFails(
7055     GLES2DecoderTestBase* test,
7056     GLuint client_id,
7057     GLuint service_id,
7058     int32 shm_id,
7059     uint32 shm_offset) {
7060   ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
7061
7062   BeginQueryEXT begin_cmd;
7063
7064   test->GenHelper<GenQueriesEXTImmediate>(client_id);
7065
7066   EXPECT_CALL(*gl, GenQueriesARB(1, _))
7067      .WillOnce(SetArgumentPointee<1>(service_id))
7068      .RetiresOnSaturation();
7069   EXPECT_CALL(*gl, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, service_id))
7070       .Times(1)
7071       .RetiresOnSaturation();
7072
7073   // Test bad shared memory fails
7074   begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, client_id, shm_id, shm_offset);
7075   error::Error error1 = test->ExecuteCmd(begin_cmd);
7076
7077   EXPECT_CALL(*gl, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT))
7078       .Times(1)
7079       .RetiresOnSaturation();
7080
7081   EndQueryEXT end_cmd;
7082   end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
7083   error::Error error2 = test->ExecuteCmd(end_cmd);
7084
7085   EXPECT_CALL(*gl,
7086       GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
7087       .WillOnce(SetArgumentPointee<2>(1))
7088       .RetiresOnSaturation();
7089   EXPECT_CALL(*gl,
7090       GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _))
7091       .WillOnce(SetArgumentPointee<2>(1))
7092       .RetiresOnSaturation();
7093
7094   QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
7095   ASSERT_TRUE(query_manager != NULL);
7096   bool process_success = query_manager->ProcessPendingQueries();
7097
7098   EXPECT_TRUE(error1 != error::kNoError ||
7099               error2 != error::kNoError ||
7100               !process_success);
7101
7102   EXPECT_CALL(*gl, DeleteQueriesARB(1, _))
7103       .Times(1)
7104       .RetiresOnSaturation();
7105 }
7106
7107 TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
7108   InitDecoder(
7109       "GL_EXT_occlusion_query_boolean",      // extensions
7110       true,    // has alpha
7111       false,   // has depth
7112       false,   // has stencil
7113       true,    // request alpha
7114       false,   // request depth
7115       false,   // request stencil
7116       true);   // bind generates resource
7117
7118   CheckBeginEndQueryBadMemoryFails(
7119       this, kNewClientId, kNewServiceId,
7120       kInvalidSharedMemoryId, kSharedMemoryOffset);
7121 }
7122
7123 TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
7124   InitDecoder(
7125       "GL_EXT_occlusion_query_boolean",      // extensions
7126       true,    // has alpha
7127       false,   // has depth
7128       false,   // has stencil
7129       true,    // request alpha
7130       false,   // request depth
7131       false,   // request stencil
7132       true);   // bind generates resource
7133
7134   CheckBeginEndQueryBadMemoryFails(
7135       this, kNewClientId, kNewServiceId,
7136       kSharedMemoryId, kInvalidSharedMemoryOffset);
7137 }
7138
7139 TEST_F(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
7140   BeginQueryEXT begin_cmd;
7141
7142   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
7143
7144   // Test valid parameters work.
7145   begin_cmd.Init(
7146       GL_COMMANDS_ISSUED_CHROMIUM, kNewClientId,
7147       kSharedMemoryId, kSharedMemoryOffset);
7148   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
7149   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7150
7151   QueryManager* query_manager = decoder_->GetQueryManager();
7152   ASSERT_TRUE(query_manager != NULL);
7153   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
7154   ASSERT_TRUE(query != NULL);
7155   EXPECT_FALSE(query->pending());
7156
7157   // Test end succeeds
7158   EndQueryEXT end_cmd;
7159   end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1);
7160   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
7161   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7162   EXPECT_FALSE(query->pending());
7163 }
7164
7165 TEST_F(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
7166   BeginQueryEXT begin_cmd;
7167
7168   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
7169
7170   // Test valid parameters work.
7171   begin_cmd.Init(
7172       GL_GET_ERROR_QUERY_CHROMIUM, kNewClientId,
7173       kSharedMemoryId, kSharedMemoryOffset);
7174   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
7175   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7176
7177   QueryManager* query_manager = decoder_->GetQueryManager();
7178   ASSERT_TRUE(query_manager != NULL);
7179   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
7180   ASSERT_TRUE(query != NULL);
7181   EXPECT_FALSE(query->pending());
7182
7183   // Test end succeeds
7184   QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
7185
7186   EXPECT_CALL(*gl_, GetError())
7187       .WillOnce(Return(GL_INVALID_VALUE))
7188       .RetiresOnSaturation();
7189
7190   EndQueryEXT end_cmd;
7191   end_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 1);
7192   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
7193   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7194   EXPECT_FALSE(query->pending());
7195   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE),
7196             static_cast<GLenum>(sync->result));
7197 }
7198
7199 TEST_F(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) {
7200   GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
7201   group().mailbox_manager()->GenerateMailboxName(
7202       reinterpret_cast<MailboxName*>(mailbox));
7203
7204   memcpy(shared_memory_address_, mailbox, sizeof(mailbox));
7205
7206   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7207   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7208                0, 0);
7209   DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7210                0, 0);
7211   TextureRef* texture_ref = group().texture_manager()->GetTexture(
7212       client_texture_id_);
7213   ASSERT_TRUE(texture_ref != NULL);
7214   Texture* texture = texture_ref->texture();
7215   EXPECT_EQ(kServiceTextureId, texture->service_id());
7216
7217   ProduceTextureCHROMIUM produce_cmd;
7218   produce_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
7219   EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
7220   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7221
7222   // Texture didn't change.
7223   GLsizei width;
7224   GLsizei height;
7225   GLenum type;
7226   GLenum internal_format;
7227
7228   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7229   EXPECT_EQ(3, width);
7230   EXPECT_EQ(1, height);
7231   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7232   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7233   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7234
7235   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
7236   EXPECT_EQ(2, width);
7237   EXPECT_EQ(4, height);
7238   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
7239   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7240   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7241
7242   // Service ID has not changed.
7243   EXPECT_EQ(kServiceTextureId, texture->service_id());
7244
7245   // Create new texture for consume.
7246   EXPECT_CALL(*gl_, GenTextures(_, _))
7247       .WillOnce(SetArgumentPointee<1>(kNewServiceId))
7248       .RetiresOnSaturation();
7249   DoBindTexture(GL_TEXTURE_2D, kNewClientId, kNewServiceId);
7250
7251   // Assigns and binds original service size texture ID.
7252   EXPECT_CALL(*gl_, DeleteTextures(1, _))
7253       .Times(1)
7254       .RetiresOnSaturation();
7255   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
7256       .Times(1)
7257       .RetiresOnSaturation();
7258
7259   memcpy(shared_memory_address_, mailbox, sizeof(mailbox));
7260   ConsumeTextureCHROMIUM consume_cmd;
7261   consume_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
7262   EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
7263   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7264
7265   // Texture is redefined.
7266   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7267   EXPECT_EQ(3, width);
7268   EXPECT_EQ(1, height);
7269   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7270   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7271   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7272
7273   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
7274   EXPECT_EQ(2, width);
7275   EXPECT_EQ(4, height);
7276   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
7277   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7278   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7279
7280   // Service ID is restored.
7281   EXPECT_EQ(kServiceTextureId, texture->service_id());
7282 }
7283
7284
7285 TEST_F(GLES2DecoderTest, CanChangeSurface) {
7286   scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock);
7287   EXPECT_CALL(*other_surface.get(), GetBackingFrameBufferObject()).
7288       WillOnce(Return(7));
7289   EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 7));
7290
7291   decoder_->SetSurface(other_surface);
7292 }
7293
7294 TEST_F(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
7295   // NOTE: There are no expectations because no GL functions should be
7296   // called for DEPTH_TEST or STENCIL_TEST
7297   static const GLenum kStates[] = {
7298     GL_DEPTH_TEST,
7299     GL_STENCIL_TEST,
7300   };
7301   for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
7302     Enable enable_cmd;
7303     GLenum state = kStates[ii];
7304     enable_cmd.Init(state);
7305     EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
7306     IsEnabled::Result* result =
7307         static_cast<IsEnabled::Result*>(shared_memory_address_);
7308     IsEnabled is_enabled_cmd;
7309     is_enabled_cmd.Init(state, shared_memory_id_, shared_memory_offset_);
7310     EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
7311     EXPECT_NE(0u, *result);
7312     Disable disable_cmd;
7313     disable_cmd.Init(state);
7314     EXPECT_EQ(error::kNoError, ExecuteCmd(disable_cmd));
7315     EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
7316     EXPECT_EQ(0u, *result);
7317   }
7318 }
7319
7320 TEST_F(GLES2DecoderManualInitTest, DepthTextureBadArgs) {
7321   InitDecoder(
7322       "GL_ANGLE_depth_texture",      // extensions
7323       false,   // has alpha
7324       true,    // has depth
7325       true,    // has stencil
7326       false,   // request alpha
7327       true,    // request depth
7328       true,    // request stencil
7329       true);   // bind generates resource
7330
7331   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7332   // Check trying to upload data fails.
7333   TexImage2D tex_cmd;
7334   tex_cmd.Init(
7335       GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
7336       1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
7337       kSharedMemoryId, kSharedMemoryOffset);
7338   EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
7339   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7340   // Try level > 0.
7341   tex_cmd.Init(
7342       GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT,
7343       1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 0);
7344   EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
7345   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7346   // Make a 1 pixel depth texture.
7347   DoTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
7348                1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 0);
7349   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7350
7351   // Check that trying to update it fails.
7352   TexSubImage2D tex_sub_cmd;
7353   tex_sub_cmd.Init(
7354       GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
7355       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
7356   EXPECT_EQ(error::kNoError, ExecuteCmd(tex_sub_cmd));
7357   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7358
7359   // Check that trying to CopyTexImage2D fails
7360   CopyTexImage2D copy_tex_cmd;
7361   copy_tex_cmd.Init(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1, 1, 0);
7362   EXPECT_EQ(error::kNoError, ExecuteCmd(copy_tex_cmd));
7363   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7364
7365   // Check that trying to CopyTexSubImage2D fails
7366   CopyTexSubImage2D copy_sub_cmd;
7367   copy_sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
7368   EXPECT_EQ(error::kNoError, ExecuteCmd(copy_sub_cmd));
7369   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7370 }
7371
7372 TEST_F(GLES2DecoderManualInitTest, GenerateMipmapDepthTexture) {
7373   InitDecoder(
7374       "GL_ANGLE_depth_texture",      // extensions
7375       false,   // has alpha
7376       true,    // has depth
7377       true,    // has stencil
7378       false,   // request alpha
7379       true,    // request depth
7380       true,    // request stencil
7381       true);   // bind generates resource
7382   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7383   DoTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
7384                2, 2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
7385                0, 0);
7386   GenerateMipmap cmd;
7387   cmd.Init(GL_TEXTURE_2D);
7388   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7389   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7390 }
7391
7392 TEST_F(GLES2DecoderANGLEManualInitTest, DrawClearsDepthTexture) {
7393   InitDecoder(
7394       "GL_ANGLE_depth_texture",      // extensions
7395       true,    // has alpha
7396       true,    // has depth
7397       false,   // has stencil
7398       true,    // request alpha
7399       true,    // request depth
7400       false,   // request stencil
7401       true);   // bind generates resource
7402
7403   SetupDefaultProgram();
7404   SetupAllNeededVertexBuffers();
7405   const GLenum attachment = GL_DEPTH_ATTACHMENT;
7406   const GLenum target = GL_TEXTURE_2D;
7407   const GLint level = 0;
7408   DoBindTexture(target, client_texture_id_, kServiceTextureId);
7409
7410   // Create a depth texture.
7411   DoTexImage2D(target, level, GL_DEPTH_COMPONENT, 1, 1, 0,
7412                GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 0);
7413
7414   EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _))
7415       .Times(1)
7416       .RetiresOnSaturation();
7417   EXPECT_CALL(*gl_, BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, _))
7418       .Times(1)
7419       .RetiresOnSaturation();
7420
7421   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
7422       GL_DRAW_FRAMEBUFFER_EXT, attachment, target, kServiceTextureId, level))
7423       .Times(1)
7424       .RetiresOnSaturation();
7425   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT))
7426       .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
7427       .RetiresOnSaturation();
7428
7429   EXPECT_CALL(*gl_, ClearStencil(0))
7430       .Times(1)
7431       .RetiresOnSaturation();
7432   EXPECT_CALL(*gl_, StencilMask(-1))
7433       .Times(1)
7434       .RetiresOnSaturation();
7435   EXPECT_CALL(*gl_, ClearDepth(1.0f))
7436       .Times(1)
7437       .RetiresOnSaturation();
7438   EXPECT_CALL(*gl_, DepthMask(true))
7439       .Times(1)
7440       .RetiresOnSaturation();
7441   EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST))
7442       .Times(1)
7443       .RetiresOnSaturation();
7444
7445   EXPECT_CALL(*gl_, Clear(GL_DEPTH_BUFFER_BIT))
7446       .Times(1)
7447       .RetiresOnSaturation();
7448
7449   SetupExpectationsForRestoreClearState(
7450       0.0f, 0.0f, 0.0f, 0.0f, 0, 1.0f, false);
7451
7452   EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, _))
7453       .Times(1)
7454       .RetiresOnSaturation();
7455   EXPECT_CALL(*gl_, BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0))
7456       .Times(1)
7457       .RetiresOnSaturation();
7458
7459   SetupExpectationsForApplyingDefaultDirtyState();
7460   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
7461       .Times(1)
7462       .RetiresOnSaturation();
7463   DrawArrays cmd;
7464   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
7465   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7466   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7467 }
7468
7469 TEST_F(GLES2DecoderWithShaderTest, BindUniformLocationCHROMIUM) {
7470   const GLint kLocation = 2;
7471   const char* kName = "testing";
7472   const uint32 kNameSize = strlen(kName);
7473   const char* kBadName1 = "gl_testing";
7474   const uint32 kBadName1Size = strlen(kBadName1);
7475   const char* kBadName2 = "testing[1]";
7476   const uint32 kBadName2Size = strlen(kBadName2);
7477   memcpy(shared_memory_address_, kName, kNameSize);
7478   BindUniformLocationCHROMIUM cmd;
7479   cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
7480            kNameSize);
7481   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7482   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7483   // check negative location
7484   memcpy(shared_memory_address_, kName, kNameSize);
7485   cmd.Init(client_program_id_, -1, kSharedMemoryId, kSharedMemoryOffset,
7486            kNameSize);
7487   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7488   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
7489   // check highest location
7490   memcpy(shared_memory_address_, kName, kNameSize);
7491   GLint kMaxLocation =
7492       (kMaxFragmentUniformVectors + kMaxVertexUniformVectors) * 4 - 1;
7493   cmd.Init(client_program_id_, kMaxLocation, kSharedMemoryId,
7494            kSharedMemoryOffset, kNameSize);
7495   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7496   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7497   // check too high location
7498   memcpy(shared_memory_address_, kName, kNameSize);
7499   cmd.Init(client_program_id_, kMaxLocation + 1, kSharedMemoryId,
7500            kSharedMemoryOffset, kNameSize);
7501   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7502   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
7503   // check bad name "gl_..."
7504   memcpy(shared_memory_address_, kBadName1, kBadName1Size);
7505   cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
7506            kBadName1Size);
7507   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7508   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7509   // check bad name "name[1]" non zero
7510   memcpy(shared_memory_address_, kBadName2, kBadName2Size);
7511   cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
7512            kBadName2Size);
7513   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7514   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
7515 }
7516
7517 class GLES2DecoderVertexArraysOESTest : public GLES2DecoderWithShaderTest {
7518  public:
7519   GLES2DecoderVertexArraysOESTest() { }
7520
7521   bool vertex_array_deleted_manually_;
7522
7523   virtual void SetUp() {
7524     InitDecoder(
7525         "GL_OES_vertex_array_object",  // extensions
7526         false,  // has alpha
7527         false,  // has depth
7528         false,  // has stencil
7529         false,  // request alpha
7530         false,  // request depth
7531         false,  // request stencil
7532         true);  // bind generates resource
7533     SetupDefaultProgram();
7534
7535     AddExpectationsForGenVertexArraysOES();
7536     GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
7537
7538     vertex_array_deleted_manually_ = false;
7539   }
7540
7541   virtual void TearDown() {
7542     // This should only be set if the test handled deletion of the vertex array
7543     // itself. Necessary because vertex_array_objects are not sharable, and thus
7544     // not managed in the ContextGroup, meaning they will be destroyed during
7545     // test tear down
7546     if (!vertex_array_deleted_manually_) {
7547       AddExpectationsForDeleteVertexArraysOES();
7548     }
7549
7550     GLES2DecoderWithShaderTest::TearDown();
7551   }
7552
7553   void GenVertexArraysOESValidArgs() {
7554     AddExpectationsForGenVertexArraysOES();
7555     GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
7556     GenVertexArraysOES cmd;
7557     cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7558     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7559     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7560     EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
7561     AddExpectationsForDeleteVertexArraysOES();
7562   }
7563
7564   void GenVertexArraysOESInvalidArgs() {
7565     EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
7566     GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
7567     GenVertexArraysOES cmd;
7568     cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7569     EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
7570   }
7571
7572   void GenVertexArraysOESImmediateValidArgs() {
7573     AddExpectationsForGenVertexArraysOES();
7574     GenVertexArraysOESImmediate* cmd =
7575         GetImmediateAs<GenVertexArraysOESImmediate>();
7576     GLuint temp = kNewClientId;
7577     cmd->Init(1, &temp);
7578     EXPECT_EQ(error::kNoError,
7579               ExecuteImmediateCmd(*cmd, sizeof(temp)));
7580     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7581     EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
7582     AddExpectationsForDeleteVertexArraysOES();
7583   }
7584
7585   void GenVertexArraysOESImmediateInvalidArgs() {
7586     EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
7587     GenVertexArraysOESImmediate* cmd =
7588         GetImmediateAs<GenVertexArraysOESImmediate>();
7589     cmd->Init(1, &client_vertexarray_id_);
7590     EXPECT_EQ(error::kInvalidArguments,
7591               ExecuteImmediateCmd(*cmd, sizeof(&client_vertexarray_id_)));
7592   }
7593
7594   void DeleteVertexArraysOESValidArgs() {
7595     AddExpectationsForDeleteVertexArraysOES();
7596     GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
7597     DeleteVertexArraysOES cmd;
7598     cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7599     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7600     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7601     EXPECT_TRUE(
7602         GetVertexArrayInfo(client_vertexarray_id_) == NULL);
7603     vertex_array_deleted_manually_ = true;
7604   }
7605
7606   void DeleteVertexArraysOESInvalidArgs() {
7607     GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
7608     DeleteVertexArraysOES cmd;
7609     cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7610     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7611   }
7612
7613   void DeleteVertexArraysOESImmediateValidArgs() {
7614     AddExpectationsForDeleteVertexArraysOES();
7615     DeleteVertexArraysOESImmediate& cmd =
7616         *GetImmediateAs<DeleteVertexArraysOESImmediate>();
7617     cmd.Init(1, &client_vertexarray_id_);
7618     EXPECT_EQ(error::kNoError,
7619               ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
7620     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7621     EXPECT_TRUE(
7622         GetVertexArrayInfo(client_vertexarray_id_) == NULL);
7623     vertex_array_deleted_manually_ = true;
7624   }
7625
7626   void DeleteVertexArraysOESImmediateInvalidArgs() {
7627     DeleteVertexArraysOESImmediate& cmd =
7628         *GetImmediateAs<DeleteVertexArraysOESImmediate>();
7629     GLuint temp = kInvalidClientId;
7630     cmd.Init(1, &temp);
7631     EXPECT_EQ(error::kNoError,
7632               ExecuteImmediateCmd(cmd, sizeof(temp)));
7633   }
7634
7635   void IsVertexArrayOESValidArgs() {
7636     IsVertexArrayOES cmd;
7637     cmd.Init(client_vertexarray_id_, shared_memory_id_, shared_memory_offset_);
7638     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7639     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7640   }
7641
7642   void IsVertexArrayOESInvalidArgsBadSharedMemoryId() {
7643     IsVertexArrayOES cmd;
7644     cmd.Init(
7645         client_vertexarray_id_, kInvalidSharedMemoryId, shared_memory_offset_);
7646     EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
7647     cmd.Init(
7648         client_vertexarray_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
7649     EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
7650   }
7651
7652   void BindVertexArrayOESValidArgs() {
7653     AddExpectationsForBindVertexArrayOES();
7654     BindVertexArrayOES cmd;
7655     cmd.Init(client_vertexarray_id_);
7656     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7657     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7658   }
7659
7660   void BindVertexArrayOESValidArgsNewId() {
7661     BindVertexArrayOES cmd;
7662     cmd.Init(kNewClientId);
7663     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7664     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7665   }
7666 };
7667
7668 class GLES2DecoderEmulatedVertexArraysOESTest
7669     : public GLES2DecoderVertexArraysOESTest {
7670  public:
7671   GLES2DecoderEmulatedVertexArraysOESTest() { }
7672
7673   virtual void SetUp() {
7674     InitDecoder(
7675         "",     // extensions
7676         false,  // has alpha
7677         false,  // has depth
7678         false,  // has stencil
7679         false,  // request alpha
7680         false,  // request depth
7681         false,  // request stencil
7682         true);  // bind generates resource
7683     SetupDefaultProgram();
7684
7685     AddExpectationsForGenVertexArraysOES();
7686     GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
7687
7688     vertex_array_deleted_manually_ = false;
7689   }
7690 };
7691
7692 // Test vertex array objects with native support
7693 TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESValidArgs) {
7694   GenVertexArraysOESValidArgs();
7695 }
7696 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, GenVertexArraysOESValidArgs) {
7697   GenVertexArraysOESValidArgs();
7698 }
7699
7700 TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESInvalidArgs) {
7701   GenVertexArraysOESInvalidArgs();
7702 }
7703 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, ) {
7704   GenVertexArraysOESInvalidArgs();
7705 }
7706
7707 TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESImmediateValidArgs) {
7708   GenVertexArraysOESImmediateValidArgs();
7709 }
7710 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7711     GenVertexArraysOESImmediateValidArgs) {
7712   GenVertexArraysOESImmediateValidArgs();
7713 }
7714
7715 TEST_F(GLES2DecoderVertexArraysOESTest,
7716     GenVertexArraysOESImmediateInvalidArgs) {
7717   GenVertexArraysOESImmediateInvalidArgs();
7718 }
7719 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7720     GenVertexArraysOESImmediateInvalidArgs) {
7721   GenVertexArraysOESImmediateInvalidArgs();
7722 }
7723
7724 TEST_F(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESValidArgs) {
7725   DeleteVertexArraysOESValidArgs();
7726 }
7727 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7728     DeleteVertexArraysOESValidArgs) {
7729   DeleteVertexArraysOESValidArgs();
7730 }
7731
7732 TEST_F(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESInvalidArgs) {
7733   DeleteVertexArraysOESInvalidArgs();
7734 }
7735 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7736     DeleteVertexArraysOESInvalidArgs) {
7737   DeleteVertexArraysOESInvalidArgs();
7738 }
7739
7740 TEST_F(GLES2DecoderVertexArraysOESTest,
7741     DeleteVertexArraysOESImmediateValidArgs) {
7742   DeleteVertexArraysOESImmediateValidArgs();
7743 }
7744 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7745     DeleteVertexArraysOESImmediateValidArgs) {
7746   DeleteVertexArraysOESImmediateValidArgs();
7747 }
7748
7749 TEST_F(GLES2DecoderVertexArraysOESTest,
7750     DeleteVertexArraysOESImmediateInvalidArgs) {
7751   DeleteVertexArraysOESImmediateInvalidArgs();
7752 }
7753 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7754     DeleteVertexArraysOESImmediateInvalidArgs) {
7755   DeleteVertexArraysOESImmediateInvalidArgs();
7756 }
7757
7758 TEST_F(GLES2DecoderVertexArraysOESTest, IsVertexArrayOESValidArgs) {
7759   IsVertexArrayOESValidArgs();
7760 }
7761 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, IsVertexArrayOESValidArgs) {
7762   IsVertexArrayOESValidArgs();
7763 }
7764
7765 TEST_F(GLES2DecoderVertexArraysOESTest,
7766     IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
7767   IsVertexArrayOESInvalidArgsBadSharedMemoryId();
7768 }
7769 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7770     IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
7771   IsVertexArrayOESInvalidArgsBadSharedMemoryId();
7772 }
7773
7774 TEST_F(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgs) {
7775   BindVertexArrayOESValidArgs();
7776 }
7777 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, BindVertexArrayOESValidArgs) {
7778   BindVertexArrayOESValidArgs();
7779 }
7780
7781 TEST_F(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgsNewId) {
7782   BindVertexArrayOESValidArgsNewId();
7783 }
7784 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7785     BindVertexArrayOESValidArgsNewId) {
7786   BindVertexArrayOESValidArgsNewId();
7787 }
7788
7789 TEST_F(GLES2DecoderTest, BindTexImage2DCHROMIUM) {
7790   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7791   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7792                0, 0);
7793   TextureRef* texture_ref = group().texture_manager()->GetTexture(
7794       client_texture_id_);
7795   ASSERT_TRUE(texture_ref != NULL);
7796   Texture* texture = texture_ref->texture();
7797   EXPECT_EQ(kServiceTextureId, texture->service_id());
7798
7799   group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
7800   EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
7801
7802   GLsizei width;
7803   GLsizei height;
7804   GLenum type;
7805   GLenum internal_format;
7806
7807   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7808   EXPECT_EQ(3, width);
7809   EXPECT_EQ(1, height);
7810   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7811   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7812   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7813   EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7814
7815   // Bind image to texture.
7816   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7817   EXPECT_CALL(*gl_, GetError())
7818       .WillOnce(Return(GL_NO_ERROR))
7819       .WillOnce(Return(GL_NO_ERROR))
7820       .RetiresOnSaturation();
7821   BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
7822   bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
7823   EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
7824   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7825   // Image should now be set.
7826   EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7827
7828   // Define new texture image.
7829   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7830                0, 0);
7831   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7832   // Image should no longer be set.
7833   EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7834 }
7835
7836 TEST_F(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) {
7837   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7838   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7839                0, 0);
7840   TextureRef* texture_ref = group().texture_manager()->GetTexture(
7841       client_texture_id_);
7842   ASSERT_TRUE(texture_ref != NULL);
7843   Texture* texture = texture_ref->texture();
7844   EXPECT_EQ(kServiceTextureId, texture->service_id());
7845
7846   group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
7847   EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
7848
7849   GLsizei width;
7850   GLsizei height;
7851   GLenum type;
7852   GLenum internal_format;
7853
7854   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7855   EXPECT_EQ(3, width);
7856   EXPECT_EQ(1, height);
7857   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7858   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7859   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7860   EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7861
7862   // Bind image to texture.
7863   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7864   EXPECT_CALL(*gl_, GetError())
7865       .WillOnce(Return(GL_NO_ERROR))
7866       .WillOnce(Return(GL_NO_ERROR))
7867       .RetiresOnSaturation();
7868   BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
7869   bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
7870   EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
7871   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7872   // Image should now be set.
7873   EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7874
7875   // Release image from texture.
7876   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7877   EXPECT_CALL(*gl_, GetError())
7878       .WillOnce(Return(GL_NO_ERROR))
7879       .WillOnce(Return(GL_NO_ERROR))
7880       .RetiresOnSaturation();
7881   ReleaseTexImage2DCHROMIUM release_tex_image_2d_cmd;
7882   release_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
7883   EXPECT_EQ(error::kNoError, ExecuteCmd(release_tex_image_2d_cmd));
7884   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7885   // Image should no longer be set.
7886   EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7887 }
7888
7889 class MockGLImage : public gfx::GLImage {
7890  public:
7891   MockGLImage() {}
7892
7893   // Overridden from gfx::GLImage:
7894   MOCK_METHOD0(Destroy, void());
7895   MOCK_METHOD0(GetSize, gfx::Size());
7896   MOCK_METHOD0(BindTexImage, bool());
7897   MOCK_METHOD0(ReleaseTexImage, void());
7898   MOCK_METHOD0(WillUseTexImage, void());
7899   MOCK_METHOD0(DidUseTexImage, void());
7900
7901  protected:
7902   virtual ~MockGLImage() {}
7903 };
7904
7905 TEST_F(GLES2DecoderWithShaderTest, UseTexImage) {
7906   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7907   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7908                kSharedMemoryId, kSharedMemoryOffset);
7909
7910   TextureRef* texture_ref = group().texture_manager()->GetTexture(
7911       client_texture_id_);
7912   ASSERT_TRUE(texture_ref != NULL);
7913   Texture* texture = texture_ref->texture();
7914   EXPECT_EQ(kServiceTextureId, texture->service_id());
7915
7916   const int32 kImageId = 1;
7917   scoped_refptr<MockGLImage> image(new MockGLImage);
7918   group().image_manager()->AddImage(image.get(), kImageId);
7919
7920   // Bind image to texture.
7921   EXPECT_CALL(*image, BindTexImage())
7922       .Times(1)
7923       .WillOnce(Return(true))
7924       .RetiresOnSaturation();
7925   EXPECT_CALL(*image, GetSize())
7926       .Times(1)
7927       .WillOnce(Return(gfx::Size(1, 1)))
7928       .RetiresOnSaturation();
7929   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7930   EXPECT_CALL(*gl_, GetError())
7931       .WillOnce(Return(GL_NO_ERROR))
7932       .WillOnce(Return(GL_NO_ERROR))
7933       .RetiresOnSaturation();
7934   BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
7935   bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, kImageId);
7936   EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
7937
7938   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
7939   SetupExpectationsForApplyingDefaultDirtyState();
7940
7941   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7942   EXPECT_CALL(*gl_, GetError())
7943       .WillOnce(Return(GL_NO_ERROR))
7944       .WillOnce(Return(GL_NO_ERROR))
7945       .WillOnce(Return(GL_NO_ERROR))
7946       .WillOnce(Return(GL_NO_ERROR))
7947       .RetiresOnSaturation();
7948   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
7949       .Times(3)
7950       .RetiresOnSaturation();
7951   EXPECT_CALL(*image, WillUseTexImage())
7952       .Times(1)
7953       .RetiresOnSaturation();
7954   EXPECT_CALL(*image, DidUseTexImage())
7955       .Times(1)
7956       .RetiresOnSaturation();
7957   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
7958       .Times(1)
7959       .RetiresOnSaturation();
7960   DrawArrays cmd;
7961   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
7962   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7963   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7964
7965   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
7966                     kServiceFramebufferId);
7967   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7968   EXPECT_CALL(*gl_, GetError())
7969       .WillOnce(Return(GL_NO_ERROR))
7970       .WillOnce(Return(GL_NO_ERROR))
7971       .RetiresOnSaturation();
7972   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
7973       .Times(1)
7974       .RetiresOnSaturation();
7975   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
7976       .Times(2)
7977       .RetiresOnSaturation();
7978   // Image will be 'in use' as long as bound to a framebuffer.
7979   EXPECT_CALL(*image, WillUseTexImage())
7980       .Times(1)
7981       .RetiresOnSaturation();
7982   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
7983       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
7984       kServiceTextureId, 0))
7985       .Times(1)
7986       .RetiresOnSaturation();
7987   EXPECT_CALL(*gl_, GetError())
7988       .WillOnce(Return(GL_NO_ERROR))
7989       .WillOnce(Return(GL_NO_ERROR))
7990       .RetiresOnSaturation();
7991   FramebufferTexture2D fbtex_cmd;
7992   fbtex_cmd.Init(
7993       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
7994       0);
7995   EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
7996   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7997
7998   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7999   EXPECT_CALL(*gl_, GetError())
8000       .WillOnce(Return(GL_NO_ERROR))
8001       .WillOnce(Return(GL_NO_ERROR))
8002       .RetiresOnSaturation();
8003   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
8004       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
8005       kServiceRenderbufferId))
8006       .Times(1)
8007       .RetiresOnSaturation();
8008   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
8009       .Times(1)
8010       .RetiresOnSaturation();
8011   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
8012       .Times(2)
8013       .RetiresOnSaturation();
8014   // Image should no longer be 'in use' after being unbound from framebuffer.
8015   EXPECT_CALL(*image, DidUseTexImage())
8016       .Times(1)
8017       .RetiresOnSaturation();
8018   EXPECT_CALL(*gl_, GetError())
8019       .WillOnce(Return(GL_NO_ERROR))
8020       .WillOnce(Return(GL_NO_ERROR))
8021       .RetiresOnSaturation();
8022   FramebufferRenderbuffer fbrb_cmd;
8023   fbrb_cmd.Init(
8024       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
8025       client_renderbuffer_id_);
8026   EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
8027 }
8028
8029 TEST_F(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) {
8030   InitDecoder(
8031       "GL_ARB_texture_rectangle",  // extensions
8032       false,   // has alpha
8033       false,   // has depth
8034       false,   // has stencil
8035       false,   // request alpha
8036       false,   // request depth
8037       false,   // request stencil
8038       true);   // bind generates resource
8039
8040   Texture* texture = GetTexture(client_texture_id_)->texture();
8041   EXPECT_TRUE(texture != NULL);
8042   EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
8043
8044   DoBindTexture(
8045       GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8046
8047   TexParameteri cmd;
8048   cmd.Init(GL_TEXTURE_2D,
8049            GL_TEXTURE_POOL_CHROMIUM,
8050            GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
8051   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8052   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8053
8054   cmd.Init(GL_TEXTURE_2D,
8055            GL_TEXTURE_POOL_CHROMIUM,
8056            GL_TEXTURE_POOL_MANAGED_CHROMIUM);
8057   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8058   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8059
8060   EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM);
8061
8062   cmd.Init(GL_TEXTURE_2D,
8063            GL_TEXTURE_POOL_CHROMIUM,
8064            GL_NONE);
8065   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8066   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
8067 }
8068
8069 TEST_F(GLES2DecoderManualInitTest, AsyncPixelTransfers) {
8070   InitDecoder(
8071       "GL_CHROMIUM_async_pixel_transfers",  // extensions
8072       false, false, false,  // has alpha/depth/stencil
8073       false, false, false,  // request alpha/depth/stencil
8074       true);   // bind generates resource
8075
8076   // Set up the texture.
8077   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8078   TextureRef* texture_ref = GetTexture(client_texture_id_);
8079   Texture* texture = texture_ref->texture();
8080
8081   // Set a mock Async delegate
8082   StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
8083       new StrictMock<gpu::MockAsyncPixelTransferManager>;
8084   manager->Initialize(group().texture_manager());
8085   decoder_->SetAsyncPixelTransferManagerForTest(manager);
8086   StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
8087
8088   // Tex(Sub)Image2D upload commands.
8089   AsyncTexImage2DCHROMIUM teximage_cmd;
8090   teximage_cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA,
8091                     GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
8092   AsyncTexSubImage2DCHROMIUM texsubimage_cmd;
8093   texsubimage_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA,
8094                       GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
8095   WaitAsyncTexImage2DCHROMIUM wait_cmd;
8096   wait_cmd.Init(GL_TEXTURE_2D);
8097
8098   // No transfer state exists initially.
8099   EXPECT_FALSE(
8100       decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8101           texture_ref));
8102
8103   base::Closure bind_callback;
8104
8105   // AsyncTexImage2D
8106   {
8107     // Create transfer state since it doesn't exist.
8108     EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
8109         .WillOnce(Return(
8110             delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
8111         .RetiresOnSaturation();
8112     EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _))
8113         .WillOnce(SaveArg<2>(&bind_callback))
8114         .RetiresOnSaturation();
8115     // Command succeeds.
8116     EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
8117     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8118     EXPECT_EQ(
8119         delegate,
8120         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8121             texture_ref));
8122     EXPECT_TRUE(texture->IsImmutable());
8123     // The texture is safe but the level has not been defined yet.
8124     EXPECT_TRUE(texture->SafeToRenderFrom());
8125     GLsizei width, height;
8126     EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
8127   }
8128   {
8129     // Async redefinitions are not allowed!
8130     // Command fails.
8131     EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
8132     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8133     EXPECT_EQ(
8134         delegate,
8135         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8136             texture_ref));
8137     EXPECT_TRUE(texture->IsImmutable());
8138     EXPECT_TRUE(texture->SafeToRenderFrom());
8139   }
8140
8141   // Binding/defining of the async transfer
8142   {
8143     // TODO(epenner): We should check that the manager gets the
8144     // BindCompletedAsyncTransfers() call, which is required to
8145     // guarantee the delegate calls the bind callback.
8146
8147     // Simulate the bind callback from the delegate.
8148     bind_callback.Run();
8149
8150     // After the bind callback is run, the texture is safe,
8151     // and has the right size etc.
8152     EXPECT_TRUE(texture->SafeToRenderFrom());
8153     GLsizei width, height;
8154     EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
8155     EXPECT_EQ(width, 8);
8156     EXPECT_EQ(height, 8);
8157   }
8158
8159   // AsyncTexSubImage2D
8160   decoder_->GetAsyncPixelTransferManager()
8161       ->ClearPixelTransferDelegateForTest(texture_ref);
8162   texture->SetImmutable(false);
8163   {
8164     // Create transfer state since it doesn't exist.
8165     EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
8166         .WillOnce(Return(
8167             delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
8168         .RetiresOnSaturation();
8169     EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _))
8170         .RetiresOnSaturation();
8171     // Command succeeds.
8172     EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
8173     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8174     EXPECT_EQ(
8175         delegate,
8176         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8177             texture_ref));
8178     EXPECT_TRUE(texture->IsImmutable());
8179     EXPECT_TRUE(texture->SafeToRenderFrom());
8180   }
8181   {
8182     // No transfer is in progress.
8183     EXPECT_CALL(*delegate, TransferIsInProgress())
8184         .WillOnce(Return(false))  // texSubImage validation
8185         .WillOnce(Return(false))  // async validation
8186         .RetiresOnSaturation();
8187     EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _))
8188         .RetiresOnSaturation();
8189     // Command succeeds.
8190     EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
8191     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8192     EXPECT_EQ(
8193         delegate,
8194         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8195             texture_ref));
8196     EXPECT_TRUE(texture->IsImmutable());
8197     EXPECT_TRUE(texture->SafeToRenderFrom());
8198   }
8199   {
8200     // A transfer is still in progress!
8201     EXPECT_CALL(*delegate, TransferIsInProgress())
8202         .WillOnce(Return(true))
8203         .RetiresOnSaturation();
8204     // No async call, command fails.
8205     EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
8206     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8207     EXPECT_EQ(
8208         delegate,
8209         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8210             texture_ref));
8211     EXPECT_TRUE(texture->IsImmutable());
8212     EXPECT_TRUE(texture->SafeToRenderFrom());
8213   }
8214
8215   // Delete delegate on DeleteTexture.
8216   {
8217     EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
8218     DoDeleteTexture(client_texture_id_, kServiceTextureId);
8219     EXPECT_FALSE(
8220         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8221             texture_ref));
8222     delegate = NULL;
8223   }
8224
8225   // WaitAsyncTexImage2D
8226   {
8227     // Get a fresh texture since the existing texture cannot be respecified
8228     // asynchronously and AsyncTexSubImage2D does not involved binding.
8229     EXPECT_CALL(*gl_, GenTextures(1, _))
8230         .WillOnce(SetArgumentPointee<1>(kServiceTextureId));
8231     DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8232     texture_ref = GetTexture(client_texture_id_);
8233     texture = texture_ref->texture();
8234     texture->SetImmutable(false);
8235     // Create transfer state since it doesn't exist.
8236     EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
8237         .WillOnce(Return(
8238             delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
8239         .RetiresOnSaturation();
8240     EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _))
8241         .RetiresOnSaturation();
8242     // Start async transfer.
8243     EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
8244     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8245     EXPECT_EQ(
8246         delegate,
8247         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8248             texture_ref));
8249
8250     EXPECT_TRUE(texture->IsImmutable());
8251     // Wait for completion.
8252     EXPECT_CALL(*delegate, WaitForTransferCompletion());
8253     EXPECT_CALL(*manager, BindCompletedAsyncTransfers());
8254     EXPECT_EQ(error::kNoError, ExecuteCmd(wait_cmd));
8255     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8256   }
8257 }
8258
8259 TEST_F(GLES2DecoderManualInitTest, AsyncPixelTransferManager) {
8260   InitDecoder(
8261       "GL_CHROMIUM_async_pixel_transfers",  // extensions
8262       false, false, false,  // has alpha/depth/stencil
8263       false, false, false,  // request alpha/depth/stencil
8264       true);   // bind generates resource
8265
8266   // Set up the texture.
8267   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8268   TextureRef* texture_ref = GetTexture(client_texture_id_);
8269
8270   // Set a mock Async delegate.
8271   StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
8272       new StrictMock<gpu::MockAsyncPixelTransferManager>;
8273   manager->Initialize(group().texture_manager());
8274   decoder_->SetAsyncPixelTransferManagerForTest(manager);
8275   StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
8276
8277   AsyncTexImage2DCHROMIUM teximage_cmd;
8278   teximage_cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA,
8279                     GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
8280
8281   // No transfer delegate exists initially.
8282   EXPECT_FALSE(
8283       decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8284           texture_ref));
8285
8286   // Create delegate on AsyncTexImage2D.
8287   {
8288     EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
8289         .WillOnce(Return(
8290              delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
8291         .RetiresOnSaturation();
8292     EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _)).RetiresOnSaturation();
8293
8294     // Command succeeds.
8295     EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
8296     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8297   }
8298
8299   // Delegate is cached.
8300   EXPECT_EQ(delegate,
8301             decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8302                 texture_ref));
8303
8304   // Delete delegate on manager teardown.
8305   {
8306     EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
8307     decoder_->ResetAsyncPixelTransferManagerForTest();
8308
8309     // Texture ref still valid.
8310     EXPECT_EQ(texture_ref, GetTexture(client_texture_id_));
8311   }
8312 }
8313
8314 namespace {
8315
8316 class SizeOnlyMemoryTracker : public MemoryTracker {
8317  public:
8318   SizeOnlyMemoryTracker() {
8319     // These are the default textures. 1 for TEXTURE_2D and 6 faces for
8320     // TEXTURE_CUBE_MAP.
8321     const size_t kInitialUnmanagedPoolSize = 7 * 4;
8322     const size_t kInitialManagedPoolSize = 0;
8323     pool_infos_[MemoryTracker::kUnmanaged].initial_size =
8324         kInitialUnmanagedPoolSize;
8325     pool_infos_[MemoryTracker::kManaged].initial_size =
8326         kInitialManagedPoolSize;
8327   }
8328
8329   // Ensure a certain amount of GPU memory is free. Returns true on success.
8330   MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed));
8331
8332   virtual void TrackMemoryAllocatedChange(
8333       size_t old_size, size_t new_size, Pool pool) {
8334     PoolInfo& info = pool_infos_[pool];
8335     info.size += new_size - old_size;
8336   }
8337
8338   size_t GetPoolSize(Pool pool) {
8339     const PoolInfo& info = pool_infos_[pool];
8340     return info.size - info.initial_size;
8341   }
8342
8343  private:
8344   virtual ~SizeOnlyMemoryTracker() {
8345   }
8346   struct PoolInfo {
8347     PoolInfo()
8348         : initial_size(0),
8349           size(0) {
8350     }
8351     size_t initial_size;
8352     size_t size;
8353   };
8354   std::map<Pool, PoolInfo> pool_infos_;
8355 };
8356
8357 }  // anonymous namespace.
8358
8359 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
8360   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8361       new SizeOnlyMemoryTracker();
8362   set_memory_tracker(memory_tracker.get());
8363   InitDecoder(
8364       "",      // extensions
8365       false,   // has alpha
8366       false,   // has depth
8367       false,   // has stencil
8368       false,   // request alpha
8369       false,   // request depth
8370       false,   // request stencil
8371       true);   // bind generates resource
8372   // Expect that initial size - size is 0.
8373   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8374   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
8375 }
8376
8377 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
8378   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8379       new SizeOnlyMemoryTracker();
8380   set_memory_tracker(memory_tracker.get());
8381   InitDecoder(
8382       "",      // extensions
8383       false,   // has alpha
8384       false,   // has depth
8385       false,   // has stencil
8386       false,   // request alpha
8387       false,   // request depth
8388       false,   // request stencil
8389       true);   // bind generates resource
8390   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8391   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8392       .WillOnce(Return(true)).RetiresOnSaturation();
8393   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8394                kSharedMemoryId, kSharedMemoryOffset);
8395   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8396   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
8397       .WillOnce(Return(true)).RetiresOnSaturation();
8398   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8399                kSharedMemoryId, kSharedMemoryOffset);
8400   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8401   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8402   // Check we get out of memory and no call to glTexImage2D if Ensure fails.
8403   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
8404       .WillOnce(Return(false)).RetiresOnSaturation();
8405   TexImage2D cmd;
8406   cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8407            kSharedMemoryId, kSharedMemoryOffset);
8408   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8409   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8410   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8411 }
8412
8413 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
8414   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8415       new SizeOnlyMemoryTracker();
8416   set_memory_tracker(memory_tracker.get());
8417   InitDecoder(
8418       "",      // extensions
8419       false,   // has alpha
8420       false,   // has depth
8421       false,   // has stencil
8422       false,   // request alpha
8423       false,   // request depth
8424       false,   // request stencil
8425       true);   // bind generates resource
8426   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8427   // Check we get out of memory and no call to glTexStorage2DEXT
8428   // if Ensure fails.
8429   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8430       .WillOnce(Return(false)).RetiresOnSaturation();
8431   TexStorage2DEXT cmd;
8432   cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
8433   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8434   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8435   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8436 }
8437
8438 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
8439   GLenum target = GL_TEXTURE_2D;
8440   GLint level = 0;
8441   GLenum internal_format = GL_RGBA;
8442   GLsizei width = 4;
8443   GLsizei height = 8;
8444   GLint border = 0;
8445   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8446       new SizeOnlyMemoryTracker();
8447   set_memory_tracker(memory_tracker.get());
8448   InitDecoder(
8449       "",      // extensions
8450       true,    // has alpha
8451       false,   // has depth
8452       false,   // has stencil
8453       true,    // request alpha
8454       false,   // request depth
8455       false,   // request stencil
8456       true);   // bind generates resource
8457   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8458   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8459       .WillOnce(Return(true)).RetiresOnSaturation();
8460   EXPECT_CALL(*gl_, GetError())
8461       .WillOnce(Return(GL_NO_ERROR))
8462       .WillOnce(Return(GL_NO_ERROR))
8463       .RetiresOnSaturation();
8464   EXPECT_CALL(*gl_, CopyTexImage2D(
8465       target, level, internal_format, 0, 0, width, height, border))
8466       .Times(1)
8467       .RetiresOnSaturation();
8468   CopyTexImage2D cmd;
8469   cmd.Init(target, level, internal_format, 0, 0, width, height, border);
8470   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8471   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8472   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8473   // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
8474   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8475       .WillOnce(Return(false)).RetiresOnSaturation();
8476   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8477   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8478   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8479 }
8480
8481 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
8482   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8483       new SizeOnlyMemoryTracker();
8484   set_memory_tracker(memory_tracker.get());
8485   InitDecoder(
8486       "",      // extensions
8487       false,   // has alpha
8488       false,   // has depth
8489       false,   // has stencil
8490       false,   // request alpha
8491       false,   // request depth
8492       false,   // request stencil
8493       true);   // bind generates resource
8494   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
8495                     kServiceRenderbufferId);
8496   EXPECT_CALL(*gl_, GetError())
8497       .WillOnce(Return(GL_NO_ERROR))
8498       .WillOnce(Return(GL_NO_ERROR))
8499       .RetiresOnSaturation();
8500   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8501       .WillOnce(Return(true)).RetiresOnSaturation();
8502   EXPECT_CALL(*gl_, RenderbufferStorageEXT(
8503       GL_RENDERBUFFER, GL_RGBA, 8, 4))
8504       .Times(1)
8505       .RetiresOnSaturation();
8506   RenderbufferStorage cmd;
8507   cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4);
8508   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8509   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8510   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8511   // Check we get out of memory and no call to glRenderbufferStorage if Ensure
8512   // fails.
8513   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8514       .WillOnce(Return(false)).RetiresOnSaturation();
8515   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8516   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8517   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8518 }
8519
8520 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
8521   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8522       new SizeOnlyMemoryTracker();
8523   set_memory_tracker(memory_tracker.get());
8524   InitDecoder(
8525       "",      // extensions
8526       false,   // has alpha
8527       false,   // has depth
8528       false,   // has stencil
8529       false,   // request alpha
8530       false,   // request depth
8531       false,   // request stencil
8532       true);   // bind generates resource
8533   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_,
8534                kServiceBufferId);
8535   EXPECT_CALL(*gl_, GetError())
8536       .WillOnce(Return(GL_NO_ERROR))
8537       .WillOnce(Return(GL_NO_ERROR))
8538       .RetiresOnSaturation();
8539   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8540       .WillOnce(Return(true)).RetiresOnSaturation();
8541   EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
8542       .Times(1)
8543       .RetiresOnSaturation();
8544   BufferData cmd;
8545   cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW);
8546   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8547   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8548   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
8549   // Check we get out of memory and no call to glBufferData if Ensure
8550   // fails.
8551   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8552       .WillOnce(Return(false)).RetiresOnSaturation();
8553   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8554   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8555   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
8556 }
8557
8558 TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateSuccceeds) {
8559   const GLsizei count = 1;
8560   const GLenum bufs[] = { GL_COLOR_ATTACHMENT0 };
8561   DrawBuffersEXTImmediate& cmd =
8562       *GetImmediateAs<DrawBuffersEXTImmediate>();
8563   cmd.Init(count, bufs);
8564
8565   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
8566                     kServiceFramebufferId);
8567   EXPECT_CALL(*gl_, DrawBuffersARB(count, _))
8568       .Times(1)
8569       .RetiresOnSaturation();
8570   EXPECT_EQ(error::kNoError,
8571             ExecuteImmediateCmd(cmd, sizeof(bufs)));
8572   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8573 }
8574
8575 TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateFails) {
8576   const GLsizei count = 1;
8577   const GLenum bufs[] = { GL_COLOR_ATTACHMENT1_EXT };
8578   DrawBuffersEXTImmediate& cmd =
8579       *GetImmediateAs<DrawBuffersEXTImmediate>();
8580   cmd.Init(count, bufs);
8581
8582   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
8583                     kServiceFramebufferId);
8584   EXPECT_EQ(error::kNoError,
8585             ExecuteImmediateCmd(cmd, sizeof(bufs)));
8586   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8587 }
8588
8589 TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateBackbuffer) {
8590   const GLsizei count = 1;
8591   const GLenum bufs[] = { GL_BACK };
8592   DrawBuffersEXTImmediate& cmd =
8593       *GetImmediateAs<DrawBuffersEXTImmediate>();
8594   cmd.Init(count, bufs);
8595
8596   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
8597                     kServiceFramebufferId);
8598   EXPECT_EQ(error::kNoError,
8599             ExecuteImmediateCmd(cmd, sizeof(bufs)));
8600   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8601
8602   DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);  // unbind
8603
8604   EXPECT_CALL(*gl_, DrawBuffersARB(count, _))
8605       .Times(1)
8606       .RetiresOnSaturation();
8607
8608   EXPECT_EQ(error::kNoError,
8609             ExecuteImmediateCmd(cmd, sizeof(bufs)));
8610   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8611 }
8612
8613 TEST_F(GLES2DecoderManualInitTest, DiscardFramebufferEXT) {
8614   InitDecoder("GL_EXT_discard_framebuffer",  // extensions
8615               false,                         // has alpha
8616               false,                         // has depth
8617               false,                         // has stencil
8618               false,                         // request alpha
8619               false,                         // request depth
8620               false,                         // request stencil
8621               false);                        // bind generates resource
8622
8623   const GLenum target = GL_FRAMEBUFFER;
8624   const GLsizei count = 1;
8625   const GLenum attachments[] = { GL_COLOR_ATTACHMENT0 };
8626
8627   SetupTexture();
8628   DoBindFramebuffer(
8629       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
8630   DoFramebufferTexture2D(GL_FRAMEBUFFER,
8631                          GL_COLOR_ATTACHMENT0,
8632                          GL_TEXTURE_2D,
8633                          client_texture_id_,
8634                          kServiceTextureId,
8635                          0,
8636                          GL_NO_ERROR);
8637   FramebufferManager* framebuffer_manager = group().framebuffer_manager();
8638   Framebuffer* framebuffer =
8639       framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
8640   EXPECT_TRUE(framebuffer->IsCleared());
8641
8642   EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
8643       .Times(1)
8644       .RetiresOnSaturation();
8645   DiscardFramebufferEXTImmediate& cmd =
8646       *GetImmediateAs<DiscardFramebufferEXTImmediate>();
8647   cmd.Init(target, count, attachments);
8648
8649   EXPECT_EQ(error::kNoError,
8650             ExecuteImmediateCmd(cmd, sizeof(attachments)));
8651   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8652   EXPECT_FALSE(framebuffer->IsCleared());
8653 }
8654
8655 TEST_F(GLES2DecoderTest, DiscardFramebufferEXTUnsupported) {
8656   const GLenum target = GL_FRAMEBUFFER;
8657   const GLsizei count = 1;
8658   const GLenum attachments[] = { GL_COLOR_EXT };
8659   DiscardFramebufferEXTImmediate& cmd =
8660       *GetImmediateAs<DiscardFramebufferEXTImmediate>();
8661   cmd.Init(target, count, attachments);
8662
8663   // Should not result into a call into GL.
8664   EXPECT_EQ(error::kNoError,
8665             ExecuteImmediateCmd(cmd, sizeof(attachments)));
8666   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8667 }
8668
8669 // TODO(gman): Complete this test.
8670 // TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
8671 // }
8672
8673 // TODO(gman): BufferData
8674
8675 // TODO(gman): BufferDataImmediate
8676
8677 // TODO(gman): BufferSubData
8678
8679 // TODO(gman): BufferSubDataImmediate
8680
8681 // TODO(gman): CompressedTexImage2D
8682
8683 // TODO(gman): CompressedTexImage2DImmediate
8684
8685 // TODO(gman): CompressedTexSubImage2DImmediate
8686
8687 // TODO(gman): DeleteProgram
8688
8689 // TODO(gman): DeleteShader
8690
8691 // TODO(gman): PixelStorei
8692
8693 // TODO(gman): TexImage2D
8694
8695 // TODO(gman): TexImage2DImmediate
8696
8697 // TODO(gman): TexSubImage2DImmediate
8698
8699 // TODO(gman): UseProgram
8700
8701 // TODO(gman): SwapBuffers
8702
8703 }  // namespace gles2
8704 }  // namespace gpu