summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-19 00:51:27 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-19 00:51:27 +0000
commit3a03a8f95d1499171af29fdc4b82a3b1d21ce2b5 (patch)
tree36d62f2753114e51886fdf5c50636c3274a3c3b7 /gpu/command_buffer/service
parentd5dcfb3c3346d6f65b6265ff3c0a11e968c84e16 (diff)
downloadchromium_src-3a03a8f95d1499171af29fdc4b82a3b1d21ce2b5.zip
chromium_src-3a03a8f95d1499171af29fdc4b82a3b1d21ce2b5.tar.gz
chromium_src-3a03a8f95d1499171af29fdc4b82a3b1d21ce2b5.tar.bz2
Fix renderbuffer width, height issues
TEST=unit tests BUG=76497 Review URL: http://codereview.chromium.org/6708016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78784 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/service')
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.cc11
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.h6
-rw-r--r--gpu/command_buffer/service/framebuffer_manager_unittest.cc17
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc43
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h13
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h6
7 files changed, 81 insertions, 17 deletions
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc
index 333b681..190a910 100644
--- a/gpu/command_buffer/service/framebuffer_manager.cc
+++ b/gpu/command_buffer/service/framebuffer_manager.cc
@@ -169,6 +169,17 @@ void FramebufferManager::FramebufferInfo::MarkAttachedRenderbuffersAsCleared() {
}
}
+bool FramebufferManager::FramebufferInfo::IsNotComplete() const {
+ for (AttachmentMap::const_iterator it = attachments_.begin();
+ it != attachments_.end(); ++it) {
+ Attachment* attachment = it->second;
+ if (attachment->width() == 0 || attachment->height() == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
FramebufferManager::FramebufferInfo* FramebufferManager::GetFramebufferInfo(
GLuint client_id) {
FramebufferInfoMap::iterator it = framebuffer_infos_.find(client_id);
diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h
index 82dd152..1f55673 100644
--- a/gpu/command_buffer/service/framebuffer_manager.h
+++ b/gpu/command_buffer/service/framebuffer_manager.h
@@ -72,6 +72,12 @@ class FramebufferManager {
return has_been_bound_ && !IsDeleted();
}
+ // We can't know if the frame buffer is complete since that is
+ // implementation dependent and we'd have to check after every glTexImage
+ // call but we can know in certain cases that it's NOT complete which we
+ // need to enforce the OpenGL ES 2.0 spec on top of DesktopGL.
+ bool IsNotComplete() const;
+
private:
friend class FramebufferManager;
friend class base::RefCounted<FramebufferInfo>;
diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
index cb30d8e..d3c3879 100644
--- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
@@ -147,6 +147,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
+ EXPECT_FALSE(info_->IsNotComplete());
RenderbufferManager rb_manager(kMaxRenderbufferSize);
rb_manager.CreateRenderbufferInfo(
@@ -159,16 +160,19 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
info_->AttachRenderbuffer(GL_COLOR_ATTACHMENT0, rb_info1);
EXPECT_TRUE(info_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
+ EXPECT_TRUE(info_->IsNotComplete());
// check adding another
info_->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, rb_info1);
EXPECT_TRUE(info_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
EXPECT_TRUE(info_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
+ EXPECT_TRUE(info_->IsNotComplete());
// check marking them as cleared.
info_->MarkAttachedRenderbuffersAsCleared();
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
+ EXPECT_TRUE(info_->IsNotComplete());
// Check adding one that is already cleared.
info_->AttachRenderbuffer(GL_STENCIL_ATTACHMENT, rb_info1);
@@ -176,6 +180,7 @@ TEST_F(FramebufferInfoTest, AttachRenderbuffer) {
// Check marking the renderbuffer as unclared.
rb_info1->SetInfo(kSamples1, kFormat1, kWidth1, kHeight1);
+ EXPECT_FALSE(info_->IsNotComplete());
const FramebufferManager::FramebufferInfo::Attachment* attachment =
info_->GetAttachment(GL_COLOR_ATTACHMENT0);
@@ -259,6 +264,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT));
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT));
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT));
+ EXPECT_FALSE(info_->IsNotComplete());
FeatureInfo feature_info;
TextureManager tex_manager(kMaxTextureSize, kMaxTextureSize);
@@ -267,14 +273,17 @@ TEST_F(FramebufferInfoTest, AttachTexture) {
TextureManager::TextureInfo* tex_info1 =
tex_manager.GetTextureInfo(kTextureClient1Id);
ASSERT_TRUE(tex_info1 != NULL);
- tex_manager.SetInfoTarget(tex_info1, GL_TEXTURE_2D);
- tex_manager.SetLevelInfo(
- &feature_info, tex_info1, GL_TEXTURE_2D, kLevel1,
- kFormat1, kWidth1, kHeight1, kDepth, kBorder, kFormat1, kType);
// check adding one attachment
info_->AttachTexture(GL_COLOR_ATTACHMENT0, tex_info1, kTarget1, kLevel1);
EXPECT_FALSE(info_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0));
+ EXPECT_TRUE(info_->IsNotComplete());
+
+ tex_manager.SetInfoTarget(tex_info1, GL_TEXTURE_2D);
+ tex_manager.SetLevelInfo(
+ &feature_info, tex_info1, GL_TEXTURE_2D, kLevel1,
+ kFormat1, kWidth1, kHeight1, kDepth, kBorder, kFormat1, kType);
+ EXPECT_FALSE(info_->IsNotComplete());
const FramebufferManager::FramebufferInfo::Attachment* attachment =
info_->GetAttachment(GL_COLOR_ATTACHMENT0);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index c263eae..40bc479 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -989,6 +989,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Remembers the state of some capabilities.
void SetCapabilityState(GLenum cap, bool enabled);
+ // Check that the current frame buffer is complete. Generates error if not.
+ bool CheckFramebufferComplete(const char* func_name);
+
// Checks if the current program exists and is valid. If not generates the
// appropriate GL error. Returns true if the current program is in a usable
// state.
@@ -1050,6 +1053,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Wrapper for glCheckFramebufferStatus
GLenum DoCheckFramebufferStatus(GLenum target);
+ // Wrapper for glClear
+ void DoClear(GLbitfield mask);
+
// Wrappers for clear and mask settings functions.
void DoClearColor(
GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
@@ -2218,6 +2224,15 @@ void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
glActiveTexture(GL_TEXTURE0 + active_texture_unit_);
}
+bool GLES2DecoderImpl::CheckFramebufferComplete(const char* func_name) {
+ if (bound_draw_framebuffer_ && bound_draw_framebuffer_->IsNotComplete()) {
+ SetGLError(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ (std::string(func_name) + " framebuffer incomplete").c_str());
+ return false;
+ }
+ return true;
+}
+
gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
if (bound_read_framebuffer_ != 0) {
const FramebufferManager::FramebufferInfo::Attachment* attachment =
@@ -3268,8 +3283,17 @@ error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
return error::kNoError;
}
+void GLES2DecoderImpl::DoClear(GLbitfield mask) {
+ if (CheckFramebufferComplete("glClear")) {
+ glClear(mask);
+ }
+}
+
void GLES2DecoderImpl::DoDrawArrays(
GLenum mode, GLint first, GLsizei count) {
+ if (!CheckFramebufferComplete("glDrawArrays")) {
+ return;
+ }
// We have to check this here because the prototype for glDrawArrays
// is GLint not GLsizei.
if (first < 0) {
@@ -3539,11 +3563,20 @@ void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
"glGetRenderbufferParameteriv: no renderbuffer bound");
return;
}
- if (pname == GL_RENDERBUFFER_INTERNAL_FORMAT) {
+ switch (pname) {
+ case GL_RENDERBUFFER_INTERNAL_FORMAT:
*params = bound_renderbuffer_->internal_format();
- return;
+ break;
+ case GL_RENDERBUFFER_WIDTH:
+ *params = bound_renderbuffer_->width();
+ break;
+ case GL_RENDERBUFFER_HEIGHT:
+ *params = bound_renderbuffer_->height();
+ break;
+ default:
+ glGetRenderbufferParameterivEXT(target, pname, params);
+ break;
}
- glGetRenderbufferParameterivEXT(target, pname, params);
}
void GLES2DecoderImpl::DoBlitFramebufferEXT(
@@ -4175,6 +4208,10 @@ error::Error GLES2DecoderImpl::HandleDrawElements(
return error::kNoError;
}
+ if (!CheckFramebufferComplete("glDrawElements")) {
+ return error::kNoError;
+ }
+
if (count == 0) {
return error::kNoError;
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 78bf68d..06ebf50 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -221,7 +221,7 @@ error::Error GLES2DecoderImpl::HandleCheckFramebufferStatus(
error::Error GLES2DecoderImpl::HandleClear(
uint32 immediate_data_size, const gles2::Clear& c) {
GLbitfield mask = static_cast<GLbitfield>(c.mask);
- glClear(mask);
+ DoClear(mask);
return error::kNoError;
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
index 0607a02..477c3bf 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
@@ -1491,15 +1491,15 @@ TEST_F(GLES2DecoderTest1, GetRenderbufferParameterivValidArgs) {
Result* result = static_cast<Result*>(shared_memory_address_);
EXPECT_CALL(
*gl_, GetRenderbufferParameterivEXT(
- GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, result->GetData()));
+ GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, result->GetData()));
result->size = 0;
GetRenderbufferParameteriv cmd;
cmd.Init(
- GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, shared_memory_id_,
+ GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, shared_memory_id_,
shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(
- GL_RENDERBUFFER_WIDTH),
+ GL_RENDERBUFFER_RED_SIZE),
result->GetNumResults());
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
@@ -1512,7 +1512,7 @@ TEST_F(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs0_0) {
result->size = 0;
GetRenderbufferParameteriv cmd;
cmd.Init(
- GL_FRAMEBUFFER, GL_RENDERBUFFER_WIDTH, shared_memory_id_,
+ GL_FRAMEBUFFER, GL_RENDERBUFFER_RED_SIZE, shared_memory_id_,
shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(0u, result->size);
@@ -1526,7 +1526,8 @@ TEST_F(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs2_0) {
static_cast<GetRenderbufferParameteriv::Result*>(shared_memory_address_);
result->size = 0;
GetRenderbufferParameteriv cmd;
- cmd.Init(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, kInvalidSharedMemoryId, 0);
+ cmd.Init(
+ GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, kInvalidSharedMemoryId, 0);
EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
EXPECT_EQ(0u, result->size);
}
@@ -1539,7 +1540,7 @@ TEST_F(GLES2DecoderTest1, GetRenderbufferParameterivInvalidArgs2_1) {
result->size = 0;
GetRenderbufferParameteriv cmd;
cmd.Init(
- GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, shared_memory_id_,
+ GL_RENDERBUFFER, GL_RENDERBUFFER_RED_SIZE, shared_memory_id_,
kInvalidSharedMemoryOffset);
EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
EXPECT_EQ(0u, result->size);
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
index f4ef6d8..62c71df 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -270,15 +270,15 @@ static GLenum valid_render_buffer_format_table[] = {
};
static GLenum valid_render_buffer_parameter_table[] = {
- GL_RENDERBUFFER_WIDTH,
- GL_RENDERBUFFER_HEIGHT,
- GL_RENDERBUFFER_INTERNAL_FORMAT,
GL_RENDERBUFFER_RED_SIZE,
GL_RENDERBUFFER_GREEN_SIZE,
GL_RENDERBUFFER_BLUE_SIZE,
GL_RENDERBUFFER_ALPHA_SIZE,
GL_RENDERBUFFER_DEPTH_SIZE,
GL_RENDERBUFFER_STENCIL_SIZE,
+ GL_RENDERBUFFER_WIDTH,
+ GL_RENDERBUFFER_HEIGHT,
+ GL_RENDERBUFFER_INTERNAL_FORMAT,
};
static GLenum valid_render_buffer_target_table[] = {