Home | History | Annotate | Download | only in service
      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