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