e7187d07e59a52242226f2fd55dca614301297b7
[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_EQ(error::kNoError, ExecuteCmd(cmd1));
5667   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5668
5669   BindBuffer cmd2;
5670   cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId);
5671   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
5672   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5673
5674   BindFramebuffer cmd3;
5675   cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId);
5676   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd3));
5677   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5678
5679   BindRenderbuffer cmd4;
5680   cmd4.Init(GL_RENDERBUFFER, kInvalidClientId);
5681   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd4));
5682   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
5683 }
5684
5685 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleBindTexture) {
5686   InitDecoder(
5687       "GL_ARB_texture_rectangle",  // extensions
5688       "3.0",   // gl version
5689       false,   // has alpha
5690       false,   // has depth
5691       false,   // has stencil
5692       false,   // request alpha
5693       false,   // request depth
5694       false,   // request stencil
5695       true);   // bind generates resource
5696   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_RECTANGLE_ARB, kNewServiceId));
5697   EXPECT_CALL(*gl_, GenTextures(1, _))
5698      .WillOnce(SetArgumentPointee<1>(kNewServiceId));
5699   BindTexture cmd;
5700   cmd.Init(GL_TEXTURE_RECTANGLE_ARB, kNewClientId);
5701   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5702   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5703   Texture* texture = GetTexture(kNewClientId)->texture();
5704   EXPECT_TRUE(texture != NULL);
5705   EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
5706 }
5707
5708 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleGetBinding) {
5709   InitDecoder(
5710       "GL_ARB_texture_rectangle",  // extensions
5711       "3.0",   // gl version
5712       false,   // has alpha
5713       false,   // has depth
5714       false,   // has stencil
5715       false,   // request alpha
5716       false,   // request depth
5717       false,   // request stencil
5718       true);   // bind generates resource
5719   DoBindTexture(
5720       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
5721
5722   EXPECT_CALL(*gl_, GetError())
5723       .WillOnce(Return(GL_NO_ERROR))
5724       .WillOnce(Return(GL_NO_ERROR))
5725       .RetiresOnSaturation();
5726   typedef GetIntegerv::Result Result;
5727   Result* result = static_cast<Result*>(shared_memory_address_);
5728   EXPECT_CALL(*gl_, GetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB,
5729                                 result->GetData()))
5730       .Times(0);
5731   result->size = 0;
5732   GetIntegerv cmd;
5733   cmd.Init(GL_TEXTURE_BINDING_RECTANGLE_ARB,
5734            shared_memory_id_,
5735            shared_memory_offset_);
5736   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5737   EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
5738       GL_TEXTURE_BINDING_RECTANGLE_ARB), result->GetNumResults());
5739   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5740   EXPECT_EQ(client_texture_id_, (uint32)result->GetData()[0]);
5741 }
5742
5743 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTextureDefaults) {
5744   InitDecoder(
5745       "GL_ARB_texture_rectangle",  // extensions
5746       "3.0",   // gl version
5747       false,   // has alpha
5748       false,   // has depth
5749       false,   // has stencil
5750       false,   // request alpha
5751       false,   // request depth
5752       false,   // request stencil
5753       true);   // bind generates resource
5754   DoBindTexture(
5755       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
5756
5757   Texture* texture = GetTexture(client_texture_id_)->texture();
5758   EXPECT_TRUE(texture != NULL);
5759   EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
5760   EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
5761   EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
5762   EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
5763 }
5764
5765 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParam) {
5766   InitDecoder(
5767       "GL_ARB_texture_rectangle",  // extensions
5768       "3.0",   // gl version
5769       false,   // has alpha
5770       false,   // has depth
5771       false,   // has stencil
5772       false,   // request alpha
5773       false,   // request depth
5774       false,   // request stencil
5775       true);   // bind generates resource
5776
5777   DoBindTexture(
5778       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
5779
5780   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
5781                                   GL_TEXTURE_MIN_FILTER,
5782                                   GL_NEAREST));
5783   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
5784                                   GL_TEXTURE_MIN_FILTER,
5785                                   GL_LINEAR));
5786   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
5787                                   GL_TEXTURE_WRAP_S,
5788                                   GL_CLAMP_TO_EDGE));
5789   EXPECT_CALL(*gl_, TexParameteri(GL_TEXTURE_RECTANGLE_ARB,
5790                                   GL_TEXTURE_WRAP_T,
5791                                   GL_CLAMP_TO_EDGE));
5792   TexParameteri cmd;
5793   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5794            GL_TEXTURE_MIN_FILTER,
5795            GL_NEAREST);
5796   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5797   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5798
5799   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5800            GL_TEXTURE_MIN_FILTER,
5801            GL_LINEAR);
5802   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5803   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5804
5805   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5806            GL_TEXTURE_WRAP_S,
5807            GL_CLAMP_TO_EDGE);
5808   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5809   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5810
5811   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5812            GL_TEXTURE_WRAP_T,
5813            GL_CLAMP_TO_EDGE);
5814   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5815   EXPECT_EQ(GL_NO_ERROR, GetGLError());
5816
5817   Texture* texture = GetTexture(client_texture_id_)->texture();
5818   EXPECT_TRUE(texture != NULL);
5819   EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
5820   EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
5821   EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
5822   EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
5823 }
5824
5825 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTextureParamInvalid) {
5826   InitDecoder(
5827       "GL_ARB_texture_rectangle",  // extensions
5828       "3.0",   // gl version
5829       false,   // has alpha
5830       false,   // has depth
5831       false,   // has stencil
5832       false,   // request alpha
5833       false,   // request depth
5834       false,   // request stencil
5835       true);   // bind generates resource
5836
5837   DoBindTexture(
5838       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
5839
5840   TexParameteri cmd;
5841   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5842            GL_TEXTURE_MIN_FILTER,
5843            GL_NEAREST_MIPMAP_NEAREST);
5844   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5845   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
5846
5847   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5848            GL_TEXTURE_WRAP_S,
5849            GL_REPEAT);
5850   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5851   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
5852
5853   cmd.Init(GL_TEXTURE_RECTANGLE_ARB,
5854            GL_TEXTURE_WRAP_T,
5855            GL_REPEAT);
5856   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5857   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
5858
5859   Texture* texture = GetTexture(client_texture_id_)->texture();
5860   EXPECT_TRUE(texture != NULL);
5861   EXPECT_TRUE(texture->target() == GL_TEXTURE_RECTANGLE_ARB);
5862   EXPECT_TRUE(texture->min_filter() == GL_LINEAR);
5863   EXPECT_TRUE(texture->wrap_s() == GL_CLAMP_TO_EDGE);
5864   EXPECT_TRUE(texture->wrap_t() == GL_CLAMP_TO_EDGE);
5865 }
5866
5867 TEST_F(GLES2DecoderManualInitTest, ARBTextureRectangleTexImage2DError) {
5868   InitDecoder(
5869       "GL_ARB_texture_rectangle",  // extensions
5870       "3.0",   // gl version
5871       false,   // has alpha
5872       false,   // has depth
5873       false,   // has stencil
5874       false,   // request alpha
5875       false,   // request depth
5876       false,   // request stencil
5877       true);   // bind generates resource
5878
5879   GLenum target = GL_TEXTURE_RECTANGLE_ARB;
5880   GLint level = 0;
5881   GLenum internal_format = GL_RGBA;
5882   GLsizei width = 2;
5883   GLsizei height = 4;
5884   GLint border = 0;
5885   GLenum format = GL_RGBA;
5886   GLenum type = GL_UNSIGNED_BYTE;
5887   DoBindTexture(
5888       GL_TEXTURE_RECTANGLE_ARB, client_texture_id_, kServiceTextureId);
5889   ASSERT_TRUE(GetTexture(client_texture_id_) != NULL);
5890   TexImage2D cmd;
5891   cmd.Init(target, level, internal_format, width, height, border, format,
5892            type, kSharedMemoryId, kSharedMemoryOffset);
5893   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5894
5895   // TexImage2D is not allowed with GL_TEXTURE_RECTANGLE_ARB targets.
5896   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
5897 }
5898
5899 TEST_F(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
5900   const uint32 kBadBucketId = 123;
5901   EnableFeatureCHROMIUM cmd;
5902   cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_);
5903   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
5904 }
5905
5906 TEST_F(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
5907   const uint32 kBadBucketId = 123;
5908   RequestExtensionCHROMIUM cmd;
5909   cmd.Init(kBadBucketId);
5910   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
5911 }
5912
5913 TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DNULL) {
5914   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
5915   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5916                0, 0);
5917   SetupClearTextureExpections(
5918       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
5919       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
5920   EXPECT_CALL(*gl_, TexSubImage2D(
5921       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
5922       shared_memory_address_))
5923       .Times(1)
5924       .RetiresOnSaturation();
5925   TexSubImage2D cmd;
5926   cmd.Init(
5927       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
5928       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
5929   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5930   // Test if we call it again it does not clear.
5931   EXPECT_CALL(*gl_, TexSubImage2D(
5932       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
5933       shared_memory_address_))
5934       .Times(1)
5935       .RetiresOnSaturation();
5936   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5937 }
5938
5939 TEST_F(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) {
5940   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
5941   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5942                0, 0);
5943   DoTexImage2D(
5944       GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5945       kSharedMemoryId, kSharedMemoryOffset);
5946   EXPECT_CALL(*gl_, TexSubImage2D(
5947       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
5948       shared_memory_address_))
5949       .Times(1)
5950       .RetiresOnSaturation();
5951   TexSubImage2D cmd;
5952   cmd.Init(
5953       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
5954       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
5955   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5956   // Test if we call it again it does not clear.
5957   EXPECT_CALL(*gl_, TexSubImage2D(
5958       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
5959       shared_memory_address_))
5960       .Times(1)
5961       .RetiresOnSaturation();
5962   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
5963 }
5964
5965 TEST_F(
5966     GLES2DecoderManualInitTest,
5967     TexSubImage2DDoesNotClearAfterTexImage2DNULLThenDataWithTexImage2DIsFaster) {
5968   CommandLine command_line(0, NULL);
5969   command_line.AppendSwitchASCII(
5970       switches::kGpuDriverBugWorkarounds,
5971       base::IntToString(gpu::TEXSUBIMAGE2D_FASTER_THAN_TEXIMAGE2D));
5972   InitDecoderWithCommandLine(
5973       "",     // extensions
5974       "3.0",  // gl version
5975       false,  // has alpha
5976       false,  // has depth
5977       false,  // has stencil
5978       false,  // request alpha
5979       false,  // request depth
5980       false,  // request stencil
5981       true,   // bind generates resource
5982       &command_line);
5983   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
5984   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5985                0, 0);
5986
5987   {
5988     // Uses texSubimage internally because the above workaround is active and
5989     // the update is for the full size of the texture.
5990     EXPECT_CALL(*gl_,
5991                 TexSubImage2D(
5992                     GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, _))
5993         .Times(1)
5994         .RetiresOnSaturation();
5995     cmds::TexImage2D cmd;
5996     cmd.Init(GL_TEXTURE_2D,
5997              0,
5998              GL_RGBA,
5999              2,
6000              2,
6001              0,
6002              GL_RGBA,
6003              GL_UNSIGNED_BYTE,
6004              kSharedMemoryId,
6005              kSharedMemoryOffset);
6006     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6007   }
6008
6009   EXPECT_CALL(*gl_, TexSubImage2D(
6010       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6011       shared_memory_address_))
6012       .Times(1)
6013       .RetiresOnSaturation();
6014   TexSubImage2D cmd;
6015   cmd.Init(
6016       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6017       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
6018   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6019   // Test if we call it again it does not clear.
6020   EXPECT_CALL(*gl_, TexSubImage2D(
6021       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6022       shared_memory_address_))
6023       .Times(1)
6024       .RetiresOnSaturation();
6025   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6026 }
6027
6028 TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DWithDataThenNULL) {
6029   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6030   // Put in data (so it should be marked as cleared)
6031   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6032                kSharedMemoryId, kSharedMemoryOffset);
6033   // Put in no data.
6034   TexImage2D tex_cmd;
6035   tex_cmd.Init(
6036       GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6037   // It won't actually call TexImage2D, just mark it as uncleared.
6038   EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
6039   // Next call to TexSubImage2d should clear.
6040   SetupClearTextureExpections(
6041       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6042       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6043   EXPECT_CALL(*gl_, TexSubImage2D(
6044       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6045       shared_memory_address_))
6046       .Times(1)
6047       .RetiresOnSaturation();
6048   TexSubImage2D cmd;
6049   cmd.Init(
6050       GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6051       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
6052   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6053 }
6054
6055 TEST_F(GLES2DecoderWithShaderTest, DrawArraysClearsAfterTexImage2DNULL) {
6056   SetupAllNeededVertexBuffers();
6057   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6058   // Create an uncleared texture with 2 levels.
6059   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6060                0, 0);
6061   DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6062                0, 0);
6063   // Expect 2 levels will be cleared.
6064   SetupClearTextureExpections(
6065       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6066       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6067   SetupClearTextureExpections(
6068       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6069       1, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
6070   SetupExpectationsForApplyingDefaultDirtyState();
6071   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6072       .Times(1)
6073       .RetiresOnSaturation();
6074   DrawArrays cmd;
6075   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6076   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6077   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6078
6079   // But not again
6080   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6081       .Times(1)
6082       .RetiresOnSaturation();
6083   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6084   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6085 }
6086
6087 TEST_F(GLES2DecoderWithShaderTest, DrawElementsClearsAfterTexImage2DNULL) {
6088   SetupAllNeededVertexBuffers();
6089   SetupIndexBuffer();
6090   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6091   // Create an uncleared texture with 2 levels.
6092   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6093                0, 0);
6094   DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6095                0, 0);
6096   // Expect 2 levels will be cleared.
6097   SetupClearTextureExpections(
6098       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6099       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6100   SetupClearTextureExpections(
6101       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6102       1, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
6103   SetupExpectationsForApplyingDefaultDirtyState();
6104
6105   EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
6106                                  GL_UNSIGNED_SHORT,
6107                                  BufferOffset(kValidIndexRangeStart * 2)))
6108       .Times(1)
6109       .RetiresOnSaturation();
6110   DrawElements cmd;
6111   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
6112            kValidIndexRangeStart * 2);
6113   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6114   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6115
6116   // But not again
6117   EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount,
6118                                  GL_UNSIGNED_SHORT,
6119                                  BufferOffset(kValidIndexRangeStart * 2)))
6120       .Times(1)
6121       .RetiresOnSaturation();
6122   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6123   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6124 }
6125
6126 TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterTexImage2DNULLInFBO) {
6127   const GLuint kFBOClientTextureId = 4100;
6128   const GLuint kFBOServiceTextureId = 4101;
6129
6130   SetupAllNeededVertexBuffers();
6131   // Register a texture id.
6132   EXPECT_CALL(*gl_, GenTextures(_, _))
6133       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6134       .RetiresOnSaturation();
6135   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6136
6137   // Setup "render to" texture.
6138   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6139   DoTexImage2D(
6140       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6141   DoBindFramebuffer(
6142       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6143   DoFramebufferTexture2D(
6144       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6145       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6146
6147   // Setup "render from" texture.
6148   SetupTexture();
6149
6150   SetupExpectationsForFramebufferClearing(
6151       GL_FRAMEBUFFER,         // target
6152       GL_COLOR_BUFFER_BIT,    // clear bits
6153       0, 0, 0, 0,             // color
6154       0,                      // stencil
6155       1.0f,                   // depth
6156       false);                 // scissor test
6157
6158   SetupExpectationsForApplyingDirtyState(
6159       false,   // Framebuffer is RGB
6160       false,   // Framebuffer has depth
6161       false,   // Framebuffer has stencil
6162       0x1111,  // color bits
6163       false,   // depth mask
6164       false,   // depth enabled
6165       0,       // front stencil mask
6166       0,       // back stencil mask
6167       false,   // stencil enabled
6168       false,   // cull_face_enabled
6169       false,   // scissor_test_enabled
6170       false);  // blend_enabled
6171
6172   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6173       .Times(1)
6174       .RetiresOnSaturation();
6175   DrawArrays cmd;
6176   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6177   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6178   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6179
6180   // But not again.
6181   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6182       .Times(1)
6183       .RetiresOnSaturation();
6184   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6185   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6186 }
6187
6188 TEST_F(GLES2DecoderWithShaderTest, DrawWitFBOThatCantClearDoesNotDraw) {
6189   const GLuint kFBOClientTextureId = 4100;
6190   const GLuint kFBOServiceTextureId = 4101;
6191
6192   // Register a texture id.
6193   EXPECT_CALL(*gl_, GenTextures(_, _))
6194       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6195       .RetiresOnSaturation();
6196   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6197
6198   // Setup "render to" texture.
6199   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6200   DoTexImage2D(
6201       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6202   DoBindFramebuffer(
6203       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6204   DoFramebufferTexture2D(
6205       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6206       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6207
6208   // Setup "render from" texture.
6209   SetupTexture();
6210
6211   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
6212       .WillOnce(Return(GL_FRAMEBUFFER_UNSUPPORTED))
6213       .RetiresOnSaturation();
6214   EXPECT_CALL(*gl_, DrawArrays(_, _, _))
6215       .Times(0)
6216       .RetiresOnSaturation();
6217   DrawArrays cmd;
6218   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6219   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6220   EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
6221 }
6222
6223 TEST_F(GLES2DecoderTest, CopyTexImage2DMarksTextureAsCleared) {
6224   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6225
6226   TextureManager* manager = group().texture_manager();
6227   TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
6228   ASSERT_TRUE(texture_ref != NULL);
6229   Texture* texture = texture_ref->texture();
6230
6231   EXPECT_CALL(*gl_, GetError())
6232       .WillOnce(Return(GL_NO_ERROR))
6233       .RetiresOnSaturation();
6234   EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0))
6235       .Times(1)
6236       .RetiresOnSaturation();
6237   EXPECT_CALL(*gl_, GetError())
6238       .WillOnce(Return(GL_NO_ERROR))
6239       .RetiresOnSaturation();
6240   CopyTexImage2D cmd;
6241   cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 1, 1, 0);
6242   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6243
6244   EXPECT_TRUE(texture->SafeToRenderFrom());
6245 }
6246
6247 TEST_F(GLES2DecoderTest, CopyTexSubImage2DClearsUnclearedTexture) {
6248   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6249   DoTexImage2D(
6250       GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6251
6252   SetupClearTextureExpections(
6253       kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D,
6254       0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6255   EXPECT_CALL(*gl_, CopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1))
6256       .Times(1)
6257       .RetiresOnSaturation();
6258   CopyTexSubImage2D cmd;
6259   cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
6260   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6261 }
6262
6263 TEST_F(GLES2DecoderManualInitTest, CompressedImage2DMarksTextureAsCleared) {
6264   InitDecoder(
6265       "GL_EXT_texture_compression_s3tc",  // extensions
6266       "3.0",   // gl version
6267       false,   // has alpha
6268       false,   // has depth
6269       false,   // has stencil
6270       false,   // request alpha
6271       false,   // request depth
6272       false,   // request stencil
6273       true);   // bind generates resource
6274
6275   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6276   EXPECT_CALL(*gl_, GetError())
6277       .WillOnce(Return(GL_NO_ERROR))
6278       .RetiresOnSaturation();
6279   EXPECT_CALL(*gl_, CompressedTexImage2D(
6280       GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, 8, _))
6281       .Times(1)
6282       .RetiresOnSaturation();
6283   EXPECT_CALL(*gl_, GetError())
6284       .WillOnce(Return(GL_NO_ERROR))
6285       .RetiresOnSaturation();
6286   CompressedTexImage2D cmd;
6287   cmd.Init(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
6288            8, kSharedMemoryId, kSharedMemoryOffset);
6289   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6290   TextureManager* manager = group().texture_manager();
6291   TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
6292   EXPECT_TRUE(texture_ref->texture()->SafeToRenderFrom());
6293 }
6294
6295 TEST_F(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnClear) {
6296   const GLuint kFBOClientTextureId = 4100;
6297   const GLuint kFBOServiceTextureId = 4101;
6298
6299   // Register a texture id.
6300   EXPECT_CALL(*gl_, GenTextures(_, _))
6301       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6302       .RetiresOnSaturation();
6303   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6304
6305   // Setup "render to" texture.
6306   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6307   DoTexImage2D(
6308       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6309   DoBindFramebuffer(
6310       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6311   DoFramebufferTexture2D(
6312       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6313       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6314
6315   // Setup "render from" texture.
6316   SetupTexture();
6317
6318   SetupExpectationsForFramebufferClearing(
6319       GL_FRAMEBUFFER,         // target
6320       GL_COLOR_BUFFER_BIT,    // clear bits
6321       0, 0, 0, 0,             // color
6322       0,                      // stencil
6323       1.0f,                   // depth
6324       false);                 // scissor test
6325   SetupExpectationsForApplyingDirtyState(
6326       false,   // Framebuffer is RGB
6327       false,   // Framebuffer has depth
6328       false,   // Framebuffer has stencil
6329       0x1111,  // color bits
6330       false,   // depth mask
6331       false,   // depth enabled
6332       0,       // front stencil mask
6333       0,       // back stencil mask
6334       false,   // stencil enabled
6335       false,   // cull_face_enabled
6336       false,   // scissor_test_enabled
6337       false);  // blend_enabled
6338
6339   EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT))
6340       .Times(1)
6341       .RetiresOnSaturation();
6342
6343   Clear cmd;
6344   cmd.Init(GL_COLOR_BUFFER_BIT);
6345   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6346   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6347 }
6348
6349 TEST_F(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnReadPixels) {
6350   const GLuint kFBOClientTextureId = 4100;
6351   const GLuint kFBOServiceTextureId = 4101;
6352
6353   // Register a texture id.
6354   EXPECT_CALL(*gl_, GenTextures(_, _))
6355       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6356       .RetiresOnSaturation();
6357   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6358
6359   // Setup "render to" texture.
6360   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6361   DoTexImage2D(
6362       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6363   DoBindFramebuffer(
6364       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6365   DoFramebufferTexture2D(
6366       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6367       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6368
6369   // Setup "render from" texture.
6370   SetupTexture();
6371
6372   SetupExpectationsForFramebufferClearing(
6373       GL_FRAMEBUFFER,         // target
6374       GL_COLOR_BUFFER_BIT,    // clear bits
6375       0, 0, 0, 0,             // color
6376       0,                      // stencil
6377       1.0f,                   // depth
6378       false);                 // scissor test
6379
6380   EXPECT_CALL(*gl_, GetError())
6381      .WillOnce(Return(GL_NO_ERROR))
6382      .WillOnce(Return(GL_NO_ERROR))
6383      .RetiresOnSaturation();
6384   EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
6385       .Times(1)
6386       .RetiresOnSaturation();
6387   typedef ReadPixels::Result Result;
6388   Result* result = GetSharedMemoryAs<Result*>();
6389   uint32 result_shm_id = kSharedMemoryId;
6390   uint32 result_shm_offset = kSharedMemoryOffset;
6391   uint32 pixels_shm_id = kSharedMemoryId;
6392   uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
6393   ReadPixels cmd;
6394   cmd.Init(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6395            pixels_shm_id, pixels_shm_offset,
6396            result_shm_id, result_shm_offset,
6397            false);
6398   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6399   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6400 }
6401
6402 TEST_F(GLES2DecoderManualInitTest,
6403        UnClearedAttachmentsGetClearedOnReadPixelsAndDrawBufferGetsRestored) {
6404   InitDecoder(
6405       "GL_EXT_framebuffer_multisample",  // extensions
6406       "2.1",   // gl version
6407       false,   // has alpha
6408       false,   // has depth
6409       false,   // has stencil
6410       false,   // request alpha
6411       false,   // request depth
6412       false,   // request stencil
6413       true);   // bind generates resource
6414   const GLuint kFBOClientTextureId = 4100;
6415   const GLuint kFBOServiceTextureId = 4101;
6416
6417   // Register a texture id.
6418   EXPECT_CALL(*gl_, GenTextures(_, _))
6419       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6420       .RetiresOnSaturation();
6421   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6422
6423   // Setup "render from" texture.
6424   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6425   DoTexImage2D(
6426       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6427   DoBindFramebuffer(
6428       GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6429   DoFramebufferTexture2D(
6430       GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6431       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6432
6433   SetupExpectationsForFramebufferClearingMulti(
6434       kServiceFramebufferId,  // read framebuffer service id
6435       0,                      // backbuffer service id
6436       GL_READ_FRAMEBUFFER,    // target
6437       GL_COLOR_BUFFER_BIT,    // clear bits
6438       0, 0, 0, 0,             // color
6439       0,                      // stencil
6440       1.0f,                   // depth
6441       false);                 // scissor test
6442
6443   EXPECT_CALL(*gl_, GetError())
6444      .WillOnce(Return(GL_NO_ERROR))
6445      .WillOnce(Return(GL_NO_ERROR))
6446      .RetiresOnSaturation();
6447   EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
6448       .Times(1)
6449       .RetiresOnSaturation();
6450   typedef ReadPixels::Result Result;
6451   uint32 result_shm_id = kSharedMemoryId;
6452   uint32 result_shm_offset = kSharedMemoryOffset;
6453   uint32 pixels_shm_id = kSharedMemoryId;
6454   uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
6455   ReadPixels cmd;
6456   cmd.Init(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
6457            pixels_shm_id, pixels_shm_offset,
6458            result_shm_id, result_shm_offset,
6459            false);
6460   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6461   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6462 }
6463
6464 TEST_F(GLES2DecoderWithShaderTest, DrawClearsAfterRenderbufferStorageInFBO) {
6465   SetupTexture();
6466   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6467                     kServiceRenderbufferId);
6468   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6469                     kServiceFramebufferId);
6470   DoRenderbufferStorage(
6471       GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 100, 50, GL_NO_ERROR);
6472   DoFramebufferRenderbuffer(
6473       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
6474       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6475
6476   SetupExpectationsForFramebufferClearing(
6477       GL_FRAMEBUFFER,         // target
6478       GL_COLOR_BUFFER_BIT,    // clear bits
6479       0, 0, 0, 0,             // color
6480       0,                      // stencil
6481       1.0f,                   // depth
6482       false);                 // scissor test
6483
6484   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
6485   SetupExpectationsForApplyingDirtyState(
6486       false,   // Framebuffer is RGB
6487       false,   // Framebuffer has depth
6488       false,   // Framebuffer has stencil
6489       0x1111,  // color bits
6490       false,   // depth mask
6491       false,   // depth enabled
6492       0,       // front stencil mask
6493       0,       // back stencil mask
6494       false,   // stencil enabled
6495       false,   // cull_face_enabled
6496       false,   // scissor_test_enabled
6497       false);  // blend_enabled
6498
6499   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6500       .Times(1)
6501       .RetiresOnSaturation();
6502   DrawArrays cmd;
6503   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6504   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6505   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6506 }
6507
6508 TEST_F(GLES2DecoderTest, DrawArraysClearsAfterTexImage2DNULLCubemap) {
6509   static const GLenum faces[] = {
6510     GL_TEXTURE_CUBE_MAP_POSITIVE_X,
6511     GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
6512     GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
6513     GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
6514     GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
6515     GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
6516   };
6517   SetupCubemapProgram();
6518   DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
6519   // Fill out all the faces for 2 levels, leave 2 uncleared.
6520   for (int ii = 0; ii < 6; ++ii) {
6521     GLenum face = faces[ii];
6522     int32 shm_id =
6523         (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryId;
6524     uint32 shm_offset =
6525         (face == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) ? 0 : kSharedMemoryOffset;
6526     DoTexImage2D(face, 0, GL_RGBA, 2, 2, 0, GL_RGBA,
6527                  GL_UNSIGNED_BYTE, shm_id, shm_offset);
6528     DoTexImage2D(face, 1, GL_RGBA, 1, 1, 0, GL_RGBA,
6529                  GL_UNSIGNED_BYTE, shm_id, shm_offset);
6530   }
6531   // Expect 2 levels will be cleared.
6532   SetupClearTextureExpections(
6533       kServiceTextureId, kServiceTextureId, GL_TEXTURE_CUBE_MAP,
6534       GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
6535   SetupClearTextureExpections(
6536       kServiceTextureId, kServiceTextureId, GL_TEXTURE_CUBE_MAP,
6537       GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
6538   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
6539   SetupExpectationsForApplyingDefaultDirtyState();
6540   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6541       .Times(1)
6542       .RetiresOnSaturation();
6543   DrawArrays cmd;
6544   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6545   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6546 }
6547
6548 TEST_F(GLES2DecoderTest, TextureUsageAngleExtNotEnabledByDefault) {
6549   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
6550
6551   TexParameteri cmd;
6552   cmd.Init(GL_TEXTURE_2D,
6553            GL_TEXTURE_USAGE_ANGLE,
6554            GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
6555   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6556   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
6557 }
6558
6559 TEST_F(GLES2DecoderWithShaderTest,
6560        DrawClearsAfterRenderbuffersWithMultipleAttachments) {
6561   const GLuint kFBOClientTextureId = 4100;
6562   const GLuint kFBOServiceTextureId = 4101;
6563
6564   // Register a texture id.
6565   EXPECT_CALL(*gl_, GenTextures(_, _))
6566       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6567       .RetiresOnSaturation();
6568   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6569
6570   // Setup "render to" texture.
6571   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6572   DoTexImage2D(
6573       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6574   DoBindFramebuffer(
6575       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6576   DoFramebufferTexture2D(
6577       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6578       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6579
6580   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6581                     kServiceRenderbufferId);
6582   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6583                     kServiceFramebufferId);
6584   DoRenderbufferStorage(
6585       GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT,
6586       1, 1, GL_NO_ERROR);
6587   DoFramebufferRenderbuffer(
6588       GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
6589       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6590
6591   SetupTexture();
6592   SetupExpectationsForFramebufferClearing(
6593       GL_FRAMEBUFFER,         // target
6594       GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,    // clear bits
6595       0, 0, 0, 0,             // color
6596       0,                      // stencil
6597       1.0f,                   // depth
6598       false);                 // scissor test
6599
6600   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
6601   SetupExpectationsForApplyingDirtyState(
6602       false,   // Framebuffer is RGB
6603       true,    // Framebuffer has depth
6604       false,   // Framebuffer has stencil
6605       0x1111,  // color bits
6606       true,    // depth mask
6607       false,   // depth enabled
6608       0,       // front stencil mask
6609       0,       // back stencil mask
6610       false,   // stencil enabled
6611       false,   // cull_face_enabled
6612       false,   // scissor_test_enabled
6613       false);  // blend_enabled
6614
6615   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6616       .Times(1)
6617       .RetiresOnSaturation();
6618   DrawArrays cmd;
6619   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6620   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6621   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6622 }
6623
6624 TEST_F(GLES2DecoderWithShaderTest, CopyTexImageWithInCompleteFBOFails) {
6625   GLenum target = GL_TEXTURE_2D;
6626   GLint level = 0;
6627   GLenum internal_format = GL_RGBA;
6628   GLsizei width = 2;
6629   GLsizei height = 4;
6630   GLint border = 0;
6631   SetupTexture();
6632   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6633                     kServiceRenderbufferId);
6634   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6635                     kServiceFramebufferId);
6636   DoRenderbufferStorage(
6637       GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 0, 0, GL_NO_ERROR);
6638   DoFramebufferRenderbuffer(
6639       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
6640       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6641
6642   EXPECT_CALL(*gl_, CopyTexImage2D(_, _, _, _, _, _, _, _))
6643       .Times(0)
6644       .RetiresOnSaturation();
6645   CopyTexImage2D cmd;
6646   cmd.Init(target, level, internal_format, 0, 0, width, height, border);
6647   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6648   EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
6649 }
6650
6651 void GLES2DecoderWithShaderTest::CheckRenderbufferChangesMarkFBOAsNotComplete(
6652     bool bound_fbo) {
6653   FramebufferManager* framebuffer_manager = group().framebuffer_manager();
6654   SetupTexture();
6655   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6656                     kServiceRenderbufferId);
6657   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6658                     kServiceFramebufferId);
6659   DoRenderbufferStorage(
6660       GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
6661   DoFramebufferRenderbuffer(
6662       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
6663       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6664
6665
6666   if (!bound_fbo) {
6667     DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
6668   }
6669
6670   Framebuffer* framebuffer =
6671       framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
6672   ASSERT_TRUE(framebuffer != NULL);
6673   framebuffer_manager->MarkAsComplete(framebuffer);
6674   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6675
6676   // Test that renderbufferStorage marks fbo as not complete.
6677   DoRenderbufferStorage(
6678       GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
6679   EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6680   framebuffer_manager->MarkAsComplete(framebuffer);
6681   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6682
6683   // Test deleting renderbuffer marks fbo as not complete.
6684   DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
6685   if (bound_fbo) {
6686     EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6687   } else {
6688     EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6689   }
6690 }
6691
6692 TEST_F(GLES2DecoderWithShaderTest,
6693        RenderbufferChangesMarkFBOAsNotCompleteBoundFBO) {
6694   CheckRenderbufferChangesMarkFBOAsNotComplete(true);
6695 }
6696
6697 TEST_F(GLES2DecoderWithShaderTest,
6698        RenderbufferChangesMarkFBOAsNotCompleteUnboundFBO) {
6699   CheckRenderbufferChangesMarkFBOAsNotComplete(false);
6700 }
6701
6702 void GLES2DecoderWithShaderTest::CheckTextureChangesMarkFBOAsNotComplete(
6703     bool bound_fbo) {
6704   FramebufferManager* framebuffer_manager = group().framebuffer_manager();
6705   const GLuint kFBOClientTextureId = 4100;
6706   const GLuint kFBOServiceTextureId = 4101;
6707
6708   // Register a texture id.
6709   EXPECT_CALL(*gl_, GenTextures(_, _))
6710       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6711       .RetiresOnSaturation();
6712   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6713
6714   SetupTexture();
6715
6716   // Setup "render to" texture.
6717   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6718   DoTexImage2D(
6719       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
6720   DoBindFramebuffer(
6721       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6722   DoFramebufferTexture2D(
6723       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6724       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6725
6726   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
6727                     kServiceRenderbufferId);
6728   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
6729                     kServiceFramebufferId);
6730   DoRenderbufferStorage(
6731       GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT,
6732       1, 1, GL_NO_ERROR);
6733   DoFramebufferRenderbuffer(
6734       GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
6735       client_renderbuffer_id_, kServiceRenderbufferId, GL_NO_ERROR);
6736
6737   if (!bound_fbo) {
6738     DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
6739   }
6740
6741   Framebuffer* framebuffer =
6742       framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
6743   ASSERT_TRUE(framebuffer != NULL);
6744   framebuffer_manager->MarkAsComplete(framebuffer);
6745   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6746
6747   // Test TexImage2D marks fbo as not complete.
6748   DoTexImage2D(
6749       GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, 0, 0);
6750   EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6751   framebuffer_manager->MarkAsComplete(framebuffer);
6752   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6753
6754   // Test CopyImage2D marks fbo as not complete.
6755   EXPECT_CALL(*gl_, GetError())
6756       .WillOnce(Return(GL_NO_ERROR))
6757       .RetiresOnSaturation();
6758   EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0))
6759       .Times(1)
6760       .RetiresOnSaturation();
6761   EXPECT_CALL(*gl_, GetError())
6762       .WillOnce(Return(GL_NO_ERROR))
6763       .RetiresOnSaturation();
6764   CopyTexImage2D cmd;
6765   cmd.Init(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0);
6766   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6767   EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6768
6769   // Test deleting texture marks fbo as not complete.
6770   framebuffer_manager->MarkAsComplete(framebuffer);
6771   EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6772   DoDeleteTexture(kFBOClientTextureId, kFBOServiceTextureId);
6773
6774   if (bound_fbo) {
6775     EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
6776   } else {
6777     EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
6778   }
6779 }
6780
6781 TEST_F(GLES2DecoderWithShaderTest, TextureChangesMarkFBOAsNotCompleteBoundFBO) {
6782   CheckTextureChangesMarkFBOAsNotComplete(true);
6783 }
6784
6785 TEST_F(GLES2DecoderWithShaderTest,
6786        TextureChangesMarkFBOAsNotCompleteUnboundFBO) {
6787   CheckTextureChangesMarkFBOAsNotComplete(false);
6788 }
6789
6790 TEST_F(GLES2DecoderWithShaderTest,
6791        DrawingWithFBOTwiceChecksForFBOCompleteOnce) {
6792   const GLuint kFBOClientTextureId = 4100;
6793   const GLuint kFBOServiceTextureId = 4101;
6794
6795   SetupAllNeededVertexBuffers();
6796
6797   // Register a texture id.
6798   EXPECT_CALL(*gl_, GenTextures(_, _))
6799       .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
6800       .RetiresOnSaturation();
6801   GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
6802
6803   // Setup "render to" texture that is cleared.
6804   DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
6805   DoTexImage2D(
6806       GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6807       kSharedMemoryId, kSharedMemoryOffset);
6808   DoBindFramebuffer(
6809       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
6810   DoFramebufferTexture2D(
6811       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
6812       kFBOClientTextureId, kFBOServiceTextureId, 0, GL_NO_ERROR);
6813
6814   // Setup "render from" texture.
6815   SetupTexture();
6816
6817   // Make sure we check for framebuffer complete.
6818   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
6819       .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
6820       .RetiresOnSaturation();
6821
6822   SetupExpectationsForApplyingDirtyState(
6823       false,   // Framebuffer is RGB
6824       false,   // Framebuffer has depth
6825       false,   // Framebuffer has stencil
6826       0x1111,  // color bits
6827       false,   // depth mask
6828       false,   // depth enabled
6829       0,       // front stencil mask
6830       0,       // back stencil mask
6831       false,   // stencil enabled
6832       false,   // cull_face_enabled
6833       false,   // scissor_test_enabled
6834       false);  // blend_enabled
6835
6836   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6837       .Times(1)
6838       .RetiresOnSaturation();
6839   DrawArrays cmd;
6840   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
6841   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6842   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6843
6844   // But not again.
6845   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
6846       .Times(1)
6847       .RetiresOnSaturation();
6848   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
6849   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6850 }
6851
6852 TEST_F(GLES2DecoderTest, BeginQueryEXTDisabled) {
6853   // Test something fails if off.
6854 }
6855
6856 TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
6857   InitDecoder(
6858       "GL_EXT_occlusion_query_boolean",      // extensions
6859       "opengl es 2.0",   // gl version
6860       true,    // has alpha
6861       false,   // has depth
6862       false,   // has stencil
6863       true,    // request alpha
6864       false,   // request depth
6865       false,   // request stencil
6866       true);   // bind generates resource
6867
6868   // Test end fails if no begin.
6869   EndQueryEXT end_cmd;
6870   end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
6871   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
6872   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
6873
6874   BeginQueryEXT begin_cmd;
6875
6876   // Test id = 0 fails.
6877   begin_cmd.Init(
6878       GL_ANY_SAMPLES_PASSED_EXT, 0, kSharedMemoryId, kSharedMemoryOffset);
6879   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
6880   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
6881
6882   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
6883
6884   // Test valid parameters work.
6885   EXPECT_CALL(*gl_, GenQueriesARB(1, _))
6886      .WillOnce(SetArgumentPointee<1>(kNewServiceId))
6887      .RetiresOnSaturation();
6888   EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
6889       .Times(1)
6890       .RetiresOnSaturation();
6891   begin_cmd.Init(
6892       GL_ANY_SAMPLES_PASSED_EXT, kNewClientId,
6893       kSharedMemoryId, kSharedMemoryOffset);
6894   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
6895   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6896
6897   QueryManager* query_manager = decoder_->GetQueryManager();
6898   ASSERT_TRUE(query_manager != NULL);
6899   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
6900   ASSERT_TRUE(query != NULL);
6901   EXPECT_FALSE(query->pending());
6902
6903   // Test trying begin again fails
6904   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
6905   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
6906
6907   // Test end fails with different target
6908   end_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1);
6909   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
6910   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
6911
6912   // Test end succeeds
6913   EXPECT_CALL(*gl_, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT))
6914       .Times(1)
6915       .RetiresOnSaturation();
6916   end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
6917   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
6918   EXPECT_EQ(GL_NO_ERROR, GetGLError());
6919   EXPECT_TRUE(query->pending());
6920
6921   EXPECT_CALL(*gl_, DeleteQueriesARB(1, _))
6922       .Times(1)
6923       .RetiresOnSaturation();
6924 }
6925
6926 static void CheckBeginEndQueryBadMemoryFails(
6927     GLES2DecoderTestBase* test,
6928     GLuint client_id,
6929     GLuint service_id,
6930     int32 shm_id,
6931     uint32 shm_offset) {
6932   ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
6933
6934   BeginQueryEXT begin_cmd;
6935
6936   test->GenHelper<GenQueriesEXTImmediate>(client_id);
6937
6938   EXPECT_CALL(*gl, GenQueriesARB(1, _))
6939      .WillOnce(SetArgumentPointee<1>(service_id))
6940      .RetiresOnSaturation();
6941   EXPECT_CALL(*gl, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, service_id))
6942       .Times(1)
6943       .RetiresOnSaturation();
6944
6945   // Test bad shared memory fails
6946   begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, client_id, shm_id, shm_offset);
6947   error::Error error1 = test->ExecuteCmd(begin_cmd);
6948
6949   EXPECT_CALL(*gl, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT))
6950       .Times(1)
6951       .RetiresOnSaturation();
6952
6953   EndQueryEXT end_cmd;
6954   end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
6955   error::Error error2 = test->ExecuteCmd(end_cmd);
6956
6957   EXPECT_CALL(*gl,
6958       GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
6959       .WillOnce(SetArgumentPointee<2>(1))
6960       .RetiresOnSaturation();
6961   EXPECT_CALL(*gl,
6962       GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _))
6963       .WillOnce(SetArgumentPointee<2>(1))
6964       .RetiresOnSaturation();
6965
6966   QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
6967   ASSERT_TRUE(query_manager != NULL);
6968   bool process_success = query_manager->ProcessPendingQueries();
6969
6970   EXPECT_TRUE(error1 != error::kNoError ||
6971               error2 != error::kNoError ||
6972               !process_success);
6973
6974   EXPECT_CALL(*gl, DeleteQueriesARB(1, _))
6975       .Times(1)
6976       .RetiresOnSaturation();
6977 }
6978
6979 TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
6980   InitDecoder(
6981       "GL_EXT_occlusion_query_boolean",      // extensions
6982       "opengl es 2.0",   // gl version
6983       true,    // has alpha
6984       false,   // has depth
6985       false,   // has stencil
6986       true,    // request alpha
6987       false,   // request depth
6988       false,   // request stencil
6989       true);   // bind generates resource
6990
6991   CheckBeginEndQueryBadMemoryFails(
6992       this, kNewClientId, kNewServiceId,
6993       kInvalidSharedMemoryId, kSharedMemoryOffset);
6994 }
6995
6996 TEST_F(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
6997   InitDecoder(
6998       "GL_EXT_occlusion_query_boolean",      // extensions
6999       "opengl es 2.0",   // gl version
7000       true,    // has alpha
7001       false,   // has depth
7002       false,   // has stencil
7003       true,    // request alpha
7004       false,   // request depth
7005       false,   // request stencil
7006       true);   // bind generates resource
7007
7008   CheckBeginEndQueryBadMemoryFails(
7009       this, kNewClientId, kNewServiceId,
7010       kSharedMemoryId, kInvalidSharedMemoryOffset);
7011 }
7012
7013 TEST_F(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
7014   BeginQueryEXT begin_cmd;
7015
7016   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
7017
7018   // Test valid parameters work.
7019   begin_cmd.Init(
7020       GL_COMMANDS_ISSUED_CHROMIUM, kNewClientId,
7021       kSharedMemoryId, kSharedMemoryOffset);
7022   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
7023   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7024
7025   QueryManager* query_manager = decoder_->GetQueryManager();
7026   ASSERT_TRUE(query_manager != NULL);
7027   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
7028   ASSERT_TRUE(query != NULL);
7029   EXPECT_FALSE(query->pending());
7030
7031   // Test end succeeds
7032   EndQueryEXT end_cmd;
7033   end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1);
7034   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
7035   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7036   EXPECT_FALSE(query->pending());
7037 }
7038
7039 TEST_F(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
7040   BeginQueryEXT begin_cmd;
7041
7042   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
7043
7044   // Test valid parameters work.
7045   begin_cmd.Init(
7046       GL_GET_ERROR_QUERY_CHROMIUM, kNewClientId,
7047       kSharedMemoryId, kSharedMemoryOffset);
7048   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
7049   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7050
7051   QueryManager* query_manager = decoder_->GetQueryManager();
7052   ASSERT_TRUE(query_manager != NULL);
7053   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
7054   ASSERT_TRUE(query != NULL);
7055   EXPECT_FALSE(query->pending());
7056
7057   // Test end succeeds
7058   QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
7059
7060   EXPECT_CALL(*gl_, GetError())
7061       .WillOnce(Return(GL_INVALID_VALUE))
7062       .RetiresOnSaturation();
7063
7064   EndQueryEXT end_cmd;
7065   end_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 1);
7066   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
7067   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7068   EXPECT_FALSE(query->pending());
7069   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE),
7070             static_cast<GLenum>(sync->result));
7071 }
7072
7073 TEST_F(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) {
7074   Mailbox mailbox = Mailbox::Generate();
7075
7076   memcpy(shared_memory_address_, mailbox.name, sizeof(mailbox.name));
7077
7078   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7079   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7080                0, 0);
7081   DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7082                0, 0);
7083   TextureRef* texture_ref = group().texture_manager()->GetTexture(
7084       client_texture_id_);
7085   ASSERT_TRUE(texture_ref != NULL);
7086   Texture* texture = texture_ref->texture();
7087   EXPECT_EQ(kServiceTextureId, texture->service_id());
7088
7089   ProduceTextureCHROMIUM produce_cmd;
7090   produce_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
7091   EXPECT_EQ(error::kNoError, ExecuteCmd(produce_cmd));
7092   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7093
7094   // Texture didn't change.
7095   GLsizei width;
7096   GLsizei height;
7097   GLenum type;
7098   GLenum internal_format;
7099
7100   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7101   EXPECT_EQ(3, width);
7102   EXPECT_EQ(1, height);
7103   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7104   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7105   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7106
7107   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
7108   EXPECT_EQ(2, width);
7109   EXPECT_EQ(4, height);
7110   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
7111   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7112   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7113
7114   // Service ID has not changed.
7115   EXPECT_EQ(kServiceTextureId, texture->service_id());
7116
7117   // Create new texture for consume.
7118   EXPECT_CALL(*gl_, GenTextures(_, _))
7119       .WillOnce(SetArgumentPointee<1>(kNewServiceId))
7120       .RetiresOnSaturation();
7121   DoBindTexture(GL_TEXTURE_2D, kNewClientId, kNewServiceId);
7122
7123   // Assigns and binds original service size texture ID.
7124   EXPECT_CALL(*gl_, DeleteTextures(1, _))
7125       .Times(1)
7126       .RetiresOnSaturation();
7127   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
7128       .Times(1)
7129       .RetiresOnSaturation();
7130
7131   memcpy(shared_memory_address_, mailbox.name, sizeof(mailbox.name));
7132   ConsumeTextureCHROMIUM consume_cmd;
7133   consume_cmd.Init(GL_TEXTURE_2D, kSharedMemoryId, kSharedMemoryOffset);
7134   EXPECT_EQ(error::kNoError, ExecuteCmd(consume_cmd));
7135   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7136
7137   // Texture is redefined.
7138   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7139   EXPECT_EQ(3, width);
7140   EXPECT_EQ(1, height);
7141   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7142   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7143   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7144
7145   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
7146   EXPECT_EQ(2, width);
7147   EXPECT_EQ(4, height);
7148   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format));
7149   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7150   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7151
7152   // Service ID is restored.
7153   EXPECT_EQ(kServiceTextureId, texture->service_id());
7154 }
7155
7156
7157 TEST_F(GLES2DecoderTest, CanChangeSurface) {
7158   scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock);
7159   EXPECT_CALL(*other_surface.get(), GetBackingFrameBufferObject()).
7160       WillOnce(Return(7));
7161   EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 7));
7162
7163   decoder_->SetSurface(other_surface);
7164 }
7165
7166 TEST_F(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
7167   // NOTE: There are no expectations because no GL functions should be
7168   // called for DEPTH_TEST or STENCIL_TEST
7169   static const GLenum kStates[] = {
7170     GL_DEPTH_TEST,
7171     GL_STENCIL_TEST,
7172   };
7173   for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
7174     Enable enable_cmd;
7175     GLenum state = kStates[ii];
7176     enable_cmd.Init(state);
7177     EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
7178     IsEnabled::Result* result =
7179         static_cast<IsEnabled::Result*>(shared_memory_address_);
7180     IsEnabled is_enabled_cmd;
7181     is_enabled_cmd.Init(state, shared_memory_id_, shared_memory_offset_);
7182     EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
7183     EXPECT_NE(0u, *result);
7184     Disable disable_cmd;
7185     disable_cmd.Init(state);
7186     EXPECT_EQ(error::kNoError, ExecuteCmd(disable_cmd));
7187     EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
7188     EXPECT_EQ(0u, *result);
7189   }
7190 }
7191
7192 TEST_F(GLES2DecoderManualInitTest, DepthTextureBadArgs) {
7193   InitDecoder(
7194       "GL_ANGLE_depth_texture",      // extensions
7195       "opengl es 2.0",   // gl version
7196       false,   // has alpha
7197       true,    // has depth
7198       true,    // has stencil
7199       false,   // request alpha
7200       true,    // request depth
7201       true,    // request stencil
7202       true);   // bind generates resource
7203
7204   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7205   // Check trying to upload data fails.
7206   TexImage2D tex_cmd;
7207   tex_cmd.Init(
7208       GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
7209       1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
7210       kSharedMemoryId, kSharedMemoryOffset);
7211   EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
7212   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7213   // Try level > 0.
7214   tex_cmd.Init(
7215       GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT,
7216       1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 0);
7217   EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd));
7218   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7219   // Make a 1 pixel depth texture.
7220   DoTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
7221                1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 0);
7222   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7223
7224   // Check that trying to update it fails.
7225   TexSubImage2D tex_sub_cmd;
7226   tex_sub_cmd.Init(
7227       GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
7228       kSharedMemoryId, kSharedMemoryOffset, GL_FALSE);
7229   EXPECT_EQ(error::kNoError, ExecuteCmd(tex_sub_cmd));
7230   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7231
7232   // Check that trying to CopyTexImage2D fails
7233   CopyTexImage2D copy_tex_cmd;
7234   copy_tex_cmd.Init(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 1, 1, 0);
7235   EXPECT_EQ(error::kNoError, ExecuteCmd(copy_tex_cmd));
7236   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7237
7238   // Check that trying to CopyTexSubImage2D fails
7239   CopyTexSubImage2D copy_sub_cmd;
7240   copy_sub_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
7241   EXPECT_EQ(error::kNoError, ExecuteCmd(copy_sub_cmd));
7242   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7243 }
7244
7245 TEST_F(GLES2DecoderManualInitTest, GenerateMipmapDepthTexture) {
7246   InitDecoder(
7247       "GL_ANGLE_depth_texture",      // extensions
7248       "opengl es 2.0",   // gl version
7249       false,   // has alpha
7250       true,    // has depth
7251       true,    // has stencil
7252       false,   // request alpha
7253       true,    // request depth
7254       true,    // request stencil
7255       true);   // bind generates resource
7256   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7257   DoTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
7258                2, 2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
7259                0, 0);
7260   GenerateMipmap cmd;
7261   cmd.Init(GL_TEXTURE_2D);
7262   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7263   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7264 }
7265
7266 TEST_F(GLES2DecoderManualInitTest, DrawClearsDepthTexture) {
7267   InitDecoder(
7268       "GL_ANGLE_depth_texture",      // extensions
7269       "opengl es 2.0",   // gl version
7270       true,    // has alpha
7271       true,    // has depth
7272       false,   // has stencil
7273       true,    // request alpha
7274       true,    // request depth
7275       false,   // request stencil
7276       true);   // bind generates resource
7277
7278   SetupDefaultProgram();
7279   SetupAllNeededVertexBuffers();
7280   const GLenum attachment = GL_DEPTH_ATTACHMENT;
7281   const GLenum target = GL_TEXTURE_2D;
7282   const GLint level = 0;
7283   DoBindTexture(target, client_texture_id_, kServiceTextureId);
7284
7285   // Create a depth texture.
7286   DoTexImage2D(target, level, GL_DEPTH_COMPONENT, 1, 1, 0,
7287                GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0, 0);
7288
7289   EXPECT_CALL(*gl_, GenFramebuffersEXT(1, _))
7290       .Times(1)
7291       .RetiresOnSaturation();
7292   EXPECT_CALL(*gl_, BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, _))
7293       .Times(1)
7294       .RetiresOnSaturation();
7295
7296   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
7297       GL_DRAW_FRAMEBUFFER_EXT, attachment, target, kServiceTextureId, level))
7298       .Times(1)
7299       .RetiresOnSaturation();
7300   EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT))
7301       .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
7302       .RetiresOnSaturation();
7303
7304   EXPECT_CALL(*gl_, ClearStencil(0))
7305       .Times(1)
7306       .RetiresOnSaturation();
7307   EXPECT_CALL(*gl_, StencilMask(-1))
7308       .Times(1)
7309       .RetiresOnSaturation();
7310   EXPECT_CALL(*gl_, ClearDepth(1.0f))
7311       .Times(1)
7312       .RetiresOnSaturation();
7313   EXPECT_CALL(*gl_, DepthMask(true))
7314       .Times(1)
7315       .RetiresOnSaturation();
7316   EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST))
7317       .Times(1)
7318       .RetiresOnSaturation();
7319
7320   EXPECT_CALL(*gl_, Clear(GL_DEPTH_BUFFER_BIT))
7321       .Times(1)
7322       .RetiresOnSaturation();
7323
7324   SetupExpectationsForRestoreClearState(
7325       0.0f, 0.0f, 0.0f, 0.0f, 0, 1.0f, false);
7326
7327   EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, _))
7328       .Times(1)
7329       .RetiresOnSaturation();
7330   EXPECT_CALL(*gl_, BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0))
7331       .Times(1)
7332       .RetiresOnSaturation();
7333
7334   SetupExpectationsForApplyingDefaultDirtyState();
7335   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
7336       .Times(1)
7337       .RetiresOnSaturation();
7338   DrawArrays cmd;
7339   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
7340   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7341   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7342 }
7343
7344 TEST_F(GLES2DecoderWithShaderTest, BindUniformLocationCHROMIUM) {
7345   const GLint kLocation = 2;
7346   const char* kName = "testing";
7347   const uint32 kNameSize = strlen(kName);
7348   const char* kBadName1 = "gl_testing";
7349   const uint32 kBadName1Size = strlen(kBadName1);
7350   const char* kBadName2 = "testing[1]";
7351   const uint32 kBadName2Size = strlen(kBadName2);
7352   memcpy(shared_memory_address_, kName, kNameSize);
7353   BindUniformLocationCHROMIUM cmd;
7354   cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
7355            kNameSize);
7356   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7357   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7358   // check negative location
7359   memcpy(shared_memory_address_, kName, kNameSize);
7360   cmd.Init(client_program_id_, -1, kSharedMemoryId, kSharedMemoryOffset,
7361            kNameSize);
7362   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7363   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
7364   // check highest location
7365   memcpy(shared_memory_address_, kName, kNameSize);
7366   GLint kMaxLocation =
7367       (kMaxFragmentUniformVectors + kMaxVertexUniformVectors) * 4 - 1;
7368   cmd.Init(client_program_id_, kMaxLocation, kSharedMemoryId,
7369            kSharedMemoryOffset, kNameSize);
7370   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7371   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7372   // check too high location
7373   memcpy(shared_memory_address_, kName, kNameSize);
7374   cmd.Init(client_program_id_, kMaxLocation + 1, kSharedMemoryId,
7375            kSharedMemoryOffset, kNameSize);
7376   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7377   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
7378   // check bad name "gl_..."
7379   memcpy(shared_memory_address_, kBadName1, kBadName1Size);
7380   cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
7381            kBadName1Size);
7382   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7383   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7384   // check bad name "name[1]" non zero
7385   memcpy(shared_memory_address_, kBadName2, kBadName2Size);
7386   cmd.Init(client_program_id_, kLocation, kSharedMemoryId, kSharedMemoryOffset,
7387            kBadName2Size);
7388   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7389   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
7390 }
7391
7392 class GLES2DecoderVertexArraysOESTest : public GLES2DecoderWithShaderTest {
7393  public:
7394   GLES2DecoderVertexArraysOESTest() { }
7395
7396   bool vertex_array_deleted_manually_;
7397
7398   virtual void SetUp() {
7399     InitDecoder(
7400         "GL_OES_vertex_array_object",  // extensions
7401         "opengl es 2.0",   // gl version
7402         false,  // has alpha
7403         false,  // has depth
7404         false,  // has stencil
7405         false,  // request alpha
7406         false,  // request depth
7407         false,  // request stencil
7408         true);  // bind generates resource
7409     SetupDefaultProgram();
7410
7411     AddExpectationsForGenVertexArraysOES();
7412     GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
7413
7414     vertex_array_deleted_manually_ = false;
7415   }
7416
7417   virtual void TearDown() {
7418     // This should only be set if the test handled deletion of the vertex array
7419     // itself. Necessary because vertex_array_objects are not sharable, and thus
7420     // not managed in the ContextGroup, meaning they will be destroyed during
7421     // test tear down
7422     if (!vertex_array_deleted_manually_) {
7423       AddExpectationsForDeleteVertexArraysOES();
7424     }
7425
7426     GLES2DecoderWithShaderTest::TearDown();
7427   }
7428
7429   void GenVertexArraysOESValidArgs() {
7430     AddExpectationsForGenVertexArraysOES();
7431     GetSharedMemoryAs<GLuint*>()[0] = kNewClientId;
7432     GenVertexArraysOES cmd;
7433     cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7434     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7435     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7436     EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
7437     AddExpectationsForDeleteVertexArraysOES();
7438   }
7439
7440   void GenVertexArraysOESInvalidArgs() {
7441     EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
7442     GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
7443     GenVertexArraysOES cmd;
7444     cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7445     EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
7446   }
7447
7448   void GenVertexArraysOESImmediateValidArgs() {
7449     AddExpectationsForGenVertexArraysOES();
7450     GenVertexArraysOESImmediate* cmd =
7451         GetImmediateAs<GenVertexArraysOESImmediate>();
7452     GLuint temp = kNewClientId;
7453     cmd->Init(1, &temp);
7454     EXPECT_EQ(error::kNoError,
7455               ExecuteImmediateCmd(*cmd, sizeof(temp)));
7456     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7457     EXPECT_TRUE(GetVertexArrayInfo(kNewClientId) != NULL);
7458     AddExpectationsForDeleteVertexArraysOES();
7459   }
7460
7461   void GenVertexArraysOESImmediateInvalidArgs() {
7462     EXPECT_CALL(*gl_, GenVertexArraysOES(_, _)).Times(0);
7463     GenVertexArraysOESImmediate* cmd =
7464         GetImmediateAs<GenVertexArraysOESImmediate>();
7465     cmd->Init(1, &client_vertexarray_id_);
7466     EXPECT_EQ(error::kInvalidArguments,
7467               ExecuteImmediateCmd(*cmd, sizeof(&client_vertexarray_id_)));
7468   }
7469
7470   void DeleteVertexArraysOESValidArgs() {
7471     AddExpectationsForDeleteVertexArraysOES();
7472     GetSharedMemoryAs<GLuint*>()[0] = client_vertexarray_id_;
7473     DeleteVertexArraysOES cmd;
7474     cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7475     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7476     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7477     EXPECT_TRUE(
7478         GetVertexArrayInfo(client_vertexarray_id_) == NULL);
7479     vertex_array_deleted_manually_ = true;
7480   }
7481
7482   void DeleteVertexArraysOESInvalidArgs() {
7483     GetSharedMemoryAs<GLuint*>()[0] = kInvalidClientId;
7484     DeleteVertexArraysOES cmd;
7485     cmd.Init(1, shared_memory_id_, shared_memory_offset_);
7486     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7487   }
7488
7489   void DeleteVertexArraysOESImmediateValidArgs() {
7490     AddExpectationsForDeleteVertexArraysOES();
7491     DeleteVertexArraysOESImmediate& cmd =
7492         *GetImmediateAs<DeleteVertexArraysOESImmediate>();
7493     cmd.Init(1, &client_vertexarray_id_);
7494     EXPECT_EQ(error::kNoError,
7495               ExecuteImmediateCmd(cmd, sizeof(client_vertexarray_id_)));
7496     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7497     EXPECT_TRUE(
7498         GetVertexArrayInfo(client_vertexarray_id_) == NULL);
7499     vertex_array_deleted_manually_ = true;
7500   }
7501
7502   void DeleteVertexArraysOESImmediateInvalidArgs() {
7503     DeleteVertexArraysOESImmediate& cmd =
7504         *GetImmediateAs<DeleteVertexArraysOESImmediate>();
7505     GLuint temp = kInvalidClientId;
7506     cmd.Init(1, &temp);
7507     EXPECT_EQ(error::kNoError,
7508               ExecuteImmediateCmd(cmd, sizeof(temp)));
7509   }
7510
7511   void IsVertexArrayOESValidArgs() {
7512     IsVertexArrayOES cmd;
7513     cmd.Init(client_vertexarray_id_, shared_memory_id_, shared_memory_offset_);
7514     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7515     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7516   }
7517
7518   void IsVertexArrayOESInvalidArgsBadSharedMemoryId() {
7519     IsVertexArrayOES cmd;
7520     cmd.Init(
7521         client_vertexarray_id_, kInvalidSharedMemoryId, shared_memory_offset_);
7522     EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
7523     cmd.Init(
7524         client_vertexarray_id_, shared_memory_id_, kInvalidSharedMemoryOffset);
7525     EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
7526   }
7527
7528   void BindVertexArrayOESValidArgs() {
7529     AddExpectationsForBindVertexArrayOES();
7530     BindVertexArrayOES cmd;
7531     cmd.Init(client_vertexarray_id_);
7532     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7533     EXPECT_EQ(GL_NO_ERROR, GetGLError());
7534   }
7535
7536   void BindVertexArrayOESValidArgsNewId() {
7537     BindVertexArrayOES cmd;
7538     cmd.Init(kNewClientId);
7539     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7540     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
7541   }
7542 };
7543
7544 class GLES2DecoderEmulatedVertexArraysOESTest
7545     : public GLES2DecoderVertexArraysOESTest {
7546  public:
7547   GLES2DecoderEmulatedVertexArraysOESTest() { }
7548
7549   virtual void SetUp() {
7550     InitDecoder(
7551         "",     // extensions
7552         "3.0",  // gl version
7553         false,  // has alpha
7554         false,  // has depth
7555         false,  // has stencil
7556         false,  // request alpha
7557         false,  // request depth
7558         false,  // request stencil
7559         true);  // bind generates resource
7560     SetupDefaultProgram();
7561
7562     AddExpectationsForGenVertexArraysOES();
7563     GenHelper<GenVertexArraysOESImmediate>(client_vertexarray_id_);
7564
7565     vertex_array_deleted_manually_ = false;
7566   }
7567 };
7568
7569 // Test vertex array objects with native support
7570 TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESValidArgs) {
7571   GenVertexArraysOESValidArgs();
7572 }
7573 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, GenVertexArraysOESValidArgs) {
7574   GenVertexArraysOESValidArgs();
7575 }
7576
7577 TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESInvalidArgs) {
7578   GenVertexArraysOESInvalidArgs();
7579 }
7580 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, ) {
7581   GenVertexArraysOESInvalidArgs();
7582 }
7583
7584 TEST_F(GLES2DecoderVertexArraysOESTest, GenVertexArraysOESImmediateValidArgs) {
7585   GenVertexArraysOESImmediateValidArgs();
7586 }
7587 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7588     GenVertexArraysOESImmediateValidArgs) {
7589   GenVertexArraysOESImmediateValidArgs();
7590 }
7591
7592 TEST_F(GLES2DecoderVertexArraysOESTest,
7593     GenVertexArraysOESImmediateInvalidArgs) {
7594   GenVertexArraysOESImmediateInvalidArgs();
7595 }
7596 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7597     GenVertexArraysOESImmediateInvalidArgs) {
7598   GenVertexArraysOESImmediateInvalidArgs();
7599 }
7600
7601 TEST_F(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESValidArgs) {
7602   DeleteVertexArraysOESValidArgs();
7603 }
7604 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7605     DeleteVertexArraysOESValidArgs) {
7606   DeleteVertexArraysOESValidArgs();
7607 }
7608
7609 TEST_F(GLES2DecoderVertexArraysOESTest, DeleteVertexArraysOESInvalidArgs) {
7610   DeleteVertexArraysOESInvalidArgs();
7611 }
7612 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7613     DeleteVertexArraysOESInvalidArgs) {
7614   DeleteVertexArraysOESInvalidArgs();
7615 }
7616
7617 TEST_F(GLES2DecoderVertexArraysOESTest,
7618     DeleteVertexArraysOESImmediateValidArgs) {
7619   DeleteVertexArraysOESImmediateValidArgs();
7620 }
7621 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7622     DeleteVertexArraysOESImmediateValidArgs) {
7623   DeleteVertexArraysOESImmediateValidArgs();
7624 }
7625
7626 TEST_F(GLES2DecoderVertexArraysOESTest,
7627     DeleteVertexArraysOESImmediateInvalidArgs) {
7628   DeleteVertexArraysOESImmediateInvalidArgs();
7629 }
7630 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7631     DeleteVertexArraysOESImmediateInvalidArgs) {
7632   DeleteVertexArraysOESImmediateInvalidArgs();
7633 }
7634
7635 TEST_F(GLES2DecoderVertexArraysOESTest, IsVertexArrayOESValidArgs) {
7636   IsVertexArrayOESValidArgs();
7637 }
7638 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, IsVertexArrayOESValidArgs) {
7639   IsVertexArrayOESValidArgs();
7640 }
7641
7642 TEST_F(GLES2DecoderVertexArraysOESTest,
7643     IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
7644   IsVertexArrayOESInvalidArgsBadSharedMemoryId();
7645 }
7646 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7647     IsVertexArrayOESInvalidArgsBadSharedMemoryId) {
7648   IsVertexArrayOESInvalidArgsBadSharedMemoryId();
7649 }
7650
7651 TEST_F(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgs) {
7652   BindVertexArrayOESValidArgs();
7653 }
7654 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest, BindVertexArrayOESValidArgs) {
7655   BindVertexArrayOESValidArgs();
7656 }
7657
7658 TEST_F(GLES2DecoderVertexArraysOESTest, BindVertexArrayOESValidArgsNewId) {
7659   BindVertexArrayOESValidArgsNewId();
7660 }
7661 TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
7662     BindVertexArrayOESValidArgsNewId) {
7663   BindVertexArrayOESValidArgsNewId();
7664 }
7665
7666 TEST_F(GLES2DecoderTest, BindTexImage2DCHROMIUM) {
7667   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7668   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7669                0, 0);
7670   TextureRef* texture_ref = group().texture_manager()->GetTexture(
7671       client_texture_id_);
7672   ASSERT_TRUE(texture_ref != NULL);
7673   Texture* texture = texture_ref->texture();
7674   EXPECT_EQ(kServiceTextureId, texture->service_id());
7675
7676   group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
7677   EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
7678
7679   GLsizei width;
7680   GLsizei height;
7681   GLenum type;
7682   GLenum internal_format;
7683
7684   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7685   EXPECT_EQ(3, width);
7686   EXPECT_EQ(1, height);
7687   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7688   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7689   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7690   EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7691
7692   // Bind image to texture.
7693   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7694   EXPECT_CALL(*gl_, GetError())
7695       .WillOnce(Return(GL_NO_ERROR))
7696       .WillOnce(Return(GL_NO_ERROR))
7697       .RetiresOnSaturation();
7698   BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
7699   bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
7700   EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
7701   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7702   // Image should now be set.
7703   EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7704
7705   // Define new texture image.
7706   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7707                0, 0);
7708   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7709   // Image should no longer be set.
7710   EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7711 }
7712
7713 TEST_F(GLES2DecoderTest, BindTexImage2DCHROMIUMCubeMapNotAllowed) {
7714   group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
7715   DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId);
7716
7717   BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
7718   bind_tex_image_2d_cmd.Init(GL_TEXTURE_CUBE_MAP, 1);
7719   EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
7720   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
7721 }
7722
7723 TEST_F(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) {
7724   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7725   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7726                0, 0);
7727   TextureRef* texture_ref = group().texture_manager()->GetTexture(
7728       client_texture_id_);
7729   ASSERT_TRUE(texture_ref != NULL);
7730   Texture* texture = texture_ref->texture();
7731   EXPECT_EQ(kServiceTextureId, texture->service_id());
7732
7733   group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0).get(), 1);
7734   EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
7735
7736   GLsizei width;
7737   GLsizei height;
7738   GLenum type;
7739   GLenum internal_format;
7740
7741   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7742   EXPECT_EQ(3, width);
7743   EXPECT_EQ(1, height);
7744   EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
7745   EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
7746   EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
7747   EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7748
7749   // Bind image to texture.
7750   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7751   EXPECT_CALL(*gl_, GetError())
7752       .WillOnce(Return(GL_NO_ERROR))
7753       .WillOnce(Return(GL_NO_ERROR))
7754       .RetiresOnSaturation();
7755   BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
7756   bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
7757   EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
7758   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7759   // Image should now be set.
7760   EXPECT_FALSE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7761
7762   // Release image from texture.
7763   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7764   EXPECT_CALL(*gl_, GetError())
7765       .WillOnce(Return(GL_NO_ERROR))
7766       .WillOnce(Return(GL_NO_ERROR))
7767       .RetiresOnSaturation();
7768   ReleaseTexImage2DCHROMIUM release_tex_image_2d_cmd;
7769   release_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
7770   EXPECT_EQ(error::kNoError, ExecuteCmd(release_tex_image_2d_cmd));
7771   EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
7772   // Image should no longer be set.
7773   EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
7774 }
7775
7776 class MockGLImage : public gfx::GLImage {
7777  public:
7778   MockGLImage() {}
7779
7780   // Overridden from gfx::GLImage:
7781   MOCK_METHOD0(Destroy, void());
7782   MOCK_METHOD0(GetSize, gfx::Size());
7783   MOCK_METHOD1(BindTexImage, bool(unsigned));
7784   MOCK_METHOD1(ReleaseTexImage, void(unsigned));
7785   MOCK_METHOD0(WillUseTexImage, void());
7786   MOCK_METHOD0(DidUseTexImage, void());
7787
7788  protected:
7789   virtual ~MockGLImage() {}
7790 };
7791
7792 TEST_F(GLES2DecoderWithShaderTest, UseTexImage) {
7793   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
7794   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7795                kSharedMemoryId, kSharedMemoryOffset);
7796
7797   TextureRef* texture_ref = group().texture_manager()->GetTexture(
7798       client_texture_id_);
7799   ASSERT_TRUE(texture_ref != NULL);
7800   Texture* texture = texture_ref->texture();
7801   EXPECT_EQ(kServiceTextureId, texture->service_id());
7802
7803   const int32 kImageId = 1;
7804   scoped_refptr<MockGLImage> image(new MockGLImage);
7805   group().image_manager()->AddImage(image.get(), kImageId);
7806
7807   // Bind image to texture.
7808   EXPECT_CALL(*image, BindTexImage(GL_TEXTURE_2D))
7809       .Times(1)
7810       .WillOnce(Return(true))
7811       .RetiresOnSaturation();
7812   EXPECT_CALL(*image, GetSize())
7813       .Times(1)
7814       .WillOnce(Return(gfx::Size(1, 1)))
7815       .RetiresOnSaturation();
7816   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7817   EXPECT_CALL(*gl_, GetError())
7818       .WillOnce(Return(GL_NO_ERROR))
7819       .WillOnce(Return(GL_NO_ERROR))
7820       .RetiresOnSaturation();
7821   BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
7822   bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, kImageId);
7823   EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
7824
7825   AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
7826   SetupExpectationsForApplyingDefaultDirtyState();
7827
7828   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7829   EXPECT_CALL(*gl_, GetError())
7830       .WillOnce(Return(GL_NO_ERROR))
7831       .WillOnce(Return(GL_NO_ERROR))
7832       .WillOnce(Return(GL_NO_ERROR))
7833       .WillOnce(Return(GL_NO_ERROR))
7834       .RetiresOnSaturation();
7835   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
7836       .Times(3)
7837       .RetiresOnSaturation();
7838   EXPECT_CALL(*image, WillUseTexImage())
7839       .Times(1)
7840       .RetiresOnSaturation();
7841   EXPECT_CALL(*image, DidUseTexImage())
7842       .Times(1)
7843       .RetiresOnSaturation();
7844   EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
7845       .Times(1)
7846       .RetiresOnSaturation();
7847   DrawArrays cmd;
7848   cmd.Init(GL_TRIANGLES, 0, kNumVertices);
7849   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7850   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7851
7852   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
7853                     kServiceFramebufferId);
7854   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7855   EXPECT_CALL(*gl_, GetError())
7856       .WillOnce(Return(GL_NO_ERROR))
7857       .WillOnce(Return(GL_NO_ERROR))
7858       .RetiresOnSaturation();
7859   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
7860       .Times(1)
7861       .RetiresOnSaturation();
7862   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
7863       .Times(2)
7864       .RetiresOnSaturation();
7865   // Image will be 'in use' as long as bound to a framebuffer.
7866   EXPECT_CALL(*image, WillUseTexImage())
7867       .Times(1)
7868       .RetiresOnSaturation();
7869   EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
7870       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
7871       kServiceTextureId, 0))
7872       .Times(1)
7873       .RetiresOnSaturation();
7874   EXPECT_CALL(*gl_, GetError())
7875       .WillOnce(Return(GL_NO_ERROR))
7876       .WillOnce(Return(GL_NO_ERROR))
7877       .RetiresOnSaturation();
7878   FramebufferTexture2D fbtex_cmd;
7879   fbtex_cmd.Init(
7880       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
7881       0);
7882   EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
7883   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7884
7885   // ScopedGLErrorSuppressor calls GetError on its constructor and destructor.
7886   EXPECT_CALL(*gl_, GetError())
7887       .WillOnce(Return(GL_NO_ERROR))
7888       .WillOnce(Return(GL_NO_ERROR))
7889       .RetiresOnSaturation();
7890   EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
7891       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
7892       kServiceRenderbufferId))
7893       .Times(1)
7894       .RetiresOnSaturation();
7895   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
7896       .Times(1)
7897       .RetiresOnSaturation();
7898   EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_2D, kServiceTextureId))
7899       .Times(2)
7900       .RetiresOnSaturation();
7901   // Image should no longer be 'in use' after being unbound from framebuffer.
7902   EXPECT_CALL(*image, DidUseTexImage())
7903       .Times(1)
7904       .RetiresOnSaturation();
7905   EXPECT_CALL(*gl_, GetError())
7906       .WillOnce(Return(GL_NO_ERROR))
7907       .WillOnce(Return(GL_NO_ERROR))
7908       .RetiresOnSaturation();
7909   FramebufferRenderbuffer fbrb_cmd;
7910   fbrb_cmd.Init(
7911       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
7912       client_renderbuffer_id_);
7913   EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
7914 }
7915
7916 TEST_F(GLES2DecoderManualInitTest, DrawWithGLImageExternal) {
7917   InitDecoder(
7918       "GL_OES_EGL_image_external",  // extensions
7919       "opengl es 2.0",              // gl version
7920       true,                         // has alpha
7921       true,                         // has depth
7922       false,                        // has stencil
7923       true,                         // request alpha
7924       true,                         // request depth
7925       false,  // request stencil
7926       true);  // bind generates resource
7927
7928   TextureRef* texture_ref = GetTexture(client_texture_id_);
7929   scoped_refptr<MockGLImage> image(new MockGLImage);
7930   group().texture_manager()->SetTarget(texture_ref, GL_TEXTURE_EXTERNAL_OES);
7931   group().texture_manager()->SetLevelInfo(texture_ref,
7932                                           GL_TEXTURE_EXTERNAL_OES,
7933                                           0,
7934                                           GL_RGBA,
7935                                           0,
7936                                           0,
7937                                           1,
7938                                           0,
7939                                           GL_RGBA,
7940                                           GL_UNSIGNED_BYTE,
7941                                           true);
7942   group().texture_manager()->SetLevelImage(
7943       texture_ref, GL_TEXTURE_EXTERNAL_OES, 0, image);
7944
7945   DoBindTexture(GL_TEXTURE_EXTERNAL_OES, client_texture_id_, kServiceTextureId);
7946   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7947
7948   SetupSamplerExternalProgram();
7949   SetupIndexBuffer();
7950   AddExpectationsForSimulatedAttrib0(kMaxValidIndex + 1, 0);
7951   SetupExpectationsForApplyingDefaultDirtyState();
7952   EXPECT_TRUE(group().texture_manager()->CanRender(texture_ref));
7953
7954   InSequence s;
7955   EXPECT_CALL(*gl_, GetError())
7956       .WillOnce(Return(GL_NO_ERROR))
7957       .RetiresOnSaturation();
7958   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
7959       .Times(1)
7960       .RetiresOnSaturation();
7961   EXPECT_CALL(*image, WillUseTexImage())
7962       .Times(1)
7963       .RetiresOnSaturation();
7964   EXPECT_CALL(*gl_, GetError())
7965       .WillOnce(Return(GL_NO_ERROR))
7966       .RetiresOnSaturation();
7967   EXPECT_CALL(*gl_, DrawElements(_, _, _, _))
7968       .Times(1);
7969   EXPECT_CALL(*gl_, GetError())
7970       .WillOnce(Return(GL_NO_ERROR))
7971       .RetiresOnSaturation();
7972   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
7973       .Times(1)
7974       .RetiresOnSaturation();
7975   EXPECT_CALL(*image, DidUseTexImage())
7976       .Times(1)
7977       .RetiresOnSaturation();
7978   EXPECT_CALL(*gl_, GetError())
7979       .WillOnce(Return(GL_NO_ERROR))
7980       .RetiresOnSaturation();
7981   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0))
7982       .Times(1)
7983       .RetiresOnSaturation();
7984   DrawElements cmd;
7985   cmd.Init(GL_TRIANGLES, kValidIndexRangeCount, GL_UNSIGNED_SHORT,
7986            kValidIndexRangeStart * 2);
7987   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
7988   EXPECT_EQ(GL_NO_ERROR, GetGLError());
7989 }
7990
7991 TEST_F(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) {
7992   InitDecoder(
7993       "GL_ARB_texture_rectangle",  // extensions
7994       "3.0",   // gl version
7995       false,   // has alpha
7996       false,   // has depth
7997       false,   // has stencil
7998       false,   // request alpha
7999       false,   // request depth
8000       false,   // request stencil
8001       true);   // bind generates resource
8002
8003   Texture* texture = GetTexture(client_texture_id_)->texture();
8004   EXPECT_TRUE(texture != NULL);
8005   EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
8006
8007   DoBindTexture(
8008       GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8009
8010   TexParameteri cmd;
8011   cmd.Init(GL_TEXTURE_2D,
8012            GL_TEXTURE_POOL_CHROMIUM,
8013            GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
8014   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8015   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8016
8017   cmd.Init(GL_TEXTURE_2D,
8018            GL_TEXTURE_POOL_CHROMIUM,
8019            GL_TEXTURE_POOL_MANAGED_CHROMIUM);
8020   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8021   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8022
8023   EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM);
8024
8025   cmd.Init(GL_TEXTURE_2D,
8026            GL_TEXTURE_POOL_CHROMIUM,
8027            GL_NONE);
8028   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8029   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
8030 }
8031
8032 TEST_F(GLES2DecoderManualInitTest, AsyncPixelTransfers) {
8033   InitDecoder(
8034       "GL_CHROMIUM_async_pixel_transfers",  // extensions
8035       "3.0",   // gl version
8036       false, false, false,  // has alpha/depth/stencil
8037       false, false, false,  // request alpha/depth/stencil
8038       true);   // bind generates resource
8039
8040   // Set up the texture.
8041   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8042   TextureRef* texture_ref = GetTexture(client_texture_id_);
8043   Texture* texture = texture_ref->texture();
8044
8045   // Set a mock Async delegate
8046   StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
8047       new StrictMock<gpu::MockAsyncPixelTransferManager>;
8048   manager->Initialize(group().texture_manager());
8049   decoder_->SetAsyncPixelTransferManagerForTest(manager);
8050   StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
8051
8052   // Tex(Sub)Image2D upload commands.
8053   AsyncTexImage2DCHROMIUM teximage_cmd;
8054   teximage_cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA,
8055                     GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
8056   AsyncTexSubImage2DCHROMIUM texsubimage_cmd;
8057   texsubimage_cmd.Init(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA,
8058                       GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
8059   WaitAsyncTexImage2DCHROMIUM wait_cmd;
8060   wait_cmd.Init(GL_TEXTURE_2D);
8061
8062   // No transfer state exists initially.
8063   EXPECT_FALSE(
8064       decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8065           texture_ref));
8066
8067   base::Closure bind_callback;
8068
8069   // AsyncTexImage2D
8070   {
8071     // Create transfer state since it doesn't exist.
8072     EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
8073         .WillOnce(Return(
8074             delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
8075         .RetiresOnSaturation();
8076     EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _))
8077         .WillOnce(SaveArg<2>(&bind_callback))
8078         .RetiresOnSaturation();
8079     // Command succeeds.
8080     EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
8081     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8082     EXPECT_EQ(
8083         delegate,
8084         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8085             texture_ref));
8086     EXPECT_TRUE(texture->IsImmutable());
8087     // The texture is safe but the level has not been defined yet.
8088     EXPECT_TRUE(texture->SafeToRenderFrom());
8089     GLsizei width, height;
8090     EXPECT_FALSE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
8091   }
8092   {
8093     // Async redefinitions are not allowed!
8094     // Command fails.
8095     EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
8096     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8097     EXPECT_EQ(
8098         delegate,
8099         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8100             texture_ref));
8101     EXPECT_TRUE(texture->IsImmutable());
8102     EXPECT_TRUE(texture->SafeToRenderFrom());
8103   }
8104
8105   // Binding/defining of the async transfer
8106   {
8107     // TODO(epenner): We should check that the manager gets the
8108     // BindCompletedAsyncTransfers() call, which is required to
8109     // guarantee the delegate calls the bind callback.
8110
8111     // Simulate the bind callback from the delegate.
8112     bind_callback.Run();
8113
8114     // After the bind callback is run, the texture is safe,
8115     // and has the right size etc.
8116     EXPECT_TRUE(texture->SafeToRenderFrom());
8117     GLsizei width, height;
8118     EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
8119     EXPECT_EQ(width, 8);
8120     EXPECT_EQ(height, 8);
8121   }
8122
8123   // AsyncTexSubImage2D
8124   decoder_->GetAsyncPixelTransferManager()
8125       ->ClearPixelTransferDelegateForTest(texture_ref);
8126   texture->SetImmutable(false);
8127   {
8128     // Create transfer state since it doesn't exist.
8129     EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
8130         .WillOnce(Return(
8131             delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
8132         .RetiresOnSaturation();
8133     EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _))
8134         .RetiresOnSaturation();
8135     // Command succeeds.
8136     EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
8137     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8138     EXPECT_EQ(
8139         delegate,
8140         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8141             texture_ref));
8142     EXPECT_TRUE(texture->IsImmutable());
8143     EXPECT_TRUE(texture->SafeToRenderFrom());
8144   }
8145   {
8146     // No transfer is in progress.
8147     EXPECT_CALL(*delegate, TransferIsInProgress())
8148         .WillOnce(Return(false))  // texSubImage validation
8149         .WillOnce(Return(false))  // async validation
8150         .RetiresOnSaturation();
8151     EXPECT_CALL(*delegate, AsyncTexSubImage2D(_, _))
8152         .RetiresOnSaturation();
8153     // Command succeeds.
8154     EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
8155     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8156     EXPECT_EQ(
8157         delegate,
8158         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8159             texture_ref));
8160     EXPECT_TRUE(texture->IsImmutable());
8161     EXPECT_TRUE(texture->SafeToRenderFrom());
8162   }
8163   {
8164     // A transfer is still in progress!
8165     EXPECT_CALL(*delegate, TransferIsInProgress())
8166         .WillOnce(Return(true))
8167         .RetiresOnSaturation();
8168     // No async call, command fails.
8169     EXPECT_EQ(error::kNoError, ExecuteCmd(texsubimage_cmd));
8170     EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8171     EXPECT_EQ(
8172         delegate,
8173         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8174             texture_ref));
8175     EXPECT_TRUE(texture->IsImmutable());
8176     EXPECT_TRUE(texture->SafeToRenderFrom());
8177   }
8178
8179   // Delete delegate on DeleteTexture.
8180   {
8181     EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
8182     DoDeleteTexture(client_texture_id_, kServiceTextureId);
8183     EXPECT_FALSE(
8184         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8185             texture_ref));
8186     delegate = NULL;
8187   }
8188
8189   // WaitAsyncTexImage2D
8190   {
8191     // Get a fresh texture since the existing texture cannot be respecified
8192     // asynchronously and AsyncTexSubImage2D does not involved binding.
8193     EXPECT_CALL(*gl_, GenTextures(1, _))
8194         .WillOnce(SetArgumentPointee<1>(kServiceTextureId));
8195     DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8196     texture_ref = GetTexture(client_texture_id_);
8197     texture = texture_ref->texture();
8198     texture->SetImmutable(false);
8199     // Create transfer state since it doesn't exist.
8200     EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
8201         .WillOnce(Return(
8202             delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
8203         .RetiresOnSaturation();
8204     EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _))
8205         .RetiresOnSaturation();
8206     // Start async transfer.
8207     EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
8208     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8209     EXPECT_EQ(
8210         delegate,
8211         decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8212             texture_ref));
8213
8214     EXPECT_TRUE(texture->IsImmutable());
8215     // Wait for completion.
8216     EXPECT_CALL(*delegate, WaitForTransferCompletion());
8217     EXPECT_CALL(*manager, BindCompletedAsyncTransfers());
8218     EXPECT_EQ(error::kNoError, ExecuteCmd(wait_cmd));
8219     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8220   }
8221 }
8222
8223 TEST_F(GLES2DecoderManualInitTest, AsyncPixelTransferManager) {
8224   InitDecoder(
8225       "GL_CHROMIUM_async_pixel_transfers",  // extensions
8226       "3.0",   // gl version
8227       false, false, false,  // has alpha/depth/stencil
8228       false, false, false,  // request alpha/depth/stencil
8229       true);   // bind generates resource
8230
8231   // Set up the texture.
8232   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8233   TextureRef* texture_ref = GetTexture(client_texture_id_);
8234
8235   // Set a mock Async delegate.
8236   StrictMock<gpu::MockAsyncPixelTransferManager>* manager =
8237       new StrictMock<gpu::MockAsyncPixelTransferManager>;
8238   manager->Initialize(group().texture_manager());
8239   decoder_->SetAsyncPixelTransferManagerForTest(manager);
8240   StrictMock<gpu::MockAsyncPixelTransferDelegate>* delegate = NULL;
8241
8242   AsyncTexImage2DCHROMIUM teximage_cmd;
8243   teximage_cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA,
8244                     GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset);
8245
8246   // No transfer delegate exists initially.
8247   EXPECT_FALSE(
8248       decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8249           texture_ref));
8250
8251   // Create delegate on AsyncTexImage2D.
8252   {
8253     EXPECT_CALL(*manager, CreatePixelTransferDelegateImpl(texture_ref, _))
8254         .WillOnce(Return(
8255              delegate = new StrictMock<gpu::MockAsyncPixelTransferDelegate>))
8256         .RetiresOnSaturation();
8257     EXPECT_CALL(*delegate, AsyncTexImage2D(_, _, _)).RetiresOnSaturation();
8258
8259     // Command succeeds.
8260     EXPECT_EQ(error::kNoError, ExecuteCmd(teximage_cmd));
8261     EXPECT_EQ(GL_NO_ERROR, GetGLError());
8262   }
8263
8264   // Delegate is cached.
8265   EXPECT_EQ(delegate,
8266             decoder_->GetAsyncPixelTransferManager()->GetPixelTransferDelegate(
8267                 texture_ref));
8268
8269   // Delete delegate on manager teardown.
8270   {
8271     EXPECT_CALL(*delegate, Destroy()).RetiresOnSaturation();
8272     decoder_->ResetAsyncPixelTransferManagerForTest();
8273
8274     // Texture ref still valid.
8275     EXPECT_EQ(texture_ref, GetTexture(client_texture_id_));
8276   }
8277 }
8278
8279 namespace {
8280
8281 class SizeOnlyMemoryTracker : public MemoryTracker {
8282  public:
8283   SizeOnlyMemoryTracker() {
8284     // These are the default textures. 1 for TEXTURE_2D and 6 faces for
8285     // TEXTURE_CUBE_MAP.
8286     const size_t kInitialUnmanagedPoolSize = 7 * 4;
8287     const size_t kInitialManagedPoolSize = 0;
8288     pool_infos_[MemoryTracker::kUnmanaged].initial_size =
8289         kInitialUnmanagedPoolSize;
8290     pool_infos_[MemoryTracker::kManaged].initial_size =
8291         kInitialManagedPoolSize;
8292   }
8293
8294   // Ensure a certain amount of GPU memory is free. Returns true on success.
8295   MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed));
8296
8297   virtual void TrackMemoryAllocatedChange(
8298       size_t old_size, size_t new_size, Pool pool) {
8299     PoolInfo& info = pool_infos_[pool];
8300     info.size += new_size - old_size;
8301   }
8302
8303   size_t GetPoolSize(Pool pool) {
8304     const PoolInfo& info = pool_infos_[pool];
8305     return info.size - info.initial_size;
8306   }
8307
8308  private:
8309   virtual ~SizeOnlyMemoryTracker() {
8310   }
8311   struct PoolInfo {
8312     PoolInfo()
8313         : initial_size(0),
8314           size(0) {
8315     }
8316     size_t initial_size;
8317     size_t size;
8318   };
8319   std::map<Pool, PoolInfo> pool_infos_;
8320 };
8321
8322 }  // anonymous namespace.
8323
8324 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
8325   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8326       new SizeOnlyMemoryTracker();
8327   set_memory_tracker(memory_tracker.get());
8328   InitDecoder(
8329       "",      // extensions
8330       "3.0",   // gl version
8331       false,   // has alpha
8332       false,   // has depth
8333       false,   // has stencil
8334       false,   // request alpha
8335       false,   // request depth
8336       false,   // request stencil
8337       true);   // bind generates resource
8338   // Expect that initial size - size is 0.
8339   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8340   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
8341 }
8342
8343 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
8344   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8345       new SizeOnlyMemoryTracker();
8346   set_memory_tracker(memory_tracker.get());
8347   InitDecoder(
8348       "",      // extensions
8349       "3.0",   // gl version
8350       false,   // has alpha
8351       false,   // has depth
8352       false,   // has stencil
8353       false,   // request alpha
8354       false,   // request depth
8355       false,   // request stencil
8356       true);   // bind generates resource
8357   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8358   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8359       .WillOnce(Return(true)).RetiresOnSaturation();
8360   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8361                kSharedMemoryId, kSharedMemoryOffset);
8362   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8363   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
8364       .WillOnce(Return(true)).RetiresOnSaturation();
8365   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8366                kSharedMemoryId, kSharedMemoryOffset);
8367   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8368   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8369   // Check we get out of memory and no call to glTexImage2D if Ensure fails.
8370   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
8371       .WillOnce(Return(false)).RetiresOnSaturation();
8372   TexImage2D cmd;
8373   cmd.Init(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8374            kSharedMemoryId, kSharedMemoryOffset);
8375   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8376   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8377   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8378 }
8379
8380 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
8381   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8382       new SizeOnlyMemoryTracker();
8383   set_memory_tracker(memory_tracker.get());
8384   InitDecoder(
8385       "",      // extensions
8386       "3.0",   // gl version
8387       false,   // has alpha
8388       false,   // has depth
8389       false,   // has stencil
8390       false,   // request alpha
8391       false,   // request depth
8392       false,   // request stencil
8393       true);   // bind generates resource
8394   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8395   // Check we get out of memory and no call to glTexStorage2DEXT
8396   // if Ensure fails.
8397   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8398       .WillOnce(Return(false)).RetiresOnSaturation();
8399   TexStorage2DEXT cmd;
8400   cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
8401   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8402   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8403   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8404 }
8405
8406 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
8407   GLenum target = GL_TEXTURE_2D;
8408   GLint level = 0;
8409   GLenum internal_format = GL_RGBA;
8410   GLsizei width = 4;
8411   GLsizei height = 8;
8412   GLint border = 0;
8413   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8414       new SizeOnlyMemoryTracker();
8415   set_memory_tracker(memory_tracker.get());
8416   InitDecoder(
8417       "",      // extensions
8418       "3.0",   // gl version
8419       true,    // has alpha
8420       false,   // has depth
8421       false,   // has stencil
8422       true,    // request alpha
8423       false,   // request depth
8424       false,   // request stencil
8425       true);   // bind generates resource
8426   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8427   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8428       .WillOnce(Return(true)).RetiresOnSaturation();
8429   EXPECT_CALL(*gl_, GetError())
8430       .WillOnce(Return(GL_NO_ERROR))
8431       .WillOnce(Return(GL_NO_ERROR))
8432       .RetiresOnSaturation();
8433   EXPECT_CALL(*gl_, CopyTexImage2D(
8434       target, level, internal_format, 0, 0, width, height, border))
8435       .Times(1)
8436       .RetiresOnSaturation();
8437   CopyTexImage2D cmd;
8438   cmd.Init(target, level, internal_format, 0, 0, width, height, border);
8439   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8440   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8441   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8442   // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
8443   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8444       .WillOnce(Return(false)).RetiresOnSaturation();
8445   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8446   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8447   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8448 }
8449
8450 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
8451   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8452       new SizeOnlyMemoryTracker();
8453   set_memory_tracker(memory_tracker.get());
8454   InitDecoder(
8455       "",      // extensions
8456       "3.0",   // gl version
8457       false,   // has alpha
8458       false,   // has depth
8459       false,   // has stencil
8460       false,   // request alpha
8461       false,   // request depth
8462       false,   // request stencil
8463       true);   // bind generates resource
8464   DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
8465                     kServiceRenderbufferId);
8466   EXPECT_CALL(*gl_, GetError())
8467       .WillOnce(Return(GL_NO_ERROR))
8468       .WillOnce(Return(GL_NO_ERROR))
8469       .RetiresOnSaturation();
8470   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8471       .WillOnce(Return(true)).RetiresOnSaturation();
8472   EXPECT_CALL(*gl_, RenderbufferStorageEXT(
8473       GL_RENDERBUFFER, GL_RGBA, 8, 4))
8474       .Times(1)
8475       .RetiresOnSaturation();
8476   RenderbufferStorage cmd;
8477   cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4);
8478   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8479   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8480   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8481   // Check we get out of memory and no call to glRenderbufferStorage if Ensure
8482   // fails.
8483   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8484       .WillOnce(Return(false)).RetiresOnSaturation();
8485   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8486   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8487   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
8488 }
8489
8490 TEST_F(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
8491   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
8492       new SizeOnlyMemoryTracker();
8493   set_memory_tracker(memory_tracker.get());
8494   InitDecoder(
8495       "",      // extensions
8496       "3.0",   // gl version
8497       false,   // has alpha
8498       false,   // has depth
8499       false,   // has stencil
8500       false,   // request alpha
8501       false,   // request depth
8502       false,   // request stencil
8503       true);   // bind generates resource
8504   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_,
8505                kServiceBufferId);
8506   EXPECT_CALL(*gl_, GetError())
8507       .WillOnce(Return(GL_NO_ERROR))
8508       .WillOnce(Return(GL_NO_ERROR))
8509       .RetiresOnSaturation();
8510   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8511       .WillOnce(Return(true)).RetiresOnSaturation();
8512   EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
8513       .Times(1)
8514       .RetiresOnSaturation();
8515   BufferData cmd;
8516   cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW);
8517   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8518   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8519   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
8520   // Check we get out of memory and no call to glBufferData if Ensure
8521   // fails.
8522   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
8523       .WillOnce(Return(false)).RetiresOnSaturation();
8524   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8525   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
8526   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
8527 }
8528
8529 TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateSuccceeds) {
8530   const GLsizei count = 1;
8531   const GLenum bufs[] = { GL_COLOR_ATTACHMENT0 };
8532   DrawBuffersEXTImmediate& cmd =
8533       *GetImmediateAs<DrawBuffersEXTImmediate>();
8534   cmd.Init(count, bufs);
8535
8536   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
8537                     kServiceFramebufferId);
8538   EXPECT_CALL(*gl_, DrawBuffersARB(count, _))
8539       .Times(1)
8540       .RetiresOnSaturation();
8541   EXPECT_EQ(error::kNoError,
8542             ExecuteImmediateCmd(cmd, sizeof(bufs)));
8543   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8544 }
8545
8546 TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateFails) {
8547   const GLsizei count = 1;
8548   const GLenum bufs[] = { GL_COLOR_ATTACHMENT1_EXT };
8549   DrawBuffersEXTImmediate& cmd =
8550       *GetImmediateAs<DrawBuffersEXTImmediate>();
8551   cmd.Init(count, bufs);
8552
8553   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
8554                     kServiceFramebufferId);
8555   EXPECT_EQ(error::kNoError,
8556             ExecuteImmediateCmd(cmd, sizeof(bufs)));
8557   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8558 }
8559
8560 TEST_F(GLES2DecoderTest, DrawBuffersEXTImmediateBackbuffer) {
8561   const GLsizei count = 1;
8562   const GLenum bufs[] = { GL_BACK };
8563   DrawBuffersEXTImmediate& cmd =
8564       *GetImmediateAs<DrawBuffersEXTImmediate>();
8565   cmd.Init(count, bufs);
8566
8567   DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
8568                     kServiceFramebufferId);
8569   EXPECT_EQ(error::kNoError,
8570             ExecuteImmediateCmd(cmd, sizeof(bufs)));
8571   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8572
8573   DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);  // unbind
8574
8575   EXPECT_CALL(*gl_, DrawBuffersARB(count, _))
8576       .Times(1)
8577       .RetiresOnSaturation();
8578
8579   EXPECT_EQ(error::kNoError,
8580             ExecuteImmediateCmd(cmd, sizeof(bufs)));
8581   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8582 }
8583
8584 TEST_F(GLES2DecoderManualInitTest, InvalidateFramebufferBinding) {
8585   InitDecoder("",                            // extensions
8586               "opengl es 3.0",               // gl version
8587               false,                         // has alpha
8588               false,                         // has depth
8589               false,                         // has stencil
8590               false,                         // request alpha
8591               false,                         // request depth
8592               false,                         // request stencil
8593               false);                        // bind generates resource
8594
8595   // EXPECT_EQ can't be used to compare function pointers
8596   EXPECT_TRUE(
8597       gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") ==
8598       gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
8599   EXPECT_TRUE(
8600       gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") !=
8601       gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT"));
8602 }
8603
8604 TEST_F(GLES2DecoderManualInitTest, DiscardFramebufferEXT) {
8605   InitDecoder("GL_EXT_discard_framebuffer",  // extensions
8606               "opengl es 2.0",               // gl version
8607               false,                         // has alpha
8608               false,                         // has depth
8609               false,                         // has stencil
8610               false,                         // request alpha
8611               false,                         // request depth
8612               false,                         // request stencil
8613               false);                        // bind generates resource
8614
8615   // EXPECT_EQ can't be used to compare function pointers
8616   EXPECT_TRUE(
8617       gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") ==
8618       gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
8619
8620   const GLenum target = GL_FRAMEBUFFER;
8621   const GLsizei count = 1;
8622   const GLenum attachments[] = { GL_COLOR_ATTACHMENT0 };
8623
8624   SetupTexture();
8625   DoBindFramebuffer(
8626       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
8627   DoFramebufferTexture2D(GL_FRAMEBUFFER,
8628                          GL_COLOR_ATTACHMENT0,
8629                          GL_TEXTURE_2D,
8630                          client_texture_id_,
8631                          kServiceTextureId,
8632                          0,
8633                          GL_NO_ERROR);
8634   FramebufferManager* framebuffer_manager = group().framebuffer_manager();
8635   Framebuffer* framebuffer =
8636       framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
8637   EXPECT_TRUE(framebuffer->IsCleared());
8638
8639   EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
8640       .Times(1)
8641       .RetiresOnSaturation();
8642   DiscardFramebufferEXTImmediate& cmd =
8643       *GetImmediateAs<DiscardFramebufferEXTImmediate>();
8644   cmd.Init(target, count, attachments);
8645
8646   EXPECT_EQ(error::kNoError,
8647             ExecuteImmediateCmd(cmd, sizeof(attachments)));
8648   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8649   EXPECT_FALSE(framebuffer->IsCleared());
8650 }
8651
8652 TEST_F(GLES2DecoderTest, DiscardFramebufferEXTUnsupported) {
8653   const GLenum target = GL_FRAMEBUFFER;
8654   const GLsizei count = 1;
8655   const GLenum attachments[] = { GL_COLOR_EXT };
8656   DiscardFramebufferEXTImmediate& cmd =
8657       *GetImmediateAs<DiscardFramebufferEXTImmediate>();
8658   cmd.Init(target, count, attachments);
8659
8660   // Should not result into a call into GL.
8661   EXPECT_EQ(error::kNoError,
8662             ExecuteImmediateCmd(cmd, sizeof(attachments)));
8663   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
8664 }
8665
8666 TEST_F(GLES2DecoderRestoreStateTest, NullPreviousState) {
8667   InitDecoder(
8668       "",      // extensions
8669       "3.0",   // gl version
8670       false,   // has alpha
8671       false,   // has depth
8672       false,   // has stencil
8673       false,   // request alpha
8674       false,   // request depth
8675       false,   // request stencil
8676       false);  // bind generates resource
8677   SetupTexture();
8678
8679   InSequence sequence;
8680   // Expect to restore texture bindings for unit GL_TEXTURE0.
8681   AddExpectationsForActiveTexture(GL_TEXTURE0);
8682   AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
8683   AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
8684                                 TestHelper::kServiceDefaultTextureCubemapId);
8685
8686   // Expect to restore texture bindings for remaining units.
8687   for (uint32 i = 1; i < group().max_texture_units() ; ++i) {
8688     AddExpectationsForActiveTexture(GL_TEXTURE0 + i);
8689     AddExpectationsForBindTexture(GL_TEXTURE_2D,
8690                                   TestHelper::kServiceDefaultTexture2dId);
8691     AddExpectationsForBindTexture(GL_TEXTURE_CUBE_MAP,
8692                                   TestHelper::kServiceDefaultTextureCubemapId);
8693   }
8694
8695   // Expect to restore the active texture unit to GL_TEXTURE0.
8696   AddExpectationsForActiveTexture(GL_TEXTURE0);
8697
8698   GetDecoder()->RestoreAllTextureUnitBindings(NULL);
8699 }
8700
8701 TEST_F(GLES2DecoderRestoreStateTest, WithPreviousState) {
8702   InitDecoder(
8703       "",      // extensions
8704       "3.0",   // gl version
8705       false,   // has alpha
8706       false,   // has depth
8707       false,   // has stencil
8708       false,   // request alpha
8709       false,   // request depth
8710       false,   // request stencil
8711       false);  // bind generates resource
8712   SetupTexture();
8713
8714   // Construct a previous ContextState with all texture bindings
8715   // set to default textures.
8716   ContextState prev_state(NULL, NULL);
8717   InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
8718
8719   InSequence sequence;
8720   // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE0 unit,
8721   // since the rest of the bindings haven't changed between the current
8722   // state and the |prev_state|.
8723   AddExpectationsForActiveTexture(GL_TEXTURE0);
8724   AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
8725
8726   // Expect to restore active texture unit to GL_TEXTURE0.
8727   AddExpectationsForActiveTexture(GL_TEXTURE0);
8728
8729   GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
8730 }
8731
8732 TEST_F(GLES2DecoderRestoreStateTest, ActiveUnit1) {
8733   InitDecoder(
8734       "",      // extensions
8735       "3.0",   // gl version
8736       false,   // has alpha
8737       false,   // has depth
8738       false,   // has stencil
8739       false,   // request alpha
8740       false,   // request depth
8741       false,   // request stencil
8742       false);  // bind generates resource
8743
8744   // Bind a non-default texture to GL_TEXTURE1 unit.
8745   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
8746   ActiveTexture cmd;
8747   cmd.Init(GL_TEXTURE1);
8748   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8749   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8750   SetupTexture();
8751
8752   // Construct a previous ContextState with all texture bindings
8753   // set to default textures.
8754   ContextState prev_state(NULL, NULL);
8755   InitializeContextState(&prev_state, std::numeric_limits<uint32>::max(), 0);
8756
8757   InSequence sequence;
8758   // Expect to restore only GL_TEXTURE_2D binding for GL_TEXTURE1 unit,
8759   // since the rest of the bindings haven't changed between the current
8760   // state and the |prev_state|.
8761   AddExpectationsForActiveTexture(GL_TEXTURE1);
8762   AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
8763
8764   // Expect to restore active texture unit to GL_TEXTURE1.
8765   AddExpectationsForActiveTexture(GL_TEXTURE1);
8766
8767   GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
8768 }
8769
8770 TEST_F(GLES2DecoderRestoreStateTest, NonDefaultUnit0) {
8771   InitDecoder(
8772       "",      // extensions
8773       "3.0",   // gl version
8774       false,   // has alpha
8775       false,   // has depth
8776       false,   // has stencil
8777       false,   // request alpha
8778       false,   // request depth
8779       false,   // request stencil
8780       false);  // bind generates resource
8781
8782   // Bind a non-default texture to GL_TEXTURE1 unit.
8783   EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE1));
8784   SpecializedSetup<ActiveTexture, 0>(true);
8785   ActiveTexture cmd;
8786   cmd.Init(GL_TEXTURE1);
8787   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8788   EXPECT_EQ(GL_NO_ERROR, GetGLError());
8789   SetupTexture();
8790
8791   // Construct a previous ContextState with GL_TEXTURE_2D target in
8792   // GL_TEXTURE0 unit bound to a non-default texture and the rest
8793   // set to default textures.
8794   ContextState prev_state(NULL, NULL);
8795   InitializeContextState(&prev_state, 0, kServiceTextureId);
8796
8797   InSequence sequence;
8798   // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE0 unit to
8799   // a default texture.
8800   AddExpectationsForActiveTexture(GL_TEXTURE0);
8801   AddExpectationsForBindTexture(GL_TEXTURE_2D,
8802                                 TestHelper::kServiceDefaultTexture2dId);
8803
8804   // Expect to restore GL_TEXTURE_2D binding for GL_TEXTURE1 unit to
8805   // non-default.
8806   AddExpectationsForActiveTexture(GL_TEXTURE1);
8807   AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
8808
8809   // Expect to restore active texture unit to GL_TEXTURE1.
8810   AddExpectationsForActiveTexture(GL_TEXTURE1);
8811
8812   GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
8813 }
8814
8815 TEST_F(GLES2DecoderRestoreStateTest, NonDefaultUnit1) {
8816   InitDecoder(
8817       "",      // extensions
8818       "3.0",   // gl version
8819       false,   // has alpha
8820       false,   // has depth
8821       false,   // has stencil
8822       false,   // request alpha
8823       false,   // request depth
8824       false,   // request stencil
8825       false);  // bind generates resource
8826
8827   // Bind a non-default texture to GL_TEXTURE0 unit.
8828   SetupTexture();
8829
8830   // Construct a previous ContextState with GL_TEXTURE_2D target in
8831   // GL_TEXTURE1 unit bound to a non-default texture and the rest
8832   // set to default textures.
8833   ContextState prev_state(NULL, NULL);
8834   InitializeContextState(&prev_state, 1, kServiceTextureId);
8835
8836   InSequence sequence;
8837   // Expect to restore GL_TEXTURE_2D binding to the non-default texture
8838   // for GL_TEXTURE0 unit.
8839   AddExpectationsForActiveTexture(GL_TEXTURE0);
8840   AddExpectationsForBindTexture(GL_TEXTURE_2D, kServiceTextureId);
8841
8842   // Expect to restore GL_TEXTURE_2D binding to the default texture
8843   // for GL_TEXTURE1 unit.
8844   AddExpectationsForActiveTexture(GL_TEXTURE1);
8845   AddExpectationsForBindTexture(GL_TEXTURE_2D,
8846                                 TestHelper::kServiceDefaultTexture2dId);
8847
8848   // Expect to restore active texture unit to GL_TEXTURE0.
8849   AddExpectationsForActiveTexture(GL_TEXTURE0);
8850
8851   GetDecoder()->RestoreAllTextureUnitBindings(&prev_state);
8852 }
8853
8854 TEST_F(GLES2DecoderManualInitTest, ClearUniformsBeforeFirstProgramUse) {
8855   CommandLine command_line(0, NULL);
8856   command_line.AppendSwitchASCII(
8857       switches::kGpuDriverBugWorkarounds,
8858       base::IntToString(gpu::CLEAR_UNIFORMS_BEFORE_FIRST_PROGRAM_USE));
8859   InitDecoderWithCommandLine(
8860       "",      // extensions
8861       "3.0",   // gl version
8862       true,    // has alpha
8863       false,   // has depth
8864       false,   // has stencil
8865       true,    // request alpha
8866       false,   // request depth
8867       false,   // request stencil
8868       true,    // bind generates resource
8869       &command_line);
8870   {
8871     static AttribInfo attribs[] = {
8872       { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
8873       { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
8874       { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
8875     };
8876     static UniformInfo uniforms[] = {
8877       { kUniform1Name, kUniform1Size, kUniform1Type,
8878         kUniform1FakeLocation, kUniform1RealLocation,
8879         kUniform1DesiredLocation },
8880       { kUniform2Name, kUniform2Size, kUniform2Type,
8881         kUniform2FakeLocation, kUniform2RealLocation,
8882         kUniform2DesiredLocation },
8883       { kUniform3Name, kUniform3Size, kUniform3Type,
8884         kUniform3FakeLocation, kUniform3RealLocation,
8885         kUniform3DesiredLocation },
8886     };
8887     SetupShader(attribs, arraysize(attribs), uniforms, arraysize(uniforms),
8888                 client_program_id_, kServiceProgramId,
8889                 client_vertex_shader_id_, kServiceVertexShaderId,
8890                 client_fragment_shader_id_, kServiceFragmentShaderId);
8891     TestHelper::SetupExpectationsForClearingUniforms(
8892         gl_.get(), uniforms, arraysize(uniforms));
8893   }
8894
8895   {
8896     EXPECT_CALL(*gl_, UseProgram(kServiceProgramId))
8897         .Times(1)
8898         .RetiresOnSaturation();
8899     cmds::UseProgram cmd;
8900     cmd.Init(client_program_id_);
8901     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
8902   }
8903 }
8904
8905 TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES2) {
8906   InitDecoder("GL_OES_texture_float",        // extensions
8907               "opengl es 2.0",               // gl version
8908               false,                         // has alpha
8909               false,                         // has depth
8910               false,                         // has stencil
8911               false,                         // request alpha
8912               false,                         // request depth
8913               false,                         // request stencil
8914               false);                        // bind generates resource
8915   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8916   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
8917   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
8918   DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0, GL_LUMINANCE,
8919                GL_FLOAT, 0, 0);
8920   DoTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0, GL_ALPHA, GL_FLOAT,
8921                0, 0);
8922   DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16, 17, 0,
8923                GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0);
8924 }
8925
8926 TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES3) {
8927   InitDecoder("GL_OES_texture_float GL_EXT_color_buffer_float", // extensions
8928               "opengl es 3.0",               // gl version
8929               false,                         // has alpha
8930               false,                         // has depth
8931               false,                         // has stencil
8932               false,                         // request alpha
8933               false,                         // request depth
8934               false,                         // request stencil
8935               false);                        // bind generates resource
8936   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8937   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0, GL_RGBA, GL_FLOAT, 0, 0);
8938   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
8939   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 17, 0, GL_RGBA, GL_FLOAT, 0,
8940                0);
8941   DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0, GL_LUMINANCE,
8942                GL_FLOAT, 0, 0);
8943   DoTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0, GL_ALPHA, GL_FLOAT,
8944                0, 0);
8945   DoTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16, 17, 0,
8946                GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0);
8947 }
8948
8949 TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatConvertsFormatDesktop) {
8950   InitDecoder("GL_ARB_texture_float",        // extensions
8951               "2.1",                         // gl version
8952               false,                         // has alpha
8953               false,                         // has depth
8954               false,                         // has stencil
8955               false,                         // request alpha
8956               false,                         // request depth
8957               false,                         // request stencil
8958               false);                        // bind generates resource
8959   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
8960   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 17, 0, GL_RGBA, GL_FLOAT, 0,
8961                0);
8962   DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 16, 17, 0, GL_RGB, GL_FLOAT, 0, 0);
8963   DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_RGBA, 16, 17, 0,
8964                                     GL_RGBA, GL_FLOAT, 0, 0, GL_RGBA32F_ARB);
8965   DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_RGB, 16, 17, 0,
8966                                     GL_RGB, GL_FLOAT, 0, 0, GL_RGB32F_ARB);
8967   DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 17, 0,
8968                                     GL_LUMINANCE, GL_FLOAT, 0, 0,
8969                                     GL_LUMINANCE32F_ARB);
8970   DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 17, 0,
8971                                     GL_ALPHA, GL_FLOAT, 0, 0, GL_ALPHA32F_ARB);
8972   DoTexImage2DConvertInternalFormat(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16,
8973                                     17, 0, GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0,
8974                                     GL_LUMINANCE_ALPHA32F_ARB);
8975 }
8976
8977 // TODO(gman): Complete this test.
8978 // TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
8979 // }
8980
8981 // TODO(gman): BufferData
8982
8983 // TODO(gman): BufferDataImmediate
8984
8985 // TODO(gman): BufferSubData
8986
8987 // TODO(gman): BufferSubDataImmediate
8988
8989 // TODO(gman): CompressedTexImage2D
8990
8991 // TODO(gman): CompressedTexImage2DImmediate
8992
8993 // TODO(gman): CompressedTexSubImage2DImmediate
8994
8995 // TODO(gman): DeleteProgram
8996
8997 // TODO(gman): DeleteShader
8998
8999 // TODO(gman): PixelStorei
9000
9001 // TODO(gman): TexImage2D
9002
9003 // TODO(gman): TexImage2DImmediate
9004
9005 // TODO(gman): TexSubImage2DImmediate
9006
9007 // TODO(gman): UseProgram
9008
9009 // TODO(gman): SwapBuffers
9010
9011 }  // namespace gles2
9012 }  // namespace gpu