1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "gpu/command_buffer/service/error_state_mock.h" 6 #include "gpu/command_buffer/service/framebuffer_manager.h" 7 #include "gpu/command_buffer/service/feature_info.h" 8 #include "gpu/command_buffer/service/renderbuffer_manager.h" 9 #include "gpu/command_buffer/service/test_helper.h" 10 #include "gpu/command_buffer/service/texture_manager.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "ui/gl/gl_mock.h" 13 14 using ::testing::Return; 15 16 namespace gpu { 17 namespace gles2 { 18 namespace { 19 20 const GLint kMaxTextureSize = 64; 21 const GLint kMaxCubemapSize = 64; 22 const GLint kMaxRenderbufferSize = 64; 23 const GLint kMaxSamples = 4; 24 const bool kDepth24Supported = false; 25 26 } // namespace 27 28 class FramebufferManagerTest : public testing::Test { 29 public: 30 FramebufferManagerTest() 31 : manager_(1, 1), 32 texture_manager_( 33 NULL, new FeatureInfo(), kMaxTextureSize, kMaxCubemapSize), 34 renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples, 35 kDepth24Supported) { 36 37 } 38 virtual ~FramebufferManagerTest() { 39 manager_.Destroy(false); 40 texture_manager_.Destroy(false); 41 renderbuffer_manager_.Destroy(false); 42 } 43 44 protected: 45 virtual void SetUp() { 46 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); 47 ::gfx::GLInterface::SetGLInterface(gl_.get()); 48 } 49 50 virtual void TearDown() { 51 ::gfx::GLInterface::SetGLInterface(NULL); 52 gl_.reset(); 53 } 54 55 // Use StrictMock to make 100% sure we know how GL will be called. 56 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; 57 FramebufferManager manager_; 58 TextureManager texture_manager_; 59 RenderbufferManager renderbuffer_manager_; 60 }; 61 62 TEST_F(FramebufferManagerTest, Basic) { 63 const GLuint kClient1Id = 1; 64 const GLuint kService1Id = 11; 65 const GLuint kClient2Id = 2; 66 // Check we can create framebuffer. 67 manager_.CreateFramebuffer(kClient1Id, kService1Id); 68 // Check framebuffer got created. 69 Framebuffer* framebuffer1 = manager_.GetFramebuffer(kClient1Id); 70 ASSERT_TRUE(framebuffer1 != NULL); 71 EXPECT_FALSE(framebuffer1->IsDeleted()); 72 EXPECT_EQ(kService1Id, framebuffer1->service_id()); 73 GLuint client_id = 0; 74 EXPECT_TRUE(manager_.GetClientId(framebuffer1->service_id(), &client_id)); 75 EXPECT_EQ(kClient1Id, client_id); 76 // Check we get nothing for a non-existent framebuffer. 77 EXPECT_TRUE(manager_.GetFramebuffer(kClient2Id) == NULL); 78 // Check trying to a remove non-existent framebuffers does not crash. 79 manager_.RemoveFramebuffer(kClient2Id); 80 // Check framebuffer gets deleted when last reference is released. 81 EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id))) 82 .Times(1) 83 .RetiresOnSaturation(); 84 // Check we can't get the framebuffer after we remove it. 85 manager_.RemoveFramebuffer(kClient1Id); 86 EXPECT_TRUE(manager_.GetFramebuffer(kClient1Id) == NULL); 87 } 88 89 TEST_F(FramebufferManagerTest, Destroy) { 90 const GLuint kClient1Id = 1; 91 const GLuint kService1Id = 11; 92 // Check we can create framebuffer. 93 manager_.CreateFramebuffer(kClient1Id, kService1Id); 94 // Check framebuffer got created. 95 Framebuffer* framebuffer1 = manager_.GetFramebuffer(kClient1Id); 96 ASSERT_TRUE(framebuffer1 != NULL); 97 EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id))) 98 .Times(1) 99 .RetiresOnSaturation(); 100 manager_.Destroy(true); 101 // Check the resources were released. 102 framebuffer1 = manager_.GetFramebuffer(kClient1Id); 103 ASSERT_TRUE(framebuffer1 == NULL); 104 } 105 106 class FramebufferInfoTest : public testing::Test { 107 public: 108 static const GLuint kClient1Id = 1; 109 static const GLuint kService1Id = 11; 110 111 FramebufferInfoTest() 112 : manager_(1, 1), 113 texture_manager_( 114 NULL, new FeatureInfo(), kMaxTextureSize, kMaxCubemapSize), 115 renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples, 116 kDepth24Supported) { 117 } 118 virtual ~FramebufferInfoTest() { 119 manager_.Destroy(false); 120 texture_manager_.Destroy(false); 121 renderbuffer_manager_.Destroy(false); 122 } 123 124 protected: 125 virtual void SetUp() { 126 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); 127 ::gfx::GLInterface::SetGLInterface(gl_.get()); 128 manager_.CreateFramebuffer(kClient1Id, kService1Id); 129 error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>()); 130 framebuffer_ = manager_.GetFramebuffer(kClient1Id); 131 ASSERT_TRUE(framebuffer_ != NULL); 132 } 133 134 virtual void TearDown() { 135 ::gfx::GLInterface::SetGLInterface(NULL); 136 gl_.reset(); 137 } 138 139 // Use StrictMock to make 100% sure we know how GL will be called. 140 scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; 141 FramebufferManager manager_; 142 Framebuffer* framebuffer_; 143 TextureManager texture_manager_; 144 RenderbufferManager renderbuffer_manager_; 145 scoped_ptr<MockErrorState> error_state_; 146 }; 147 148 // GCC requires these declarations, but MSVC requires they not be present 149 #ifndef COMPILER_MSVC 150 const GLuint FramebufferInfoTest::kClient1Id; 151 const GLuint FramebufferInfoTest::kService1Id; 152 #endif 153 154 TEST_F(FramebufferInfoTest, Basic) { 155 EXPECT_EQ(kService1Id, framebuffer_->service_id()); 156 EXPECT_FALSE(framebuffer_->IsDeleted()); 157 EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0)); 158 EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT)); 159 EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT)); 160 EXPECT_TRUE( 161 NULL == framebuffer_->GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT)); 162 EXPECT_FALSE(framebuffer_->HasDepthAttachment()); 163 EXPECT_FALSE(framebuffer_->HasStencilAttachment()); 164 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT), 165 framebuffer_->IsPossiblyComplete()); 166 EXPECT_TRUE(framebuffer_->IsCleared()); 167 EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat()); 168 EXPECT_FALSE(manager_.IsComplete(framebuffer_)); 169 } 170 171 TEST_F(FramebufferInfoTest, AttachRenderbuffer) { 172 const GLuint kRenderbufferClient1Id = 33; 173 const GLuint kRenderbufferService1Id = 333; 174 const GLuint kRenderbufferClient2Id = 34; 175 const GLuint kRenderbufferService2Id = 334; 176 const GLuint kRenderbufferClient3Id = 35; 177 const GLuint kRenderbufferService3Id = 335; 178 const GLuint kRenderbufferClient4Id = 36; 179 const GLuint kRenderbufferService4Id = 336; 180 const GLsizei kWidth1 = 16; 181 const GLsizei kHeight1 = 32; 182 const GLenum kFormat1 = GL_RGBA4; 183 const GLenum kBadFormat1 = GL_DEPTH_COMPONENT16; 184 const GLsizei kSamples1 = 0; 185 const GLsizei kWidth2 = 16; 186 const GLsizei kHeight2 = 32; 187 const GLenum kFormat2 = GL_DEPTH_COMPONENT16; 188 const GLsizei kSamples2 = 0; 189 const GLsizei kWidth3 = 16; 190 const GLsizei kHeight3 = 32; 191 const GLenum kFormat3 = GL_STENCIL_INDEX8; 192 const GLsizei kSamples3 = 0; 193 const GLsizei kWidth4 = 16; 194 const GLsizei kHeight4 = 32; 195 const GLenum kFormat4 = GL_STENCIL_INDEX8; 196 const GLsizei kSamples4 = 0; 197 198 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); 199 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT)); 200 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT)); 201 EXPECT_FALSE( 202 framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)); 203 204 renderbuffer_manager_.CreateRenderbuffer( 205 kRenderbufferClient1Id, kRenderbufferService1Id); 206 Renderbuffer* renderbuffer1 = 207 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); 208 ASSERT_TRUE(renderbuffer1 != NULL); 209 210 // check adding one attachment 211 framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1); 212 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); 213 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT)); 214 EXPECT_EQ(static_cast<GLenum>(GL_RGBA4), 215 framebuffer_->GetColorAttachmentFormat()); 216 EXPECT_FALSE(framebuffer_->HasDepthAttachment()); 217 EXPECT_FALSE(framebuffer_->HasStencilAttachment()); 218 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), 219 framebuffer_->IsPossiblyComplete()); 220 EXPECT_TRUE(framebuffer_->IsCleared()); 221 222 // Try a format that's not good for COLOR_ATTACHMENT0. 223 renderbuffer_manager_.SetInfo( 224 renderbuffer1, kSamples1, kBadFormat1, kWidth1, kHeight1); 225 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), 226 framebuffer_->IsPossiblyComplete()); 227 228 // Try a good format. 229 renderbuffer_manager_.SetInfo( 230 renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1); 231 EXPECT_EQ(static_cast<GLenum>(kFormat1), 232 framebuffer_->GetColorAttachmentFormat()); 233 EXPECT_FALSE(framebuffer_->HasDepthAttachment()); 234 EXPECT_FALSE(framebuffer_->HasStencilAttachment()); 235 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 236 framebuffer_->IsPossiblyComplete()); 237 EXPECT_FALSE(framebuffer_->IsCleared()); 238 239 // check adding another 240 renderbuffer_manager_.CreateRenderbuffer( 241 kRenderbufferClient2Id, kRenderbufferService2Id); 242 Renderbuffer* renderbuffer2 = 243 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id); 244 ASSERT_TRUE(renderbuffer2 != NULL); 245 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer2); 246 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); 247 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT)); 248 EXPECT_EQ(static_cast<GLenum>(kFormat1), 249 framebuffer_->GetColorAttachmentFormat()); 250 EXPECT_TRUE(framebuffer_->HasDepthAttachment()); 251 EXPECT_FALSE(framebuffer_->HasStencilAttachment()); 252 // The attachment has a size of 0,0 so depending on the order of the map 253 // of attachments it could either get INCOMPLETE_ATTACHMENT because it's 0,0 254 // or INCOMPLETE_DIMENSIONS because it's not the same size as the other 255 // attachment. 256 GLenum status = framebuffer_->IsPossiblyComplete(); 257 EXPECT_TRUE( 258 status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT || 259 status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT); 260 EXPECT_FALSE(framebuffer_->IsCleared()); 261 262 renderbuffer_manager_.SetInfo( 263 renderbuffer2, kSamples2, kFormat2, kWidth2, kHeight2); 264 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 265 framebuffer_->IsPossiblyComplete()); 266 EXPECT_FALSE(framebuffer_->IsCleared()); 267 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT)); 268 269 // check marking them as cleared. 270 manager_.MarkAttachmentsAsCleared( 271 framebuffer_, &renderbuffer_manager_, &texture_manager_); 272 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); 273 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT)); 274 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 275 framebuffer_->IsPossiblyComplete()); 276 EXPECT_TRUE(framebuffer_->IsCleared()); 277 278 // Check adding one that is already cleared. 279 renderbuffer_manager_.CreateRenderbuffer( 280 kRenderbufferClient3Id, kRenderbufferService3Id); 281 Renderbuffer* renderbuffer3 = 282 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient3Id); 283 ASSERT_TRUE(renderbuffer3 != NULL); 284 renderbuffer_manager_.SetInfo( 285 renderbuffer3, kSamples3, kFormat3, kWidth3, kHeight3); 286 renderbuffer_manager_.SetCleared(renderbuffer3, true); 287 288 framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer3); 289 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT)); 290 EXPECT_EQ(static_cast<GLenum>(kFormat1), 291 framebuffer_->GetColorAttachmentFormat()); 292 EXPECT_TRUE(framebuffer_->HasDepthAttachment()); 293 EXPECT_TRUE(framebuffer_->HasStencilAttachment()); 294 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 295 framebuffer_->IsPossiblyComplete()); 296 EXPECT_TRUE(framebuffer_->IsCleared()); 297 298 // Check marking the renderbuffer as unclared. 299 renderbuffer_manager_.SetInfo( 300 renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1); 301 EXPECT_EQ(static_cast<GLenum>(kFormat1), 302 framebuffer_->GetColorAttachmentFormat()); 303 EXPECT_TRUE(framebuffer_->HasDepthAttachment()); 304 EXPECT_TRUE(framebuffer_->HasStencilAttachment()); 305 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 306 framebuffer_->IsPossiblyComplete()); 307 EXPECT_FALSE(framebuffer_->IsCleared()); 308 309 const Framebuffer::Attachment* attachment = 310 framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0); 311 ASSERT_TRUE(attachment != NULL); 312 EXPECT_EQ(kWidth1, attachment->width()); 313 EXPECT_EQ(kHeight1, attachment->height()); 314 EXPECT_EQ(kSamples1, attachment->samples()); 315 EXPECT_EQ(kFormat1, attachment->internal_format()); 316 EXPECT_FALSE(attachment->cleared()); 317 318 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); 319 320 // Clear it. 321 manager_.MarkAttachmentsAsCleared( 322 framebuffer_, &renderbuffer_manager_, &texture_manager_); 323 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); 324 EXPECT_TRUE(framebuffer_->IsCleared()); 325 326 // Check replacing an attachment 327 renderbuffer_manager_.CreateRenderbuffer( 328 kRenderbufferClient4Id, kRenderbufferService4Id); 329 Renderbuffer* renderbuffer4 = 330 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient4Id); 331 ASSERT_TRUE(renderbuffer4 != NULL); 332 renderbuffer_manager_.SetInfo( 333 renderbuffer4, kSamples4, kFormat4, kWidth4, kHeight4); 334 335 framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer4); 336 EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT)); 337 EXPECT_FALSE(framebuffer_->IsCleared()); 338 339 attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT); 340 ASSERT_TRUE(attachment != NULL); 341 EXPECT_EQ(kWidth4, attachment->width()); 342 EXPECT_EQ(kHeight4, attachment->height()); 343 EXPECT_EQ(kSamples4, attachment->samples()); 344 EXPECT_EQ(kFormat4, attachment->internal_format()); 345 EXPECT_FALSE(attachment->cleared()); 346 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 347 framebuffer_->IsPossiblyComplete()); 348 349 // Check changing an attachment. 350 renderbuffer_manager_.SetInfo( 351 renderbuffer4, kSamples4, kFormat4, kWidth4 + 1, kHeight4); 352 353 attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT); 354 ASSERT_TRUE(attachment != NULL); 355 EXPECT_EQ(kWidth4 + 1, attachment->width()); 356 EXPECT_EQ(kHeight4, attachment->height()); 357 EXPECT_EQ(kSamples4, attachment->samples()); 358 EXPECT_EQ(kFormat4, attachment->internal_format()); 359 EXPECT_FALSE(attachment->cleared()); 360 EXPECT_FALSE(framebuffer_->IsCleared()); 361 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT), 362 framebuffer_->IsPossiblyComplete()); 363 364 // Check removing it. 365 framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, NULL); 366 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT)); 367 EXPECT_EQ(static_cast<GLenum>(kFormat1), 368 framebuffer_->GetColorAttachmentFormat()); 369 EXPECT_TRUE(framebuffer_->HasDepthAttachment()); 370 EXPECT_FALSE(framebuffer_->HasStencilAttachment()); 371 372 EXPECT_TRUE(framebuffer_->IsCleared()); 373 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 374 framebuffer_->IsPossiblyComplete()); 375 376 // Remove depth, Set color to 0 size. 377 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, NULL); 378 renderbuffer_manager_.SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0); 379 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), 380 framebuffer_->IsPossiblyComplete()); 381 382 // Remove color. 383 framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, NULL); 384 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT), 385 framebuffer_->IsPossiblyComplete()); 386 } 387 388 TEST_F(FramebufferInfoTest, AttachTexture) { 389 const GLuint kTextureClient1Id = 33; 390 const GLuint kTextureService1Id = 333; 391 const GLuint kTextureClient2Id = 34; 392 const GLuint kTextureService2Id = 334; 393 const GLint kDepth = 1; 394 const GLint kBorder = 0; 395 const GLenum kType = GL_UNSIGNED_BYTE; 396 const GLsizei kWidth1 = 16; 397 const GLsizei kHeight1 = 32; 398 const GLint kLevel1 = 0; 399 const GLenum kFormat1 = GL_RGBA; 400 const GLenum kBadFormat1 = GL_DEPTH_COMPONENT16; 401 const GLenum kTarget1 = GL_TEXTURE_2D; 402 const GLsizei kSamples1 = 0; 403 const GLsizei kWidth2 = 16; 404 const GLsizei kHeight2 = 32; 405 const GLint kLevel2 = 0; 406 const GLenum kFormat2 = GL_RGB; 407 const GLenum kTarget2 = GL_TEXTURE_2D; 408 const GLsizei kSamples2 = 0; 409 const GLsizei kWidth3 = 75; 410 const GLsizei kHeight3 = 123; 411 const GLint kLevel3 = 0; 412 const GLenum kFormat3 = GL_RGB565; 413 const GLsizei kSamples3 = 0; 414 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); 415 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT)); 416 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT)); 417 EXPECT_FALSE( 418 framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)); 419 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT), 420 framebuffer_->IsPossiblyComplete()); 421 422 texture_manager_.CreateTexture(kTextureClient1Id, kTextureService1Id); 423 scoped_refptr<TextureRef> texture1( 424 texture_manager_.GetTexture(kTextureClient1Id)); 425 ASSERT_TRUE(texture1.get() != NULL); 426 427 // check adding one attachment 428 framebuffer_->AttachTexture( 429 GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1); 430 EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); 431 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), 432 framebuffer_->IsPossiblyComplete()); 433 EXPECT_TRUE(framebuffer_->IsCleared()); 434 EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat()); 435 436 // Try format that doesn't work with COLOR_ATTACHMENT0 437 texture_manager_.SetTarget(texture1.get(), GL_TEXTURE_2D); 438 texture_manager_.SetLevelInfo(texture1.get(), 439 GL_TEXTURE_2D, 440 kLevel1, 441 kBadFormat1, 442 kWidth1, 443 kHeight1, 444 kDepth, 445 kBorder, 446 kBadFormat1, 447 kType, 448 true); 449 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), 450 framebuffer_->IsPossiblyComplete()); 451 452 // Try a good format. 453 texture_manager_.SetLevelInfo(texture1.get(), 454 GL_TEXTURE_2D, 455 kLevel1, 456 kFormat1, 457 kWidth1, 458 kHeight1, 459 kDepth, 460 kBorder, 461 kFormat1, 462 kType, 463 false); 464 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 465 framebuffer_->IsPossiblyComplete()); 466 EXPECT_FALSE(framebuffer_->IsCleared()); 467 texture_manager_.SetLevelInfo(texture1.get(), 468 GL_TEXTURE_2D, 469 kLevel1, 470 kFormat1, 471 kWidth1, 472 kHeight1, 473 kDepth, 474 kBorder, 475 kFormat1, 476 kType, 477 true); 478 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 479 framebuffer_->IsPossiblyComplete()); 480 EXPECT_TRUE(framebuffer_->IsCleared()); 481 EXPECT_EQ(static_cast<GLenum>(kFormat1), 482 framebuffer_->GetColorAttachmentFormat()); 483 484 const Framebuffer::Attachment* attachment = 485 framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0); 486 ASSERT_TRUE(attachment != NULL); 487 EXPECT_EQ(kWidth1, attachment->width()); 488 EXPECT_EQ(kHeight1, attachment->height()); 489 EXPECT_EQ(kSamples1, attachment->samples()); 490 EXPECT_EQ(kFormat1, attachment->internal_format()); 491 EXPECT_TRUE(attachment->cleared()); 492 493 // Check replacing an attachment 494 texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id); 495 scoped_refptr<TextureRef> texture2( 496 texture_manager_.GetTexture(kTextureClient2Id)); 497 ASSERT_TRUE(texture2.get() != NULL); 498 texture_manager_.SetTarget(texture2.get(), GL_TEXTURE_2D); 499 texture_manager_.SetLevelInfo(texture2.get(), 500 GL_TEXTURE_2D, 501 kLevel2, 502 kFormat2, 503 kWidth2, 504 kHeight2, 505 kDepth, 506 kBorder, 507 kFormat2, 508 kType, 509 true); 510 511 framebuffer_->AttachTexture( 512 GL_COLOR_ATTACHMENT0, texture2.get(), kTarget2, kLevel2, kSamples2); 513 EXPECT_EQ(static_cast<GLenum>(kFormat2), 514 framebuffer_->GetColorAttachmentFormat()); 515 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 516 framebuffer_->IsPossiblyComplete()); 517 EXPECT_TRUE(framebuffer_->IsCleared()); 518 519 attachment = framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0); 520 ASSERT_TRUE(attachment != NULL); 521 EXPECT_EQ(kWidth2, attachment->width()); 522 EXPECT_EQ(kHeight2, attachment->height()); 523 EXPECT_EQ(kSamples2, attachment->samples()); 524 EXPECT_EQ(kFormat2, attachment->internal_format()); 525 EXPECT_TRUE(attachment->cleared()); 526 527 // Check changing attachment 528 texture_manager_.SetLevelInfo(texture2.get(), 529 GL_TEXTURE_2D, 530 kLevel3, 531 kFormat3, 532 kWidth3, 533 kHeight3, 534 kDepth, 535 kBorder, 536 kFormat3, 537 kType, 538 false); 539 attachment = framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0); 540 ASSERT_TRUE(attachment != NULL); 541 EXPECT_EQ(kWidth3, attachment->width()); 542 EXPECT_EQ(kHeight3, attachment->height()); 543 EXPECT_EQ(kSamples3, attachment->samples()); 544 EXPECT_EQ(kFormat3, attachment->internal_format()); 545 EXPECT_FALSE(attachment->cleared()); 546 EXPECT_EQ(static_cast<GLenum>(kFormat3), 547 framebuffer_->GetColorAttachmentFormat()); 548 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 549 framebuffer_->IsPossiblyComplete()); 550 EXPECT_FALSE(framebuffer_->IsCleared()); 551 552 // Set to size 0 553 texture_manager_.SetLevelInfo(texture2.get(), 554 GL_TEXTURE_2D, 555 kLevel3, 556 kFormat3, 557 0, 558 0, 559 kDepth, 560 kBorder, 561 kFormat3, 562 kType, 563 false); 564 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), 565 framebuffer_->IsPossiblyComplete()); 566 567 // Check removing it. 568 framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT0, NULL, 0, 0, 0); 569 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL); 570 EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat()); 571 572 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT), 573 framebuffer_->IsPossiblyComplete()); 574 EXPECT_TRUE(framebuffer_->IsCleared()); 575 } 576 577 TEST_F(FramebufferInfoTest, UnbindRenderbuffer) { 578 const GLuint kRenderbufferClient1Id = 33; 579 const GLuint kRenderbufferService1Id = 333; 580 const GLuint kRenderbufferClient2Id = 34; 581 const GLuint kRenderbufferService2Id = 334; 582 583 renderbuffer_manager_.CreateRenderbuffer( 584 kRenderbufferClient1Id, kRenderbufferService1Id); 585 Renderbuffer* renderbuffer1 = 586 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); 587 ASSERT_TRUE(renderbuffer1 != NULL); 588 renderbuffer_manager_.CreateRenderbuffer( 589 kRenderbufferClient2Id, kRenderbufferService2Id); 590 Renderbuffer* renderbuffer2 = 591 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id); 592 ASSERT_TRUE(renderbuffer2 != NULL); 593 594 // Attach to 2 attachment points. 595 framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1); 596 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1); 597 // Check they were attached. 598 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL); 599 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL); 600 // Unbind unattached renderbuffer. 601 framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer2); 602 // Should be no-op. 603 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL); 604 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL); 605 // Unbind renderbuffer. 606 framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1); 607 // Check they were detached 608 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL); 609 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) == NULL); 610 } 611 612 TEST_F(FramebufferInfoTest, UnbindTexture) { 613 const GLuint kTextureClient1Id = 33; 614 const GLuint kTextureService1Id = 333; 615 const GLuint kTextureClient2Id = 34; 616 const GLuint kTextureService2Id = 334; 617 const GLenum kTarget1 = GL_TEXTURE_2D; 618 const GLint kLevel1 = 0; 619 const GLint kSamples1 = 0; 620 621 texture_manager_.CreateTexture(kTextureClient1Id, kTextureService1Id); 622 scoped_refptr<TextureRef> texture1( 623 texture_manager_.GetTexture(kTextureClient1Id)); 624 ASSERT_TRUE(texture1.get() != NULL); 625 texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id); 626 scoped_refptr<TextureRef> texture2( 627 texture_manager_.GetTexture(kTextureClient2Id)); 628 ASSERT_TRUE(texture2.get() != NULL); 629 630 // Attach to 2 attachment points. 631 framebuffer_->AttachTexture( 632 GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1); 633 framebuffer_->AttachTexture( 634 GL_DEPTH_ATTACHMENT, texture1.get(), kTarget1, kLevel1, kSamples1); 635 // Check they were attached. 636 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL); 637 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL); 638 // Unbind unattached texture. 639 framebuffer_->UnbindTexture(kTarget1, texture2.get()); 640 // Should be no-op. 641 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL); 642 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL); 643 // Unbind texture. 644 framebuffer_->UnbindTexture(kTarget1, texture1.get()); 645 // Check they were detached 646 EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL); 647 EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) == NULL); 648 } 649 650 TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) { 651 const GLuint kRenderbufferClient1Id = 33; 652 const GLuint kRenderbufferService1Id = 333; 653 const GLuint kTextureClient2Id = 34; 654 const GLuint kTextureService2Id = 334; 655 const GLenum kTarget1 = GL_TEXTURE_2D; 656 const GLint kLevel1 = 0; 657 const GLint kSamples1 = 0; 658 659 renderbuffer_manager_.CreateRenderbuffer( 660 kRenderbufferClient1Id, kRenderbufferService1Id); 661 Renderbuffer* renderbuffer1 = 662 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); 663 ASSERT_TRUE(renderbuffer1 != NULL); 664 texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id); 665 scoped_refptr<TextureRef> texture2( 666 texture_manager_.GetTexture(kTextureClient2Id)); 667 ASSERT_TRUE(texture2.get() != NULL); 668 669 // Check MarkAsComlete marks as complete. 670 manager_.MarkAsComplete(framebuffer_); 671 EXPECT_TRUE(manager_.IsComplete(framebuffer_)); 672 673 // Check at attaching marks as not complete. 674 framebuffer_->AttachTexture( 675 GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1); 676 EXPECT_FALSE(manager_.IsComplete(framebuffer_)); 677 manager_.MarkAsComplete(framebuffer_); 678 EXPECT_TRUE(manager_.IsComplete(framebuffer_)); 679 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1); 680 EXPECT_FALSE(manager_.IsComplete(framebuffer_)); 681 682 // Check MarkAttachmentsAsCleared marks as complete. 683 manager_.MarkAttachmentsAsCleared( 684 framebuffer_, &renderbuffer_manager_, &texture_manager_); 685 EXPECT_TRUE(manager_.IsComplete(framebuffer_)); 686 687 // Check Unbind marks as not complete. 688 framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1); 689 EXPECT_FALSE(manager_.IsComplete(framebuffer_)); 690 manager_.MarkAsComplete(framebuffer_); 691 EXPECT_TRUE(manager_.IsComplete(framebuffer_)); 692 framebuffer_->UnbindTexture(kTarget1, texture2.get()); 693 EXPECT_FALSE(manager_.IsComplete(framebuffer_)); 694 } 695 696 TEST_F(FramebufferInfoTest, GetStatus) { 697 const GLuint kRenderbufferClient1Id = 33; 698 const GLuint kRenderbufferService1Id = 333; 699 const GLuint kTextureClient2Id = 34; 700 const GLuint kTextureService2Id = 334; 701 const GLenum kTarget1 = GL_TEXTURE_2D; 702 const GLint kLevel1 = 0; 703 const GLint kSamples1 = 0; 704 705 renderbuffer_manager_.CreateRenderbuffer( 706 kRenderbufferClient1Id, kRenderbufferService1Id); 707 Renderbuffer* renderbuffer1 = 708 renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id); 709 ASSERT_TRUE(renderbuffer1 != NULL); 710 texture_manager_.CreateTexture(kTextureClient2Id, kTextureService2Id); 711 scoped_refptr<TextureRef> texture2( 712 texture_manager_.GetTexture(kTextureClient2Id)); 713 ASSERT_TRUE(texture2.get() != NULL); 714 texture_manager_.SetTarget(texture2.get(), GL_TEXTURE_2D); 715 716 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) 717 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 718 .RetiresOnSaturation(); 719 framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER); 720 721 // Check a second call for the same type does not call anything 722 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) { 723 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) 724 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 725 .RetiresOnSaturation(); 726 } 727 framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER); 728 729 // Check changing the attachments calls CheckFramebufferStatus. 730 framebuffer_->AttachTexture( 731 GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1); 732 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) 733 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)).RetiresOnSaturation(); 734 framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER); 735 736 // Check a second call for the same type does not call anything. 737 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) { 738 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) 739 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 740 .RetiresOnSaturation(); 741 } 742 framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER); 743 744 // Check a second call with a different target calls CheckFramebufferStatus. 745 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER)) 746 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 747 .RetiresOnSaturation(); 748 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER); 749 750 // Check a second call for the same type does not call anything. 751 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) { 752 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER)) 753 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 754 .RetiresOnSaturation(); 755 } 756 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER); 757 758 // Check adding another attachment calls CheckFramebufferStatus. 759 framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1); 760 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER)) 761 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 762 .RetiresOnSaturation(); 763 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER); 764 765 // Check a second call for the same type does not call anything. 766 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) { 767 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER)) 768 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 769 .RetiresOnSaturation(); 770 } 771 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER); 772 773 // Check changing the format calls CheckFramebuffferStatus. 774 TestHelper::SetTexParameterWithExpectations(gl_.get(), 775 error_state_.get(), 776 &texture_manager_, 777 texture2.get(), 778 GL_TEXTURE_WRAP_S, 779 GL_CLAMP_TO_EDGE, 780 GL_NO_ERROR); 781 782 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER)) 783 .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)) 784 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 785 .RetiresOnSaturation(); 786 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER); 787 788 // Check since it did not return FRAMEBUFFER_COMPLETE that it calls 789 // CheckFramebufferStatus 790 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER); 791 792 // Check putting it back does not call CheckFramebufferStatus. 793 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) { 794 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER)) 795 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 796 .RetiresOnSaturation(); 797 } 798 TestHelper::SetTexParameterWithExpectations(gl_.get(), 799 error_state_.get(), 800 &texture_manager_, 801 texture2.get(), 802 GL_TEXTURE_WRAP_S, 803 GL_REPEAT, 804 GL_NO_ERROR); 805 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER); 806 807 // Check Unbinding does not call CheckFramebufferStatus 808 framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1); 809 if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) { 810 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER)) 811 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) 812 .RetiresOnSaturation(); 813 } 814 framebuffer_->GetStatus(&texture_manager_, GL_READ_FRAMEBUFFER); 815 } 816 817 } // namespace gles2 818 } // namespace gpu 819 820 821