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