Upstream version 10.39.225.0
[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_unittest.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.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::AtLeast;
39 using ::testing::DoAll;
40 using ::testing::InSequence;
41 using ::testing::Invoke;
42 using ::testing::MatcherCast;
43 using ::testing::Mock;
44 using ::testing::Pointee;
45 using ::testing::Return;
46 using ::testing::SaveArg;
47 using ::testing::SetArrayArgument;
48 using ::testing::SetArgumentPointee;
49 using ::testing::SetArgPointee;
50 using ::testing::StrEq;
51 using ::testing::StrictMock;
52
53 namespace gpu {
54 namespace gles2 {
55
56 using namespace cmds;
57
58 void GLES2DecoderRGBBackbufferTest::SetUp() {
59   // Test codepath with workaround clear_alpha_in_readpixels because
60   // ReadPixelsEmulator emulates the incorrect driver behavior.
61   CommandLine command_line(0, NULL);
62   command_line.AppendSwitchASCII(
63       switches::kGpuDriverBugWorkarounds,
64       base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS));
65   InitState init;
66   init.gl_version = "3.0";
67   init.bind_generates_resource = true;
68   InitDecoderWithCommandLine(init, &command_line);
69   SetupDefaultProgram();
70 }
71
72 // Override default setup so nothing gets setup.
73 void GLES2DecoderManualInitTest::SetUp() {
74 }
75
76 void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap,
77                                                    bool enable,
78                                                    bool expect_set) {
79   if (expect_set) {
80     SetupExpectationsForEnableDisable(cap, enable);
81   }
82   if (enable) {
83     Enable cmd;
84     cmd.Init(cap);
85     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
86     EXPECT_EQ(GL_NO_ERROR, GetGLError());
87   } else {
88     Disable cmd;
89     cmd.Init(cap);
90     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
91     EXPECT_EQ(GL_NO_ERROR, GetGLError());
92   }
93 }
94
95 TEST_P(GLES2DecoderTest, GetIntegervCached) {
96   struct TestInfo {
97     GLenum pname;
98     GLint expected;
99   };
100   TestInfo tests[] = {
101       {
102        GL_MAX_TEXTURE_SIZE, TestHelper::kMaxTextureSize,
103       },
104       {
105        GL_MAX_CUBE_MAP_TEXTURE_SIZE, TestHelper::kMaxCubeMapTextureSize,
106       },
107       {
108        GL_MAX_RENDERBUFFER_SIZE, TestHelper::kMaxRenderbufferSize,
109       },
110   };
111   typedef GetIntegerv::Result Result;
112   for (size_t ii = 0; ii < sizeof(tests) / sizeof(tests[0]); ++ii) {
113     const TestInfo& test = tests[ii];
114     Result* result = static_cast<Result*>(shared_memory_address_);
115     EXPECT_CALL(*gl_, GetError())
116         .WillOnce(Return(GL_NO_ERROR))
117         .WillOnce(Return(GL_NO_ERROR))
118         .RetiresOnSaturation();
119     EXPECT_CALL(*gl_, GetIntegerv(test.pname, _)).Times(0);
120     result->size = 0;
121     GetIntegerv cmd2;
122     cmd2.Init(test.pname, shared_memory_id_, shared_memory_offset_);
123     EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
124     EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(test.pname),
125               result->GetNumResults());
126     EXPECT_EQ(GL_NO_ERROR, GetGLError());
127     EXPECT_EQ(test.expected, result->GetData()[0]);
128   }
129 }
130
131 TEST_P(GLES2DecoderWithShaderTest, GetMaxValueInBufferCHROMIUM) {
132   SetupIndexBuffer();
133   GetMaxValueInBufferCHROMIUM::Result* result =
134       static_cast<GetMaxValueInBufferCHROMIUM::Result*>(shared_memory_address_);
135   *result = 0;
136
137   GetMaxValueInBufferCHROMIUM cmd;
138   cmd.Init(client_element_buffer_id_,
139            kValidIndexRangeCount,
140            GL_UNSIGNED_SHORT,
141            kValidIndexRangeStart * 2,
142            kSharedMemoryId,
143            kSharedMemoryOffset);
144   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
145   EXPECT_EQ(7u, *result);
146   EXPECT_EQ(GL_NO_ERROR, GetGLError());
147   cmd.Init(client_element_buffer_id_,
148            kValidIndexRangeCount + 1,
149            GL_UNSIGNED_SHORT,
150            kValidIndexRangeStart * 2,
151            kSharedMemoryId,
152            kSharedMemoryOffset);
153   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
154   EXPECT_EQ(100u, *result);
155   EXPECT_EQ(GL_NO_ERROR, GetGLError());
156
157   cmd.Init(kInvalidClientId,
158            kValidIndexRangeCount,
159            GL_UNSIGNED_SHORT,
160            kValidIndexRangeStart * 2,
161            kSharedMemoryId,
162            kSharedMemoryOffset);
163   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
164   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
165   cmd.Init(client_element_buffer_id_,
166            kOutOfRangeIndexRangeEnd,
167            GL_UNSIGNED_SHORT,
168            kValidIndexRangeStart * 2,
169            kSharedMemoryId,
170            kSharedMemoryOffset);
171   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
172   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
173   cmd.Init(client_element_buffer_id_,
174            kValidIndexRangeCount + 1,
175            GL_UNSIGNED_SHORT,
176            kOutOfRangeIndexRangeEnd * 2,
177            kSharedMemoryId,
178            kSharedMemoryOffset);
179   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
180   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
181   cmd.Init(client_element_buffer_id_,
182            kValidIndexRangeCount + 1,
183            GL_UNSIGNED_SHORT,
184            kValidIndexRangeStart * 2,
185            kSharedMemoryId,
186            kSharedMemoryOffset);
187   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
188   cmd.Init(client_buffer_id_,
189            kValidIndexRangeCount + 1,
190            GL_UNSIGNED_SHORT,
191            kValidIndexRangeStart * 2,
192            kSharedMemoryId,
193            kSharedMemoryOffset);
194   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
195   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
196   cmd.Init(client_element_buffer_id_,
197            kValidIndexRangeCount + 1,
198            GL_UNSIGNED_SHORT,
199            kValidIndexRangeStart * 2,
200            kInvalidSharedMemoryId,
201            kSharedMemoryOffset);
202   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
203   cmd.Init(client_element_buffer_id_,
204            kValidIndexRangeCount + 1,
205            GL_UNSIGNED_SHORT,
206            kValidIndexRangeStart * 2,
207            kSharedMemoryId,
208            kInvalidSharedMemoryOffset);
209   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
210 }
211
212 TEST_P(GLES2DecoderTest, SharedIds) {
213   GenSharedIdsCHROMIUM gen_cmd;
214   RegisterSharedIdsCHROMIUM reg_cmd;
215   DeleteSharedIdsCHROMIUM del_cmd;
216
217   const GLuint kNamespaceId = id_namespaces::kTextures;
218   const GLuint kExpectedId1 = 1;
219   const GLuint kExpectedId2 = 2;
220   const GLuint kExpectedId3 = 4;
221   const GLuint kRegisterId = 3;
222   GLuint* ids = GetSharedMemoryAs<GLuint*>();
223   gen_cmd.Init(kNamespaceId, 0, 2, kSharedMemoryId, kSharedMemoryOffset);
224   EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
225   IdAllocatorInterface* id_allocator = GetIdAllocator(kNamespaceId);
226   ASSERT_TRUE(id_allocator != NULL);
227   // This check is implementation dependant but it's kind of hard to check
228   // otherwise.
229   EXPECT_EQ(kExpectedId1, ids[0]);
230   EXPECT_EQ(kExpectedId2, ids[1]);
231   EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
232   EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
233   EXPECT_FALSE(id_allocator->InUse(kRegisterId));
234   EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
235
236   ClearSharedMemory();
237   ids[0] = kRegisterId;
238   reg_cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
239   EXPECT_EQ(error::kNoError, ExecuteCmd(reg_cmd));
240   EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
241   EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
242   EXPECT_TRUE(id_allocator->InUse(kRegisterId));
243   EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
244
245   ClearSharedMemory();
246   gen_cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kSharedMemoryOffset);
247   EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
248   EXPECT_EQ(kExpectedId3, ids[0]);
249   EXPECT_TRUE(id_allocator->InUse(kExpectedId1));
250   EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
251   EXPECT_TRUE(id_allocator->InUse(kRegisterId));
252   EXPECT_TRUE(id_allocator->InUse(kExpectedId3));
253
254   ClearSharedMemory();
255   ids[0] = kExpectedId1;
256   ids[1] = kRegisterId;
257   del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset);
258   EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd));
259   EXPECT_FALSE(id_allocator->InUse(kExpectedId1));
260   EXPECT_TRUE(id_allocator->InUse(kExpectedId2));
261   EXPECT_FALSE(id_allocator->InUse(kRegisterId));
262   EXPECT_TRUE(id_allocator->InUse(kExpectedId3));
263
264   ClearSharedMemory();
265   ids[0] = kExpectedId3;
266   ids[1] = kExpectedId2;
267   del_cmd.Init(kNamespaceId, 2, kSharedMemoryId, kSharedMemoryOffset);
268   EXPECT_EQ(error::kNoError, ExecuteCmd(del_cmd));
269   EXPECT_FALSE(id_allocator->InUse(kExpectedId1));
270   EXPECT_FALSE(id_allocator->InUse(kExpectedId2));
271   EXPECT_FALSE(id_allocator->InUse(kRegisterId));
272   EXPECT_FALSE(id_allocator->InUse(kExpectedId3));
273
274   // Check passing in an id_offset.
275   ClearSharedMemory();
276   const GLuint kOffset = 0xABCDEF;
277   gen_cmd.Init(kNamespaceId, kOffset, 2, kSharedMemoryId, kSharedMemoryOffset);
278   EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd));
279   EXPECT_EQ(kOffset, ids[0]);
280   EXPECT_EQ(kOffset + 1, ids[1]);
281 }
282
283 TEST_P(GLES2DecoderTest, GenSharedIdsCHROMIUMBadArgs) {
284   const GLuint kNamespaceId = id_namespaces::kTextures;
285   GenSharedIdsCHROMIUM cmd;
286   cmd.Init(kNamespaceId, 0, -1, kSharedMemoryId, kSharedMemoryOffset);
287   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
288   cmd.Init(kNamespaceId, 0, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
289   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
290   cmd.Init(kNamespaceId, 0, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
291   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
292 }
293
294 TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMBadArgs) {
295   const GLuint kNamespaceId = id_namespaces::kTextures;
296   RegisterSharedIdsCHROMIUM cmd;
297   cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
298   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
299   cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
300   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
301   cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
302   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
303 }
304
305 TEST_P(GLES2DecoderTest, RegisterSharedIdsCHROMIUMDuplicateIds) {
306   const GLuint kNamespaceId = id_namespaces::kTextures;
307   const GLuint kRegisterId = 3;
308   RegisterSharedIdsCHROMIUM cmd;
309   GLuint* ids = GetSharedMemoryAs<GLuint*>();
310   ids[0] = kRegisterId;
311   cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
312   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
313   cmd.Init(kNamespaceId, 1, kSharedMemoryId, kSharedMemoryOffset);
314   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
315   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
316 }
317
318 TEST_P(GLES2DecoderTest, DeleteSharedIdsCHROMIUMBadArgs) {
319   const GLuint kNamespaceId = id_namespaces::kTextures;
320   DeleteSharedIdsCHROMIUM cmd;
321   cmd.Init(kNamespaceId, -1, kSharedMemoryId, kSharedMemoryOffset);
322   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
323   cmd.Init(kNamespaceId, 1, kInvalidSharedMemoryId, kSharedMemoryOffset);
324   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
325   cmd.Init(kNamespaceId, 1, kSharedMemoryId, kInvalidSharedMemoryOffset);
326   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
327 }
328
329 TEST_P(GLES2DecoderTest, IsBuffer) {
330   EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
331   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
332   EXPECT_TRUE(DoIsBuffer(client_buffer_id_));
333   DoDeleteBuffer(client_buffer_id_, kServiceBufferId);
334   EXPECT_FALSE(DoIsBuffer(client_buffer_id_));
335 }
336
337 TEST_P(GLES2DecoderTest, IsFramebuffer) {
338   EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
339   DoBindFramebuffer(
340       GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
341   EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_));
342   DoDeleteFramebuffer(client_framebuffer_id_,
343                       kServiceFramebufferId,
344                       true,
345                       GL_FRAMEBUFFER,
346                       0,
347                       true,
348                       GL_FRAMEBUFFER,
349                       0);
350   EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_));
351 }
352
353 TEST_P(GLES2DecoderTest, IsProgram) {
354   // IsProgram is true as soon as the program is created.
355   EXPECT_TRUE(DoIsProgram(client_program_id_));
356   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
357       .Times(1)
358       .RetiresOnSaturation();
359   DoDeleteProgram(client_program_id_, kServiceProgramId);
360   EXPECT_FALSE(DoIsProgram(client_program_id_));
361 }
362
363 TEST_P(GLES2DecoderTest, IsRenderbuffer) {
364   EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
365   DoBindRenderbuffer(
366       GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
367   EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_));
368   DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
369   EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_));
370 }
371
372 TEST_P(GLES2DecoderTest, IsShader) {
373   // IsShader is true as soon as the program is created.
374   EXPECT_TRUE(DoIsShader(client_shader_id_));
375   DoDeleteShader(client_shader_id_, kServiceShaderId);
376   EXPECT_FALSE(DoIsShader(client_shader_id_));
377 }
378
379 TEST_P(GLES2DecoderTest, IsTexture) {
380   EXPECT_FALSE(DoIsTexture(client_texture_id_));
381   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
382   EXPECT_TRUE(DoIsTexture(client_texture_id_));
383   DoDeleteTexture(client_texture_id_, kServiceTextureId);
384   EXPECT_FALSE(DoIsTexture(client_texture_id_));
385 }
386
387 TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMValidArgs) {
388   const GLsizei kCount = 3;
389   GLenum* pnames = GetSharedMemoryAs<GLenum*>();
390   pnames[0] = GL_DEPTH_WRITEMASK;
391   pnames[1] = GL_COLOR_WRITEMASK;
392   pnames[2] = GL_STENCIL_WRITEMASK;
393   GLint* results =
394       GetSharedMemoryAsWithOffset<GLint*>(sizeof(*pnames) * kCount);
395
396   GLsizei num_results = 0;
397   for (GLsizei ii = 0; ii < kCount; ++ii) {
398     num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
399   }
400   const GLsizei result_size = num_results * sizeof(*results);
401   memset(results, 0, result_size);
402
403   const GLint kSentinel = 0x12345678;
404   results[num_results] = kSentinel;
405
406   GetMultipleIntegervCHROMIUM cmd;
407   cmd.Init(kSharedMemoryId,
408            kSharedMemoryOffset,
409            kCount,
410            kSharedMemoryId,
411            kSharedMemoryOffset + sizeof(*pnames) * kCount,
412            result_size);
413
414   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
415   EXPECT_EQ(GL_NO_ERROR, GetGLError());
416   EXPECT_EQ(1, results[0]);                    // Depth writemask
417   EXPECT_EQ(1, results[1]);                    // color writemask red
418   EXPECT_EQ(1, results[2]);                    // color writemask green
419   EXPECT_EQ(1, results[3]);                    // color writemask blue
420   EXPECT_EQ(1, results[4]);                    // color writemask alpha
421   EXPECT_EQ(-1, results[5]);                   // stencil writemask alpha
422   EXPECT_EQ(kSentinel, results[num_results]);  // End of results
423 }
424
425 TEST_P(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) {
426   const GLsizei kCount = 3;
427   // Offset the pnames because GLGetError will use the first uint32.
428   const uint32 kPnameOffset = sizeof(uint32);
429   const uint32 kResultsOffset = kPnameOffset + sizeof(GLint) * kCount;
430   GLenum* pnames = GetSharedMemoryAsWithOffset<GLenum*>(kPnameOffset);
431   pnames[0] = GL_DEPTH_WRITEMASK;
432   pnames[1] = GL_COLOR_WRITEMASK;
433   pnames[2] = GL_STENCIL_WRITEMASK;
434   GLint* results = GetSharedMemoryAsWithOffset<GLint*>(kResultsOffset);
435
436   GLsizei num_results = 0;
437   for (GLsizei ii = 0; ii < kCount; ++ii) {
438     num_results += decoder_->GetGLES2Util()->GLGetNumValuesReturned(pnames[ii]);
439   }
440   const GLsizei result_size = num_results * sizeof(*results);
441   memset(results, 0, result_size);
442
443   const GLint kSentinel = 0x12345678;
444   results[num_results] = kSentinel;
445
446   GetMultipleIntegervCHROMIUM cmd;
447   // Check bad pnames pointer.
448   cmd.Init(kInvalidSharedMemoryId,
449            kSharedMemoryOffset + kPnameOffset,
450            kCount,
451            kSharedMemoryId,
452            kSharedMemoryOffset + kResultsOffset,
453            result_size);
454   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
455   EXPECT_EQ(GL_NO_ERROR, GetGLError());
456   // Check bad pnames pointer.
457   cmd.Init(kSharedMemoryId,
458            kInvalidSharedMemoryOffset,
459            kCount,
460            kSharedMemoryId,
461            kSharedMemoryOffset + kResultsOffset,
462            result_size);
463   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
464   EXPECT_EQ(GL_NO_ERROR, GetGLError());
465   // Check bad count.
466   cmd.Init(kSharedMemoryId,
467            kSharedMemoryOffset + kPnameOffset,
468            static_cast<GLuint>(-1),
469            kSharedMemoryId,
470            kSharedMemoryOffset + kResultsOffset,
471            result_size);
472   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
473   EXPECT_EQ(GL_NO_ERROR, GetGLError());
474   // Check bad results pointer.
475   cmd.Init(kSharedMemoryId,
476            kSharedMemoryOffset + kPnameOffset,
477            kCount,
478            kInvalidSharedMemoryId,
479            kSharedMemoryOffset + kResultsOffset,
480            result_size);
481   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
482   EXPECT_EQ(GL_NO_ERROR, GetGLError());
483   // Check bad results pointer.
484   cmd.Init(kSharedMemoryId,
485            kSharedMemoryOffset + kPnameOffset,
486            kCount,
487            kSharedMemoryId,
488            kInvalidSharedMemoryOffset,
489            result_size);
490   EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
491   EXPECT_EQ(GL_NO_ERROR, GetGLError());
492   // Check bad size.
493   cmd.Init(kSharedMemoryId,
494            kSharedMemoryOffset + kPnameOffset,
495            kCount,
496            kSharedMemoryId,
497            kSharedMemoryOffset + kResultsOffset,
498            result_size + 1);
499   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
500   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
501   // Check bad size.
502   cmd.Init(kSharedMemoryId,
503            kSharedMemoryOffset + kPnameOffset,
504            kCount,
505            kSharedMemoryId,
506            kSharedMemoryOffset + kResultsOffset,
507            result_size - 1);
508   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
509   EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
510   // Check bad enum.
511   cmd.Init(kSharedMemoryId,
512            kSharedMemoryOffset + kPnameOffset,
513            kCount,
514            kSharedMemoryId,
515            kSharedMemoryOffset + kResultsOffset,
516            result_size);
517   GLenum temp = pnames[2];
518   pnames[2] = GL_TRUE;
519   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
520   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
521   pnames[2] = temp;
522   // Check results area has not been cleared by client.
523   results[1] = 1;
524   EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
525   // Check buffer is what we expect
526   EXPECT_EQ(0, results[0]);
527   EXPECT_EQ(1, results[1]);
528   EXPECT_EQ(0, results[2]);
529   EXPECT_EQ(0, results[3]);
530   EXPECT_EQ(0, results[4]);
531   EXPECT_EQ(0, results[5]);
532   EXPECT_EQ(kSentinel, results[num_results]);  // End of results
533 }
534
535 TEST_P(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) {
536   InitState init;
537   init.gl_version = "3.0";
538   InitDecoder(init);
539
540   BindTexture cmd1;
541   cmd1.Init(GL_TEXTURE_2D, kInvalidClientId);
542   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd1));
543   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
544
545   BindBuffer cmd2;
546   cmd2.Init(GL_ARRAY_BUFFER, kInvalidClientId);
547   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
548   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
549
550   BindFramebuffer cmd3;
551   cmd3.Init(GL_FRAMEBUFFER, kInvalidClientId);
552   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd3));
553   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
554
555   BindRenderbuffer cmd4;
556   cmd4.Init(GL_RENDERBUFFER, kInvalidClientId);
557   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd4));
558   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
559 }
560
561 TEST_P(GLES2DecoderTest, EnableFeatureCHROMIUMBadBucket) {
562   const uint32 kBadBucketId = 123;
563   EnableFeatureCHROMIUM cmd;
564   cmd.Init(kBadBucketId, shared_memory_id_, shared_memory_offset_);
565   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
566 }
567
568 TEST_P(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
569   const uint32 kBadBucketId = 123;
570   RequestExtensionCHROMIUM cmd;
571   cmd.Init(kBadBucketId);
572   EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
573 }
574
575 TEST_P(GLES2DecoderTest, BeginQueryEXTDisabled) {
576   // Test something fails if off.
577 }
578
579 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXT) {
580   InitState init;
581   init.extensions = "GL_EXT_occlusion_query_boolean";
582   init.gl_version = "opengl es 2.0";
583   init.has_alpha = true;
584   init.request_alpha = true;
585   init.bind_generates_resource = true;
586   InitDecoder(init);
587
588   // Test end fails if no begin.
589   EndQueryEXT end_cmd;
590   end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
591   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
592   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
593
594   BeginQueryEXT begin_cmd;
595
596   // Test id = 0 fails.
597   begin_cmd.Init(
598       GL_ANY_SAMPLES_PASSED_EXT, 0, kSharedMemoryId, kSharedMemoryOffset);
599   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
600   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
601
602   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
603
604   // Test valid parameters work.
605   EXPECT_CALL(*gl_, GenQueriesARB(1, _))
606       .WillOnce(SetArgumentPointee<1>(kNewServiceId))
607       .RetiresOnSaturation();
608   EXPECT_CALL(*gl_, BeginQueryARB(GL_ANY_SAMPLES_PASSED_EXT, kNewServiceId))
609       .Times(1)
610       .RetiresOnSaturation();
611
612   // Query object should not be created untill BeginQueriesEXT.
613   QueryManager* query_manager = decoder_->GetQueryManager();
614   ASSERT_TRUE(query_manager != NULL);
615   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
616   EXPECT_TRUE(query == NULL);
617
618   // BeginQueryEXT should fail  if id is not generated from GenQueriesEXT.
619   begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
620                  kInvalidClientId,
621                  kSharedMemoryId,
622                  kSharedMemoryOffset);
623   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
624   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
625
626   begin_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT,
627                  kNewClientId,
628                  kSharedMemoryId,
629                  kSharedMemoryOffset);
630   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
631   EXPECT_EQ(GL_NO_ERROR, GetGLError());
632
633   // After BeginQueriesEXT id name should have query object associated with it.
634   query = query_manager->GetQuery(kNewClientId);
635   ASSERT_TRUE(query != NULL);
636   EXPECT_FALSE(query->pending());
637
638   // Test trying begin again fails
639   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
640   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
641
642   // Test end fails with different target
643   end_cmd.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1);
644   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
645   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
646
647   // Test end succeeds
648   EXPECT_CALL(*gl_, EndQueryARB(GL_ANY_SAMPLES_PASSED_EXT))
649       .Times(1)
650       .RetiresOnSaturation();
651   end_cmd.Init(GL_ANY_SAMPLES_PASSED_EXT, 1);
652   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
653   EXPECT_EQ(GL_NO_ERROR, GetGLError());
654   EXPECT_TRUE(query->pending());
655
656   EXPECT_CALL(*gl_, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation();
657 }
658
659 struct QueryType {
660   GLenum type;
661   bool is_gl;
662 };
663
664 const QueryType kQueryTypes[] = {
665     {GL_COMMANDS_ISSUED_CHROMIUM, false},
666     {GL_LATENCY_QUERY_CHROMIUM, false},
667     {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, false},
668     {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, false},
669     {GL_GET_ERROR_QUERY_CHROMIUM, false},
670     {GL_COMMANDS_COMPLETED_CHROMIUM, false},
671     {GL_ANY_SAMPLES_PASSED_EXT, true},
672 };
673
674 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
675                                              GLuint client_id,
676                                              GLuint service_id,
677                                              const QueryType& query_type,
678                                              int32 shm_id,
679                                              uint32 shm_offset) {
680   // We need to reset the decoder on each iteration, because we lose the
681   // context every time.
682   GLES2DecoderTestBase::InitState init;
683   init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
684   init.gl_version = "opengl es 2.0";
685   init.has_alpha = true;
686   init.request_alpha = true;
687   init.bind_generates_resource = true;
688   test->InitDecoder(init);
689   ::testing::StrictMock< ::gfx::MockGLInterface>* gl = test->GetGLMock();
690
691   BeginQueryEXT begin_cmd;
692
693   test->GenHelper<GenQueriesEXTImmediate>(client_id);
694
695   if (query_type.is_gl) {
696     EXPECT_CALL(*gl, GenQueriesARB(1, _))
697         .WillOnce(SetArgumentPointee<1>(service_id))
698         .RetiresOnSaturation();
699     EXPECT_CALL(*gl, BeginQueryARB(query_type.type, service_id))
700         .Times(1)
701         .RetiresOnSaturation();
702   }
703
704   // Test bad shared memory fails
705   begin_cmd.Init(query_type.type, client_id, shm_id, shm_offset);
706   error::Error error1 = test->ExecuteCmd(begin_cmd);
707
708   if (query_type.is_gl) {
709     EXPECT_CALL(*gl, EndQueryARB(query_type.type))
710         .Times(1)
711         .RetiresOnSaturation();
712   }
713   if (query_type.type == GL_GET_ERROR_QUERY_CHROMIUM) {
714     EXPECT_CALL(*gl, GetError())
715         .WillOnce(Return(GL_NO_ERROR))
716         .RetiresOnSaturation();
717   }
718   GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
719   if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
720     EXPECT_CALL(*gl, Flush()).RetiresOnSaturation();
721     EXPECT_CALL(*gl, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
722         .WillOnce(Return(kGlSync))
723         .RetiresOnSaturation();
724 #if DCHECK_IS_ON
725     EXPECT_CALL(*gl, IsSync(kGlSync))
726         .WillOnce(Return(GL_TRUE))
727         .RetiresOnSaturation();
728 #endif
729   }
730
731   EndQueryEXT end_cmd;
732   end_cmd.Init(query_type.type, 1);
733   error::Error error2 = test->ExecuteCmd(end_cmd);
734
735   if (query_type.is_gl) {
736     EXPECT_CALL(
737         *gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
738         .WillOnce(SetArgumentPointee<2>(1))
739         .RetiresOnSaturation();
740     EXPECT_CALL(*gl, GetQueryObjectuivARB(service_id, GL_QUERY_RESULT_EXT, _))
741         .WillOnce(SetArgumentPointee<2>(1))
742         .RetiresOnSaturation();
743   }
744   if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
745 #if DCHECK_IS_ON
746     EXPECT_CALL(*gl, IsSync(kGlSync))
747         .WillOnce(Return(GL_TRUE))
748         .RetiresOnSaturation();
749 #endif
750     EXPECT_CALL(*gl, ClientWaitSync(kGlSync, _, _))
751         .WillOnce(Return(GL_ALREADY_SIGNALED))
752         .RetiresOnSaturation();
753   }
754
755   QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
756   ASSERT_TRUE(query_manager != NULL);
757   bool process_success = query_manager->ProcessPendingQueries();
758
759   EXPECT_TRUE(error1 != error::kNoError || error2 != error::kNoError ||
760               !process_success);
761
762   if (query_type.is_gl) {
763     EXPECT_CALL(*gl, DeleteQueriesARB(1, _)).Times(1).RetiresOnSaturation();
764   }
765   if (query_type.type == GL_COMMANDS_COMPLETED_CHROMIUM) {
766 #if DCHECK_IS_ON
767     EXPECT_CALL(*gl, IsSync(kGlSync))
768         .WillOnce(Return(GL_TRUE))
769         .RetiresOnSaturation();
770 #endif
771     EXPECT_CALL(*gl, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
772   }
773   test->ResetDecoder();
774 }
775
776 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
777   for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
778     CheckBeginEndQueryBadMemoryFails(this,
779                                      kNewClientId,
780                                      kNewServiceId,
781                                      kQueryTypes[i],
782                                      kInvalidSharedMemoryId,
783                                      kSharedMemoryOffset);
784   }
785 }
786
787 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
788   for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
789     // Out-of-bounds.
790     CheckBeginEndQueryBadMemoryFails(this,
791                                      kNewClientId,
792                                      kNewServiceId,
793                                      kQueryTypes[i],
794                                      kSharedMemoryId,
795                                      kInvalidSharedMemoryOffset);
796     // Overflow.
797     CheckBeginEndQueryBadMemoryFails(this,
798                                      kNewClientId,
799                                      kNewServiceId,
800                                      kQueryTypes[i],
801                                      kSharedMemoryId,
802                                      0xfffffffcu);
803   }
804 }
805
806 TEST_P(GLES2DecoderTest, BeginEndQueryEXTCommandsIssuedCHROMIUM) {
807   BeginQueryEXT begin_cmd;
808
809   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
810
811   // Test valid parameters work.
812   begin_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM,
813                  kNewClientId,
814                  kSharedMemoryId,
815                  kSharedMemoryOffset);
816   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
817   EXPECT_EQ(GL_NO_ERROR, GetGLError());
818
819   QueryManager* query_manager = decoder_->GetQueryManager();
820   ASSERT_TRUE(query_manager != NULL);
821   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
822   ASSERT_TRUE(query != NULL);
823   EXPECT_FALSE(query->pending());
824
825   // Test end succeeds
826   EndQueryEXT end_cmd;
827   end_cmd.Init(GL_COMMANDS_ISSUED_CHROMIUM, 1);
828   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
829   EXPECT_EQ(GL_NO_ERROR, GetGLError());
830   EXPECT_FALSE(query->pending());
831 }
832
833 TEST_P(GLES2DecoderTest, BeginEndQueryEXTGetErrorQueryCHROMIUM) {
834   BeginQueryEXT begin_cmd;
835
836   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
837
838   // Test valid parameters work.
839   begin_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM,
840                  kNewClientId,
841                  kSharedMemoryId,
842                  kSharedMemoryOffset);
843   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
844   EXPECT_EQ(GL_NO_ERROR, GetGLError());
845
846   QueryManager* query_manager = decoder_->GetQueryManager();
847   ASSERT_TRUE(query_manager != NULL);
848   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
849   ASSERT_TRUE(query != NULL);
850   EXPECT_FALSE(query->pending());
851
852   // Test end succeeds
853   QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
854
855   EXPECT_CALL(*gl_, GetError())
856       .WillOnce(Return(GL_INVALID_VALUE))
857       .RetiresOnSaturation();
858
859   EndQueryEXT end_cmd;
860   end_cmd.Init(GL_GET_ERROR_QUERY_CHROMIUM, 1);
861   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
862   EXPECT_EQ(GL_NO_ERROR, GetGLError());
863   EXPECT_FALSE(query->pending());
864   EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE),
865             static_cast<GLenum>(sync->result));
866 }
867
868 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTCommandsCompletedCHROMIUM) {
869   InitState init;
870   init.extensions = "GL_EXT_occlusion_query_boolean GL_ARB_sync";
871   init.gl_version = "opengl es 2.0";
872   init.has_alpha = true;
873   init.request_alpha = true;
874   init.bind_generates_resource = true;
875   InitDecoder(init);
876
877   GenHelper<GenQueriesEXTImmediate>(kNewClientId);
878
879   BeginQueryEXT begin_cmd;
880   begin_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM,
881                  kNewClientId,
882                  kSharedMemoryId,
883                  kSharedMemoryOffset);
884   EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd));
885   EXPECT_EQ(GL_NO_ERROR, GetGLError());
886
887   QueryManager* query_manager = decoder_->GetQueryManager();
888   ASSERT_TRUE(query_manager != NULL);
889   QueryManager::Query* query = query_manager->GetQuery(kNewClientId);
890   ASSERT_TRUE(query != NULL);
891   EXPECT_FALSE(query->pending());
892
893   GLsync kGlSync = reinterpret_cast<GLsync>(0xdeadbeef);
894   EXPECT_CALL(*gl_, Flush()).RetiresOnSaturation();
895   EXPECT_CALL(*gl_, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
896       .WillOnce(Return(kGlSync))
897       .RetiresOnSaturation();
898 #if DCHECK_IS_ON
899   EXPECT_CALL(*gl_, IsSync(kGlSync))
900       .WillOnce(Return(GL_TRUE))
901       .RetiresOnSaturation();
902 #endif
903
904   EndQueryEXT end_cmd;
905   end_cmd.Init(GL_COMMANDS_COMPLETED_CHROMIUM, 1);
906   EXPECT_EQ(error::kNoError, ExecuteCmd(end_cmd));
907   EXPECT_EQ(GL_NO_ERROR, GetGLError());
908   EXPECT_TRUE(query->pending());
909
910 #if DCHECK_IS_ON
911   EXPECT_CALL(*gl_, IsSync(kGlSync))
912       .WillOnce(Return(GL_TRUE))
913       .RetiresOnSaturation();
914 #endif
915   EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
916       .WillOnce(Return(GL_TIMEOUT_EXPIRED))
917       .RetiresOnSaturation();
918   bool process_success = query_manager->ProcessPendingQueries();
919
920   EXPECT_TRUE(process_success);
921   EXPECT_TRUE(query->pending());
922
923 #if DCHECK_IS_ON
924   EXPECT_CALL(*gl_, IsSync(kGlSync))
925       .WillOnce(Return(GL_TRUE))
926       .RetiresOnSaturation();
927 #endif
928   EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
929       .WillOnce(Return(GL_ALREADY_SIGNALED))
930       .RetiresOnSaturation();
931   process_success = query_manager->ProcessPendingQueries();
932
933   EXPECT_TRUE(process_success);
934   EXPECT_FALSE(query->pending());
935   QuerySync* sync = static_cast<QuerySync*>(shared_memory_address_);
936   EXPECT_EQ(static_cast<GLenum>(0), static_cast<GLenum>(sync->result));
937
938 #if DCHECK_IS_ON
939   EXPECT_CALL(*gl_, IsSync(kGlSync))
940       .WillOnce(Return(GL_TRUE))
941       .RetiresOnSaturation();
942 #endif
943   EXPECT_CALL(*gl_, DeleteSync(kGlSync)).Times(1).RetiresOnSaturation();
944   ResetDecoder();
945 }
946
947 TEST_P(GLES2DecoderTest, IsEnabledReturnsCachedValue) {
948   // NOTE: There are no expectations because no GL functions should be
949   // called for DEPTH_TEST or STENCIL_TEST
950   static const GLenum kStates[] = {
951       GL_DEPTH_TEST, GL_STENCIL_TEST,
952   };
953   for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
954     Enable enable_cmd;
955     GLenum state = kStates[ii];
956     enable_cmd.Init(state);
957     EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
958     IsEnabled::Result* result =
959         static_cast<IsEnabled::Result*>(shared_memory_address_);
960     IsEnabled is_enabled_cmd;
961     is_enabled_cmd.Init(state, shared_memory_id_, shared_memory_offset_);
962     EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
963     EXPECT_NE(0u, *result);
964     Disable disable_cmd;
965     disable_cmd.Init(state);
966     EXPECT_EQ(error::kNoError, ExecuteCmd(disable_cmd));
967     EXPECT_EQ(error::kNoError, ExecuteCmd(is_enabled_cmd));
968     EXPECT_EQ(0u, *result);
969   }
970 }
971
972 TEST_P(GLES2DecoderManualInitTest, GpuMemoryManagerCHROMIUM) {
973   InitState init;
974   init.extensions = "GL_ARB_texture_rectangle";
975   init.gl_version = "3.0";
976   init.bind_generates_resource = true;
977   InitDecoder(init);
978
979   Texture* texture = GetTexture(client_texture_id_)->texture();
980   EXPECT_TRUE(texture != NULL);
981   EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
982
983   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
984
985   TexParameteri cmd;
986   cmd.Init(GL_TEXTURE_2D,
987            GL_TEXTURE_POOL_CHROMIUM,
988            GL_TEXTURE_POOL_UNMANAGED_CHROMIUM);
989   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
990   EXPECT_EQ(GL_NO_ERROR, GetGLError());
991
992   cmd.Init(GL_TEXTURE_2D,
993            GL_TEXTURE_POOL_CHROMIUM,
994            GL_TEXTURE_POOL_MANAGED_CHROMIUM);
995   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
996   EXPECT_EQ(GL_NO_ERROR, GetGLError());
997
998   EXPECT_TRUE(texture->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM);
999
1000   cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_NONE);
1001   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1002   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1003 }
1004
1005 namespace {
1006
1007 class SizeOnlyMemoryTracker : public MemoryTracker {
1008  public:
1009   SizeOnlyMemoryTracker() {
1010     // These are the default textures. 1 for TEXTURE_2D and 6 faces for
1011     // TEXTURE_CUBE_MAP.
1012     const size_t kInitialUnmanagedPoolSize = 7 * 4;
1013     const size_t kInitialManagedPoolSize = 0;
1014     pool_infos_[MemoryTracker::kUnmanaged].initial_size =
1015         kInitialUnmanagedPoolSize;
1016     pool_infos_[MemoryTracker::kManaged].initial_size = kInitialManagedPoolSize;
1017   }
1018
1019   // Ensure a certain amount of GPU memory is free. Returns true on success.
1020   MOCK_METHOD1(EnsureGPUMemoryAvailable, bool(size_t size_needed));
1021
1022   virtual void TrackMemoryAllocatedChange(size_t old_size,
1023                                           size_t new_size,
1024                                           Pool pool) {
1025     PoolInfo& info = pool_infos_[pool];
1026     info.size += new_size - old_size;
1027   }
1028
1029   size_t GetPoolSize(Pool pool) {
1030     const PoolInfo& info = pool_infos_[pool];
1031     return info.size - info.initial_size;
1032   }
1033
1034  private:
1035   virtual ~SizeOnlyMemoryTracker() {}
1036   struct PoolInfo {
1037     PoolInfo() : initial_size(0), size(0) {}
1038     size_t initial_size;
1039     size_t size;
1040   };
1041   std::map<Pool, PoolInfo> pool_infos_;
1042 };
1043
1044 }  // anonymous namespace.
1045
1046 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerInitialSize) {
1047   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1048       new SizeOnlyMemoryTracker();
1049   set_memory_tracker(memory_tracker.get());
1050   InitState init;
1051   init.gl_version = "3.0";
1052   init.bind_generates_resource = true;
1053   InitDecoder(init);
1054   // Expect that initial size - size is 0.
1055   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1056   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1057 }
1058
1059 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexImage2D) {
1060   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1061       new SizeOnlyMemoryTracker();
1062   set_memory_tracker(memory_tracker.get());
1063   InitState init;
1064   init.gl_version = "3.0";
1065   init.bind_generates_resource = true;
1066   InitDecoder(init);
1067   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1068   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1069       .WillOnce(Return(true))
1070       .RetiresOnSaturation();
1071   DoTexImage2D(GL_TEXTURE_2D,
1072                0,
1073                GL_RGBA,
1074                8,
1075                4,
1076                0,
1077                GL_RGBA,
1078                GL_UNSIGNED_BYTE,
1079                kSharedMemoryId,
1080                kSharedMemoryOffset);
1081   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1082   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
1083       .WillOnce(Return(true))
1084       .RetiresOnSaturation();
1085   DoTexImage2D(GL_TEXTURE_2D,
1086                0,
1087                GL_RGBA,
1088                4,
1089                4,
1090                0,
1091                GL_RGBA,
1092                GL_UNSIGNED_BYTE,
1093                kSharedMemoryId,
1094                kSharedMemoryOffset);
1095   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1096   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1097   // Check we get out of memory and no call to glTexImage2D if Ensure fails.
1098   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(64))
1099       .WillOnce(Return(false))
1100       .RetiresOnSaturation();
1101   TexImage2D cmd;
1102   cmd.Init(GL_TEXTURE_2D,
1103            0,
1104            GL_RGBA,
1105            4,
1106            4,
1107            GL_RGBA,
1108            GL_UNSIGNED_BYTE,
1109            kSharedMemoryId,
1110            kSharedMemoryOffset);
1111   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1112   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1113   EXPECT_EQ(64u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1114 }
1115
1116 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerTexStorage2DEXT) {
1117   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1118       new SizeOnlyMemoryTracker();
1119   set_memory_tracker(memory_tracker.get());
1120   InitState init;
1121   init.gl_version = "3.0";
1122   init.bind_generates_resource = true;
1123   InitDecoder(init);
1124   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1125   // Check we get out of memory and no call to glTexStorage2DEXT
1126   // if Ensure fails.
1127   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1128       .WillOnce(Return(false))
1129       .RetiresOnSaturation();
1130   TexStorage2DEXT cmd;
1131   cmd.Init(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 4);
1132   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1133   EXPECT_EQ(0u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1134   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1135 }
1136
1137 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerCopyTexImage2D) {
1138   GLenum target = GL_TEXTURE_2D;
1139   GLint level = 0;
1140   GLenum internal_format = GL_RGBA;
1141   GLsizei width = 4;
1142   GLsizei height = 8;
1143   GLint border = 0;
1144   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1145       new SizeOnlyMemoryTracker();
1146   set_memory_tracker(memory_tracker.get());
1147   InitState init;
1148   init.gl_version = "3.0";
1149   init.has_alpha = true;
1150   init.request_alpha = true;
1151   init.bind_generates_resource = true;
1152   InitDecoder(init);
1153   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1154   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1155       .WillOnce(Return(true))
1156       .RetiresOnSaturation();
1157   EXPECT_CALL(*gl_, GetError())
1158       .WillOnce(Return(GL_NO_ERROR))
1159       .WillOnce(Return(GL_NO_ERROR))
1160       .RetiresOnSaturation();
1161   EXPECT_CALL(*gl_,
1162               CopyTexImage2D(
1163                   target, level, internal_format, 0, 0, width, height, border))
1164       .Times(1)
1165       .RetiresOnSaturation();
1166   CopyTexImage2D cmd;
1167   cmd.Init(target, level, internal_format, 0, 0, width, height);
1168   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1169   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1170   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1171   // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1172   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1173       .WillOnce(Return(false))
1174       .RetiresOnSaturation();
1175   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1176   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1177   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1178 }
1179
1180 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerRenderbufferStorage) {
1181   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1182       new SizeOnlyMemoryTracker();
1183   set_memory_tracker(memory_tracker.get());
1184   InitState init;
1185   init.gl_version = "3.0";
1186   init.bind_generates_resource = true;
1187   InitDecoder(init);
1188   DoBindRenderbuffer(
1189       GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1190   EnsureRenderbufferBound(false);
1191   EXPECT_CALL(*gl_, GetError())
1192       .WillOnce(Return(GL_NO_ERROR))
1193       .WillOnce(Return(GL_NO_ERROR))
1194       .RetiresOnSaturation();
1195   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1196       .WillOnce(Return(true))
1197       .RetiresOnSaturation();
1198   EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 8, 4))
1199       .Times(1)
1200       .RetiresOnSaturation();
1201   RenderbufferStorage cmd;
1202   cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 8, 4);
1203   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1204   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1205   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1206   // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1207   // fails.
1208   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1209       .WillOnce(Return(false))
1210       .RetiresOnSaturation();
1211   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1212   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1213   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kUnmanaged));
1214 }
1215
1216 TEST_P(GLES2DecoderManualInitTest, MemoryTrackerBufferData) {
1217   scoped_refptr<SizeOnlyMemoryTracker> memory_tracker =
1218       new SizeOnlyMemoryTracker();
1219   set_memory_tracker(memory_tracker.get());
1220   InitState init;
1221   init.gl_version = "3.0";
1222   init.bind_generates_resource = true;
1223   InitDecoder(init);
1224   DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
1225   EXPECT_CALL(*gl_, GetError())
1226       .WillOnce(Return(GL_NO_ERROR))
1227       .WillOnce(Return(GL_NO_ERROR))
1228       .RetiresOnSaturation();
1229   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1230       .WillOnce(Return(true))
1231       .RetiresOnSaturation();
1232   EXPECT_CALL(*gl_, BufferData(GL_ARRAY_BUFFER, 128, _, GL_STREAM_DRAW))
1233       .Times(1)
1234       .RetiresOnSaturation();
1235   BufferData cmd;
1236   cmd.Init(GL_ARRAY_BUFFER, 128, 0, 0, GL_STREAM_DRAW);
1237   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1238   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1239   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1240   // Check we get out of memory and no call to glBufferData if Ensure
1241   // fails.
1242   EXPECT_CALL(*memory_tracker.get(), EnsureGPUMemoryAvailable(128))
1243       .WillOnce(Return(false))
1244       .RetiresOnSaturation();
1245   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1246   EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1247   EXPECT_EQ(128u, memory_tracker->GetPoolSize(MemoryTracker::kManaged));
1248 }
1249
1250 TEST_P(GLES2DecoderManualInitTest, ImmutableCopyTexImage2D) {
1251   const GLenum kTarget = GL_TEXTURE_2D;
1252   const GLint kLevel = 0;
1253   const GLenum kInternalFormat = GL_RGBA;
1254   const GLenum kSizedInternalFormat = GL_RGBA8;
1255   const GLsizei kWidth = 4;
1256   const GLsizei kHeight = 8;
1257   const GLint kBorder = 0;
1258   InitState init;
1259   init.extensions = "GL_EXT_texture_storage";
1260   init.gl_version = "3.0";
1261   init.has_alpha = true;
1262   init.request_alpha = true;
1263   init.bind_generates_resource = true;
1264   InitDecoder(init);
1265   DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1266
1267   // CopyTexImage2D will call arbitrary amount of GetErrors.
1268   EXPECT_CALL(*gl_, GetError())
1269       .Times(AtLeast(1));
1270
1271   EXPECT_CALL(*gl_,
1272               CopyTexImage2D(
1273                   kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight,
1274                   kBorder))
1275       .Times(1);
1276
1277   EXPECT_CALL(*gl_,
1278               TexStorage2DEXT(
1279                   kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight))
1280       .Times(1);
1281   CopyTexImage2D copy_cmd;
1282   copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
1283   EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
1284   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1285
1286   TexStorage2DEXT storage_cmd;
1287   storage_cmd.Init(kTarget, kLevel, kSizedInternalFormat, kWidth, kHeight);
1288   EXPECT_EQ(error::kNoError, ExecuteCmd(storage_cmd));
1289   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1290
1291   // This should not invoke CopyTexImage2D.
1292   copy_cmd.Init(kTarget, kLevel, kInternalFormat, 0, 0, kWidth, kHeight);
1293   EXPECT_EQ(error::kNoError, ExecuteCmd(copy_cmd));
1294   EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1295 }
1296
1297 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMValidArgs) {
1298   EXPECT_CALL(*mock_decoder_, LoseContext(GL_GUILTY_CONTEXT_RESET_ARB))
1299       .Times(1);
1300   cmds::LoseContextCHROMIUM cmd;
1301   cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_GUILTY_CONTEXT_RESET_ARB);
1302   EXPECT_EQ(error::kLostContext, ExecuteCmd(cmd));
1303   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1304 }
1305
1306 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs0_0) {
1307   EXPECT_CALL(*mock_decoder_, LoseContext(_))
1308       .Times(0);
1309   cmds::LoseContextCHROMIUM cmd;
1310   cmd.Init(GL_NONE, GL_GUILTY_CONTEXT_RESET_ARB);
1311   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1312   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1313 }
1314
1315 TEST_P(GLES2DecoderTest, LoseContextCHROMIUMInvalidArgs1_0) {
1316   EXPECT_CALL(*mock_decoder_, LoseContext(_))
1317       .Times(0);
1318   cmds::LoseContextCHROMIUM cmd;
1319   cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_NONE);
1320   EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1321   EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
1322 }
1323
1324 class GLES2DecoderDoCommandsTest : public GLES2DecoderTest {
1325  public:
1326   GLES2DecoderDoCommandsTest() {
1327     for (int i = 0; i < 3; i++) {
1328       cmds_[i].Init(GL_BLEND);
1329     }
1330     entries_per_cmd_ = ComputeNumEntries(cmds_[0].ComputeSize());
1331   }
1332
1333   void SetExpectationsForNCommands(int num_commands) {
1334     for (int i = 0; i < num_commands; i++)
1335       SetupExpectationsForEnableDisable(GL_BLEND, true);
1336   }
1337
1338  protected:
1339   Enable cmds_[3];
1340   int entries_per_cmd_;
1341 };
1342
1343 // Test that processing with 0 entries does nothing.
1344 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfZero) {
1345   int num_processed = -1;
1346   SetExpectationsForNCommands(0);
1347   EXPECT_EQ(
1348       error::kNoError,
1349       decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 0, &num_processed));
1350   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1351   EXPECT_EQ(0, num_processed);
1352 }
1353
1354 // Test processing at granularity of single commands.
1355 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOneOfOne) {
1356   int num_processed = -1;
1357   SetExpectationsForNCommands(1);
1358   EXPECT_EQ(
1359       error::kNoError,
1360       decoder_->DoCommands(1, &cmds_, entries_per_cmd_ * 1, &num_processed));
1361   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1362   EXPECT_EQ(entries_per_cmd_, num_processed);
1363 }
1364
1365 // Test processing at granularity of multiple commands.
1366 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsThreeOfThree) {
1367   int num_processed = -1;
1368   SetExpectationsForNCommands(3);
1369   EXPECT_EQ(
1370       error::kNoError,
1371       decoder_->DoCommands(3, &cmds_, entries_per_cmd_ * 3, &num_processed));
1372   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1373   EXPECT_EQ(entries_per_cmd_ * 3, num_processed);
1374 }
1375
1376 // Test processing a request smaller than available entries.
1377 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsTwoOfThree) {
1378   int num_processed = -1;
1379   SetExpectationsForNCommands(2);
1380   EXPECT_EQ(
1381       error::kNoError,
1382       decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 3, &num_processed));
1383   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1384   EXPECT_EQ(entries_per_cmd_ * 2, num_processed);
1385 }
1386
1387 // Test that processing stops on a command with size 0.
1388 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsZeroCmdSize) {
1389   cmds_[1].header.size = 0;
1390   int num_processed = -1;
1391   SetExpectationsForNCommands(1);
1392   EXPECT_EQ(
1393       error::kInvalidSize,
1394       decoder_->DoCommands(2, &cmds_, entries_per_cmd_ * 2, &num_processed));
1395   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1396   EXPECT_EQ(entries_per_cmd_, num_processed);
1397 }
1398
1399 // Test that processing stops on a command with size greater than available.
1400 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsOutOfBounds) {
1401   int num_processed = -1;
1402   SetExpectationsForNCommands(1);
1403   EXPECT_EQ(error::kOutOfBounds,
1404             decoder_->DoCommands(
1405                 2, &cmds_, entries_per_cmd_ * 2 - 1, &num_processed));
1406   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1407   EXPECT_EQ(entries_per_cmd_, num_processed);
1408 }
1409
1410 // Test that commands with bad argument size are skipped without processing.
1411 TEST_P(GLES2DecoderDoCommandsTest, DoCommandsBadArgSize) {
1412   cmds_[1].header.size += 1;
1413   int num_processed = -1;
1414   SetExpectationsForNCommands(1);
1415   EXPECT_EQ(error::kInvalidArguments,
1416             decoder_->DoCommands(
1417                 2, &cmds_, entries_per_cmd_ * 2 + 1, &num_processed));
1418   EXPECT_EQ(GL_NO_ERROR, GetGLError());
1419   EXPECT_EQ(entries_per_cmd_ + cmds_[1].header.size, num_processed);
1420 }
1421
1422 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool());
1423
1424 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool());
1425
1426 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderManualInitTest, ::testing::Bool());
1427
1428 INSTANTIATE_TEST_CASE_P(Service,
1429                         GLES2DecoderRGBBackbufferTest,
1430                         ::testing::Bool());
1431
1432 INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDoCommandsTest, ::testing::Bool());
1433
1434 }  // namespace gles2
1435 }  // namespace gpu