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
36using ::gfx::MockGLInterface;
37using ::testing::_;
38using ::testing::AtLeast;
39using ::testing::DoAll;
40using ::testing::InSequence;
41using ::testing::Invoke;
42using ::testing::MatcherCast;
43using ::testing::Mock;
44using ::testing::Pointee;
45using ::testing::Return;
46using ::testing::SaveArg;
47using ::testing::SetArrayArgument;
48using ::testing::SetArgumentPointee;
49using ::testing::SetArgPointee;
50using ::testing::StrEq;
51using ::testing::StrictMock;
52
53namespace gpu {
54namespace gles2 {
55
56using namespace cmds;
57
58void 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.
73void GLES2DecoderManualInitTest::SetUp() {
74}
75
76void 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
95TEST_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
131TEST_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
212TEST_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
283TEST_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
294TEST_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
305TEST_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
318TEST_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
329TEST_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
337TEST_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
353TEST_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
363TEST_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
372TEST_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
379TEST_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
387TEST_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
425TEST_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
535TEST_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
561TEST_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
568TEST_P(GLES2DecoderTest, RequestExtensionCHROMIUMBadBucket) {
569  const uint32 kBadBucketId = 123;
570  RequestExtensionCHROMIUM cmd;
571  cmd.Init(kBadBucketId);
572  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
573}
574
575TEST_P(GLES2DecoderTest, BeginQueryEXTDisabled) {
576  // Test something fails if off.
577}
578
579TEST_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
659struct QueryType {
660  GLenum type;
661  bool is_gl;
662};
663
664const 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
674static 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
776TEST_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
787TEST_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
806TEST_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
833TEST_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
868TEST_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
947TEST_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
972TEST_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
1005namespace {
1006
1007class 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
1046TEST_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
1059TEST_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
1116TEST_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
1137TEST_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
1180TEST_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
1216TEST_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
1250TEST_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
1297TEST_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
1306TEST_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
1315TEST_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
1324class 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.
1344TEST_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.
1355TEST_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.
1366TEST_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.
1377TEST_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.
1388TEST_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.
1400TEST_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.
1411TEST_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
1422INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTest, ::testing::Bool());
1423
1424INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderWithShaderTest, ::testing::Bool());
1425
1426INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderManualInitTest, ::testing::Bool());
1427
1428INSTANTIATE_TEST_CASE_P(Service,
1429                        GLES2DecoderRGBBackbufferTest,
1430                        ::testing::Bool());
1431
1432INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderDoCommandsTest, ::testing::Bool());
1433
1434}  // namespace gles2
1435}  // namespace gpu
1436