blob: e5f8f18a0970962eb868fd712d1ba01e19de2725 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#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/gpu_service_test.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::_;
using ::testing::Return;
namespace gpu {
namespace gles2 {
namespace {
const GLint kMaxTextureSize = 64;
const GLint kMaxCubemapSize = 64;
const GLint kMaxRectangleTextureSize = 64;
const GLint kMax3DTextureSize = 256;
const GLint kMaxRenderbufferSize = 64;
const GLint kMaxSamples = 4;
const uint32 kMaxDrawBuffers = 16;
const uint32 kMaxColorAttachments = 16;
const bool kUseDefaultTextures = false;
} // namespace
class FramebufferManagerTest : public GpuServiceTest {
public:
FramebufferManagerTest()
: manager_(1, 1, CONTEXT_TYPE_OPENGLES2, NULL),
feature_info_(new FeatureInfo()) {
texture_manager_.reset(new TextureManager(NULL,
feature_info_.get(),
kMaxTextureSize,
kMaxCubemapSize,
kMaxRectangleTextureSize,
kMax3DTextureSize,
kUseDefaultTextures));
renderbuffer_manager_.reset(new RenderbufferManager(NULL,
kMaxRenderbufferSize,
kMaxSamples,
feature_info_.get()));
}
~FramebufferManagerTest() override {
manager_.Destroy(false);
texture_manager_->Destroy(false);
renderbuffer_manager_->Destroy(false);
}
protected:
FramebufferManager manager_;
scoped_refptr<FeatureInfo> feature_info_;
scoped_ptr<TextureManager> texture_manager_;
scoped_ptr<RenderbufferManager> renderbuffer_manager_;
};
TEST_F(FramebufferManagerTest, Basic) {
const GLuint kClient1Id = 1;
const GLuint kService1Id = 11;
const GLuint kClient2Id = 2;
// Check we can create framebuffer.
manager_.CreateFramebuffer(kClient1Id, kService1Id);
// Check framebuffer got created.
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);
// Check we get nothing for a non-existent framebuffer.
EXPECT_TRUE(manager_.GetFramebuffer(kClient2Id) == NULL);
// Check trying to a remove non-existent framebuffers does not crash.
manager_.RemoveFramebuffer(kClient2Id);
// Check framebuffer gets deleted when last reference is released.
EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id)))
.Times(1)
.RetiresOnSaturation();
// Check we can't get the framebuffer after we remove it.
manager_.RemoveFramebuffer(kClient1Id);
EXPECT_TRUE(manager_.GetFramebuffer(kClient1Id) == NULL);
}
TEST_F(FramebufferManagerTest, Destroy) {
const GLuint kClient1Id = 1;
const GLuint kService1Id = 11;
// Check we can create framebuffer.
manager_.CreateFramebuffer(kClient1Id, kService1Id);
// Check framebuffer got created.
Framebuffer* framebuffer1 = manager_.GetFramebuffer(kClient1Id);
ASSERT_TRUE(framebuffer1 != NULL);
EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, ::testing::Pointee(kService1Id)))
.Times(1)
.RetiresOnSaturation();
manager_.Destroy(true);
// Check the resources were released.
framebuffer1 = manager_.GetFramebuffer(kClient1Id);
ASSERT_TRUE(framebuffer1 == NULL);
}
class FramebufferInfoTestBase : public GpuServiceTest {
public:
static const GLuint kClient1Id = 1;
static const GLuint kService1Id = 11;
explicit FramebufferInfoTestBase(ContextType context_type)
: manager_(kMaxDrawBuffers,
kMaxColorAttachments,
context_type,
new FramebufferCompletenessCache),
feature_info_(new FeatureInfo()) {
texture_manager_.reset(new TextureManager(NULL,
feature_info_.get(),
kMaxTextureSize,
kMaxCubemapSize,
kMaxRectangleTextureSize,
kMax3DTextureSize,
kUseDefaultTextures));
renderbuffer_manager_.reset(new RenderbufferManager(NULL,
kMaxRenderbufferSize,
kMaxSamples,
feature_info_.get()));
}
~FramebufferInfoTestBase() override {
manager_.Destroy(false);
texture_manager_->Destroy(false);
renderbuffer_manager_->Destroy(false);
}
protected:
void SetUp() override {
InitializeContext("2.0", "GL_EXT_framebuffer_object");
}
void InitializeContext(const char* gl_version, const char* extensions) {
GpuServiceTest::SetUpWithGLVersion(gl_version, extensions);
TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(gl_.get(),
extensions, "", gl_version);
feature_info_->InitializeForTesting();
manager_.CreateFramebuffer(kClient1Id, kService1Id);
error_state_.reset(new ::testing::StrictMock<gles2::MockErrorState>());
framebuffer_ = manager_.GetFramebuffer(kClient1Id);
ASSERT_TRUE(framebuffer_ != NULL);
}
FramebufferManager manager_;
Framebuffer* framebuffer_;
scoped_refptr<FeatureInfo> feature_info_;
scoped_ptr<TextureManager> texture_manager_;
scoped_ptr<RenderbufferManager> renderbuffer_manager_;
scoped_ptr<MockErrorState> error_state_;
};
class FramebufferInfoTest : public FramebufferInfoTestBase {
public:
FramebufferInfoTest() : FramebufferInfoTestBase(CONTEXT_TYPE_OPENGLES2) {}
};
// GCC requires these declarations, but MSVC requires they not be present
#ifndef COMPILER_MSVC
const GLuint FramebufferInfoTestBase::kClient1Id;
const GLuint FramebufferInfoTestBase::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_->GetReadBufferInternalFormat());
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);
// check adding one attachment
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_->GetReadBufferInternalFormat());
EXPECT_FALSE(framebuffer_->HasDepthAttachment());
EXPECT_FALSE(framebuffer_->HasStencilAttachment());
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
framebuffer_->IsPossiblyComplete());
EXPECT_TRUE(framebuffer_->IsCleared());
// Try a format that's not good for COLOR_ATTACHMENT0.
renderbuffer_manager_->SetInfo(
renderbuffer1, kSamples1, kBadFormat1, kWidth1, kHeight1);
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
framebuffer_->IsPossiblyComplete());
// Try a good format.
renderbuffer_manager_->SetInfo(
renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
EXPECT_EQ(static_cast<GLenum>(kFormat1),
framebuffer_->GetReadBufferInternalFormat());
EXPECT_FALSE(framebuffer_->HasDepthAttachment());
EXPECT_FALSE(framebuffer_->HasStencilAttachment());
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
framebuffer_->IsPossiblyComplete());
EXPECT_FALSE(framebuffer_->IsCleared());
// check adding another
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_->GetReadBufferInternalFormat());
EXPECT_TRUE(framebuffer_->HasDepthAttachment());
EXPECT_FALSE(framebuffer_->HasStencilAttachment());
// The attachment has a size of 0,0 so depending on the order of the map
// of attachments it could either get INCOMPLETE_ATTACHMENT because it's 0,0
// or INCOMPLETE_DIMENSIONS because it's not the same size as the other
// attachment.
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));
// check marking them as cleared.
manager_.MarkAttachmentsAsCleared(
framebuffer_, renderbuffer_manager_.get(), 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());
// Check adding one that is already cleared.
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_->GetReadBufferInternalFormat());
EXPECT_TRUE(framebuffer_->HasDepthAttachment());
EXPECT_TRUE(framebuffer_->HasStencilAttachment());
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
framebuffer_->IsPossiblyComplete());
EXPECT_TRUE(framebuffer_->IsCleared());
// Check marking the renderbuffer as unclared.
renderbuffer_manager_->SetInfo(
renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
EXPECT_EQ(static_cast<GLenum>(kFormat1),
framebuffer_->GetReadBufferInternalFormat());
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));
// Clear it.
manager_.MarkAttachmentsAsCleared(
framebuffer_, renderbuffer_manager_.get(), texture_manager_.get());
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
EXPECT_TRUE(framebuffer_->IsCleared());
// Check replacing an attachment
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());
// Check changing an attachment.
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());
// Check removing it.
framebuffer_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, NULL);
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
EXPECT_EQ(static_cast<GLenum>(kFormat1),
framebuffer_->GetReadBufferInternalFormat());
EXPECT_TRUE(framebuffer_->HasDepthAttachment());
EXPECT_FALSE(framebuffer_->HasStencilAttachment());
EXPECT_TRUE(framebuffer_->IsCleared());
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
framebuffer_->IsPossiblyComplete());
// Remove depth, Set color to 0 size.
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());
// Remove color.
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);
// check adding one attachment
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_->GetReadBufferInternalFormat());
// Try format that doesn't work with COLOR_ATTACHMENT0
texture_manager_->SetTarget(texture1.get(), GL_TEXTURE_2D);
texture_manager_->SetLevelInfo(
texture1.get(), GL_TEXTURE_2D, kLevel1, kBadFormat1, kWidth1, kHeight1,
kDepth, kBorder, kBadFormat1, kType, gfx::Rect(kWidth1, kHeight1));
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
framebuffer_->IsPossiblyComplete());
// Try a good format.
texture_manager_->SetLevelInfo(texture1.get(), GL_TEXTURE_2D, kLevel1,
kFormat1, kWidth1, kHeight1, kDepth, kBorder,
kFormat1, kType, gfx::Rect());
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, gfx::Rect(kWidth1, kHeight1));
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
framebuffer_->IsPossiblyComplete());
EXPECT_TRUE(framebuffer_->IsCleared());
EXPECT_EQ(static_cast<GLenum>(kFormat1),
framebuffer_->GetReadBufferInternalFormat());
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());
// Check replacing an attachment
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, gfx::Rect(kWidth2, kHeight2));
framebuffer_->AttachTexture(
GL_COLOR_ATTACHMENT0, texture2.get(), kTarget2, kLevel2, kSamples2);
EXPECT_EQ(static_cast<GLenum>(kFormat2),
framebuffer_->GetReadBufferInternalFormat());
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());
// Check changing attachment
texture_manager_->SetLevelInfo(texture2.get(), GL_TEXTURE_2D, kLevel3,
kFormat3, kWidth3, kHeight3, kDepth, kBorder,
kFormat3, kType, gfx::Rect());
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_->GetReadBufferInternalFormat());
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
framebuffer_->IsPossiblyComplete());
EXPECT_FALSE(framebuffer_->IsCleared());
// Set to size 0
texture_manager_->SetLevelInfo(texture2.get(), GL_TEXTURE_2D, kLevel3,
kFormat3, 0, 0, kDepth, kBorder, kFormat3,
kType, gfx::Rect());
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
framebuffer_->IsPossiblyComplete());
// Check removing it.
framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT0, NULL, 0, 0, 0);
EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL);
EXPECT_EQ(static_cast<GLenum>(0),
framebuffer_->GetReadBufferInternalFormat());
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
framebuffer_->IsPossiblyComplete());
EXPECT_TRUE(framebuffer_->IsCleared());
}
TEST_F(FramebufferInfoTest, DrawBuffers) {
const GLuint kTextureClientId[] = { 33, 34 };
const GLuint kTextureServiceId[] = { 333, 334 };
for (GLenum i = GL_COLOR_ATTACHMENT0;
i < GL_COLOR_ATTACHMENT0 + kMaxColorAttachments; ++i) {
EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(i));
}
EXPECT_FALSE(framebuffer_->HasUnclearedColorAttachments());
EXPECT_EQ(static_cast<GLenum>(GL_COLOR_ATTACHMENT0),
framebuffer_->GetDrawBuffer(GL_DRAW_BUFFER0_ARB));
for (GLenum i = GL_DRAW_BUFFER1_ARB;
i < GL_DRAW_BUFFER0_ARB + kMaxDrawBuffers; ++i) {
EXPECT_EQ(static_cast<GLenum>(GL_NONE),
framebuffer_->GetDrawBuffer(i));
}
for (size_t ii = 0; ii < arraysize(kTextureClientId); ++ii) {
texture_manager_->CreateTexture(
kTextureClientId[ii], kTextureServiceId[ii]);
scoped_refptr<TextureRef> texture(
texture_manager_->GetTexture(kTextureClientId[ii]));
ASSERT_TRUE(texture.get() != NULL);
framebuffer_->AttachTexture(
GL_COLOR_ATTACHMENT0 + ii, texture.get(), GL_TEXTURE_2D, 0, 0);
EXPECT_FALSE(
framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0 + ii));
const Framebuffer::Attachment* attachment =
framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0 + ii);
ASSERT_TRUE(attachment != NULL);
EXPECT_TRUE(attachment->cleared());
}
EXPECT_TRUE(framebuffer_->IsCleared());
EXPECT_FALSE(framebuffer_->HasUnclearedColorAttachments());
// Set a texture as uncleared.
scoped_refptr<TextureRef> texture1(
texture_manager_->GetTexture(kTextureClientId[1]));
texture_manager_->SetTarget(texture1.get(), GL_TEXTURE_2D);
texture_manager_->SetLevelInfo(texture1.get(), GL_TEXTURE_2D, 0, GL_RGBA, 4,
4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
gfx::Rect());
const Framebuffer::Attachment* attachment1 =
framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT1);
ASSERT_TRUE(attachment1 != NULL);
EXPECT_FALSE(attachment1->cleared());
EXPECT_FALSE(framebuffer_->IsCleared());
EXPECT_TRUE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT1));
EXPECT_TRUE(framebuffer_->HasUnclearedColorAttachments());
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
framebuffer_->SetDrawBuffers(2, buffers);
EXPECT_EQ(static_cast<GLenum>(GL_COLOR_ATTACHMENT0),
framebuffer_->GetDrawBuffer(GL_DRAW_BUFFER0_ARB));
EXPECT_EQ(static_cast<GLenum>(GL_COLOR_ATTACHMENT1),
framebuffer_->GetDrawBuffer(GL_DRAW_BUFFER1_ARB));
for (GLenum i = GL_DRAW_BUFFER2_ARB;
i < GL_DRAW_BUFFER0_ARB + kMaxDrawBuffers; ++i) {
EXPECT_EQ(static_cast<GLenum>(GL_NONE),
framebuffer_->GetDrawBuffer(i));
}
// Nothing happens.
framebuffer_->PrepareDrawBuffersForClear();
framebuffer_->RestoreDrawBuffersAfterClear();
// Now we disable a draw buffer 1.
buffers[1] = GL_NONE;
framebuffer_->SetDrawBuffers(2, buffers);
// We will enable the disabled draw buffer for clear(), and disable it
// after the clear.
EXPECT_CALL(*gl_, DrawBuffersARB(kMaxDrawBuffers, _))
.Times(1)
.RetiresOnSaturation();
framebuffer_->PrepareDrawBuffersForClear();
EXPECT_CALL(*gl_, DrawBuffersARB(kMaxDrawBuffers, _))
.Times(1)
.RetiresOnSaturation();
framebuffer_->RestoreDrawBuffersAfterClear();
// Now remove draw buffer 1's attachment.
framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT1, NULL, 0, 0, 0);
EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT1) == NULL);
// Nothing happens.
framebuffer_->PrepareDrawBuffersForClear();
framebuffer_->RestoreDrawBuffersAfterClear();
}
class FramebufferInfoFloatTest : public FramebufferInfoTest {
public:
FramebufferInfoFloatTest()
: FramebufferInfoTest() {
}
~FramebufferInfoFloatTest() override {}
protected:
void SetUp() override {
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_->GetReadBufferInternalFormat());
texture_manager_->SetTarget(texture.get(), GL_TEXTURE_2D);
texture_manager_->SetLevelInfo(texture.get(), GL_TEXTURE_2D, kLevel,
kInternalFormat, kWidth, kHeight, kDepth,
kBorder, kFormat, kType, gfx::Rect());
// Texture with a sized float internalformat is allowed as an attachment
// since float color attachment extension is present.
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);
// Attach to 2 attachment points.
framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1);
framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer1);
// Check they were attached.
EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
// Unbind unattached renderbuffer.
framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer2);
// Should be no-op.
EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
// Unbind renderbuffer.
framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
// Check they were detached
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);
// Attach to 2 attachment points.
framebuffer_->AttachTexture(
GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1);
framebuffer_->AttachTexture(
GL_DEPTH_ATTACHMENT, texture1.get(), kTarget1, kLevel1, kSamples1);
// Check they were attached.
EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
// Unbind unattached texture.
framebuffer_->UnbindTexture(kTarget1, texture2.get());
// Should be no-op.
EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL);
EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL);
// Unbind texture.
framebuffer_->UnbindTexture(kTarget1, texture1.get());
// Check they were detached
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);
// Check MarkAsComlete marks as complete.
manager_.MarkAsComplete(framebuffer_);
EXPECT_TRUE(manager_.IsComplete(framebuffer_));
// Check at attaching marks as not complete.
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_));
// Check MarkAttachmentsAsCleared marks as complete.
manager_.MarkAttachmentsAsCleared(
framebuffer_, renderbuffer_manager_.get(), texture_manager_.get());
EXPECT_TRUE(manager_.IsComplete(framebuffer_));
// Check Unbind marks as not complete.
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);
// Check a second call for the same type does not call anything
framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check changing the attachments calls CheckFramebufferStatus.
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);
// Check a second call for the same type does not call anything.
framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check a second call with a different target calls CheckFramebufferStatus.
EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
.WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
.RetiresOnSaturation();
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check a second call for the same type does not call anything.
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check adding another attachment calls CheckFramebufferStatus.
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);
// Check a second call for the same type does not call anything.
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check changing the format calls CheckFramebuffferStatus.
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);
// Check since it did not return FRAMEBUFFER_COMPLETE that it calls
// CheckFramebufferStatus
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check putting it back does not call CheckFramebufferStatus.
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);
// Check Unbinding does not call CheckFramebufferStatus
framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
}
class FramebufferInfoES3Test : public FramebufferInfoTestBase {
public:
FramebufferInfoES3Test() : FramebufferInfoTestBase(CONTEXT_TYPE_WEBGL2) {}
};
TEST_F(FramebufferInfoES3Test, DifferentDimensions) {
const GLuint kRenderbufferClient1Id = 33;
const GLuint kRenderbufferService1Id = 333;
const GLuint kRenderbufferClient2Id = 34;
const GLuint kRenderbufferService2Id = 334;
const GLsizei kWidth1 = 16;
const GLsizei kHeight1 = 32;
const GLenum kFormat1 = GL_RGBA4;
const GLsizei kSamples1 = 0;
const GLsizei kWidth2 = 32; // Different from kWidth1
const GLsizei kHeight2 = 32;
const GLenum kFormat2 = GL_DEPTH_COMPONENT16;
const GLsizei kSamples2 = 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);
renderbuffer_manager_->SetInfo(
renderbuffer1, kSamples1, kFormat1, kWidth1, kHeight1);
framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, renderbuffer1);
renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClient2Id, kRenderbufferService2Id);
Renderbuffer* renderbuffer2 =
renderbuffer_manager_->GetRenderbuffer(kRenderbufferClient2Id);
ASSERT_TRUE(renderbuffer2 != NULL);
renderbuffer_manager_->SetInfo(
renderbuffer2, kSamples2, kFormat2, kWidth2, kHeight2);
framebuffer_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, renderbuffer2);
EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
framebuffer_->IsPossiblyComplete());
}
TEST_F(FramebufferInfoES3Test, ReadBuffer) {
const GLuint kRenderbufferClientId = 33;
const GLuint kRenderbufferServiceId = 333;
EXPECT_EQ(static_cast<GLenum>(GL_COLOR_ATTACHMENT0),
framebuffer_->read_buffer());
framebuffer_->set_read_buffer(GL_NONE);
EXPECT_EQ(static_cast<GLenum>(GL_NONE), framebuffer_->read_buffer());
EXPECT_FALSE(framebuffer_->GetReadBufferAttachment());
framebuffer_->set_read_buffer(GL_COLOR_ATTACHMENT1);
EXPECT_FALSE(framebuffer_->GetReadBufferAttachment());
renderbuffer_manager_->CreateRenderbuffer(
kRenderbufferClientId, kRenderbufferServiceId);
Renderbuffer* renderbuffer =
renderbuffer_manager_->GetRenderbuffer(kRenderbufferClientId);
ASSERT_TRUE(renderbuffer != NULL);
framebuffer_->AttachRenderbuffer(GL_COLOR_ATTACHMENT1, renderbuffer);
EXPECT_TRUE(framebuffer_->GetReadBufferAttachment());
}
} // namespace gles2
} // namespace gpu