diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-07 04:57:15 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-07 04:57:15 +0000 |
commit | 57edfdad6cd742450214afd0484ade47012279ad (patch) | |
tree | 594994c2c98f77e904d698413d9f4aa2d646e546 /gpu | |
parent | 5114ead21ba9377026b0a7af118a2166de4e8c04 (diff) | |
download | chromium_src-57edfdad6cd742450214afd0484ade47012279ad.zip chromium_src-57edfdad6cd742450214afd0484ade47012279ad.tar.gz chromium_src-57edfdad6cd742450214afd0484ade47012279ad.tar.bz2 |
Fix TexImage2D clearing too agressively
TEST=unit tests and WebGL conformance test
BUG=112668
R=apatrick@chromium.org
Review URL: http://codereview.chromium.org/9307102
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120721 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
5 files changed, 125 insertions, 12 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index e45d183..2c56c7b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -131,14 +131,6 @@ const CommandInfo g_command_info[] = { #undef GLES2_CMD_OP }; -static bool IsAngle() { -#if defined(OS_WIN) - return gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; -#else - return false; -#endif -} - // Return true if a character belongs to the ASCII subset as defined in // GLSL ES 1.0 spec section 3.1. static bool CharacterIsValidForGLES(unsigned char c) { @@ -508,6 +500,21 @@ GLES2Decoder::GLES2Decoder() GLES2Decoder::~GLES2Decoder() { } +bool GLES2Decoder::testing_force_is_angle_; + +void GLES2Decoder::set_testing_force_is_angle(bool force) { + testing_force_is_angle_ = force; +} + +bool GLES2Decoder::IsAngle() { +#if defined(OS_WIN) + return testing_force_is_angle_ || + gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; +#else + return testing_force_is_angle_; +#endif +} + // This class implements GLES2Decoder so we don't have to expose all the GLES2 // cmd stuff to outside this class. class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, @@ -1606,7 +1613,7 @@ ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( const int width = decoder_->offscreen_size_.width(); const int height = decoder_->offscreen_size_.height(); glDisable(GL_SCISSOR_TEST); - if (IsAngle()) { + if (GLES2Decoder::IsAngle()) { glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else { @@ -1746,7 +1753,7 @@ bool RenderBuffer::AllocateStorage(const gfx::Size& size, GLenum format, size.width(), size.height()); } else { - if (IsAngle()) { + if (GLES2Decoder::IsAngle()) { glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, samples, format, @@ -6559,6 +6566,7 @@ error::Error GLES2DecoderImpl::DoTexImage2D( if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) { glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); + texture_manager()->SetLevelCleared(info, target, level); tex_image_2d_failed_ = false; return error::kNoError; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 302a355..8da3528 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -145,12 +145,18 @@ class GLES2Decoder : public CommonDecoder { // A callback for messages from the decoder. virtual void SetMsgCallback(const MsgCallback& callback) = 0; + static bool IsAngle(); + + // Used for testing only + static void set_testing_force_is_angle(bool force); + protected: GLES2Decoder(); private: bool debug_; bool log_commands_; + static bool testing_force_is_angle_; DISALLOW_COPY_AND_ASSIGN(GLES2Decoder); }; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index e3c6598..76f7eb8 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -51,6 +51,18 @@ class GLES2DecoderTest : public GLES2DecoderTestBase { bool init); }; +class GLES2DecoderANGLETest : public GLES2DecoderTestBase { + public: + GLES2DecoderANGLETest() + : GLES2DecoderTestBase() { + GLES2Decoder::set_testing_force_is_angle(true); + } + + virtual ~GLES2DecoderANGLETest() { + GLES2Decoder::set_testing_force_is_angle(false); + } +}; + class GLES2DecoderWithShaderTest : public GLES2DecoderWithShaderTestBase { public: GLES2DecoderWithShaderTest() @@ -5134,6 +5146,59 @@ TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DNULL) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } +TEST_F(GLES2DecoderTest, TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) { + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + 0, 0); + DoTexImage2DSameSize( + GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, TexSubImage2D( + GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_address_)) + .Times(1) + .RetiresOnSaturation(); + TexSubImage2D cmd; + cmd.Init( + GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + // Test if we call it again it does not clear. + EXPECT_CALL(*gl_, TexSubImage2D( + GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_address_)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + +TEST_F(GLES2DecoderANGLETest, + TexSubImage2DDoesNotClearAfterTexImage2DNULLThenData) { + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + 0, 0); + DoTexImage2DSameSize( + GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + kSharedMemoryId, kSharedMemoryOffset); + EXPECT_CALL(*gl_, TexSubImage2D( + GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_address_)) + .Times(1) + .RetiresOnSaturation(); + TexSubImage2D cmd; + cmd.Init( + GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + // Test if we call it again it does not clear. + EXPECT_CALL(*gl_, TexSubImage2D( + GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + shared_memory_address_)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DWithDataThenNULL) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); // Put in data (so it should be marked as cleared) 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 9ffef0b..4a6de90 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -662,6 +662,35 @@ void GLES2DecoderTestBase::DoTexImage2D( EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } +void GLES2DecoderTestBase::DoTexImage2DSameSize( + GLenum target, GLint level, GLenum internal_format, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, + uint32 shared_memory_id, uint32 shared_memory_offset) { + if (GLES2Decoder::IsAngle()) + { + EXPECT_CALL(*gl_, TexSubImage2D( + target, level, 0, 0, width, height, format, type, _)) + .Times(1) + .RetiresOnSaturation(); + } else { + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, TexImage2D(target, level, internal_format, + width, height, border, format, type, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GetError()) + .WillOnce(Return(GL_NO_ERROR)) + .RetiresOnSaturation(); + } + TexImage2D cmd; + cmd.Init(target, level, internal_format, width, height, border, format, + type, shared_memory_id, shared_memory_offset); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); +} + void GLES2DecoderTestBase::DoRenderbufferStorage( GLenum target, GLenum internal_format, GLenum actual_format, GLsizei width, GLsizei height, GLenum error) { 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 d3ef6f8..0b8a3a4 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// 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. @@ -282,6 +282,11 @@ class GLES2DecoderTestBase : public testing::Test { GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, uint32 shared_memory_id, uint32 shared_memory_offset); + void DoTexImage2DSameSize( + GLenum target, GLint level, GLenum internal_format, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, + uint32 shared_memory_id, uint32 shared_memory_offset); void DoRenderbufferStorage( GLenum target, GLenum internal_format, GLenum actual_format, GLsizei width, GLsizei height, GLenum error); |