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