This source file includes following definitions.
- renderbuffer_manager_
 
- SetUp
 
- TearDown
 
- TEST_F
 
- TEST_F
 
- renderbuffer_manager_
 
- SetUp
 
- InitializeContext
 
- TearDown
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- SetUp
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
- TEST_F
 
#include "gpu/command_buffer/service/error_state_mock.h"
#include "gpu/command_buffer/service/framebuffer_manager.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/renderbuffer_manager.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_mock.h"
using ::testing::Return;
namespace gpu {
namespace gles2 {
namespace {
const GLint kMaxTextureSize = 64;
const GLint kMaxCubemapSize = 64;
const GLint kMaxRenderbufferSize = 64;
const GLint kMaxSamples = 4;
const bool kDepth24Supported = false;
}  
class FramebufferManagerTest : public testing::Test {
 public:
  FramebufferManagerTest()
      : manager_(1, 1),
        texture_manager_(
          NULL, new FeatureInfo(), kMaxTextureSize, kMaxCubemapSize),
        renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
                              kDepth24Supported) {
  }
  virtual ~FramebufferManagerTest() {
    manager_.Destroy(false);
    texture_manager_.Destroy(false);
    renderbuffer_manager_.Destroy(false);
  }
 protected:
  virtual void SetUp() {
    gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
    ::gfx::MockGLInterface::SetGLInterface(gl_.get());
  }
  virtual void TearDown() {
    ::gfx::MockGLInterface::SetGLInterface(NULL);
    gl_.reset();
  }
  
  scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
  FramebufferManager manager_;
  TextureManager texture_manager_;
  RenderbufferManager renderbuffer_manager_;
};
TEST_F(FramebufferManagerTest, Basic) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  const GLuint kClient2Id = 2;
  
  manager_.CreateFramebuffer(kClient1Id, kService1Id);
  
  Framebuffer* framebuffer1 = manager_.GetFramebuffer(kClient1Id);
  ASSERT_TRUE(framebuffer1 != NULL);
  EXPECT_FALSE(framebuffer1->IsDeleted());
  EXPECT_EQ(kService1Id, framebuffer1->service_id());
  GLuint client_id = 0;
  EXPECT_TRUE(manager_.GetClientId(framebuffer1->service_id(), &client_id));
  EXPECT_EQ(kClient1Id, client_id);
  
  EXPECT_TRUE(manager_.GetFramebuffer(kClient2Id) == NULL);
  
  manager_.RemoveFramebuffer(kClient2Id);
  
  EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
  
  manager_.RemoveFramebuffer(kClient1Id);
  EXPECT_TRUE(manager_.GetFramebuffer(kClient1Id) == NULL);
}
TEST_F(FramebufferManagerTest, Destroy) {
  const GLuint kClient1Id = 1;
  const GLuint kService1Id = 11;
  
  manager_.CreateFramebuffer(kClient1Id, kService1Id);
  
  Framebuffer* framebuffer1 = manager_.GetFramebuffer(kClient1Id);
  ASSERT_TRUE(framebuffer1 != NULL);
  EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id)))
      .Times(1)
      .RetiresOnSaturation();
  manager_.Destroy(true);
  
  framebuffer1 = manager_.GetFramebuffer(kClient1Id);
  ASSERT_TRUE(framebuffer1 == NULL);
}
class FramebufferInfoTest : public testing::Test {
 public:
  static const GLuint kClient1Id = 1;
  static const GLuint kService1Id = 11;
  FramebufferInfoTest()
      : manager_(1, 1),
        feature_info_(new FeatureInfo()),
        renderbuffer_manager_(NULL, kMaxRenderbufferSize, kMaxSamples,
                              kDepth24Supported) {
    texture_manager_.reset(new TextureManager(NULL, feature_info_.get(),
        kMaxTextureSize, kMaxCubemapSize));
  }
  virtual ~FramebufferInfoTest() {
    manager_.Destroy(false);
    texture_manager_->Destroy(false);
    renderbuffer_manager_.Destroy(false);
  }
 protected:
  virtual void SetUp() {
    InitializeContext("", "");
  }
  void InitializeContext(const char* gl_version, const char* extensions) {
    gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
    ::gfx::MockGLInterface::SetGLInterface(gl_.get());
    TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(gl_.get(),
        extensions, "", gl_version);
    feature_info_->Initialize();
    manager_.CreateFramebuffer(kClient1Id, kService1Id);
    error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>());
    framebuffer_ = manager_.GetFramebuffer(kClient1Id);
    ASSERT_TRUE(framebuffer_ != NULL);
  }
  virtual void TearDown() {
    ::gfx::MockGLInterface::SetGLInterface(NULL);
    gl_.reset();
  }
  
  scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
  FramebufferManager manager_;
  Framebuffer* framebuffer_;
  scoped_refptr<FeatureInfo> feature_info_;
  scoped_ptr<TextureManager> texture_manager_;
  RenderbufferManager renderbuffer_manager_;
  scoped_ptr<MockErrorState> error_state_;
};
#ifndef COMPILER_MSVC
const GLuint FramebufferInfoTest::kClient1Id;
const GLuint FramebufferInfoTest::kService1Id;
#endif
TEST_F(FramebufferInfoTest, Basic) {
  EXPECT_EQ(kService1Id, framebuffer_->service_id());
  EXPECT_FALSE(framebuffer_->IsDeleted());
  EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0));
  EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT));
  EXPECT_TRUE(NULL == framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT));
  EXPECT_TRUE(
      NULL == framebuffer_->GetAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
  EXPECT_FALSE(framebuffer_->HasDepthAttachment());
  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
  EXPECT_TRUE(framebuffer_->IsCleared());
  EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
}
TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
  const GLuint kRenderbufferClient1Id = 33;
  const GLuint kRenderbufferService1Id = 333;
  const GLuint kRenderbufferClient2Id = 34;
  const GLuint kRenderbufferService2Id = 334;
  const GLuint kRenderbufferClient3Id = 35;
  const GLuint kRenderbufferService3Id = 335;
  const GLuint kRenderbufferClient4Id = 36;
  const GLuint kRenderbufferService4Id = 336;
  const GLsizei kWidth1 = 16;
  const GLsizei kHeight1 = 32;
  const GLenum kFormat1 = GL_RGBA4;
  const GLenum kBadFormat1 = GL_DEPTH_COMPONENT16;
  const GLsizei kSamples1 = 0;
  const GLsizei kWidth2 = 16;
  const GLsizei kHeight2 = 32;
  const GLenum kFormat2 = GL_DEPTH_COMPONENT16;
  const GLsizei kSamples2 = 0;
  const GLsizei kWidth3 = 16;
  const GLsizei kHeight3 = 32;
  const GLenum kFormat3 = GL_STENCIL_INDEX8;
  const GLsizei kSamples3 = 0;
  const GLsizei kWidth4 = 16;
  const GLsizei kHeight4 = 32;
  const GLenum kFormat4 = GL_STENCIL_INDEX8;
  const GLsizei kSamples4 = 0;
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
  EXPECT_FALSE(
      framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
  renderbuffer_manager_.CreateRenderbuffer(
      kRenderbufferClient1Id, kRenderbufferService1Id);
  Renderbuffer* renderbuffer1 =
      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
  ASSERT_TRUE(renderbuffer1 != NULL);
  
  framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1);
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
  EXPECT_EQ(static_cast<GLenum>(GL_RGBA4),
            framebuffer_->GetColorAttachmentFormat());
  EXPECT_FALSE(framebuffer_->HasDepthAttachment());
  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
  EXPECT_TRUE(framebuffer_->IsCleared());
  
  renderbuffer_manager_.SetInfo(
      renderbuffer1, kSamples1, kBadFormat1, kWidth1, kHeight1);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
  
  renderbuffer_manager_.SetInfo(
      renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
  EXPECT_EQ(static_cast<GLenum>(kFormat1),
            framebuffer_->GetColorAttachmentFormat());
  EXPECT_FALSE(framebuffer_->HasDepthAttachment());
  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  EXPECT_FALSE(framebuffer_->IsCleared());
  
  renderbuffer_manager_.CreateRenderbuffer(
      kRenderbufferClient2Id, kRenderbufferService2Id);
  Renderbuffer* renderbuffer2 =
      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id);
  ASSERT_TRUE(renderbuffer2 != NULL);
  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer2);
  EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
  EXPECT_EQ(static_cast<GLenum>(kFormat1),
            framebuffer_->GetColorAttachmentFormat());
  EXPECT_TRUE(framebuffer_->HasDepthAttachment());
  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
  
  
  
  
  GLenum status = framebuffer_->IsPossiblyComplete();
  EXPECT_TRUE(
      status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT ||
      status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
  EXPECT_FALSE(framebuffer_->IsCleared());
  renderbuffer_manager_.SetInfo(
      renderbuffer2, kSamples2, kFormat2, kWidth2, kHeight2);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  EXPECT_FALSE(framebuffer_->IsCleared());
  EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
  
  manager_.MarkAttachmentsAsCleared(
      framebuffer_, &renderbuffer_manager_, texture_manager_.get());
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  EXPECT_TRUE(framebuffer_->IsCleared());
  
  renderbuffer_manager_.CreateRenderbuffer(
      kRenderbufferClient3Id, kRenderbufferService3Id);
  Renderbuffer* renderbuffer3 =
      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient3Id);
  ASSERT_TRUE(renderbuffer3 != NULL);
  renderbuffer_manager_.SetInfo(
      renderbuffer3, kSamples3, kFormat3, kWidth3, kHeight3);
  renderbuffer_manager_.SetCleared(renderbuffer3, true);
  framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer3);
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
  EXPECT_EQ(static_cast<GLenum>(kFormat1),
            framebuffer_->GetColorAttachmentFormat());
  EXPECT_TRUE(framebuffer_->HasDepthAttachment());
  EXPECT_TRUE(framebuffer_->HasStencilAttachment());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  EXPECT_TRUE(framebuffer_->IsCleared());
  
  renderbuffer_manager_.SetInfo(
      renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
  EXPECT_EQ(static_cast<GLenum>(kFormat1),
            framebuffer_->GetColorAttachmentFormat());
  EXPECT_TRUE(framebuffer_->HasDepthAttachment());
  EXPECT_TRUE(framebuffer_->HasStencilAttachment());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  EXPECT_FALSE(framebuffer_->IsCleared());
  const Framebuffer::Attachment* attachment =
      framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
  ASSERT_TRUE(attachment != NULL);
  EXPECT_EQ(kWidth1, attachment->width());
  EXPECT_EQ(kHeight1, attachment->height());
  EXPECT_EQ(kSamples1, attachment->samples());
  EXPECT_EQ(kFormat1, attachment->internal_format());
  EXPECT_FALSE(attachment->cleared());
  EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
  
  manager_.MarkAttachmentsAsCleared(
      framebuffer_, &renderbuffer_manager_, texture_manager_.get());
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
  EXPECT_TRUE(framebuffer_->IsCleared());
  
  renderbuffer_manager_.CreateRenderbuffer(
      kRenderbufferClient4Id, kRenderbufferService4Id);
  Renderbuffer* renderbuffer4 =
      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient4Id);
  ASSERT_TRUE(renderbuffer4 != NULL);
  renderbuffer_manager_.SetInfo(
      renderbuffer4, kSamples4, kFormat4, kWidth4, kHeight4);
  framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, renderbuffer4);
  EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
  EXPECT_FALSE(framebuffer_->IsCleared());
  attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT);
  ASSERT_TRUE(attachment != NULL);
  EXPECT_EQ(kWidth4, attachment->width());
  EXPECT_EQ(kHeight4, attachment->height());
  EXPECT_EQ(kSamples4, attachment->samples());
  EXPECT_EQ(kFormat4, attachment->internal_format());
  EXPECT_FALSE(attachment->cleared());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  
  renderbuffer_manager_.SetInfo(
      renderbuffer4, kSamples4, kFormat4, kWidth4 + 1, kHeight4);
  attachment = framebuffer_->GetAttachment(GL_STENCIL_ATTACHMENT);
  ASSERT_TRUE(attachment != NULL);
  EXPECT_EQ(kWidth4 + 1, attachment->width());
  EXPECT_EQ(kHeight4, attachment->height());
  EXPECT_EQ(kSamples4, attachment->samples());
  EXPECT_EQ(kFormat4, attachment->internal_format());
  EXPECT_FALSE(attachment->cleared());
  EXPECT_FALSE(framebuffer_->IsCleared());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT),
            framebuffer_->IsPossiblyComplete());
  
  framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, NULL);
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
  EXPECT_EQ(static_cast<GLenum>(kFormat1),
            framebuffer_->GetColorAttachmentFormat());
  EXPECT_TRUE(framebuffer_->HasDepthAttachment());
  EXPECT_FALSE(framebuffer_->HasStencilAttachment());
  EXPECT_TRUE(framebuffer_->IsCleared());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  
  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, NULL);
  renderbuffer_manager_.SetInfo(renderbuffer1, kSamples1, kFormat1, 0, 0);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
  
  framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, NULL);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
}
TEST_F(FramebufferInfoTest, AttachTexture) {
  const GLuint kTextureClient1Id = 33;
  const GLuint kTextureService1Id = 333;
  const GLuint kTextureClient2Id = 34;
  const GLuint kTextureService2Id = 334;
  const GLint kDepth = 1;
  const GLint kBorder = 0;
  const GLenum kType = GL_UNSIGNED_BYTE;
  const GLsizei kWidth1 = 16;
  const GLsizei kHeight1 = 32;
  const GLint kLevel1 = 0;
  const GLenum kFormat1 = GL_RGBA;
  const GLenum kBadFormat1 = GL_DEPTH_COMPONENT16;
  const GLenum kTarget1 = GL_TEXTURE_2D;
  const GLsizei kSamples1 = 0;
  const GLsizei kWidth2 = 16;
  const GLsizei kHeight2 = 32;
  const GLint kLevel2 = 0;
  const GLenum kFormat2 = GL_RGB;
  const GLenum kTarget2 = GL_TEXTURE_2D;
  const GLsizei kSamples2 = 0;
  const GLsizei kWidth3 = 75;
  const GLsizei kHeight3 = 123;
  const GLint kLevel3 = 0;
  const GLenum kFormat3 = GL_RGB565;
  const GLsizei kSamples3 = 0;
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
  EXPECT_FALSE(
      framebuffer_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
  texture_manager_->CreateTexture(kTextureClient1Id, kTextureService1Id);
  scoped_refptr<TextureRef> texture1(
      texture_manager_->GetTexture(kTextureClient1Id));
  ASSERT_TRUE(texture1.get() != NULL);
  
  framebuffer_->AttachTexture(
      GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1);
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
  EXPECT_TRUE(framebuffer_->IsCleared());
  EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
  
  texture_manager_->SetTarget(texture1.get(), GL_TEXTURE_2D);
  texture_manager_->SetLevelInfo(texture1.get(),
                                GL_TEXTURE_2D,
                                kLevel1,
                                kBadFormat1,
                                kWidth1,
                                kHeight1,
                                kDepth,
                                kBorder,
                                kBadFormat1,
                                kType,
                                true);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
  
  texture_manager_->SetLevelInfo(texture1.get(),
                                GL_TEXTURE_2D,
                                kLevel1,
                                kFormat1,
                                kWidth1,
                                kHeight1,
                                kDepth,
                                kBorder,
                                kFormat1,
                                kType,
                                false);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  EXPECT_FALSE(framebuffer_->IsCleared());
  texture_manager_->SetLevelInfo(texture1.get(),
                                GL_TEXTURE_2D,
                                kLevel1,
                                kFormat1,
                                kWidth1,
                                kHeight1,
                                kDepth,
                                kBorder,
                                kFormat1,
                                kType,
                                true);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  EXPECT_TRUE(framebuffer_->IsCleared());
  EXPECT_EQ(static_cast<GLenum>(kFormat1),
            framebuffer_->GetColorAttachmentFormat());
  const Framebuffer::Attachment* attachment =
      framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
  ASSERT_TRUE(attachment != NULL);
  EXPECT_EQ(kWidth1, attachment->width());
  EXPECT_EQ(kHeight1, attachment->height());
  EXPECT_EQ(kSamples1, attachment->samples());
  EXPECT_EQ(kFormat1, attachment->internal_format());
  EXPECT_TRUE(attachment->cleared());
  
  texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
  scoped_refptr<TextureRef> texture2(
      texture_manager_->GetTexture(kTextureClient2Id));
  ASSERT_TRUE(texture2.get() != NULL);
  texture_manager_->SetTarget(texture2.get(), GL_TEXTURE_2D);
  texture_manager_->SetLevelInfo(texture2.get(),
                                GL_TEXTURE_2D,
                                kLevel2,
                                kFormat2,
                                kWidth2,
                                kHeight2,
                                kDepth,
                                kBorder,
                                kFormat2,
                                kType,
                                true);
  framebuffer_->AttachTexture(
      GL_COLOR_ATTACHMENT0, texture2.get(), kTarget2, kLevel2, kSamples2);
  EXPECT_EQ(static_cast<GLenum>(kFormat2),
            framebuffer_->GetColorAttachmentFormat());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  EXPECT_TRUE(framebuffer_->IsCleared());
  attachment = framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
  ASSERT_TRUE(attachment != NULL);
  EXPECT_EQ(kWidth2, attachment->width());
  EXPECT_EQ(kHeight2, attachment->height());
  EXPECT_EQ(kSamples2, attachment->samples());
  EXPECT_EQ(kFormat2, attachment->internal_format());
  EXPECT_TRUE(attachment->cleared());
  
  texture_manager_->SetLevelInfo(texture2.get(),
                                GL_TEXTURE_2D,
                                kLevel3,
                                kFormat3,
                                kWidth3,
                                kHeight3,
                                kDepth,
                                kBorder,
                                kFormat3,
                                kType,
                                false);
  attachment = framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0);
  ASSERT_TRUE(attachment != NULL);
  EXPECT_EQ(kWidth3, attachment->width());
  EXPECT_EQ(kHeight3, attachment->height());
  EXPECT_EQ(kSamples3, attachment->samples());
  EXPECT_EQ(kFormat3, attachment->internal_format());
  EXPECT_FALSE(attachment->cleared());
  EXPECT_EQ(static_cast<GLenum>(kFormat3),
            framebuffer_->GetColorAttachmentFormat());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
  EXPECT_FALSE(framebuffer_->IsCleared());
  
  texture_manager_->SetLevelInfo(texture2.get(),
                                GL_TEXTURE_2D,
                                kLevel3,
                                kFormat3,
                                0,
                                0,
                                kDepth,
                                kBorder,
                                kFormat3,
                                kType,
                                false);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
  
  framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT0, NULL, 0, 0, 0);
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
  EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
            framebuffer_->IsPossiblyComplete());
  EXPECT_TRUE(framebuffer_->IsCleared());
}
class FramebufferInfoFloatTest : public FramebufferInfoTest {
 public:
  FramebufferInfoFloatTest()
    : FramebufferInfoTest() {
  }
  virtual ~FramebufferInfoFloatTest() {
  }
 protected:
  virtual void SetUp() {
    InitializeContext("OpenGL ES 3.0",
        "GL_OES_texture_float GL_EXT_color_buffer_float");
  }
};
TEST_F(FramebufferInfoFloatTest, AttachFloatTexture) {
  const GLuint kTextureClientId = 33;
  const GLuint kTextureServiceId = 333;
  const GLint kDepth = 1;
  const GLint kBorder = 0;
  const GLenum kType = GL_FLOAT;
  const GLsizei kWidth = 16;
  const GLsizei kHeight = 32;
  const GLint kLevel = 0;
  const GLenum kFormat = GL_RGBA;
  const GLenum kInternalFormat = GL_RGBA32F;
  const GLenum kTarget = GL_TEXTURE_2D;
  const GLsizei kSamples = 0;
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
  EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
  texture_manager_->CreateTexture(kTextureClientId, kTextureServiceId);
  scoped_refptr<TextureRef> texture(
      texture_manager_->GetTexture(kTextureClientId));
  ASSERT_TRUE(texture.get() != NULL);
  framebuffer_->AttachTexture(
      GL_COLOR_ATTACHMENT0, texture.get(), kTarget, kLevel, kSamples);
  EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat());
  texture_manager_->SetTarget(texture.get(), GL_TEXTURE_2D);
  texture_manager_->SetLevelInfo(texture.get(),
                                GL_TEXTURE_2D,
                                kLevel,
                                kInternalFormat,
                                kWidth,
                                kHeight,
                                kDepth,
                                kBorder,
                                kFormat,
                                kType,
                                false);
  
  
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            framebuffer_->IsPossiblyComplete());
}
TEST_F(FramebufferInfoTest, UnbindRenderbuffer) {
  const GLuint kRenderbufferClient1Id = 33;
  const GLuint kRenderbufferService1Id = 333;
  const GLuint kRenderbufferClient2Id = 34;
  const GLuint kRenderbufferService2Id = 334;
  renderbuffer_manager_.CreateRenderbuffer(
      kRenderbufferClient1Id, kRenderbufferService1Id);
  Renderbuffer* renderbuffer1 =
      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
  ASSERT_TRUE(renderbuffer1 != NULL);
  renderbuffer_manager_.CreateRenderbuffer(
      kRenderbufferClient2Id, kRenderbufferService2Id);
  Renderbuffer* renderbuffer2 =
      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient2Id);
  ASSERT_TRUE(renderbuffer2 != NULL);
  
  framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1);
  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
  
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
  
  framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer2);
  
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
  
  framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
  
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) == NULL);
}
TEST_F(FramebufferInfoTest, UnbindTexture) {
  const GLuint kTextureClient1Id = 33;
  const GLuint kTextureService1Id = 333;
  const GLuint kTextureClient2Id = 34;
  const GLuint kTextureService2Id = 334;
  const GLenum kTarget1 = GL_TEXTURE_2D;
  const GLint kLevel1 = 0;
  const GLint kSamples1 = 0;
  texture_manager_->CreateTexture(kTextureClient1Id, kTextureService1Id);
  scoped_refptr<TextureRef> texture1(
      texture_manager_->GetTexture(kTextureClient1Id));
  ASSERT_TRUE(texture1.get() != NULL);
  texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
  scoped_refptr<TextureRef> texture2(
      texture_manager_->GetTexture(kTextureClient2Id));
  ASSERT_TRUE(texture2.get() != NULL);
  
  framebuffer_->AttachTexture(
      GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1);
  framebuffer_->AttachTexture(
      GL_DEPTH_ATTACHMENT, texture1.get(), kTarget1, kLevel1, kSamples1);
  
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
  
  framebuffer_->UnbindTexture(kTarget1, texture2.get());
  
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
  
  framebuffer_->UnbindTexture(kTarget1, texture1.get());
  
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
  EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) == NULL);
}
TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) {
  const GLuint kRenderbufferClient1Id = 33;
  const GLuint kRenderbufferService1Id = 333;
  const GLuint kTextureClient2Id = 34;
  const GLuint kTextureService2Id = 334;
  const GLenum kTarget1 = GL_TEXTURE_2D;
  const GLint kLevel1 = 0;
  const GLint kSamples1 = 0;
  renderbuffer_manager_.CreateRenderbuffer(
      kRenderbufferClient1Id, kRenderbufferService1Id);
  Renderbuffer* renderbuffer1 =
      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
  ASSERT_TRUE(renderbuffer1 != NULL);
  texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
  scoped_refptr<TextureRef> texture2(
      texture_manager_->GetTexture(kTextureClient2Id));
  ASSERT_TRUE(texture2.get() != NULL);
  
  manager_.MarkAsComplete(framebuffer_);
  EXPECT_TRUE(manager_.IsComplete(framebuffer_));
  
  framebuffer_->AttachTexture(
      GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1);
  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
  manager_.MarkAsComplete(framebuffer_);
  EXPECT_TRUE(manager_.IsComplete(framebuffer_));
  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
  
  manager_.MarkAttachmentsAsCleared(
      framebuffer_, &renderbuffer_manager_, texture_manager_.get());
  EXPECT_TRUE(manager_.IsComplete(framebuffer_));
  
  framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
  manager_.MarkAsComplete(framebuffer_);
  EXPECT_TRUE(manager_.IsComplete(framebuffer_));
  framebuffer_->UnbindTexture(kTarget1, texture2.get());
  EXPECT_FALSE(manager_.IsComplete(framebuffer_));
}
TEST_F(FramebufferInfoTest, GetStatus) {
  const GLuint kRenderbufferClient1Id = 33;
  const GLuint kRenderbufferService1Id = 333;
  const GLuint kTextureClient2Id = 34;
  const GLuint kTextureService2Id = 334;
  const GLenum kTarget1 = GL_TEXTURE_2D;
  const GLint kLevel1 = 0;
  const GLint kSamples1 = 0;
  renderbuffer_manager_.CreateRenderbuffer(
      kRenderbufferClient1Id, kRenderbufferService1Id);
  Renderbuffer* renderbuffer1 =
      renderbuffer_manager_.GetRenderbuffer(kRenderbufferClient1Id);
  ASSERT_TRUE(renderbuffer1 != NULL);
  texture_manager_->CreateTexture(kTextureClient2Id, kTextureService2Id);
  scoped_refptr<TextureRef> texture2(
      texture_manager_->GetTexture(kTextureClient2Id));
  ASSERT_TRUE(texture2.get() != NULL);
  texture_manager_->SetTarget(texture2.get(), GL_TEXTURE_2D);
  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
      .RetiresOnSaturation();
  framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
  
  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
        .RetiresOnSaturation();
  }
  framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
  
  framebuffer_->AttachTexture(
      GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1);
  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)).RetiresOnSaturation();
  framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
  
  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
        .RetiresOnSaturation();
  }
  framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
  
  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
      .RetiresOnSaturation();
  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
  
  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
        .RetiresOnSaturation();
  }
  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
  
  framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
      .RetiresOnSaturation();
  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
  
  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
        .RetiresOnSaturation();
  }
  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
  
  TestHelper::SetTexParameteriWithExpectations(gl_.get(),
                                               error_state_.get(),
                                               texture_manager_.get(),
                                               texture2.get(),
                                               GL_TEXTURE_WRAP_S,
                                               GL_CLAMP_TO_EDGE,
                                               GL_NO_ERROR);
  EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
      .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
      .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
      .RetiresOnSaturation();
  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
  
  
  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
  
  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
        .RetiresOnSaturation();
  }
  TestHelper::SetTexParameteriWithExpectations(gl_.get(),
                                               error_state_.get(),
                                               texture_manager_.get(),
                                               texture2.get(),
                                               GL_TEXTURE_WRAP_S,
                                               GL_REPEAT,
                                               GL_NO_ERROR);
  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
  
  framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
  if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
    EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
        .RetiresOnSaturation();
  }
  framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
}
}  
}