summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-28 22:39:04 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-28 22:39:04 +0000
commit1002c2d04bae30582f43afd0cd3ee8c6d86621eb (patch)
tree71cd3038045044c5385d5e69360b95232f0e84d3 /gpu
parentf9682409ab601aad49dc953ae7b41108af157175 (diff)
downloadchromium_src-1002c2d04bae30582f43afd0cd3ee8c6d86621eb.zip
chromium_src-1002c2d04bae30582f43afd0cd3ee8c6d86621eb.tar.gz
chromium_src-1002c2d04bae30582f43afd0cd3ee8c6d86621eb.tar.bz2
Return error after allocating GL resource.
We were checking for errors but not reporting them to the user. TEST=unit tests BUG=none R=apatrick@chromium.org Review URL: http://codereview.chromium.org/7272010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90856 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc36
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc202
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc2
-rw-r--r--gpu/command_buffer/service/texture_manager.cc16
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc8
5 files changed, 237 insertions, 27 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 61f8742..b337ff3 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1293,6 +1293,10 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Gets the GLError through our wrapper.
GLenum GetGLError();
+ // Gets the GLError and stores it in our wrapper. Effectively
+ // this lets us peek at the error without losing it.
+ GLenum PeekGLError();
+
// Sets our wrapper for the GLError.
void SetGLError(GLenum error, const char* msg);
@@ -3647,7 +3651,7 @@ void GLES2DecoderImpl::DoFramebufferRenderbuffer(
CopyRealGLErrorsToWrapper();
glFramebufferRenderbufferEXT(
target, attachment, renderbuffertarget, service_id);
- GLenum error = glGetError();
+ GLenum error = PeekGLError();
if (error == GL_NO_ERROR) {
framebuffer_info->AttachRenderbuffer(attachment, info);
if (service_id == 0 ||
@@ -3832,7 +3836,7 @@ void GLES2DecoderImpl::DoFramebufferTexture2D(
}
CopyRealGLErrorsToWrapper();
glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
- GLenum error = glGetError();
+ GLenum error = PeekGLError();
if (error == GL_NO_ERROR) {
framebuffer_info->AttachTexture(attachment, info, textarget, level);
if (service_id != 0 &&
@@ -3949,7 +3953,7 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
glRenderbufferStorageMultisampleEXT(
target, samples, impl_format, width, height);
}
- GLenum error = glGetError();
+ GLenum error = PeekGLError();
if (error == GL_NO_ERROR) {
bound_renderbuffer_->SetInfo(samples, internalformat, width, height);
}
@@ -3981,7 +3985,7 @@ void GLES2DecoderImpl::DoRenderbufferStorage(
CopyRealGLErrorsToWrapper();
glRenderbufferStorageEXT(target, impl_format, width, height);
- GLenum error = glGetError();
+ GLenum error = PeekGLError();
if (error == GL_NO_ERROR) {
bound_renderbuffer_->SetInfo(0, internalformat, width, height);
}
@@ -4307,6 +4311,14 @@ GLenum GLES2DecoderImpl::GetGLError() {
return error;
}
+GLenum GLES2DecoderImpl::PeekGLError() {
+ GLenum error = glGetError();
+ if (error != GL_NO_ERROR) {
+ SetGLError(error, "");
+ }
+ return error;
+}
+
void GLES2DecoderImpl::SetGLError(GLenum error, const char* msg) {
if (msg) {
last_error_ = msg;
@@ -5315,7 +5327,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(
} else {
glReadPixels(x, y, width, height, format, type, pixels);
}
- GLenum error = glGetError();
+ GLenum error = PeekGLError();
if (error == GL_NO_ERROR) {
*result = true;
@@ -5366,8 +5378,6 @@ error::Error GLES2DecoderImpl::HandleReadPixels(
break;
}
}
- } else {
- SetGLError(error, NULL);
}
return error::kNoError;
@@ -5598,10 +5608,8 @@ void GLES2DecoderImpl::DoBufferData(
CopyRealGLErrorsToWrapper();
glBufferData(target, size, data, usage);
- GLenum error = glGetError();
- if (error != GL_NO_ERROR) {
- SetGLError(error, NULL);
- } else {
+ GLenum error = PeekGLError();
+ if (error == GL_NO_ERROR) {
buffer_manager()->SetInfo(info, size, usage);
info->SetRange(0, size, data);
}
@@ -5701,7 +5709,7 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
CopyRealGLErrorsToWrapper();
glCompressedTexImage2D(
target, level, internal_format, width, height, border, image_size, data);
- GLenum error = glGetError();
+ GLenum error = PeekGLError();
if (error == GL_NO_ERROR) {
texture_manager()->SetLevelInfo(
feature_info_,
@@ -5880,7 +5888,7 @@ error::Error GLES2DecoderImpl::DoTexImage2D(
WrappedTexImage2D(
target, level, internal_format, width, height, border, format, type,
pixels);
- GLenum error = glGetError();
+ GLenum error = PeekGLError();
if (error == GL_NO_ERROR) {
texture_manager()->SetLevelInfo(feature_info_, info,
target, level, internal_format, width, height, 1, border, format, type);
@@ -6082,7 +6090,7 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
glCopyTexImage2D(target, level, internal_format,
copyX, copyY, copyWidth, copyHeight, border);
}
- GLenum error = glGetError();
+ GLenum error = PeekGLError();
if (error == GL_NO_ERROR) {
texture_manager()->SetLevelInfo(
feature_info_, info, target, level, internal_format, width, height, 1,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index e84c93a..981991b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -4013,6 +4013,208 @@ TEST_F(GLES2DecoderTest, GetMultipleIntegervCHROMIUMInvalidArgs) {
EXPECT_EQ(kSentinel, results[num_results]); // End of results
}
+TEST_F(GLES2DecoderTest, TexImage2DGLError) {
+ GLenum target = GL_TEXTURE_2D;
+ GLint level = 0;
+ GLenum internal_format = GL_RGBA;
+ GLsizei width = 2;
+ GLsizei height = 4;
+ GLint border = 0;
+ GLenum format = GL_RGBA;
+ GLenum type = GL_UNSIGNED_BYTE;
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ TextureManager* manager = group().texture_manager();
+ TextureManager::TextureInfo* info =
+ manager->GetTextureInfo(client_texture_id_);
+ ASSERT_TRUE(info != NULL);
+ EXPECT_FALSE(info->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_OUT_OF_MEMORY))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, TexImage2D(target, level, internal_format,
+ width, height, border, format, type, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ TexImage2D cmd;
+ cmd.Init(target, level, internal_format, width, height, border, format,
+ type, kSharedMemoryId, kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+ EXPECT_FALSE(info->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
+}
+
+TEST_F(GLES2DecoderTest, BufferDataGLError) {
+ GLenum target = GL_ARRAY_BUFFER;
+ GLsizeiptr size = 4;
+ DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId);
+ BufferManager* manager = group().buffer_manager();
+ BufferManager::BufferInfo* info =
+ manager->GetBufferInfo(client_buffer_id_);
+ ASSERT_TRUE(info != NULL);
+ EXPECT_EQ(0, info->size());
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_OUT_OF_MEMORY))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, BufferData(target, size, _, GL_STREAM_DRAW))
+ .Times(1)
+ .RetiresOnSaturation();
+ BufferData cmd;
+ cmd.Init(target, size, 0, 0, GL_STREAM_DRAW);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+ EXPECT_EQ(0, info->size());
+}
+
+TEST_F(GLES2DecoderTest, CopyTexImage2DGLError) {
+ GLenum target = GL_TEXTURE_2D;
+ GLint level = 0;
+ GLenum internal_format = GL_RGBA;
+ GLsizei width = 2;
+ GLsizei height = 4;
+ GLint border = 0;
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ TextureManager* manager = group().texture_manager();
+ TextureManager::TextureInfo* info =
+ manager->GetTextureInfo(client_texture_id_);
+ ASSERT_TRUE(info != NULL);
+ EXPECT_FALSE(info->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_OUT_OF_MEMORY))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, CopyTexImage2D(
+ target, level, internal_format, 0, 0, width, height, border))
+ .Times(1)
+ .RetiresOnSaturation();
+ CopyTexImage2D cmd;
+ cmd.Init(target, level, internal_format, 0, 0, width, height, border);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+ EXPECT_FALSE(info->GetLevelSize(GL_TEXTURE_2D, level, &width, &height));
+}
+
+TEST_F(GLES2DecoderTest, FramebufferRenderbufferGLError) {
+ DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
+ kServiceFramebufferId);
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_OUT_OF_MEMORY))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, FramebufferRenderbufferEXT(
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ kServiceRenderbufferId))
+ .Times(1)
+ .RetiresOnSaturation();
+ FramebufferRenderbuffer cmd;
+ cmd.Init(
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ client_renderbuffer_id_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+TEST_F(GLES2DecoderTest, FramebufferTexture2DGLError) {
+ const GLsizei kWidth = 5;
+ const GLsizei kHeight = 3;
+ const GLenum kFormat = GL_RGB;
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, kFormat, kWidth, kHeight, 0,
+ kFormat, GL_UNSIGNED_BYTE, 0, 0);
+ DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_,
+ kServiceFramebufferId);
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_OUT_OF_MEMORY))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, FramebufferTexture2DEXT(
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ kServiceTextureId, 0))
+ .Times(1)
+ .RetiresOnSaturation();
+ FramebufferTexture2D fbtex_cmd;
+ fbtex_cmd.Init(
+ GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
+ 0);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(fbtex_cmd));
+ EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+TEST_F(GLES2DecoderTest, RenderbufferStorageGLError) {
+ DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
+ kServiceRenderbufferId);
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_OUT_OF_MEMORY))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, RenderbufferStorageEXT(
+ GL_RENDERBUFFER, GL_RGBA, 100, 50))
+ .Times(1)
+ .RetiresOnSaturation();
+ RenderbufferStorage cmd;
+ cmd.Init(GL_RENDERBUFFER, GL_RGBA4, 100, 50);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+TEST_F(GLES2DecoderManualInitTest, RenderbufferStorageMultisampleGLError) {
+ InitDecoder(
+ "GL_EXT_framebuffer_multisample", // extensions
+ false, // has alpha
+ false, // has depth
+ false, // has stencil
+ false, // request alpha
+ false, // request depth
+ false); // request stencil
+ DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_,
+ kServiceRenderbufferId);
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_OUT_OF_MEMORY))
+ .RetiresOnSaturation();
+ EXPECT_CALL(*gl_, RenderbufferStorageMultisampleEXT(
+ GL_RENDERBUFFER, 1, GL_RGBA, 100, 50))
+ .Times(1)
+ .RetiresOnSaturation();
+ RenderbufferStorageMultisampleEXT cmd;
+ cmd.Init(GL_RENDERBUFFER, 1, GL_RGBA4, 100, 50);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+TEST_F(GLES2DecoderTest, ReadPixelsGLError) {
+ GLenum kFormat = GL_RGBA;
+ GLint x = 0;
+ GLint y = 0;
+ GLsizei width = 2;
+ GLsizei height = 4;
+ typedef ReadPixels::Result Result;
+ Result* result = GetSharedMemoryAs<Result*>();
+ uint32 result_shm_id = kSharedMemoryId;
+ uint32 result_shm_offset = kSharedMemoryOffset;
+ uint32 pixels_shm_id = kSharedMemoryId;
+ uint32 pixels_shm_offset = kSharedMemoryOffset + sizeof(*result);
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_OUT_OF_MEMORY))
+ .RetiresOnSaturation();
+ EXPECT_CALL(
+ *gl_, ReadPixels(x, y, width, height, kFormat, GL_UNSIGNED_BYTE, _))
+ .Times(1)
+ .RetiresOnSaturation();
+ ReadPixels cmd;
+ cmd.Init(x, y, width, height, kFormat, GL_UNSIGNED_BYTE,
+ pixels_shm_id, pixels_shm_offset,
+ result_shm_id, result_shm_offset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_OUT_OF_MEMORY, GetGLError());
+}
+
+// TODO(gman): Complete this test.
+// TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
+// }
+
// TODO(gman): BufferData
// TODO(gman): BufferDataImmediate
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index dd6e181..8e56d708 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -76,7 +76,7 @@ void GLES2DecoderTestBase::InitDecoder(
TestHelper::SetupContextGroupInitExpectations(gl_.get(),
DisallowedExtensions(), extensions);
- EXPECT_TRUE(group_->Initialize(DisallowedExtensions(), extensions));
+ EXPECT_TRUE(group_->Initialize(DisallowedExtensions(), NULL));
EXPECT_CALL(*gl_, EnableVertexAttribArray(0))
.Times(1)
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 70bef85..596c109 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -230,9 +230,11 @@ bool TextureManager::TextureInfo::GetLevelSize(
if (!IsDeleted() && level >= 0 && face_index < level_infos_.size() &&
static_cast<size_t>(level) < level_infos_[face_index].size()) {
const LevelInfo& info = level_infos_[GLTargetToFaceIndex(face)][level];
- *width = info.width;
- *height = info.height;
- return true;
+ if (info.valid) {
+ *width = info.width;
+ *height = info.height;
+ return true;
+ }
}
return false;
}
@@ -245,9 +247,11 @@ bool TextureManager::TextureInfo::GetLevelType(
if (!IsDeleted() && level >= 0 && face_index < level_infos_.size() &&
static_cast<size_t>(level) < level_infos_[face_index].size()) {
const LevelInfo& info = level_infos_[GLTargetToFaceIndex(face)][level];
- *type = info.type;
- *internal_format = info.internal_format;
- return true;
+ if (info.valid) {
+ *type = info.type;
+ *internal_format = info.internal_format;
+ return true;
+ }
}
return false;
}
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index e5b0d4d..54e15df 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -502,9 +502,7 @@ TEST_F(TextureInfoTest, GetLevelSize) {
GLsizei height = -1;
EXPECT_FALSE(info_->GetLevelSize(GL_TEXTURE_2D, -1, &width, &height));
EXPECT_FALSE(info_->GetLevelSize(GL_TEXTURE_2D, 1000, &width, &height));
- EXPECT_TRUE(info_->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
- EXPECT_EQ(0, width);
- EXPECT_EQ(0, height);
+ EXPECT_FALSE(info_->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
EXPECT_TRUE(info_->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height));
EXPECT_EQ(4, width);
EXPECT_EQ(5, height);
@@ -520,9 +518,7 @@ TEST_F(TextureInfoTest, GetLevelType) {
GLenum format = -1;
EXPECT_FALSE(info_->GetLevelType(GL_TEXTURE_2D, -1, &type, &format));
EXPECT_FALSE(info_->GetLevelType(GL_TEXTURE_2D, 1000, &type, &format));
- EXPECT_TRUE(info_->GetLevelType(GL_TEXTURE_2D, 0, &type, &format));
- EXPECT_EQ(0u, type);
- EXPECT_EQ(0u, format);
+ EXPECT_FALSE(info_->GetLevelType(GL_TEXTURE_2D, 0, &type, &format));
EXPECT_TRUE(info_->GetLevelType(GL_TEXTURE_2D, 1, &type, &format));
EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
EXPECT_EQ(static_cast<GLenum>(GL_RGBA), format);