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