1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
6
7#include "base/command_line.h"
8#include "base/strings/string_number_conversions.h"
9#include "gpu/command_buffer/common/gles2_cmd_format.h"
10#include "gpu/command_buffer/common/gles2_cmd_utils.h"
11#include "gpu/command_buffer/common/id_allocator.h"
12#include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
13#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
14#include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
15#include "gpu/command_buffer/service/cmd_buffer_engine.h"
16#include "gpu/command_buffer/service/context_group.h"
17#include "gpu/command_buffer/service/context_state.h"
18#include "gpu/command_buffer/service/gl_surface_mock.h"
19#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
20
21#include "gpu/command_buffer/service/gpu_switches.h"
22#include "gpu/command_buffer/service/image_manager.h"
23#include "gpu/command_buffer/service/mailbox_manager.h"
24#include "gpu/command_buffer/service/mocks.h"
25#include "gpu/command_buffer/service/program_manager.h"
26#include "gpu/command_buffer/service/test_helper.h"
27#include "testing/gtest/include/gtest/gtest.h"
28#include "ui/gl/gl_implementation.h"
29#include "ui/gl/gl_mock.h"
30#include "ui/gl/gl_surface_stub.h"
31
32#if !defined(GL_DEPTH24_STENCIL8)
33#define GL_DEPTH24_STENCIL8 0x88F0
34#endif
35
36using ::gfx::MockGLInterface;
37using ::testing::_;
38using ::testing::DoAll;
39using ::testing::InSequence;
40using ::testing::Invoke;
41using ::testing::MatcherCast;
42using ::testing::Mock;
43using ::testing::Pointee;
44using ::testing::Return;
45using ::testing::SaveArg;
46using ::testing::SetArrayArgument;
47using ::testing::SetArgumentPointee;
48using ::testing::SetArgPointee;
49using ::testing::StrEq;
50using ::testing::StrictMock;
51
52namespace gpu {
53namespace gles2 {
54
55using namespace cmds;
56
57class GLES2DecoderTestWithExtensionsOnGLES2 : public GLES2DecoderTest {
58 public:
59  GLES2DecoderTestWithExtensionsOnGLES2() {}
60
61  virtual void SetUp() {}
62  void Init(const char* extensions) {
63    InitState init;
64    init.extensions = extensions;
65    init.gl_version = "opengl es 2.0";
66    init.has_alpha = true;
67    init.has_depth = true;
68    init.request_alpha = true;
69    init.request_depth = true;
70    InitDecoder(init);
71  }
72};
73
74TEST_P(GLES2DecoderTest, CheckFramebufferStatusWithNoBoundTarget) {
75  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_)).Times(0);
76  CheckFramebufferStatus::Result* result =
77      static_cast<CheckFramebufferStatus::Result*>(shared_memory_address_);
78  *result = 0;
79  CheckFramebufferStatus cmd;
80  cmd.Init(GL_FRAMEBUFFER, shared_memory_id_, shared_memory_offset_);
81  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
82  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), *result);
83}
84
85TEST_P(GLES2DecoderWithShaderTest, BindAndDeleteFramebuffer) {
86  SetupTexture();
87  AddExpectationsForSimulatedAttrib0(kNumVertices, 0);
88  SetupExpectationsForApplyingDefaultDirtyState();
89  DoBindFramebuffer(
90      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
91  DoDeleteFramebuffer(client_framebuffer_id_,
92                      kServiceFramebufferId,
93                      true,
94                      GL_FRAMEBUFFER,
95                      0,
96                      true,
97                      GL_FRAMEBUFFER,
98                      0);
99  EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices))
100      .Times(1)
101      .RetiresOnSaturation();
102  DrawArrays cmd;
103  cmd.Init(GL_TRIANGLES, 0, kNumVertices);
104  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
105  EXPECT_EQ(GL_NO_ERROR, GetGLError());
106}
107
108TEST_P(GLES2DecoderTest, FramebufferRenderbufferWithNoBoundTarget) {
109  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(_, _, _, _)).Times(0);
110  FramebufferRenderbuffer cmd;
111  cmd.Init(GL_FRAMEBUFFER,
112           GL_COLOR_ATTACHMENT0,
113           GL_RENDERBUFFER,
114           client_renderbuffer_id_);
115  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
116  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
117}
118
119TEST_P(GLES2DecoderTest, FramebufferTexture2DWithNoBoundTarget) {
120  EXPECT_CALL(*gl_, FramebufferTexture2DEXT(_, _, _, _, _)).Times(0);
121  FramebufferTexture2D cmd;
122  cmd.Init(GL_FRAMEBUFFER,
123           GL_COLOR_ATTACHMENT0,
124           GL_TEXTURE_2D,
125           client_texture_id_);
126  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
127  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
128}
129
130TEST_P(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithNoBoundTarget) {
131  EXPECT_CALL(*gl_, GetError())
132      .WillOnce(Return(GL_NO_ERROR))
133      .WillOnce(Return(GL_NO_ERROR))
134      .RetiresOnSaturation();
135  EXPECT_CALL(*gl_, GetFramebufferAttachmentParameterivEXT(_, _, _, _))
136      .Times(0);
137  GetFramebufferAttachmentParameteriv cmd;
138  cmd.Init(GL_FRAMEBUFFER,
139           GL_COLOR_ATTACHMENT0,
140           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
141           shared_memory_id_,
142           shared_memory_offset_);
143  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
144  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
145}
146
147TEST_P(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithRenderbuffer) {
148  DoBindFramebuffer(
149      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
150  EXPECT_CALL(*gl_, GetError())
151      .WillOnce(Return(GL_NO_ERROR))
152      .RetiresOnSaturation();
153  EXPECT_CALL(*gl_,
154              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
155                                         GL_COLOR_ATTACHMENT0,
156                                         GL_RENDERBUFFER,
157                                         kServiceRenderbufferId))
158      .Times(1)
159      .RetiresOnSaturation();
160  EXPECT_CALL(*gl_, GetError())
161      .WillOnce(Return(GL_NO_ERROR))
162      .RetiresOnSaturation();
163  EXPECT_CALL(*gl_, GetError())
164      .WillOnce(Return(GL_NO_ERROR))
165      .WillOnce(Return(GL_NO_ERROR))
166      .RetiresOnSaturation();
167  GetFramebufferAttachmentParameteriv::Result* result =
168      static_cast<GetFramebufferAttachmentParameteriv::Result*>(
169          shared_memory_address_);
170  result->size = 0;
171  const GLint* result_value = result->GetData();
172  FramebufferRenderbuffer fbrb_cmd;
173  GetFramebufferAttachmentParameteriv cmd;
174  fbrb_cmd.Init(GL_FRAMEBUFFER,
175                GL_COLOR_ATTACHMENT0,
176                GL_RENDERBUFFER,
177                client_renderbuffer_id_);
178  cmd.Init(GL_FRAMEBUFFER,
179           GL_COLOR_ATTACHMENT0,
180           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
181           shared_memory_id_,
182           shared_memory_offset_);
183  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
184  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
185  EXPECT_EQ(GL_NO_ERROR, GetGLError());
186  EXPECT_EQ(static_cast<GLuint>(*result_value), client_renderbuffer_id_);
187}
188
189TEST_P(GLES2DecoderTest, GetFramebufferAttachmentParameterivWithTexture) {
190  DoBindFramebuffer(
191      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
192  EXPECT_CALL(*gl_, GetError())
193      .WillOnce(Return(GL_NO_ERROR))
194      .RetiresOnSaturation();
195  EXPECT_CALL(*gl_,
196              FramebufferTexture2DEXT(GL_FRAMEBUFFER,
197                                      GL_COLOR_ATTACHMENT0,
198                                      GL_TEXTURE_2D,
199                                      kServiceTextureId,
200                                      0))
201      .Times(1)
202      .RetiresOnSaturation();
203  EXPECT_CALL(*gl_, GetError())
204      .WillOnce(Return(GL_NO_ERROR))
205      .RetiresOnSaturation();
206  EXPECT_CALL(*gl_, GetError())
207      .WillOnce(Return(GL_NO_ERROR))
208      .WillOnce(Return(GL_NO_ERROR))
209      .RetiresOnSaturation();
210  GetFramebufferAttachmentParameteriv::Result* result =
211      static_cast<GetFramebufferAttachmentParameteriv::Result*>(
212          shared_memory_address_);
213  result->SetNumResults(0);
214  const GLint* result_value = result->GetData();
215  FramebufferTexture2D fbtex_cmd;
216  GetFramebufferAttachmentParameteriv cmd;
217  fbtex_cmd.Init(GL_FRAMEBUFFER,
218                 GL_COLOR_ATTACHMENT0,
219                 GL_TEXTURE_2D,
220                 client_texture_id_);
221  cmd.Init(GL_FRAMEBUFFER,
222           GL_COLOR_ATTACHMENT0,
223           GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
224           shared_memory_id_,
225           shared_memory_offset_);
226  EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
227  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
228  EXPECT_EQ(GL_NO_ERROR, GetGLError());
229  EXPECT_EQ(static_cast<GLuint>(*result_value), client_texture_id_);
230}
231
232TEST_P(GLES2DecoderWithShaderTest,
233       GetRenderbufferParameterivRebindRenderbuffer) {
234  SetupTexture();
235  DoBindRenderbuffer(
236      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
237  DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
238
239  GetRenderbufferParameteriv cmd;
240  cmd.Init(GL_RENDERBUFFER,
241           GL_RENDERBUFFER_RED_SIZE,
242           shared_memory_id_,
243           shared_memory_offset_);
244
245  RestoreRenderbufferBindings();
246  EnsureRenderbufferBound(true);
247
248  EXPECT_CALL(*gl_, GetError())
249      .WillOnce(Return(GL_NO_ERROR))
250      .WillOnce(Return(GL_NO_ERROR))
251      .RetiresOnSaturation();
252  EXPECT_CALL(*gl_,
253              GetRenderbufferParameterivEXT(
254                  GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, _));
255  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
256  EXPECT_EQ(GL_NO_ERROR, GetGLError());
257}
258
259TEST_P(GLES2DecoderTest, GetRenderbufferParameterivWithNoBoundTarget) {
260  EXPECT_CALL(*gl_, GetError())
261      .WillOnce(Return(GL_NO_ERROR))
262      .WillOnce(Return(GL_NO_ERROR))
263      .RetiresOnSaturation();
264  EXPECT_CALL(*gl_, GetRenderbufferParameterivEXT(_, _, _)).Times(0);
265  GetRenderbufferParameteriv cmd;
266  cmd.Init(GL_RENDERBUFFER,
267           GL_RENDERBUFFER_WIDTH,
268           shared_memory_id_,
269           shared_memory_offset_);
270  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
271  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
272}
273
274TEST_P(GLES2DecoderWithShaderTest, RenderbufferStorageRebindRenderbuffer) {
275  SetupTexture();
276  DoBindRenderbuffer(
277      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
278  RestoreRenderbufferBindings();
279  EnsureRenderbufferBound(true);
280  DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
281}
282
283TEST_P(GLES2DecoderTest, RenderbufferStorageWithNoBoundTarget) {
284  EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _)).Times(0);
285  RenderbufferStorage cmd;
286  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 3, 4);
287  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
288  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
289}
290
291namespace {
292
293// A class to emulate glReadPixels
294class ReadPixelsEmulator {
295 public:
296  // pack_alignment is the alignment you want ReadPixels to use
297  // when copying. The actual data passed in pixels should be contiguous.
298  ReadPixelsEmulator(GLsizei width,
299                     GLsizei height,
300                     GLint bytes_per_pixel,
301                     const void* src_pixels,
302                     const void* expected_pixels,
303                     GLint pack_alignment)
304      : width_(width),
305        height_(height),
306        pack_alignment_(pack_alignment),
307        bytes_per_pixel_(bytes_per_pixel),
308        src_pixels_(reinterpret_cast<const int8*>(src_pixels)),
309        expected_pixels_(reinterpret_cast<const int8*>(expected_pixels)) {}
310
311  void ReadPixels(GLint x,
312                  GLint y,
313                  GLsizei width,
314                  GLsizei height,
315                  GLenum format,
316                  GLenum type,
317                  void* pixels) const {
318    DCHECK_GE(x, 0);
319    DCHECK_GE(y, 0);
320    DCHECK_LE(x + width, width_);
321    DCHECK_LE(y + height, height_);
322    for (GLint yy = 0; yy < height; ++yy) {
323      const int8* src = GetPixelAddress(src_pixels_, x, y + yy);
324      const void* dst = ComputePackAlignmentAddress(0, yy, width, pixels);
325      memcpy(const_cast<void*>(dst), src, width * bytes_per_pixel_);
326    }
327  }
328
329  bool CompareRowSegment(GLint x,
330                         GLint y,
331                         GLsizei width,
332                         const void* data) const {
333    DCHECK(x + width <= width_ || width == 0);
334    return memcmp(data,
335                  GetPixelAddress(expected_pixels_, x, y),
336                  width * bytes_per_pixel_) == 0;
337  }
338
339  // Helper to compute address of pixel in pack aligned data.
340  const void* ComputePackAlignmentAddress(GLint x,
341                                          GLint y,
342                                          GLsizei width,
343                                          const void* address) const {
344    GLint unpadded_row_size = ComputeImageDataSize(width, 1);
345    GLint two_rows_size = ComputeImageDataSize(width, 2);
346    GLsizei padded_row_size = two_rows_size - unpadded_row_size;
347    GLint offset = y * padded_row_size + x * bytes_per_pixel_;
348    return static_cast<const int8*>(address) + offset;
349  }
350
351  GLint ComputeImageDataSize(GLint width, GLint height) const {
352    GLint row_size = width * bytes_per_pixel_;
353    if (height > 1) {
354      GLint temp = row_size + pack_alignment_ - 1;
355      GLint padded_row_size = (temp / pack_alignment_) * pack_alignment_;
356      GLint size_of_all_but_last_row = (height - 1) * padded_row_size;
357      return size_of_all_but_last_row + row_size;
358    } else {
359      return height * row_size;
360    }
361  }
362
363 private:
364  const int8* GetPixelAddress(const int8* base, GLint x, GLint y) const {
365    return base + (width_ * y + x) * bytes_per_pixel_;
366  }
367
368  GLsizei width_;
369  GLsizei height_;
370  GLint pack_alignment_;
371  GLint bytes_per_pixel_;
372  const int8* src_pixels_;
373  const int8* expected_pixels_;
374};
375
376}  // anonymous namespace
377
378void GLES2DecoderTest::CheckReadPixelsOutOfRange(GLint in_read_x,
379                                                 GLint in_read_y,
380                                                 GLsizei in_read_width,
381                                                 GLsizei in_read_height,
382                                                 bool init) {
383  const GLsizei kWidth = 5;
384  const GLsizei kHeight = 3;
385  const GLint kBytesPerPixel = 3;
386  const GLint kPackAlignment = 4;
387  const GLenum kFormat = GL_RGB;
388  static const int8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
389      12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 18, 19, 13,
390      29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21, 22, 21, 28,
391      31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32, 37, 32, 34,
392  };
393
394  ClearSharedMemory();
395
396  // We need to setup an FBO so we can know the max size that ReadPixels will
397  // access
398  if (init) {
399    DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
400    DoTexImage2D(GL_TEXTURE_2D,
401                 0,
402                 kFormat,
403                 kWidth,
404                 kHeight,
405                 0,
406                 kFormat,
407                 GL_UNSIGNED_BYTE,
408                 kSharedMemoryId,
409                 kSharedMemoryOffset);
410    DoBindFramebuffer(
411        GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
412    DoFramebufferTexture2D(GL_FRAMEBUFFER,
413                           GL_COLOR_ATTACHMENT0,
414                           GL_TEXTURE_2D,
415                           client_texture_id_,
416                           kServiceTextureId,
417                           0,
418                           GL_NO_ERROR);
419    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
420        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
421        .RetiresOnSaturation();
422  }
423
424  ReadPixelsEmulator emu(
425      kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
426  typedef ReadPixels::Result Result;
427  Result* result = GetSharedMemoryAs<Result*>();
428  uint32 result_shm_id = kSharedMemoryId;
429  uint32 result_shm_offset = kSharedMemoryOffset;
430  uint32 pixels_shm_id = kSharedMemoryId;
431  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
432  void* dest = &result[1];
433  EXPECT_CALL(*gl_, GetError())
434      .WillOnce(Return(GL_NO_ERROR))
435      .WillOnce(Return(GL_NO_ERROR))
436      .RetiresOnSaturation();
437  // ReadPixels will be called for valid size only even though the command
438  // is requesting a larger size.
439  GLint read_x = std::max(0, in_read_x);
440  GLint read_y = std::max(0, in_read_y);
441  GLint read_end_x = std::max(0, std::min(kWidth, in_read_x + in_read_width));
442  GLint read_end_y = std::max(0, std::min(kHeight, in_read_y + in_read_height));
443  GLint read_width = read_end_x - read_x;
444  GLint read_height = read_end_y - read_y;
445  if (read_width > 0 && read_height > 0) {
446    for (GLint yy = read_y; yy < read_end_y; ++yy) {
447      EXPECT_CALL(
448          *gl_,
449          ReadPixels(read_x, yy, read_width, 1, kFormat, GL_UNSIGNED_BYTE, _))
450          .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels))
451          .RetiresOnSaturation();
452    }
453  }
454  ReadPixels cmd;
455  cmd.Init(in_read_x,
456           in_read_y,
457           in_read_width,
458           in_read_height,
459           kFormat,
460           GL_UNSIGNED_BYTE,
461           pixels_shm_id,
462           pixels_shm_offset,
463           result_shm_id,
464           result_shm_offset,
465           false);
466  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
467
468  GLint unpadded_row_size = emu.ComputeImageDataSize(in_read_width, 1);
469  scoped_ptr<int8[]> zero(new int8[unpadded_row_size]);
470  scoped_ptr<int8[]> pack(new int8[kPackAlignment]);
471  memset(zero.get(), 0, unpadded_row_size);
472  memset(pack.get(), kInitialMemoryValue, kPackAlignment);
473  for (GLint yy = 0; yy < in_read_height; ++yy) {
474    const int8* row = static_cast<const int8*>(
475        emu.ComputePackAlignmentAddress(0, yy, in_read_width, dest));
476    GLint y = in_read_y + yy;
477    if (y < 0 || y >= kHeight) {
478      EXPECT_EQ(0, memcmp(zero.get(), row, unpadded_row_size));
479    } else {
480      // check off left.
481      GLint num_left_pixels = std::max(-in_read_x, 0);
482      GLint num_left_bytes = num_left_pixels * kBytesPerPixel;
483      EXPECT_EQ(0, memcmp(zero.get(), row, num_left_bytes));
484
485      // check off right.
486      GLint num_right_pixels = std::max(in_read_x + in_read_width - kWidth, 0);
487      GLint num_right_bytes = num_right_pixels * kBytesPerPixel;
488      EXPECT_EQ(0,
489                memcmp(zero.get(),
490                       row + unpadded_row_size - num_right_bytes,
491                       num_right_bytes));
492
493      // check middle.
494      GLint x = std::max(in_read_x, 0);
495      GLint num_middle_pixels =
496          std::max(in_read_width - num_left_pixels - num_right_pixels, 0);
497      EXPECT_TRUE(
498          emu.CompareRowSegment(x, y, num_middle_pixels, row + num_left_bytes));
499    }
500
501    // check padding
502    if (yy != in_read_height - 1) {
503      GLint num_padding_bytes =
504          (kPackAlignment - 1) - (unpadded_row_size % kPackAlignment);
505      EXPECT_EQ(0,
506                memcmp(pack.get(), row + unpadded_row_size, num_padding_bytes));
507    }
508  }
509}
510
511TEST_P(GLES2DecoderTest, ReadPixels) {
512  const GLsizei kWidth = 5;
513  const GLsizei kHeight = 3;
514  const GLint kBytesPerPixel = 3;
515  const GLint kPackAlignment = 4;
516  static const int8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
517      12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 18, 19, 13,
518      29, 28, 23, 22, 21, 22, 21, 29, 28, 23, 22, 21, 22, 21, 28,
519      31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32, 37, 32, 34,
520  };
521
522  surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
523
524  ReadPixelsEmulator emu(
525      kWidth, kHeight, kBytesPerPixel, kSrcPixels, kSrcPixels, kPackAlignment);
526  typedef ReadPixels::Result Result;
527  Result* result = GetSharedMemoryAs<Result*>();
528  uint32 result_shm_id = kSharedMemoryId;
529  uint32 result_shm_offset = kSharedMemoryOffset;
530  uint32 pixels_shm_id = kSharedMemoryId;
531  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
532  void* dest = &result[1];
533  EXPECT_CALL(*gl_, GetError())
534      .WillOnce(Return(GL_NO_ERROR))
535      .WillOnce(Return(GL_NO_ERROR))
536      .RetiresOnSaturation();
537  EXPECT_CALL(*gl_,
538              ReadPixels(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, _))
539      .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
540  ReadPixels cmd;
541  cmd.Init(0,
542           0,
543           kWidth,
544           kHeight,
545           GL_RGB,
546           GL_UNSIGNED_BYTE,
547           pixels_shm_id,
548           pixels_shm_offset,
549           result_shm_id,
550           result_shm_offset,
551           false);
552  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
553  for (GLint yy = 0; yy < kHeight; ++yy) {
554    EXPECT_TRUE(emu.CompareRowSegment(
555        0, yy, kWidth, emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
556  }
557}
558
559TEST_P(GLES2DecoderRGBBackbufferTest, ReadPixelsNoAlphaBackbuffer) {
560  const GLsizei kWidth = 3;
561  const GLsizei kHeight = 3;
562  const GLint kBytesPerPixel = 4;
563  const GLint kPackAlignment = 4;
564  static const uint8 kExpectedPixels[kWidth * kHeight * kBytesPerPixel] = {
565      12, 13, 14, 255, 19, 18, 19, 255, 13, 14, 18, 255,
566      29, 28, 23, 255, 21, 22, 21, 255, 28, 23, 22, 255,
567      31, 34, 39, 255, 32, 37, 32, 255, 34, 39, 37, 255,
568  };
569  static const uint8 kSrcPixels[kWidth * kHeight * kBytesPerPixel] = {
570      12, 13, 14, 18, 19, 18, 19, 12, 13, 14, 18, 19, 29, 28, 23, 22, 21, 22,
571      21, 29, 28, 23, 22, 21, 31, 34, 39, 37, 32, 37, 32, 31, 34, 39, 37, 32,
572  };
573
574  surface_->SetSize(gfx::Size(INT_MAX, INT_MAX));
575
576  ReadPixelsEmulator emu(kWidth,
577                         kHeight,
578                         kBytesPerPixel,
579                         kSrcPixels,
580                         kExpectedPixels,
581                         kPackAlignment);
582  typedef ReadPixels::Result Result;
583  Result* result = GetSharedMemoryAs<Result*>();
584  uint32 result_shm_id = kSharedMemoryId;
585  uint32 result_shm_offset = kSharedMemoryOffset;
586  uint32 pixels_shm_id = kSharedMemoryId;
587  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
588  void* dest = &result[1];
589  EXPECT_CALL(*gl_, GetError())
590      .WillOnce(Return(GL_NO_ERROR))
591      .WillOnce(Return(GL_NO_ERROR))
592      .RetiresOnSaturation();
593  EXPECT_CALL(*gl_,
594              ReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, _))
595      .WillOnce(Invoke(&emu, &ReadPixelsEmulator::ReadPixels));
596  ReadPixels cmd;
597  cmd.Init(0,
598           0,
599           kWidth,
600           kHeight,
601           GL_RGBA,
602           GL_UNSIGNED_BYTE,
603           pixels_shm_id,
604           pixels_shm_offset,
605           result_shm_id,
606           result_shm_offset,
607           false);
608  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
609  for (GLint yy = 0; yy < kHeight; ++yy) {
610    EXPECT_TRUE(emu.CompareRowSegment(
611        0, yy, kWidth, emu.ComputePackAlignmentAddress(0, yy, kWidth, dest)));
612  }
613}
614
615TEST_P(GLES2DecoderTest, ReadPixelsOutOfRange) {
616  static GLint tests[][4] = {
617      {
618       -2, -1, 9, 5,
619      },  // out of range on all sides
620      {
621       2, 1, 9, 5,
622      },  // out of range on right, bottom
623      {
624       -7, -4, 9, 5,
625      },  // out of range on left, top
626      {
627       0, -5, 9, 5,
628      },  // completely off top
629      {
630       0, 3, 9, 5,
631      },  // completely off bottom
632      {
633       -9, 0, 9, 5,
634      },  // completely off left
635      {
636       5, 0, 9, 5,
637      },  // completely off right
638  };
639
640  for (size_t tt = 0; tt < arraysize(tests); ++tt) {
641    CheckReadPixelsOutOfRange(
642        tests[tt][0], tests[tt][1], tests[tt][2], tests[tt][3], tt == 0);
643  }
644}
645
646TEST_P(GLES2DecoderTest, ReadPixelsInvalidArgs) {
647  typedef ReadPixels::Result Result;
648  Result* result = GetSharedMemoryAs<Result*>();
649  uint32 result_shm_id = kSharedMemoryId;
650  uint32 result_shm_offset = kSharedMemoryOffset;
651  uint32 pixels_shm_id = kSharedMemoryId;
652  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
653  EXPECT_CALL(*gl_, ReadPixels(_, _, _, _, _, _, _)).Times(0);
654  ReadPixels cmd;
655  cmd.Init(0,
656           0,
657           -1,
658           1,
659           GL_RGB,
660           GL_UNSIGNED_BYTE,
661           pixels_shm_id,
662           pixels_shm_offset,
663           result_shm_id,
664           result_shm_offset,
665           false);
666  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
667  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
668  cmd.Init(0,
669           0,
670           1,
671           -1,
672           GL_RGB,
673           GL_UNSIGNED_BYTE,
674           pixels_shm_id,
675           pixels_shm_offset,
676           result_shm_id,
677           result_shm_offset,
678           false);
679  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
680  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
681  cmd.Init(0,
682           0,
683           1,
684           1,
685           GL_RGB,
686           GL_INT,
687           pixels_shm_id,
688           pixels_shm_offset,
689           result_shm_id,
690           result_shm_offset,
691           false);
692  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
693  EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
694  cmd.Init(0,
695           0,
696           1,
697           1,
698           GL_RGB,
699           GL_UNSIGNED_BYTE,
700           kInvalidSharedMemoryId,
701           pixels_shm_offset,
702           result_shm_id,
703           result_shm_offset,
704           false);
705  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
706  cmd.Init(0,
707           0,
708           1,
709           1,
710           GL_RGB,
711           GL_UNSIGNED_BYTE,
712           pixels_shm_id,
713           kInvalidSharedMemoryOffset,
714           result_shm_id,
715           result_shm_offset,
716           false);
717  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
718  cmd.Init(0,
719           0,
720           1,
721           1,
722           GL_RGB,
723           GL_UNSIGNED_BYTE,
724           pixels_shm_id,
725           pixels_shm_offset,
726           kInvalidSharedMemoryId,
727           result_shm_offset,
728           false);
729  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
730  cmd.Init(0,
731           0,
732           1,
733           1,
734           GL_RGB,
735           GL_UNSIGNED_BYTE,
736           pixels_shm_id,
737           pixels_shm_offset,
738           result_shm_id,
739           kInvalidSharedMemoryOffset,
740           false);
741  EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
742}
743
744TEST_P(GLES2DecoderManualInitTest, ReadPixelsAsyncError) {
745  InitState init;
746  init.extensions = "GL_ARB_sync";
747  init.gl_version = "opengl es 3.0";
748  init.has_alpha = true;
749  init.request_alpha = true;
750  init.bind_generates_resource = true;
751  InitDecoder(init);
752
753  typedef ReadPixels::Result Result;
754  Result* result = GetSharedMemoryAs<Result*>();
755
756  const GLsizei kWidth = 4;
757  const GLsizei kHeight = 4;
758  uint32 result_shm_id = kSharedMemoryId;
759  uint32 result_shm_offset = kSharedMemoryOffset;
760  uint32 pixels_shm_id = kSharedMemoryId;
761  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
762
763  EXPECT_CALL(*gl_, GetError())
764      // first error check must pass to get to the test
765      .WillOnce(Return(GL_NO_ERROR))
766      // second check is after BufferData, simulate fail here
767      .WillOnce(Return(GL_INVALID_OPERATION))
768      // third error check is fall-through call to sync ReadPixels
769      .WillOnce(Return(GL_NO_ERROR))
770      .RetiresOnSaturation();
771
772  EXPECT_CALL(*gl_,
773              ReadPixels(0, 0, kWidth, kHeight, GL_RGB, GL_UNSIGNED_BYTE, _))
774      .Times(1);
775  EXPECT_CALL(*gl_, GenBuffersARB(1, _)).Times(1);
776  EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_PACK_BUFFER_ARB, _)).Times(2);
777  EXPECT_CALL(*gl_,
778              BufferData(GL_PIXEL_PACK_BUFFER_ARB, _, NULL, GL_STREAM_READ))
779      .Times(1);
780
781  ReadPixels cmd;
782  cmd.Init(0,
783           0,
784           kWidth,
785           kHeight,
786           GL_RGB,
787           GL_UNSIGNED_BYTE,
788           pixels_shm_id,
789           pixels_shm_offset,
790           result_shm_id,
791           result_shm_offset,
792           true);
793  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
794}
795
796// Check that if a renderbuffer is attached and GL returns
797// GL_FRAMEBUFFER_COMPLETE that the buffer is cleared and state is restored.
798TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearColor) {
799  DoBindFramebuffer(
800      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
801  ClearColor color_cmd;
802  ColorMask color_mask_cmd;
803  Enable enable_cmd;
804  FramebufferRenderbuffer cmd;
805  color_cmd.Init(0.1f, 0.2f, 0.3f, 0.4f);
806  color_mask_cmd.Init(0, 1, 0, 1);
807  enable_cmd.Init(GL_SCISSOR_TEST);
808  cmd.Init(GL_FRAMEBUFFER,
809           GL_COLOR_ATTACHMENT0,
810           GL_RENDERBUFFER,
811           client_renderbuffer_id_);
812  InSequence sequence;
813  EXPECT_CALL(*gl_, ClearColor(0.1f, 0.2f, 0.3f, 0.4f))
814      .Times(1)
815      .RetiresOnSaturation();
816  SetupExpectationsForEnableDisable(GL_SCISSOR_TEST, true);
817  EXPECT_CALL(*gl_, GetError())
818      .WillOnce(Return(GL_NO_ERROR))
819      .RetiresOnSaturation();
820  EXPECT_CALL(*gl_,
821              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
822                                         GL_COLOR_ATTACHMENT0,
823                                         GL_RENDERBUFFER,
824                                         kServiceRenderbufferId))
825      .Times(1)
826      .RetiresOnSaturation();
827  EXPECT_CALL(*gl_, GetError())
828      .WillOnce(Return(GL_NO_ERROR))
829      .RetiresOnSaturation();
830  EXPECT_EQ(error::kNoError, ExecuteCmd(color_cmd));
831  EXPECT_EQ(error::kNoError, ExecuteCmd(color_mask_cmd));
832  EXPECT_EQ(error::kNoError, ExecuteCmd(enable_cmd));
833  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
834}
835
836TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearDepth) {
837  DoBindFramebuffer(
838      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
839  ClearDepthf depth_cmd;
840  DepthMask depth_mask_cmd;
841  FramebufferRenderbuffer cmd;
842  depth_cmd.Init(0.5f);
843  depth_mask_cmd.Init(false);
844  cmd.Init(GL_FRAMEBUFFER,
845           GL_DEPTH_ATTACHMENT,
846           GL_RENDERBUFFER,
847           client_renderbuffer_id_);
848  InSequence sequence;
849  EXPECT_CALL(*gl_, ClearDepth(0.5f)).Times(1).RetiresOnSaturation();
850  EXPECT_CALL(*gl_, GetError())
851      .WillOnce(Return(GL_NO_ERROR))
852      .RetiresOnSaturation();
853  EXPECT_CALL(*gl_,
854              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
855                                         GL_DEPTH_ATTACHMENT,
856                                         GL_RENDERBUFFER,
857                                         kServiceRenderbufferId))
858      .Times(1)
859      .RetiresOnSaturation();
860  EXPECT_CALL(*gl_, GetError())
861      .WillOnce(Return(GL_NO_ERROR))
862      .RetiresOnSaturation();
863  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
864  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_mask_cmd));
865  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
866}
867
868TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearStencil) {
869  DoBindFramebuffer(
870      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
871  ClearStencil stencil_cmd;
872  StencilMaskSeparate stencil_mask_separate_cmd;
873  FramebufferRenderbuffer cmd;
874  stencil_cmd.Init(123);
875  stencil_mask_separate_cmd.Init(GL_BACK, 0x1234u);
876  cmd.Init(GL_FRAMEBUFFER,
877           GL_STENCIL_ATTACHMENT,
878           GL_RENDERBUFFER,
879           client_renderbuffer_id_);
880  InSequence sequence;
881  EXPECT_CALL(*gl_, ClearStencil(123)).Times(1).RetiresOnSaturation();
882  EXPECT_CALL(*gl_, GetError())
883      .WillOnce(Return(GL_NO_ERROR))
884      .RetiresOnSaturation();
885  EXPECT_CALL(*gl_,
886              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
887                                         GL_STENCIL_ATTACHMENT,
888                                         GL_RENDERBUFFER,
889                                         kServiceRenderbufferId))
890      .Times(1)
891      .RetiresOnSaturation();
892  EXPECT_CALL(*gl_, GetError())
893      .WillOnce(Return(GL_NO_ERROR))
894      .RetiresOnSaturation();
895  EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
896  EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_mask_separate_cmd));
897  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
898}
899
900#if 0  // Turn this test on once we allow GL_DEPTH_STENCIL_ATTACHMENT
901TEST_P(GLES2DecoderTest, FramebufferRenderbufferClearDepthStencil) {
902  DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
903                    kServiceFramebufferId);
904  ClearDepthf depth_cmd;
905  ClearStencil stencil_cmd;
906  FramebufferRenderbuffer cmd;
907  depth_cmd.Init(0.5f);
908  stencil_cmd.Init(123);
909  cmd.Init(
910      GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
911      client_renderbuffer_id_);
912  InSequence sequence;
913  EXPECT_CALL(*gl_, ClearDepth(0.5f))
914      .Times(1)
915      .RetiresOnSaturation();
916  EXPECT_CALL(*gl_, ClearStencil(123))
917      .Times(1)
918      .RetiresOnSaturation();
919  EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
920      GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
921      kServiceRenderbufferId))
922      .Times(1)
923      .RetiresOnSaturation();
924  EXPECT_EQ(error::kNoError, ExecuteCmd(depth_cmd));
925  EXPECT_EQ(error::kNoError, ExecuteCmd(stencil_cmd));
926  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
927}
928#endif
929
930TEST_P(GLES2DecoderManualInitTest, ActualAlphaMatchesRequestedAlpha) {
931  InitState init;
932  init.gl_version = "3.0";
933  init.has_alpha = true;
934  init.request_alpha = true;
935  init.bind_generates_resource = true;
936  InitDecoder(init);
937
938  EXPECT_CALL(*gl_, GetError())
939      .WillOnce(Return(GL_NO_ERROR))
940      .WillOnce(Return(GL_NO_ERROR))
941      .RetiresOnSaturation();
942  typedef GetIntegerv::Result Result;
943  Result* result = static_cast<Result*>(shared_memory_address_);
944  EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
945      .WillOnce(SetArgumentPointee<1>(8))
946      .RetiresOnSaturation();
947  result->size = 0;
948  GetIntegerv cmd2;
949  cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
950  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
951  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
952            result->GetNumResults());
953  EXPECT_EQ(GL_NO_ERROR, GetGLError());
954  EXPECT_EQ(8, result->GetData()[0]);
955}
956
957TEST_P(GLES2DecoderManualInitTest, ActualAlphaDoesNotMatchRequestedAlpha) {
958  InitState init;
959  init.gl_version = "3.0";
960  init.has_alpha = true;
961  init.bind_generates_resource = true;
962  InitDecoder(init);
963
964  EXPECT_CALL(*gl_, GetError())
965      .WillOnce(Return(GL_NO_ERROR))
966      .WillOnce(Return(GL_NO_ERROR))
967      .RetiresOnSaturation();
968  typedef GetIntegerv::Result Result;
969  Result* result = static_cast<Result*>(shared_memory_address_);
970  EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _))
971      .WillOnce(SetArgumentPointee<1>(8))
972      .RetiresOnSaturation();
973  result->size = 0;
974  GetIntegerv cmd2;
975  cmd2.Init(GL_ALPHA_BITS, shared_memory_id_, shared_memory_offset_);
976  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
977  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ALPHA_BITS),
978            result->GetNumResults());
979  EXPECT_EQ(GL_NO_ERROR, GetGLError());
980  EXPECT_EQ(0, result->GetData()[0]);
981}
982
983TEST_P(GLES2DecoderManualInitTest, ActualDepthMatchesRequestedDepth) {
984  InitState init;
985  init.gl_version = "3.0";
986  init.has_depth = true;
987  init.request_depth = true;
988  init.bind_generates_resource = true;
989  InitDecoder(init);
990
991  EXPECT_CALL(*gl_, GetError())
992      .WillOnce(Return(GL_NO_ERROR))
993      .WillOnce(Return(GL_NO_ERROR))
994      .RetiresOnSaturation();
995  typedef GetIntegerv::Result Result;
996  Result* result = static_cast<Result*>(shared_memory_address_);
997  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
998      .WillOnce(SetArgumentPointee<1>(24))
999      .RetiresOnSaturation();
1000  result->size = 0;
1001  GetIntegerv cmd2;
1002  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1003  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1004  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1005            result->GetNumResults());
1006  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1007  EXPECT_EQ(24, result->GetData()[0]);
1008}
1009
1010TEST_P(GLES2DecoderManualInitTest, ActualDepthDoesNotMatchRequestedDepth) {
1011  InitState init;
1012  init.gl_version = "3.0";
1013  init.has_depth = true;
1014  init.bind_generates_resource = true;
1015  InitDecoder(init);
1016
1017  EXPECT_CALL(*gl_, GetError())
1018      .WillOnce(Return(GL_NO_ERROR))
1019      .WillOnce(Return(GL_NO_ERROR))
1020      .RetiresOnSaturation();
1021  typedef GetIntegerv::Result Result;
1022  Result* result = static_cast<Result*>(shared_memory_address_);
1023  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1024      .WillOnce(SetArgumentPointee<1>(24))
1025      .RetiresOnSaturation();
1026  result->size = 0;
1027  GetIntegerv cmd2;
1028  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1029  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1030  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1031            result->GetNumResults());
1032  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1033  EXPECT_EQ(0, result->GetData()[0]);
1034}
1035
1036TEST_P(GLES2DecoderManualInitTest, ActualStencilMatchesRequestedStencil) {
1037  InitState init;
1038  init.gl_version = "3.0";
1039  init.has_stencil = true;
1040  init.request_stencil = true;
1041  init.bind_generates_resource = true;
1042  InitDecoder(init);
1043
1044  EXPECT_CALL(*gl_, GetError())
1045      .WillOnce(Return(GL_NO_ERROR))
1046      .WillOnce(Return(GL_NO_ERROR))
1047      .RetiresOnSaturation();
1048  typedef GetIntegerv::Result Result;
1049  Result* result = static_cast<Result*>(shared_memory_address_);
1050  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1051      .WillOnce(SetArgumentPointee<1>(8))
1052      .RetiresOnSaturation();
1053  result->size = 0;
1054  GetIntegerv cmd2;
1055  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1056  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1057  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1058            result->GetNumResults());
1059  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1060  EXPECT_EQ(8, result->GetData()[0]);
1061}
1062
1063TEST_P(GLES2DecoderManualInitTest, ActualStencilDoesNotMatchRequestedStencil) {
1064  InitState init;
1065  init.gl_version = "3.0";
1066  init.has_stencil = true;
1067  init.bind_generates_resource = true;
1068  InitDecoder(init);
1069
1070  EXPECT_CALL(*gl_, GetError())
1071      .WillOnce(Return(GL_NO_ERROR))
1072      .WillOnce(Return(GL_NO_ERROR))
1073      .RetiresOnSaturation();
1074  typedef GetIntegerv::Result Result;
1075  Result* result = static_cast<Result*>(shared_memory_address_);
1076  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1077      .WillOnce(SetArgumentPointee<1>(8))
1078      .RetiresOnSaturation();
1079  result->size = 0;
1080  GetIntegerv cmd2;
1081  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1082  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1083  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1084            result->GetNumResults());
1085  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1086  EXPECT_EQ(0, result->GetData()[0]);
1087}
1088
1089TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilReportsCorrectValues) {
1090  InitState init;
1091  init.extensions = "GL_OES_packed_depth_stencil";
1092  init.gl_version = "opengl es 2.0";
1093  init.has_depth = true;
1094  init.has_stencil = true;
1095  init.request_depth = true;
1096  init.request_stencil = true;
1097  init.bind_generates_resource = true;
1098  InitDecoder(init);
1099
1100  EXPECT_CALL(*gl_, GetError())
1101      .WillOnce(Return(GL_NO_ERROR))
1102      .WillOnce(Return(GL_NO_ERROR))
1103      .WillOnce(Return(GL_NO_ERROR))
1104      .WillOnce(Return(GL_NO_ERROR))
1105      .RetiresOnSaturation();
1106  typedef GetIntegerv::Result Result;
1107  Result* result = static_cast<Result*>(shared_memory_address_);
1108  result->size = 0;
1109  GetIntegerv cmd2;
1110  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1111  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1112      .WillOnce(SetArgumentPointee<1>(8))
1113      .RetiresOnSaturation();
1114  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1115  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1116            result->GetNumResults());
1117  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1118  EXPECT_EQ(8, result->GetData()[0]);
1119  result->size = 0;
1120  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1121  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1122      .WillOnce(SetArgumentPointee<1>(24))
1123      .RetiresOnSaturation();
1124  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1125  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1126            result->GetNumResults());
1127  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1128  EXPECT_EQ(24, result->GetData()[0]);
1129}
1130
1131TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilNoRequestedStencil) {
1132  InitState init;
1133  init.extensions = "GL_OES_packed_depth_stencil";
1134  init.gl_version = "opengl es 2.0";
1135  init.has_depth = true;
1136  init.has_stencil = true;
1137  init.request_depth = true;
1138  init.bind_generates_resource = true;
1139  InitDecoder(init);
1140
1141  EXPECT_CALL(*gl_, GetError())
1142      .WillOnce(Return(GL_NO_ERROR))
1143      .WillOnce(Return(GL_NO_ERROR))
1144      .WillOnce(Return(GL_NO_ERROR))
1145      .WillOnce(Return(GL_NO_ERROR))
1146      .RetiresOnSaturation();
1147  typedef GetIntegerv::Result Result;
1148  Result* result = static_cast<Result*>(shared_memory_address_);
1149  result->size = 0;
1150  GetIntegerv cmd2;
1151  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1152  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1153      .WillOnce(SetArgumentPointee<1>(8))
1154      .RetiresOnSaturation();
1155  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1156  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1157            result->GetNumResults());
1158  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1159  EXPECT_EQ(0, result->GetData()[0]);
1160  result->size = 0;
1161  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1162  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1163      .WillOnce(SetArgumentPointee<1>(24))
1164      .RetiresOnSaturation();
1165  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1166  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1167            result->GetNumResults());
1168  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1169  EXPECT_EQ(24, result->GetData()[0]);
1170}
1171
1172TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferDepth) {
1173  InitState init;
1174  init.extensions = "GL_OES_packed_depth_stencil";
1175  init.gl_version = "opengl es 2.0";
1176  init.bind_generates_resource = true;
1177  InitDecoder(init);
1178  DoBindRenderbuffer(
1179      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1180  DoBindFramebuffer(
1181      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1182
1183  EnsureRenderbufferBound(false);
1184  EXPECT_CALL(*gl_, GetError())
1185      .WillOnce(Return(GL_NO_ERROR))  // for RenderbufferStoage
1186      .WillOnce(Return(GL_NO_ERROR))
1187      .WillOnce(Return(GL_NO_ERROR))  // for FramebufferRenderbuffer
1188      .WillOnce(Return(GL_NO_ERROR))
1189      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
1190      .WillOnce(Return(GL_NO_ERROR))
1191      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
1192      .WillOnce(Return(GL_NO_ERROR))
1193      .RetiresOnSaturation();
1194
1195  EXPECT_CALL(
1196      *gl_,
1197      RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
1198      .Times(1)
1199      .RetiresOnSaturation();
1200  RenderbufferStorage cmd;
1201  cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
1202  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1203  EXPECT_CALL(*gl_,
1204              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1205                                         GL_DEPTH_ATTACHMENT,
1206                                         GL_RENDERBUFFER,
1207                                         kServiceRenderbufferId))
1208      .Times(1)
1209      .RetiresOnSaturation();
1210  FramebufferRenderbuffer fbrb_cmd;
1211  fbrb_cmd.Init(GL_FRAMEBUFFER,
1212                GL_DEPTH_ATTACHMENT,
1213                GL_RENDERBUFFER,
1214                client_renderbuffer_id_);
1215  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
1216
1217  typedef GetIntegerv::Result Result;
1218  Result* result = static_cast<Result*>(shared_memory_address_);
1219  result->size = 0;
1220  GetIntegerv cmd2;
1221  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1222  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1223      .WillOnce(SetArgumentPointee<1>(8))
1224      .RetiresOnSaturation();
1225  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1226  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1227            result->GetNumResults());
1228  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1229  EXPECT_EQ(0, result->GetData()[0]);
1230  result->size = 0;
1231  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1232  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1233      .WillOnce(SetArgumentPointee<1>(24))
1234      .RetiresOnSaturation();
1235  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1236  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1237            result->GetNumResults());
1238  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1239  EXPECT_EQ(24, result->GetData()[0]);
1240}
1241
1242TEST_P(GLES2DecoderManualInitTest, PackedDepthStencilRenderbufferStencil) {
1243  InitState init;
1244  init.extensions = "GL_OES_packed_depth_stencil";
1245  init.gl_version = "opengl es 2.0";
1246  init.bind_generates_resource = true;
1247  InitDecoder(init);
1248  DoBindRenderbuffer(
1249      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1250  DoBindFramebuffer(
1251      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1252
1253  EnsureRenderbufferBound(false);
1254  EXPECT_CALL(*gl_, GetError())
1255      .WillOnce(Return(GL_NO_ERROR))  // for RenderbufferStoage
1256      .WillOnce(Return(GL_NO_ERROR))
1257      .WillOnce(Return(GL_NO_ERROR))  // for FramebufferRenderbuffer
1258      .WillOnce(Return(GL_NO_ERROR))
1259      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
1260      .WillOnce(Return(GL_NO_ERROR))
1261      .WillOnce(Return(GL_NO_ERROR))  // for GetIntegerv
1262      .WillOnce(Return(GL_NO_ERROR))
1263      .RetiresOnSaturation();
1264
1265  EXPECT_CALL(
1266      *gl_,
1267      RenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50))
1268      .Times(1)
1269      .RetiresOnSaturation();
1270  RenderbufferStorage cmd;
1271  cmd.Init(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 100, 50);
1272  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1273  EXPECT_CALL(*gl_,
1274              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1275                                         GL_STENCIL_ATTACHMENT,
1276                                         GL_RENDERBUFFER,
1277                                         kServiceRenderbufferId))
1278      .Times(1)
1279      .RetiresOnSaturation();
1280  FramebufferRenderbuffer fbrb_cmd;
1281  fbrb_cmd.Init(GL_FRAMEBUFFER,
1282                GL_STENCIL_ATTACHMENT,
1283                GL_RENDERBUFFER,
1284                client_renderbuffer_id_);
1285  EXPECT_EQ(error::kNoError, ExecuteCmd(fbrb_cmd));
1286
1287  typedef GetIntegerv::Result Result;
1288  Result* result = static_cast<Result*>(shared_memory_address_);
1289  result->size = 0;
1290  GetIntegerv cmd2;
1291  cmd2.Init(GL_STENCIL_BITS, shared_memory_id_, shared_memory_offset_);
1292  EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _))
1293      .WillOnce(SetArgumentPointee<1>(8))
1294      .RetiresOnSaturation();
1295  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1296  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_STENCIL_BITS),
1297            result->GetNumResults());
1298  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1299  EXPECT_EQ(8, result->GetData()[0]);
1300  result->size = 0;
1301  cmd2.Init(GL_DEPTH_BITS, shared_memory_id_, shared_memory_offset_);
1302  EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _))
1303      .WillOnce(SetArgumentPointee<1>(24))
1304      .RetiresOnSaturation();
1305  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2));
1306  EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_DEPTH_BITS),
1307            result->GetNumResults());
1308  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1309  EXPECT_EQ(0, result->GetData()[0]);
1310}
1311
1312TEST_P(GLES2DecoderTest, FramebufferRenderbufferGLError) {
1313  DoBindFramebuffer(
1314      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1315  EXPECT_CALL(*gl_, GetError())
1316      .WillOnce(Return(GL_NO_ERROR))
1317      .WillOnce(Return(GL_OUT_OF_MEMORY))
1318      .RetiresOnSaturation();
1319  EXPECT_CALL(*gl_,
1320              FramebufferRenderbufferEXT(GL_FRAMEBUFFER,
1321                                         GL_COLOR_ATTACHMENT0,
1322                                         GL_RENDERBUFFER,
1323                                         kServiceRenderbufferId))
1324      .Times(1)
1325      .RetiresOnSaturation();
1326  FramebufferRenderbuffer cmd;
1327  cmd.Init(GL_FRAMEBUFFER,
1328           GL_COLOR_ATTACHMENT0,
1329           GL_RENDERBUFFER,
1330           client_renderbuffer_id_);
1331  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1332  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1333}
1334
1335TEST_P(GLES2DecoderTest, FramebufferTexture2DGLError) {
1336  const GLsizei kWidth = 5;
1337  const GLsizei kHeight = 3;
1338  const GLenum kFormat = GL_RGB;
1339  DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
1340  DoTexImage2D(GL_TEXTURE_2D,
1341               0,
1342               kFormat,
1343               kWidth,
1344               kHeight,
1345               0,
1346               kFormat,
1347               GL_UNSIGNED_BYTE,
1348               0,
1349               0);
1350  DoBindFramebuffer(
1351      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1352  EXPECT_CALL(*gl_, GetError())
1353      .WillOnce(Return(GL_NO_ERROR))
1354      .WillOnce(Return(GL_OUT_OF_MEMORY))
1355      .RetiresOnSaturation();
1356  EXPECT_CALL(*gl_,
1357              FramebufferTexture2DEXT(GL_FRAMEBUFFER,
1358                                      GL_COLOR_ATTACHMENT0,
1359                                      GL_TEXTURE_2D,
1360                                      kServiceTextureId,
1361                                      0))
1362      .Times(1)
1363      .RetiresOnSaturation();
1364  FramebufferTexture2D fbtex_cmd;
1365  fbtex_cmd.Init(GL_FRAMEBUFFER,
1366                 GL_COLOR_ATTACHMENT0,
1367                 GL_TEXTURE_2D,
1368                 client_texture_id_);
1369  EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
1370  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1371}
1372
1373TEST_P(GLES2DecoderTest, RenderbufferStorageGLError) {
1374  DoBindRenderbuffer(
1375      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1376  EnsureRenderbufferBound(false);
1377  EXPECT_CALL(*gl_, GetError())
1378      .WillOnce(Return(GL_NO_ERROR))
1379      .WillOnce(Return(GL_OUT_OF_MEMORY))
1380      .RetiresOnSaturation();
1381  EXPECT_CALL(*gl_, RenderbufferStorageEXT(GL_RENDERBUFFER, GL_RGBA, 100, 50))
1382      .Times(1)
1383      .RetiresOnSaturation();
1384  RenderbufferStorage cmd;
1385  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 100, 50);
1386  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1387  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1388}
1389
1390TEST_P(GLES2DecoderTest, RenderbufferStorageBadArgs) {
1391  DoBindRenderbuffer(
1392      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1393  EXPECT_CALL(*gl_, RenderbufferStorageEXT(_, _, _, _))
1394      .Times(0)
1395      .RetiresOnSaturation();
1396  RenderbufferStorage cmd;
1397  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, TestHelper::kMaxRenderbufferSize + 1, 1);
1398  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1399  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1400  cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 1, TestHelper::kMaxRenderbufferSize + 1);
1401  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1402  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1403}
1404
1405TEST_P(GLES2DecoderManualInitTest,
1406       RenderbufferStorageMultisampleCHROMIUMGLError) {
1407  InitState init;
1408  init.extensions = "GL_EXT_framebuffer_multisample";
1409  init.gl_version = "2.1";
1410  init.bind_generates_resource = true;
1411  InitDecoder(init);
1412  DoBindRenderbuffer(
1413      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1414  EnsureRenderbufferBound(false);
1415  EXPECT_CALL(*gl_, GetError())
1416      .WillOnce(Return(GL_NO_ERROR))
1417      .WillOnce(Return(GL_OUT_OF_MEMORY))
1418      .RetiresOnSaturation();
1419  EXPECT_CALL(
1420      *gl_,
1421      RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 1, GL_RGBA, 100, 50))
1422      .Times(1)
1423      .RetiresOnSaturation();
1424  RenderbufferStorageMultisampleCHROMIUM cmd;
1425  cmd.Init(GL_RENDERBUFFER, 1, GL_RGBA4, 100, 50);
1426  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1427  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1428}
1429
1430TEST_P(GLES2DecoderManualInitTest,
1431       RenderbufferStorageMultisampleCHROMIUMBadArgs) {
1432  InitState init;
1433  init.extensions = "GL_EXT_framebuffer_multisample";
1434  init.gl_version = "2.1";
1435  init.bind_generates_resource = true;
1436  InitDecoder(init);
1437  DoBindRenderbuffer(
1438      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1439  EXPECT_CALL(*gl_, RenderbufferStorageMultisampleEXT(_, _, _, _, _))
1440      .Times(0)
1441      .RetiresOnSaturation();
1442  RenderbufferStorageMultisampleCHROMIUM cmd;
1443  cmd.Init(GL_RENDERBUFFER,
1444           TestHelper::kMaxSamples + 1,
1445           GL_RGBA4,
1446           TestHelper::kMaxRenderbufferSize,
1447           1);
1448  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1449  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1450  cmd.Init(GL_RENDERBUFFER,
1451           TestHelper::kMaxSamples,
1452           GL_RGBA4,
1453           TestHelper::kMaxRenderbufferSize + 1,
1454           1);
1455  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1456  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1457  cmd.Init(GL_RENDERBUFFER,
1458           TestHelper::kMaxSamples,
1459           GL_RGBA4,
1460           1,
1461           TestHelper::kMaxRenderbufferSize + 1);
1462  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1463  EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
1464}
1465
1466TEST_P(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleCHROMIUM) {
1467  InitState init;
1468  init.extensions = "GL_EXT_framebuffer_multisample";
1469  init.gl_version = "2.1";
1470  InitDecoder(init);
1471  DoBindRenderbuffer(
1472      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1473  InSequence sequence;
1474  EnsureRenderbufferBound(false);
1475  DoRenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER,
1476                                           TestHelper::kMaxSamples,
1477                                           GL_RGBA4,
1478                                           GL_RGBA,
1479                                           TestHelper::kMaxRenderbufferSize,
1480                                           1);
1481}
1482
1483TEST_P(GLES2DecoderManualInitTest,
1484       RenderbufferStorageMultisampleCHROMIUMRebindRenderbuffer) {
1485  InitState init;
1486  init.extensions = "GL_EXT_framebuffer_multisample";
1487  init.gl_version = "2.1";
1488  InitDecoder(init);
1489  DoBindRenderbuffer(
1490      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1491  RestoreRenderbufferBindings();
1492  InSequence sequence;
1493  EnsureRenderbufferBound(true);
1494  DoRenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER,
1495                                           TestHelper::kMaxSamples,
1496                                           GL_RGBA4,
1497                                           GL_RGBA,
1498                                           TestHelper::kMaxRenderbufferSize,
1499                                           1);
1500}
1501
1502TEST_P(GLES2DecoderManualInitTest,
1503       RenderbufferStorageMultisampleEXTNotSupported) {
1504  InitState init;
1505  init.extensions = "GL_EXT_framebuffer_multisample";
1506  init.gl_version = "2.1";
1507  init.bind_generates_resource = true;
1508  InitDecoder(init);
1509  DoBindRenderbuffer(
1510      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1511  InSequence sequence;
1512  // GL_EXT_framebuffer_multisample uses RenderbufferStorageMultisampleCHROMIUM.
1513  RenderbufferStorageMultisampleEXT cmd;
1514  cmd.Init(GL_RENDERBUFFER,
1515           TestHelper::kMaxSamples,
1516           GL_RGBA4,
1517           TestHelper::kMaxRenderbufferSize,
1518           1);
1519  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1520  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1521}
1522
1523class GLES2DecoderMultisampledRenderToTextureTest
1524    : public GLES2DecoderTestWithExtensionsOnGLES2 {
1525 public:
1526  void TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM() {
1527    DoBindRenderbuffer(
1528        GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1529    RenderbufferStorageMultisampleCHROMIUM cmd;
1530    cmd.Init(GL_RENDERBUFFER,
1531             TestHelper::kMaxSamples,
1532             GL_RGBA4,
1533             TestHelper::kMaxRenderbufferSize,
1534             1);
1535    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1536    EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
1537  }
1538
1539  void TestRenderbufferStorageMultisampleEXT(const char* extension,
1540                                             bool rb_rebind) {
1541    DoBindRenderbuffer(
1542        GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1543    InSequence sequence;
1544    if (rb_rebind) {
1545      RestoreRenderbufferBindings();
1546      EnsureRenderbufferBound(true);
1547    } else {
1548      EnsureRenderbufferBound(false);
1549    }
1550
1551    EXPECT_CALL(*gl_, GetError())
1552        .WillOnce(Return(GL_NO_ERROR))
1553        .RetiresOnSaturation();
1554    if (strstr(extension, "GL_IMG_multisampled_render_to_texture")) {
1555      EXPECT_CALL(
1556          *gl_,
1557          RenderbufferStorageMultisampleIMG(GL_RENDERBUFFER,
1558                                            TestHelper::kMaxSamples,
1559                                            GL_RGBA,
1560                                            TestHelper::kMaxRenderbufferSize,
1561                                            1))
1562          .Times(1)
1563          .RetiresOnSaturation();
1564    } else {
1565      EXPECT_CALL(
1566          *gl_,
1567          RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
1568                                            TestHelper::kMaxSamples,
1569                                            GL_RGBA,
1570                                            TestHelper::kMaxRenderbufferSize,
1571                                            1))
1572          .Times(1)
1573          .RetiresOnSaturation();
1574    }
1575    EXPECT_CALL(*gl_, GetError())
1576        .WillOnce(Return(GL_NO_ERROR))
1577        .RetiresOnSaturation();
1578    RenderbufferStorageMultisampleEXT cmd;
1579    cmd.Init(GL_RENDERBUFFER,
1580             TestHelper::kMaxSamples,
1581             GL_RGBA4,
1582             TestHelper::kMaxRenderbufferSize,
1583             1);
1584    EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1585    EXPECT_EQ(GL_NO_ERROR, GetGLError());
1586  }
1587};
1588
1589INSTANTIATE_TEST_CASE_P(Service,
1590                        GLES2DecoderMultisampledRenderToTextureTest,
1591                        ::testing::Bool());
1592
1593TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
1594       NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM_EXT) {
1595  Init("GL_EXT_multisampled_render_to_texture");
1596  TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM();
1597}
1598
1599TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
1600       NotCompatibleWithRenderbufferStorageMultisampleCHROMIUM_IMG) {
1601  Init("GL_IMG_multisampled_render_to_texture");
1602  TestNotCompatibleWithRenderbufferStorageMultisampleCHROMIUM();
1603}
1604
1605TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
1606       RenderbufferStorageMultisampleEXT_EXT) {
1607  Init("GL_EXT_multisampled_render_to_texture");
1608  TestRenderbufferStorageMultisampleEXT("GL_EXT_multisampled_render_to_texture",
1609                                        false);
1610}
1611
1612TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
1613       RenderbufferStorageMultisampleEXT_IMG) {
1614  Init("GL_IMG_multisampled_render_to_texture");
1615  TestRenderbufferStorageMultisampleEXT("GL_IMG_multisampled_render_to_texture",
1616                                        false);
1617}
1618
1619TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
1620       RenderbufferStorageMultisampleEXT_EXT_RebindRenderbuffer) {
1621  Init("GL_EXT_multisampled_render_to_texture");
1622  TestRenderbufferStorageMultisampleEXT("GL_EXT_multisampled_render_to_texture",
1623                                        true);
1624}
1625
1626TEST_P(GLES2DecoderMultisampledRenderToTextureTest,
1627       RenderbufferStorageMultisampleEXT_IMG_RebindRenderbuffer) {
1628  Init("GL_IMG_multisampled_render_to_texture");
1629  TestRenderbufferStorageMultisampleEXT("GL_IMG_multisampled_render_to_texture",
1630                                        true);
1631}
1632
1633TEST_P(GLES2DecoderTest, ReadPixelsGLError) {
1634  GLenum kFormat = GL_RGBA;
1635  GLint x = 0;
1636  GLint y = 0;
1637  GLsizei width = 2;
1638  GLsizei height = 4;
1639  typedef ReadPixels::Result Result;
1640  Result* result = GetSharedMemoryAs<Result*>();
1641  uint32 result_shm_id = kSharedMemoryId;
1642  uint32 result_shm_offset = kSharedMemoryOffset;
1643  uint32 pixels_shm_id = kSharedMemoryId;
1644  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
1645  EXPECT_CALL(*gl_, GetError())
1646      .WillOnce(Return(GL_NO_ERROR))
1647      .WillOnce(Return(GL_OUT_OF_MEMORY))
1648      .RetiresOnSaturation();
1649  EXPECT_CALL(*gl_,
1650              ReadPixels(x, y, width, height, kFormat, GL_UNSIGNED_BYTE, _))
1651      .Times(1)
1652      .RetiresOnSaturation();
1653  ReadPixels cmd;
1654  cmd.Init(x,
1655           y,
1656           width,
1657           height,
1658           kFormat,
1659           GL_UNSIGNED_BYTE,
1660           pixels_shm_id,
1661           pixels_shm_offset,
1662           result_shm_id,
1663           result_shm_offset,
1664           false);
1665  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1666  EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
1667}
1668
1669TEST_P(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnClear) {
1670  const GLuint kFBOClientTextureId = 4100;
1671  const GLuint kFBOServiceTextureId = 4101;
1672
1673  // Register a texture id.
1674  EXPECT_CALL(*gl_, GenTextures(_, _))
1675      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
1676      .RetiresOnSaturation();
1677  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
1678
1679  // Setup "render to" texture.
1680  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
1681  DoTexImage2D(
1682      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
1683  DoBindFramebuffer(
1684      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1685  DoFramebufferTexture2D(GL_FRAMEBUFFER,
1686                         GL_COLOR_ATTACHMENT0,
1687                         GL_TEXTURE_2D,
1688                         kFBOClientTextureId,
1689                         kFBOServiceTextureId,
1690                         0,
1691                         GL_NO_ERROR);
1692
1693  // Setup "render from" texture.
1694  SetupTexture();
1695
1696  SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER,       // target
1697                                          GL_COLOR_BUFFER_BIT,  // clear bits
1698                                          0,
1699                                          0,
1700                                          0,
1701                                          0,       // color
1702                                          0,       // stencil
1703                                          1.0f,    // depth
1704                                          false);  // scissor test
1705  SetupExpectationsForApplyingDirtyState(false,    // Framebuffer is RGB
1706                                         false,    // Framebuffer has depth
1707                                         false,    // Framebuffer has stencil
1708                                         0x1111,   // color bits
1709                                         false,    // depth mask
1710                                         false,    // depth enabled
1711                                         0,        // front stencil mask
1712                                         0,        // back stencil mask
1713                                         false);   // stencil enabled
1714
1715  EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)).Times(1).RetiresOnSaturation();
1716
1717  Clear cmd;
1718  cmd.Init(GL_COLOR_BUFFER_BIT);
1719  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1720  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1721}
1722
1723TEST_P(GLES2DecoderWithShaderTest, UnClearedAttachmentsGetClearedOnReadPixels) {
1724  const GLuint kFBOClientTextureId = 4100;
1725  const GLuint kFBOServiceTextureId = 4101;
1726
1727  // Register a texture id.
1728  EXPECT_CALL(*gl_, GenTextures(_, _))
1729      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
1730      .RetiresOnSaturation();
1731  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
1732
1733  // Setup "render to" texture.
1734  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
1735  DoTexImage2D(
1736      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
1737  DoBindFramebuffer(
1738      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1739  DoFramebufferTexture2D(GL_FRAMEBUFFER,
1740                         GL_COLOR_ATTACHMENT0,
1741                         GL_TEXTURE_2D,
1742                         kFBOClientTextureId,
1743                         kFBOServiceTextureId,
1744                         0,
1745                         GL_NO_ERROR);
1746
1747  // Setup "render from" texture.
1748  SetupTexture();
1749
1750  SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER,       // target
1751                                          GL_COLOR_BUFFER_BIT,  // clear bits
1752                                          0,
1753                                          0,
1754                                          0,
1755                                          0,       // color
1756                                          0,       // stencil
1757                                          1.0f,    // depth
1758                                          false);  // scissor test
1759
1760  EXPECT_CALL(*gl_, GetError())
1761      .WillOnce(Return(GL_NO_ERROR))
1762      .WillOnce(Return(GL_NO_ERROR))
1763      .RetiresOnSaturation();
1764  EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
1765      .Times(1)
1766      .RetiresOnSaturation();
1767  typedef ReadPixels::Result Result;
1768  Result* result = GetSharedMemoryAs<Result*>();
1769  uint32 result_shm_id = kSharedMemoryId;
1770  uint32 result_shm_offset = kSharedMemoryOffset;
1771  uint32 pixels_shm_id = kSharedMemoryId;
1772  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
1773  ReadPixels cmd;
1774  cmd.Init(0,
1775           0,
1776           1,
1777           1,
1778           GL_RGBA,
1779           GL_UNSIGNED_BYTE,
1780           pixels_shm_id,
1781           pixels_shm_offset,
1782           result_shm_id,
1783           result_shm_offset,
1784           false);
1785  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1786  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1787}
1788
1789TEST_P(GLES2DecoderManualInitTest,
1790       UnClearedAttachmentsGetClearedOnReadPixelsAndDrawBufferGetsRestored) {
1791  InitState init;
1792  init.extensions = "GL_EXT_framebuffer_multisample";
1793  init.gl_version = "2.1";
1794  init.bind_generates_resource = true;
1795  InitDecoder(init);
1796  const GLuint kFBOClientTextureId = 4100;
1797  const GLuint kFBOServiceTextureId = 4101;
1798
1799  // Register a texture id.
1800  EXPECT_CALL(*gl_, GenTextures(_, _))
1801      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
1802      .RetiresOnSaturation();
1803  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
1804
1805  // Setup "render from" texture.
1806  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
1807  DoTexImage2D(
1808      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
1809  DoBindFramebuffer(
1810      GL_READ_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1811  DoFramebufferTexture2D(GL_READ_FRAMEBUFFER,
1812                         GL_COLOR_ATTACHMENT0,
1813                         GL_TEXTURE_2D,
1814                         kFBOClientTextureId,
1815                         kFBOServiceTextureId,
1816                         0,
1817                         GL_NO_ERROR);
1818
1819  // Enable GL_SCISSOR_TEST to make sure we disable it in the clear,
1820  // then re-enable after.
1821  DoEnableDisable(GL_SCISSOR_TEST, true);
1822
1823  SetupExpectationsForFramebufferClearingMulti(
1824      kServiceFramebufferId,  // read framebuffer service id
1825      0,                      // backbuffer service id
1826      GL_READ_FRAMEBUFFER,    // target
1827      GL_COLOR_BUFFER_BIT,    // clear bits
1828      0,
1829      0,
1830      0,
1831      0,      // color
1832      0,      // stencil
1833      1.0f,   // depth
1834      true);  // scissor test
1835
1836  EXPECT_CALL(*gl_, GetError())
1837      .WillOnce(Return(GL_NO_ERROR))
1838      .WillOnce(Return(GL_NO_ERROR))
1839      .RetiresOnSaturation();
1840  EXPECT_CALL(*gl_, ReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, _))
1841      .Times(1)
1842      .RetiresOnSaturation();
1843  typedef ReadPixels::Result Result;
1844  uint32 result_shm_id = kSharedMemoryId;
1845  uint32 result_shm_offset = kSharedMemoryOffset;
1846  uint32 pixels_shm_id = kSharedMemoryId;
1847  uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(Result);
1848  ReadPixels cmd;
1849  cmd.Init(0,
1850           0,
1851           1,
1852           1,
1853           GL_RGBA,
1854           GL_UNSIGNED_BYTE,
1855           pixels_shm_id,
1856           pixels_shm_offset,
1857           result_shm_id,
1858           result_shm_offset,
1859           false);
1860  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1861  EXPECT_EQ(GL_NO_ERROR, GetGLError());
1862}
1863
1864TEST_P(GLES2DecoderWithShaderTest, CopyTexImageWithInCompleteFBOFails) {
1865  GLenum target = GL_TEXTURE_2D;
1866  GLint level = 0;
1867  GLenum internal_format = GL_RGBA;
1868  GLsizei width = 2;
1869  GLsizei height = 4;
1870  SetupTexture();
1871  DoBindRenderbuffer(
1872      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1873  DoBindFramebuffer(
1874      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1875  DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 0, 0, GL_NO_ERROR);
1876  DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
1877                            GL_COLOR_ATTACHMENT0,
1878                            GL_RENDERBUFFER,
1879                            client_renderbuffer_id_,
1880                            kServiceRenderbufferId,
1881                            GL_NO_ERROR);
1882
1883  EXPECT_CALL(*gl_, CopyTexImage2D(_, _, _, _, _, _, _, _))
1884      .Times(0)
1885      .RetiresOnSaturation();
1886  CopyTexImage2D cmd;
1887  cmd.Init(target, level, internal_format, 0, 0, width, height);
1888  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
1889  EXPECT_EQ(GL_INVALID_FRAMEBUFFER_OPERATION, GetGLError());
1890}
1891
1892void GLES2DecoderWithShaderTest::CheckRenderbufferChangesMarkFBOAsNotComplete(
1893    bool bound_fbo) {
1894  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
1895  SetupTexture();
1896  DoBindRenderbuffer(
1897      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1898  DoBindFramebuffer(
1899      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1900  DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
1901  DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
1902                            GL_COLOR_ATTACHMENT0,
1903                            GL_RENDERBUFFER,
1904                            client_renderbuffer_id_,
1905                            kServiceRenderbufferId,
1906                            GL_NO_ERROR);
1907
1908  if (!bound_fbo) {
1909    DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
1910  }
1911
1912  Framebuffer* framebuffer =
1913      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
1914  ASSERT_TRUE(framebuffer != NULL);
1915  framebuffer_manager->MarkAsComplete(framebuffer);
1916  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
1917
1918  // Test that renderbufferStorage marks fbo as not complete.
1919  DoRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, GL_RGBA, 1, 1, GL_NO_ERROR);
1920  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
1921  framebuffer_manager->MarkAsComplete(framebuffer);
1922  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
1923
1924  // Test deleting renderbuffer marks fbo as not complete.
1925  DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId);
1926  if (bound_fbo) {
1927    EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
1928  } else {
1929    EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
1930  }
1931  // Cleanup
1932  DoDeleteFramebuffer(client_framebuffer_id_,
1933                      kServiceFramebufferId,
1934                      bound_fbo,
1935                      GL_FRAMEBUFFER,
1936                      0,
1937                      bound_fbo,
1938                      GL_FRAMEBUFFER,
1939                      0);
1940}
1941
1942TEST_P(GLES2DecoderWithShaderTest,
1943       RenderbufferChangesMarkFBOAsNotCompleteBoundFBO) {
1944  CheckRenderbufferChangesMarkFBOAsNotComplete(true);
1945}
1946
1947TEST_P(GLES2DecoderWithShaderTest,
1948       RenderbufferChangesMarkFBOAsNotCompleteUnboundFBO) {
1949  CheckRenderbufferChangesMarkFBOAsNotComplete(false);
1950}
1951
1952void GLES2DecoderWithShaderTest::CheckTextureChangesMarkFBOAsNotComplete(
1953    bool bound_fbo) {
1954  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
1955  const GLuint kFBOClientTextureId = 4100;
1956  const GLuint kFBOServiceTextureId = 4101;
1957
1958  // Register a texture id.
1959  EXPECT_CALL(*gl_, GenTextures(_, _))
1960      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
1961      .RetiresOnSaturation();
1962  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
1963
1964  SetupTexture();
1965
1966  // Setup "render to" texture.
1967  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
1968  DoTexImage2D(
1969      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
1970  DoBindFramebuffer(
1971      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1972  DoFramebufferTexture2D(GL_FRAMEBUFFER,
1973                         GL_COLOR_ATTACHMENT0,
1974                         GL_TEXTURE_2D,
1975                         kFBOClientTextureId,
1976                         kFBOServiceTextureId,
1977                         0,
1978                         GL_NO_ERROR);
1979
1980  DoBindRenderbuffer(
1981      GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
1982  DoBindFramebuffer(
1983      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
1984  DoRenderbufferStorage(GL_RENDERBUFFER,
1985                        GL_DEPTH_COMPONENT16,
1986                        GL_DEPTH_COMPONENT,
1987                        1,
1988                        1,
1989                        GL_NO_ERROR);
1990  DoFramebufferRenderbuffer(GL_FRAMEBUFFER,
1991                            GL_DEPTH_ATTACHMENT,
1992                            GL_RENDERBUFFER,
1993                            client_renderbuffer_id_,
1994                            kServiceRenderbufferId,
1995                            GL_NO_ERROR);
1996
1997  if (!bound_fbo) {
1998    DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);
1999  }
2000
2001  Framebuffer* framebuffer =
2002      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
2003  ASSERT_TRUE(framebuffer != NULL);
2004  framebuffer_manager->MarkAsComplete(framebuffer);
2005  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
2006
2007  // Test TexImage2D marks fbo as not complete.
2008  DoTexImage2D(
2009      GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, 0, 0);
2010  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
2011  framebuffer_manager->MarkAsComplete(framebuffer);
2012  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
2013
2014  // Test CopyImage2D marks fbo as not complete.
2015  EXPECT_CALL(*gl_, GetError())
2016      .WillOnce(Return(GL_NO_ERROR))
2017      .RetiresOnSaturation();
2018  EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1, 0))
2019      .Times(1)
2020      .RetiresOnSaturation();
2021  EXPECT_CALL(*gl_, GetError())
2022      .WillOnce(Return(GL_NO_ERROR))
2023      .RetiresOnSaturation();
2024  CopyTexImage2D cmd;
2025  cmd.Init(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 1, 1);
2026  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2027  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
2028
2029  // Test deleting texture marks fbo as not complete.
2030  framebuffer_manager->MarkAsComplete(framebuffer);
2031  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
2032  DoDeleteTexture(kFBOClientTextureId, kFBOServiceTextureId);
2033
2034  if (bound_fbo) {
2035    EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
2036  } else {
2037    EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
2038  }
2039  // Cleanup
2040  DoDeleteFramebuffer(client_framebuffer_id_,
2041                      kServiceFramebufferId,
2042                      bound_fbo,
2043                      GL_FRAMEBUFFER,
2044                      0,
2045                      bound_fbo,
2046                      GL_FRAMEBUFFER,
2047                      0);
2048}
2049
2050TEST_P(GLES2DecoderWithShaderTest, TextureChangesMarkFBOAsNotCompleteBoundFBO) {
2051  CheckTextureChangesMarkFBOAsNotComplete(true);
2052}
2053
2054TEST_P(GLES2DecoderWithShaderTest,
2055       TextureChangesMarkFBOAsNotCompleteUnboundFBO) {
2056  CheckTextureChangesMarkFBOAsNotComplete(false);
2057}
2058
2059TEST_P(GLES2DecoderTest, CanChangeSurface) {
2060  scoped_refptr<GLSurfaceMock> other_surface(new GLSurfaceMock);
2061  EXPECT_CALL(*other_surface.get(), GetBackingFrameBufferObject())
2062      .WillOnce(Return(7));
2063  EXPECT_CALL(*gl_, BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 7));
2064
2065  decoder_->SetSurface(other_surface);
2066}
2067
2068TEST_P(GLES2DecoderTest, DrawBuffersEXTImmediateSuccceeds) {
2069  const GLsizei count = 1;
2070  const GLenum bufs[] = {GL_COLOR_ATTACHMENT0};
2071  DrawBuffersEXTImmediate& cmd = *GetImmediateAs<DrawBuffersEXTImmediate>();
2072  cmd.Init(count, bufs);
2073
2074  DoBindFramebuffer(
2075      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2076  EXPECT_CALL(*gl_, DrawBuffersARB(count, _)).Times(1).RetiresOnSaturation();
2077  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
2078  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2079}
2080
2081TEST_P(GLES2DecoderTest, DrawBuffersEXTImmediateFails) {
2082  const GLsizei count = 1;
2083  const GLenum bufs[] = {GL_COLOR_ATTACHMENT1_EXT};
2084  DrawBuffersEXTImmediate& cmd = *GetImmediateAs<DrawBuffersEXTImmediate>();
2085  cmd.Init(count, bufs);
2086
2087  DoBindFramebuffer(
2088      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2089  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
2090  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2091}
2092
2093TEST_P(GLES2DecoderTest, DrawBuffersEXTImmediateBackbuffer) {
2094  const GLsizei count = 1;
2095  const GLenum bufs[] = {GL_BACK};
2096  DrawBuffersEXTImmediate& cmd = *GetImmediateAs<DrawBuffersEXTImmediate>();
2097  cmd.Init(count, bufs);
2098
2099  DoBindFramebuffer(
2100      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2101  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
2102  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2103
2104  DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0);  // unbind
2105
2106  EXPECT_CALL(*gl_, DrawBuffersARB(count, _)).Times(1).RetiresOnSaturation();
2107
2108  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(bufs)));
2109  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2110}
2111
2112TEST_P(GLES2DecoderManualInitTest, InvalidateFramebufferBinding) {
2113  InitState init;
2114  init.gl_version = "opengl es 3.0";
2115  InitDecoder(init);
2116
2117  // EXPECT_EQ can't be used to compare function pointers
2118  EXPECT_TRUE(
2119      gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") ==
2120      gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
2121  EXPECT_TRUE(
2122      gfx::MockGLInterface::GetGLProcAddress("glInvalidateFramebuffer") !=
2123      gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT"));
2124}
2125
2126TEST_P(GLES2DecoderManualInitTest, DiscardFramebufferEXT) {
2127  InitState init;
2128  init.extensions = "GL_EXT_discard_framebuffer";
2129  init.gl_version = "opengl es 2.0";
2130  InitDecoder(init);
2131
2132  // EXPECT_EQ can't be used to compare function pointers
2133  EXPECT_TRUE(
2134      gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") ==
2135      gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
2136
2137  const GLenum target = GL_FRAMEBUFFER;
2138  const GLsizei count = 1;
2139  const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
2140
2141  SetupTexture();
2142  DoBindFramebuffer(
2143      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2144  DoFramebufferTexture2D(GL_FRAMEBUFFER,
2145                         GL_COLOR_ATTACHMENT0,
2146                         GL_TEXTURE_2D,
2147                         client_texture_id_,
2148                         kServiceTextureId,
2149                         0,
2150                         GL_NO_ERROR);
2151  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
2152  Framebuffer* framebuffer =
2153      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
2154  EXPECT_TRUE(framebuffer->IsCleared());
2155
2156  EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
2157      .Times(1)
2158      .RetiresOnSaturation();
2159  DiscardFramebufferEXTImmediate& cmd =
2160      *GetImmediateAs<DiscardFramebufferEXTImmediate>();
2161  cmd.Init(target, count, attachments);
2162
2163  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
2164  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2165  EXPECT_FALSE(framebuffer->IsCleared());
2166}
2167
2168TEST_P(GLES2DecoderTest, DiscardFramebufferEXTUnsupported) {
2169  const GLenum target = GL_FRAMEBUFFER;
2170  const GLsizei count = 1;
2171  const GLenum attachments[] = {GL_COLOR_EXT};
2172  DiscardFramebufferEXTImmediate& cmd =
2173      *GetImmediateAs<DiscardFramebufferEXTImmediate>();
2174  cmd.Init(target, count, attachments);
2175
2176  // Should not result into a call into GL.
2177  EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(attachments)));
2178  EXPECT_EQ(GL_INVALID_OPERATION, GetGLError());
2179}
2180
2181TEST_P(GLES2DecoderManualInitTest,
2182       DiscardedAttachmentsEXTMarksFramebufferIncomplete) {
2183  InitState init;
2184  init.extensions = "GL_EXT_discard_framebuffer";
2185  init.gl_version = "opengl es 2.0";
2186  init.has_alpha = true;
2187  init.bind_generates_resource = true;
2188  InitDecoder(init);
2189
2190  const GLuint kFBOClientTextureId = 4100;
2191  const GLuint kFBOServiceTextureId = 4101;
2192
2193  // Register a texture id.
2194  EXPECT_CALL(*gl_, GenTextures(_, _))
2195      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
2196      .RetiresOnSaturation();
2197  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
2198
2199  // Setup "render to" texture.
2200  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2201  DoTexImage2D(
2202      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
2203  DoBindFramebuffer(
2204      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2205  DoFramebufferTexture2D(GL_FRAMEBUFFER,
2206                         GL_COLOR_ATTACHMENT0,
2207                         GL_TEXTURE_2D,
2208                         kFBOClientTextureId,
2209                         kFBOServiceTextureId,
2210                         0,
2211                         GL_NO_ERROR);
2212
2213  // Setup "render from" texture.
2214  SetupTexture();
2215
2216  SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER,       // target
2217                                          GL_COLOR_BUFFER_BIT,  // clear bits
2218                                          0,
2219                                          0,
2220                                          0,
2221                                          0,       // color
2222                                          0,       // stencil
2223                                          1.0f,    // depth
2224                                          false);  // scissor test
2225  SetupExpectationsForApplyingDirtyState(false,    // Framebuffer is RGB
2226                                         false,    // Framebuffer has depth
2227                                         false,    // Framebuffer has stencil
2228                                         0x1111,   // color bits
2229                                         false,    // depth mask
2230                                         false,    // depth enabled
2231                                         0,        // front stencil mask
2232                                         0,        // back stencil mask
2233                                         false);   // stencil enabled
2234
2235  EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)).Times(1).RetiresOnSaturation();
2236
2237  Clear clear_cmd;
2238  clear_cmd.Init(GL_COLOR_BUFFER_BIT);
2239  EXPECT_EQ(error::kNoError, ExecuteCmd(clear_cmd));
2240  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2241
2242  // Check that framebuffer is cleared and complete.
2243  FramebufferManager* framebuffer_manager = group().framebuffer_manager();
2244  Framebuffer* framebuffer =
2245      framebuffer_manager->GetFramebuffer(client_framebuffer_id_);
2246  EXPECT_TRUE(framebuffer->IsCleared());
2247  EXPECT_TRUE(framebuffer_manager->IsComplete(framebuffer));
2248
2249  // Check that Discard GL_COLOR_ATTACHMENT0, sets the attachment as uncleared
2250  // and the framebuffer as incomplete.
2251  EXPECT_TRUE(
2252      gfx::MockGLInterface::GetGLProcAddress("glDiscardFramebufferEXT") ==
2253      gfx::g_driver_gl.fn.glDiscardFramebufferEXTFn);
2254
2255  const GLenum target = GL_FRAMEBUFFER;
2256  const GLsizei count = 1;
2257  const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
2258
2259  DiscardFramebufferEXTImmediate& discard_cmd =
2260      *GetImmediateAs<DiscardFramebufferEXTImmediate>();
2261  discard_cmd.Init(target, count, attachments);
2262
2263  EXPECT_CALL(*gl_, DiscardFramebufferEXT(target, count, _))
2264      .Times(1)
2265      .RetiresOnSaturation();
2266  EXPECT_EQ(error::kNoError,
2267            ExecuteImmediateCmd(discard_cmd, sizeof(attachments)));
2268  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2269  EXPECT_FALSE(framebuffer->IsCleared());
2270  EXPECT_FALSE(framebuffer_manager->IsComplete(framebuffer));
2271}
2272
2273TEST_P(GLES2DecoderManualInitTest, ReadFormatExtension) {
2274  InitState init;
2275  init.extensions = "GL_OES_read_format";
2276  init.gl_version = "2.1";
2277  init.bind_generates_resource = true;
2278  InitDecoder(init);
2279
2280  EXPECT_CALL(*gl_, GetError())
2281      .WillOnce(Return(GL_NO_ERROR))
2282      .WillOnce(Return(GL_NO_ERROR))
2283      .WillOnce(Return(GL_NO_ERROR))
2284      .WillOnce(Return(GL_NO_ERROR))
2285      .RetiresOnSaturation();
2286  EXPECT_CALL(*gl_, GetError()).Times(6).RetiresOnSaturation();
2287
2288  typedef GetIntegerv::Result Result;
2289  Result* result = static_cast<Result*>(shared_memory_address_);
2290  GetIntegerv cmd;
2291  const GLuint kFBOClientTextureId = 4100;
2292  const GLuint kFBOServiceTextureId = 4101;
2293
2294  // Register a texture id.
2295  EXPECT_CALL(*gl_, GenTextures(_, _))
2296      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
2297      .RetiresOnSaturation();
2298  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
2299
2300  // Setup "render to" texture.
2301  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2302  DoTexImage2D(
2303      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
2304  DoBindFramebuffer(
2305      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2306  DoFramebufferTexture2D(GL_FRAMEBUFFER,
2307                         GL_COLOR_ATTACHMENT0,
2308                         GL_TEXTURE_2D,
2309                         kFBOClientTextureId,
2310                         kFBOServiceTextureId,
2311                         0,
2312                         GL_NO_ERROR);
2313
2314  result->size = 0;
2315  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(1).RetiresOnSaturation();
2316  cmd.Init(GL_IMPLEMENTATION_COLOR_READ_FORMAT,
2317           shared_memory_id_,
2318           shared_memory_offset_);
2319  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2320  EXPECT_EQ(1, result->GetNumResults());
2321  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2322
2323  result->size = 0;
2324  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(1).RetiresOnSaturation();
2325  cmd.Init(GL_IMPLEMENTATION_COLOR_READ_TYPE,
2326           shared_memory_id_,
2327           shared_memory_offset_);
2328  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2329  EXPECT_EQ(1, result->GetNumResults());
2330  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2331}
2332
2333TEST_P(GLES2DecoderManualInitTest, NoReadFormatExtension) {
2334  InitState init;
2335  init.gl_version = "2.1";
2336  init.bind_generates_resource = true;
2337  InitDecoder(init);
2338
2339  EXPECT_CALL(*gl_, GetError())
2340      .WillOnce(Return(GL_NO_ERROR))
2341      .WillOnce(Return(GL_NO_ERROR))
2342      .WillOnce(Return(GL_NO_ERROR))
2343      .WillOnce(Return(GL_NO_ERROR))
2344      .RetiresOnSaturation();
2345
2346  typedef GetIntegerv::Result Result;
2347  Result* result = static_cast<Result*>(shared_memory_address_);
2348  GetIntegerv cmd;
2349  const GLuint kFBOClientTextureId = 4100;
2350  const GLuint kFBOServiceTextureId = 4101;
2351
2352  // Register a texture id.
2353  EXPECT_CALL(*gl_, GenTextures(_, _))
2354      .WillOnce(SetArgumentPointee<1>(kFBOServiceTextureId))
2355      .RetiresOnSaturation();
2356  GenHelper<GenTexturesImmediate>(kFBOClientTextureId);
2357
2358  // Setup "render to" texture.
2359  DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId);
2360  DoTexImage2D(
2361      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
2362  DoBindFramebuffer(
2363      GL_FRAMEBUFFER, client_framebuffer_id_, kServiceFramebufferId);
2364  DoFramebufferTexture2D(GL_FRAMEBUFFER,
2365                         GL_COLOR_ATTACHMENT0,
2366                         GL_TEXTURE_2D,
2367                         kFBOClientTextureId,
2368                         kFBOServiceTextureId,
2369                         0,
2370                         GL_NO_ERROR);
2371
2372  result->size = 0;
2373  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0).RetiresOnSaturation();
2374  cmd.Init(GL_IMPLEMENTATION_COLOR_READ_FORMAT,
2375           shared_memory_id_,
2376           shared_memory_offset_);
2377  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2378  EXPECT_EQ(1, result->GetNumResults());
2379  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2380
2381  result->size = 0;
2382  EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0).RetiresOnSaturation();
2383  cmd.Init(GL_IMPLEMENTATION_COLOR_READ_TYPE,
2384           shared_memory_id_,
2385           shared_memory_offset_);
2386  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
2387  EXPECT_EQ(1, result->GetNumResults());
2388  EXPECT_EQ(GL_NO_ERROR, GetGLError());
2389}
2390
2391// TODO(gman): PixelStorei
2392
2393// TODO(gman): SwapBuffers
2394
2395}  // namespace gles2
2396}  // namespace gpu
2397