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