summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-07 04:57:15 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-07 04:57:15 +0000
commit57edfdad6cd742450214afd0484ade47012279ad (patch)
tree594994c2c98f77e904d698413d9f4aa2d646e546 /gpu
parent5114ead21ba9377026b0a7af118a2166de4e8c04 (diff)
downloadchromium_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')
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc28
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.h6
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc67
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc29
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h7
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);