diff options
author | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-05 18:00:36 +0000 |
---|---|---|
committer | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-05 18:00:36 +0000 |
commit | 06c8b08739df0a493445459d8ede0ae4eecc9a31 (patch) | |
tree | bd038ad2bd8a733b2f597c2d9d17e2b96b400d75 /gpu | |
parent | 3339229822e7af543067d5267d3b9795bd6e4485 (diff) | |
download | chromium_src-06c8b08739df0a493445459d8ede0ae4eecc9a31.zip chromium_src-06c8b08739df0a493445459d8ede0ae4eecc9a31.tar.gz chromium_src-06c8b08739df0a493445459d8ede0ae4eecc9a31.tar.bz2 |
Fix glIsFoo() functions for non-bound objects in command buffer.
BUG=62617
TEST=LayoutTests/fast/canvas/webgl/is-object.html
Review URL: http://codereview.chromium.org/4723003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70517 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
9 files changed, 218 insertions, 36 deletions
diff --git a/gpu/command_buffer/service/buffer_manager.h b/gpu/command_buffer/service/buffer_manager.h index 81ad2af..43f5ad1 100644 --- a/gpu/command_buffer/service/buffer_manager.h +++ b/gpu/command_buffer/service/buffer_manager.h @@ -52,10 +52,14 @@ class BufferManager { // Returns a pointer to shadowed data. const void* GetRange(GLintptr offset, GLsizeiptr size) const; - bool IsDeleted() { + bool IsDeleted() const { return service_id_ == 0; } + bool IsValid() const { + return target() && !IsDeleted(); + } + private: friend class BufferManager; friend class BufferManagerTest; @@ -182,5 +186,3 @@ class BufferManager { } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_BUFFER_MANAGER_H_ - - diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc index 43aa8ab..333b681 100644 --- a/gpu/command_buffer/service/framebuffer_manager.cc +++ b/gpu/command_buffer/service/framebuffer_manager.cc @@ -142,7 +142,8 @@ void FramebufferManager::CreateFramebufferInfo( } FramebufferManager::FramebufferInfo::FramebufferInfo(GLuint service_id) - : service_id_(service_id) { + : service_id_(service_id) + , has_been_bound_(false) { } FramebufferManager::FramebufferInfo::~FramebufferInfo() {} diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h index a5c5de8..82dd152 100644 --- a/gpu/command_buffer/service/framebuffer_manager.h +++ b/gpu/command_buffer/service/framebuffer_manager.h @@ -60,10 +60,18 @@ class FramebufferManager { const Attachment* GetAttachment(GLenum attachment) const; - bool IsDeleted() { + bool IsDeleted() const { return service_id_ == 0; } + void MarkAsValid() { + has_been_bound_ = true; + } + + bool IsValid() const { + return has_been_bound_ && !IsDeleted(); + } + private: friend class FramebufferManager; friend class base::RefCounted<FramebufferInfo>; @@ -78,6 +86,9 @@ class FramebufferManager { // Service side framebuffer id. GLuint service_id_; + // Whether this framebuffer has ever been bound. + bool has_been_bound_; + // A map of attachments. typedef std::map<GLenum, Attachment::Ref> AttachmentMap; AttachmentMap attachments_; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 249987f..51d4e9f1 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -2688,6 +2688,7 @@ void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { } else { service_id = info->service_id(); } + info->MarkAsValid(); } else { service_id = context_->GetBackingFrameBufferObject(); } @@ -2723,6 +2724,7 @@ void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) { } else { service_id = info->service_id(); } + info->MarkAsValid(); } bound_renderbuffer_ = info; glBindRenderbufferEXT(target, service_id); @@ -4357,27 +4359,37 @@ error::Error GLES2DecoderImpl::HandleGetShaderInfoLog( } bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) { - return GetBufferInfo(client_id) != NULL; + const BufferManager::BufferInfo* info = GetBufferInfo(client_id); + return info && info->IsValid(); } bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) { - return GetFramebufferInfo(client_id) != NULL; + const FramebufferManager::FramebufferInfo* info = + GetFramebufferInfo(client_id); + return info && info->IsValid(); } bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) { + // IsProgram is true for programs as soon as they are created, until they are + // deleted and no longer in use. return GetProgramInfo(client_id) != NULL; } bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) { - return GetRenderbufferInfo(client_id) != NULL; + const RenderbufferManager::RenderbufferInfo* info = + GetRenderbufferInfo(client_id); + return info && info->IsValid(); } bool GLES2DecoderImpl::DoIsShader(GLuint client_id) { + // IsShader is true for shaders as soon as they are created, until they + // are deleted and not attached to any programs. return GetShaderInfo(client_id) != NULL; } bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) { - return GetTextureInfo(client_id) != NULL; + const TextureManager::TextureInfo* info = GetTextureInfo(client_id); + return info && info->IsValid(); } void GLES2DecoderImpl::DoAttachShader( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index c6454bb..2d21436 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -2570,6 +2570,54 @@ TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearStencil) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } +TEST_F(GLES2DecoderTest, IsBuffer) { + EXPECT_EQ(false, DoIsBuffer(client_buffer_id_)); + DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); + EXPECT_EQ(true, DoIsBuffer(client_buffer_id_)); + DoDeleteBuffer(client_buffer_id_, kServiceBufferId); + EXPECT_EQ(false, DoIsBuffer(client_buffer_id_)); +} + +TEST_F(GLES2DecoderTest, IsFramebuffer) { + EXPECT_EQ(false, DoIsFramebuffer(client_framebuffer_id_)); + DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_, + kServiceFramebufferId); + EXPECT_EQ(true, DoIsFramebuffer(client_framebuffer_id_)); + DoDeleteFramebuffer(client_framebuffer_id_, kServiceFramebufferId); + EXPECT_EQ(false, DoIsFramebuffer(client_framebuffer_id_)); +} + +TEST_F(GLES2DecoderTest, IsProgram) { + // IsProgram is true as soon as the program is created. + EXPECT_EQ(true, DoIsProgram(client_program_id_)); + DoDeleteProgram(client_program_id_, kServiceProgramId); + EXPECT_EQ(false, DoIsProgram(client_program_id_)); +} + +TEST_F(GLES2DecoderTest, IsRenderbuffer) { + EXPECT_EQ(false, DoIsRenderbuffer(client_renderbuffer_id_)); + DoBindRenderbuffer(GL_RENDERBUFFER, client_renderbuffer_id_, + kServiceRenderbufferId); + EXPECT_EQ(true, DoIsRenderbuffer(client_renderbuffer_id_)); + DoDeleteRenderbuffer(client_renderbuffer_id_, kServiceRenderbufferId); + EXPECT_EQ(false, DoIsRenderbuffer(client_renderbuffer_id_)); +} + +TEST_F(GLES2DecoderTest, IsShader) { + // IsShader is true as soon as the program is created. + EXPECT_EQ(true, DoIsShader(client_shader_id_)); + DoDeleteShader(client_shader_id_, kServiceShaderId); + EXPECT_EQ(false, DoIsShader(client_shader_id_)); +} + +TEST_F(GLES2DecoderTest, IsTexture) { + EXPECT_EQ(false, DoIsTexture(client_texture_id_)); + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + EXPECT_EQ(true, DoIsTexture(client_texture_id_)); + DoDeleteTexture(client_texture_id_, kServiceTextureId); + EXPECT_EQ(false, DoIsTexture(client_texture_id_)); +} + #if 0 // Turn this test on once we allow GL_DEPTH_STENCIL_ATTACHMENT TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearDepthStencil) { DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_, @@ -2644,5 +2692,3 @@ TEST_F(GLES2DecoderTest, FramebufferRenderbufferClearDepthStencil) { } // namespace gles2 } // namespace gpu - - 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 db175ce..370acde 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -136,16 +136,7 @@ void GLES2DecoderTestBase::InitDecoder(const char* extensions) { .RetiresOnSaturation(); GenHelper<GenBuffersImmediate>(client_element_buffer_id_); - { - EXPECT_CALL(*gl_, CreateProgram()) - .Times(1) - .WillOnce(Return(kServiceProgramId)) - .RetiresOnSaturation(); - CreateProgram cmd; - cmd.Init(client_program_id_); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - } - + DoCreateProgram(client_program_id_, kServiceProgramId); DoCreateShader(GL_VERTEX_SHADER, client_shader_id_, kServiceShaderId); EXPECT_EQ(GL_NO_ERROR, GetGLError()); @@ -187,6 +178,45 @@ void GLES2DecoderTestBase::DoCreateShader( EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } +bool GLES2DecoderTestBase::DoIsShader(GLuint client_id) { + return IsObjectHelper<IsShader, IsShader::Result>(client_id); +} + +void GLES2DecoderTestBase::DoDeleteShader( + GLuint client_id, GLuint service_id) { + EXPECT_CALL(*gl_, DeleteShader(service_id)) + .Times(1) + .RetiresOnSaturation(); + DeleteShader cmd; + cmd.Init(client_id); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +void GLES2DecoderTestBase::DoCreateProgram( + GLuint client_id, GLuint service_id) { + EXPECT_CALL(*gl_, CreateProgram()) + .Times(1) + .WillOnce(Return(service_id)) + .RetiresOnSaturation(); + CreateProgram cmd; + cmd.Init(client_id); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +bool GLES2DecoderTestBase::DoIsProgram(GLuint client_id) { + return IsObjectHelper<IsProgram, IsProgram::Result>(client_id); +} + +void GLES2DecoderTestBase::DoDeleteProgram( + GLuint client_id, GLuint service_id) { + EXPECT_CALL(*gl_, DeleteProgram(service_id)) + .Times(1) + .RetiresOnSaturation(); + DeleteProgram cmd; + cmd.Init(client_id); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + void GLES2DecoderTestBase::SetBucketAsCString( uint32 bucket_id, const char* str) { uint32 size = str ? (strlen(str) + 1) : 0; @@ -316,6 +346,10 @@ void GLES2DecoderTestBase::DoBindBuffer( EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } +bool GLES2DecoderTestBase::DoIsBuffer(GLuint client_id) { + return IsObjectHelper<IsBuffer, IsBuffer::Result>(client_id); +} + void GLES2DecoderTestBase::DoDeleteBuffer( GLuint client_id, GLuint service_id) { EXPECT_CALL(*gl_, DeleteBuffersARB(1, Pointee(service_id))) @@ -337,6 +371,21 @@ void GLES2DecoderTestBase::DoBindFramebuffer( EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } +bool GLES2DecoderTestBase::DoIsFramebuffer(GLuint client_id) { + return IsObjectHelper<IsFramebuffer, IsFramebuffer::Result>(client_id); +} + +void GLES2DecoderTestBase::DoDeleteFramebuffer( + GLuint client_id, GLuint service_id) { + EXPECT_CALL(*gl_, DeleteFramebuffersEXT(1, Pointee(service_id))) + .Times(1) + .RetiresOnSaturation(); + DeleteFramebuffers cmd; + cmd.Init(1, shared_memory_id_, shared_memory_offset_); + memcpy(shared_memory_address_, &client_id, sizeof(client_id)); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + void GLES2DecoderTestBase::DoBindRenderbuffer( GLenum target, GLuint client_id, GLuint service_id) { EXPECT_CALL(*gl_, BindRenderbufferEXT(target, service_id)) @@ -347,6 +396,21 @@ void GLES2DecoderTestBase::DoBindRenderbuffer( EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } +bool GLES2DecoderTestBase::DoIsRenderbuffer(GLuint client_id) { + return IsObjectHelper<IsRenderbuffer, IsRenderbuffer::Result>(client_id); +} + +void GLES2DecoderTestBase::DoDeleteRenderbuffer( + GLuint client_id, GLuint service_id) { + EXPECT_CALL(*gl_, DeleteRenderbuffersEXT(1, Pointee(service_id))) + .Times(1) + .RetiresOnSaturation(); + DeleteRenderbuffers cmd; + cmd.Init(1, shared_memory_id_, shared_memory_offset_); + memcpy(shared_memory_address_, &client_id, sizeof(client_id)); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + void GLES2DecoderTestBase::DoBindTexture( GLenum target, GLuint client_id, GLuint service_id) { EXPECT_CALL(*gl_, BindTexture(target, service_id)) @@ -357,6 +421,21 @@ void GLES2DecoderTestBase::DoBindTexture( EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } +bool GLES2DecoderTestBase::DoIsTexture(GLuint client_id) { + return IsObjectHelper<IsTexture, IsTexture::Result>(client_id); +} + +void GLES2DecoderTestBase::DoDeleteTexture( + GLuint client_id, GLuint service_id) { + EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(service_id))) + .Times(1) + .RetiresOnSaturation(); + DeleteTextures cmd; + cmd.Init(1, shared_memory_id_, shared_memory_offset_); + memcpy(shared_memory_address_, &client_id, sizeof(client_id)); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + void GLES2DecoderTestBase::DoTexImage2D( GLenum target, GLint level, GLenum internal_format, GLsizei width, GLsizei height, GLint border, @@ -631,16 +710,6 @@ void GLES2DecoderWithShaderTestBase::DoBufferSubData( EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } -void GLES2DecoderWithShaderTestBase::DoDeleteProgram( - GLuint client_id, GLuint service_id) { - EXPECT_CALL(*gl_, DeleteProgram(service_id)) - .Times(1) - .RetiresOnSaturation(); - DeleteProgram cmd; - cmd.Init(client_id); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); -} - void GLES2DecoderWithShaderTestBase::SetupVertexBuffer() { DoEnableVertexAttribArray(1); DoBindBuffer(GL_ARRAY_BUFFER, client_buffer_id_, kServiceBufferId); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 78b8fb5..fb85f6dd 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -163,6 +163,7 @@ class GLES2DecoderTestBase : public testing::Test { return group_->program_manager()->GetProgramInfo(service_id); } + void DoCreateProgram(GLuint client_id, GLuint service_id); void DoCreateShader(GLenum shader_type, GLuint client_id, GLuint service_id); void SetBucketAsCString(uint32 bucket_id, const char* str); @@ -209,7 +210,21 @@ class GLES2DecoderTestBase : public testing::Test { void DoBindFramebuffer(GLenum target, GLuint client_id, GLuint service_id); void DoBindRenderbuffer(GLenum target, GLuint client_id, GLuint service_id); void DoBindTexture(GLenum target, GLuint client_id, GLuint service_id); + + bool DoIsBuffer(GLuint client_id); + bool DoIsFramebuffer(GLuint client_id); + bool DoIsProgram(GLuint client_id); + bool DoIsRenderbuffer(GLuint client_id); + bool DoIsShader(GLuint client_id); + bool DoIsTexture(GLuint client_id); + void DoDeleteBuffer(GLuint client_id, GLuint service_id); + void DoDeleteFramebuffer(GLuint client_id, GLuint service_id); + void DoDeleteProgram(GLuint client_id, GLuint service_id); + void DoDeleteRenderbuffer(GLuint client_id, GLuint service_id); + void DoDeleteShader(GLuint client_id, GLuint service_id); + void DoDeleteTexture(GLuint client_id, GLuint service_id); + void DoTexImage2D(GLenum target, GLint level, GLenum internal_format, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, @@ -235,6 +250,17 @@ class GLES2DecoderTestBase : public testing::Test { return static_cast<int8 *>(NULL)+(i); } + template <typename Command, typename Result> + bool IsObjectHelper(GLuint client_id) { + Result* result = static_cast<Result*>(shared_memory_address_); + Command cmd; + cmd.Init(client_id, kSharedMemoryId, kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + bool isObject = static_cast<bool>(*result); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + return isObject; + } + // Use StrictMock to make 100% sure we know how GL will be called. scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; gfx::StubGLContext* context_; @@ -367,8 +393,6 @@ class GLES2DecoderWithShaderTestBase : public GLES2DecoderTestBase { void DoBufferSubData( GLenum target, GLint offset, GLsizei size, const void* data); - void DoDeleteProgram(GLuint client_id, GLuint service_id); - void SetupVertexBuffer(); void SetupIndexBuffer(); @@ -385,4 +409,3 @@ class GLES2DecoderWithShaderTestBase : public GLES2DecoderTestBase { } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_BASE_H_ - diff --git a/gpu/command_buffer/service/renderbuffer_manager.h b/gpu/command_buffer/service/renderbuffer_manager.h index db9ba816..16a1d80 100644 --- a/gpu/command_buffer/service/renderbuffer_manager.h +++ b/gpu/command_buffer/service/renderbuffer_manager.h @@ -26,6 +26,7 @@ class RenderbufferManager { explicit RenderbufferInfo(GLuint service_id) : service_id_(service_id), cleared_(false), + has_been_bound_(false), samples_(0), internal_format_(GL_RGBA4), width_(0), @@ -69,10 +70,18 @@ class RenderbufferManager { cleared_ = false; } - bool IsDeleted() { + bool IsDeleted() const { return service_id_ == 0; } + void MarkAsValid() { + has_been_bound_ = true; + } + + bool IsValid() const { + return has_been_bound_ && !IsDeleted(); + } + private: friend class RenderbufferManager; friend class base::RefCounted<RenderbufferInfo>; @@ -89,6 +98,9 @@ class RenderbufferManager { // Whether this renderbuffer has been cleared bool cleared_; + // Whether this renderbuffer has ever been bound. + bool has_been_bound_; + // Number of samples (for multi-sampled renderbuffers) GLsizei samples_; diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index 182e0d1..20a4c11 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -105,6 +105,10 @@ class TextureManager { GLenum format, GLenum type) const; + bool IsValid() const { + return target() && !IsDeleted(); + } + private: friend class TextureManager; friend class base::RefCounted<TextureInfo>; @@ -210,6 +214,9 @@ class TextureManager { // Whether or not this texture is non-power-of-two bool npot_; + // Whether this texture has ever been bound. + bool has_been_bound_; + DISALLOW_COPY_AND_ASSIGN(TextureInfo); }; @@ -332,4 +339,3 @@ class TextureManager { } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_TEXTURE_MANAGER_H_ - |