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