Revert 114133 - Revert 114059 - Fixed service side implementation of glTexStorage2DEXT to only initialize the number of
levels requirested. Also ClearLevel now uses glTexSubImage2D to clear the level if the
texture is immutable. Finally, rearranged the code in doTexSubImage2D to correctly
bypass clearing a level if the bitmaps supplied matches the dimensions of the texture level.
BUG=106894
Review URL: http://codereview.chromium.org/8872061
Reverting as it may be causing a failure in the XP perf bots:
http://build.chromium.org/p/chromium.perf/builders/XP%20Perf%20%28dbg%29/builds/6854
Un-reverting original change. It doesn't seem to have been the cause for the regression.
[email protected]
Review URL: http://codereview.chromium.org/8905027
[email protected]
Review URL: http://codereview.chromium.org/8913011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114476 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 9824bdf70..b110751b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -912,7 +912,8 @@
unsigned format,
unsigned type,
int width,
- int height);
+ int height,
+ bool is_texture_immutable);
// Restore all GL state that affects clearing.
void RestoreClearState();
@@ -3244,7 +3245,7 @@
void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
if (!info ||
- !texture_manager()->MarkMipmapsGenerated(feature_info_, info, true)) {
+ !texture_manager()->MarkMipmapsGenerated(feature_info_, info)) {
SetGLError(GL_INVALID_OPERATION,
"glGenerateMipmaps: Can not generate mips for npot textures");
return;
@@ -6155,7 +6156,8 @@
unsigned format,
unsigned type,
int width,
- int height) {
+ int height,
+ bool is_texture_immutable) {
// Assumes the size has already been checked.
uint32 pixels_size = 0;
if (!GLES2Util::ComputeImageDataSize(
@@ -6165,8 +6167,13 @@
scoped_array<char> zero(new char[pixels_size]);
memset(zero.get(), 0, pixels_size);
glBindTexture(bind_target, service_id);
- WrappedTexImage2D(
- target, level, format, width, height, 0, format, type, zero.get());
+ if (is_texture_immutable) {
+ glTexSubImage2D(
+ target, level, 0, 0, width, height, format, type, zero.get());
+ } else {
+ WrappedTexImage2D(
+ target, level, format, width, height, 0, format, type, zero.get());
+ }
TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target);
glBindTexture(bind_target, info ? info->service_id() : 0);
return true;
@@ -6511,19 +6518,19 @@
if (!info->GetLevelType(target, level, &type, &internal_format)) {
SetGLError(
GL_INVALID_OPERATION,
- "glCompressdTexSubImage2D: level does not exist.");
+ "glCompressedTexSubImage2D: level does not exist.");
return;
}
if (internal_format != format) {
SetGLError(
GL_INVALID_OPERATION,
- "glCompressdTexSubImage2D: format does not match internal format.");
+ "glCompressedTexSubImage2D: format does not match internal format.");
return;
}
if (!info->ValidForTexture(
target, level, xoffset, yoffset, width, height, format, type)) {
SetGLError(GL_INVALID_VALUE,
- "glCompressdTexSubImage2D: bad dimensions.");
+ "glCompressedTexSubImage2D: bad dimensions.");
return;
}
// Note: There is no need to deal with texture cleared tracking here
@@ -6614,7 +6621,8 @@
// some part was clipped so clear the texture.
if (!ClearLevel(
info->service_id(), info->target(),
- target, level, internal_format, GL_UNSIGNED_BYTE, width, height)) {
+ target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
+ info->IsImmutable())) {
SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D: dimensions too big");
return;
}
@@ -6764,28 +6772,31 @@
return;
}
- // See if we can call glTexImage2D instead since it appears to be faster.
- if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0 &&
- !info->IsImmutable()) {
- GLsizei tex_width = 0;
- GLsizei tex_height = 0;
- bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
- DCHECK(ok);
- if (width == tex_width && height == tex_height) {
- // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
- // same as internal_foramt. If that changes we'll need to look them up.
- WrappedTexImage2D(
- target, level, format, width, height, 0, format, type, data);
- texture_manager()->SetLevelCleared(info, target, level);
+ GLsizei tex_width = 0;
+ GLsizei tex_height = 0;
+ bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
+ DCHECK(ok);
+ if (xoffset != 0 || yoffset != 0 ||
+ width != tex_width || height != tex_height) {
+ if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
+ SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big");
return;
}
- }
- if (!texture_manager()->ClearTextureLevel(this, info, target, level)) {
- SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big");
+ glTexSubImage2D(
+ target, level, xoffset, yoffset, width, height, format, type, data);
return;
}
- glTexSubImage2D(
- target, level, xoffset, yoffset, width, height, format, type, data);
+
+ if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) {
+ // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
+ // same as internal_foramt. If that changes we'll need to look them up.
+ WrappedTexImage2D(
+ target, level, format, width, height, 0, format, type, data);
+ } else {
+ glTexSubImage2D(
+ target, level, xoffset, yoffset, width, height, format, type, data);
+ }
+ texture_manager()->SetLevelCleared(info, target, level);
}
error::Error GLES2DecoderImpl::HandleTexSubImage2D(
@@ -7843,11 +7854,16 @@
if (error == GL_NO_ERROR) {
GLenum format = ExtractFormatFromStorageFormat(internal_format);
GLenum type = ExtractTypeFromStorageFormat(internal_format);
- texture_manager()->SetLevelInfo(
- feature_info_, info,
- target, 0, format, width, height, 1, 0, format, type,
- false);
- texture_manager()->MarkMipmapsGenerated(feature_info_, info, false);
+ GLsizei level_width = width;
+ GLsizei level_height = height;
+ for (int ii = 0; ii < levels; ++ii) {
+ texture_manager()->SetLevelInfo(
+ feature_info_, info,
+ target, 0, format, level_width, level_height, 1, 0, format, type,
+ false);
+ level_width = std::max(1, level_width >> 1);
+ level_height = std::max(1, level_height >> 1);
+ }
info->SetImmutable(true);
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h
index 0d6849d..e700efe 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.h
@@ -132,7 +132,8 @@
unsigned format,
unsigned type,
int width,
- int height) = 0;
+ int height,
+ bool is_texture_immutable) = 0;
// A callback for messages from the decoder.
virtual void SetMsgCallback(const MsgCallback& callback) = 0;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
index fb0151a..9fcea4a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h
@@ -57,7 +57,7 @@
uint32* service_texture_id));
MOCK_METHOD0(GetContextLostReason, error::ContextLostReason());
MOCK_CONST_METHOD1(GetCommandName, const char*(unsigned int command_id));
- MOCK_METHOD8(ClearLevel, bool(
+ MOCK_METHOD9(ClearLevel, bool(
unsigned service_id,
unsigned bind_target,
unsigned target,
@@ -65,7 +65,8 @@
unsigned format,
unsigned type,
int width,
- int height));
+ int height,
+ bool is_texture_immutable));
MOCK_METHOD1(SetMsgCallback, void(const MsgCallback& callback));
DISALLOW_COPY_AND_ASSIGN(MockGLES2Decoder);
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 03873d7e..ef0335bf 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -106,8 +106,7 @@
}
bool TextureManager::TextureInfo::MarkMipmapsGenerated(
- const FeatureInfo* feature_info,
- bool cleared) {
+ const FeatureInfo* feature_info) {
if (!CanGenerateMipmaps(feature_info)) {
return false;
}
@@ -133,7 +132,7 @@
info1.border,
info1.format,
info1.type,
- cleared);
+ true);
}
}
@@ -524,7 +523,7 @@
// needed to be able to call GL correctly.
info.cleared = decoder->ClearLevel(
service_id_, target_, info.target, info.level, info.format, info.type,
- info.width, info.height);
+ info.width, info.height, immutable_);
if (!info.cleared) {
++num_uncleared_mips_;
}
@@ -791,8 +790,7 @@
bool TextureManager::MarkMipmapsGenerated(
const FeatureInfo* feature_info,
- TextureManager::TextureInfo* info,
- bool cleared) {
+ TextureManager::TextureInfo* info) {
DCHECK(info);
if (!info->CanRender(feature_info)) {
DCHECK_NE(0, num_unrenderable_textures_);
@@ -804,7 +802,7 @@
}
num_uncleared_mips_ -= info->num_uncleared_mips();
DCHECK_GE(num_uncleared_mips_, 0);
- bool result = info->MarkMipmapsGenerated(feature_info, cleared);
+ bool result = info->MarkMipmapsGenerated(feature_info);
num_uncleared_mips_ += info->num_uncleared_mips();
if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index e38706a..0217ed9 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -254,7 +254,7 @@
const FeatureInfo* feature_info, GLenum pname, GLint param);
// Makes each of the mip levels as though they were generated.
- bool MarkMipmapsGenerated(const FeatureInfo* feature_info, bool cleared);
+ bool MarkMipmapsGenerated(const FeatureInfo* feature_info);
void MarkAsDeleted() {
service_id_ = 0;
@@ -409,8 +409,8 @@
// Makes each of the mip levels as though they were generated.
// Returns false if that's not allowed for the given texture.
- bool MarkMipmapsGenerated(const FeatureInfo* feature_info, TextureInfo* info,
- bool cleared);
+ bool MarkMipmapsGenerated(const FeatureInfo* feature_info,
+ TextureInfo* info);
// Clears any uncleared renderable levels.
bool ClearRenderableLevels(GLES2Decoder* decoder, TextureInfo* info);
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index d579ce2..9e911c6 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -373,7 +373,7 @@
EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->CanRender(&feature_info_));
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
@@ -390,7 +390,7 @@
GL_TEXTURE_2D, 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
EXPECT_TRUE(info_->CanRender(&feature_info_));
EXPECT_TRUE(info_->texture_complete());
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
@@ -402,7 +402,7 @@
// Set level zero to large size.
manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
EXPECT_FALSE(info_->npot());
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->CanRender(&feature_info_));
@@ -410,7 +410,7 @@
// Set level zero to large smaller (levels unused mips)
manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
EXPECT_FALSE(info_->npot());
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->CanRender(&feature_info_));
@@ -476,7 +476,7 @@
EXPECT_TRUE(info->CanGenerateMipmaps(&feature_info));
EXPECT_FALSE(info->CanRender(&feature_info));
EXPECT_TRUE(manager.HaveUnrenderableTextures());
- EXPECT_TRUE(manager.MarkMipmapsGenerated(&feature_info, info, true));
+ EXPECT_TRUE(manager.MarkMipmapsGenerated(&feature_info, info));
EXPECT_TRUE(info->texture_complete());
EXPECT_TRUE(info->CanRender(&feature_info));
EXPECT_FALSE(manager.HaveUnrenderableTextures());
@@ -543,7 +543,7 @@
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->cube_complete());
EXPECT_TRUE(info_->CanRender(&feature_info_));
@@ -563,7 +563,7 @@
3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->cube_complete());
}
@@ -797,7 +797,7 @@
EXPECT_TRUE(manager_.HaveUnsafeTextures());
EXPECT_TRUE(manager_.HaveUnclearedMips());
EXPECT_EQ(1, info_->num_uncleared_mips());
- manager_.MarkMipmapsGenerated(&feature_info_, info_, true);
+ manager_.MarkMipmapsGenerated(&feature_info_, info_);
EXPECT_TRUE(info_->SafeToRenderFrom());
EXPECT_FALSE(manager_.HaveUnsafeTextures());
EXPECT_FALSE(manager_.HaveUnclearedMips());
@@ -857,7 +857,7 @@
TEST_F(TextureInfoTest, ClearTexture) {
scoped_ptr<MockGLES2Decoder> decoder(new gles2::MockGLES2Decoder());
- EXPECT_CALL(*decoder, ClearLevel(_, _, _, _, _, _, _, _))
+ EXPECT_CALL(*decoder, ClearLevel(_, _, _, _, _, _, _, _, _))
.WillRepeatedly(Return(true));
manager_.SetInfoTarget(&feature_info_, info_, GL_TEXTURE_2D);
manager_.SetLevelInfo(&feature_info_, info_,