Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
index 48593f2337e6b8873ee6c757e6f20b2276e23221..d85b8c8832e54f1066c58f0ae580ca536bd69448 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
@@ -322,6 +322,29 @@ class ScopedResolvedFramebufferBinder { |
DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFramebufferBinder); |
}; |
+// Reset a texture's base level and restore it after calling texImage2D |
Ken Russell (switch to Gerrit)
2017/04/28 19:04:25
Please revise: "Reset the base level of the textur
yizhou.jiang
2017/06/09 07:58:15
Done.
|
+class ScopedTextureBaseLevelResetter { |
+ public: |
+ explicit ScopedTextureBaseLevelResetter(GLint base_level, |
+ bool reset_base_level) |
Ken Russell (switch to Gerrit)
2017/04/28 19:04:25
Please change the constructor to take in the targe
yizhou.jiang
2017/06/09 07:58:15
Done.
|
+ : base_level_(base_level), reset_base_level_(reset_base_level) { |
+ if (reset_base_level_) { |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); |
+ } |
+ } |
+ |
+ ~ScopedTextureBaseLevelResetter() { |
+ if (reset_base_level_) { |
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, base_level_); |
+ } |
+ } |
+ |
+ private: |
+ GLint base_level_; |
+ bool reset_base_level_; |
+ DISALLOW_COPY_AND_ASSIGN(ScopedTextureBaseLevelResetter); |
+}; |
+ |
// Encapsulates an OpenGL texture. |
class BackTexture { |
public: |
@@ -667,6 +690,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
private: |
friend class ScopedFramebufferBinder; |
friend class ScopedResolvedFramebufferBinder; |
+ friend class ScopedTextureBaseLevelResetter; |
friend class BackFramebuffer; |
friend class BackRenderbuffer; |
friend class BackTexture; |
@@ -6289,6 +6313,8 @@ void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { |
if (base_level != 0 && |
!tex->GetLevelType(target, 0, &type, &internal_format) && |
tex->GetLevelType(target, tex->base_level(), &type, &internal_format)) { |
+ ScopedTextureBaseLevelResetter baseLevelResetter( |
+ base_level, workarounds().reset_teximage2d_base_level); |
format = TextureManager::ExtractFormatFromStorageFormat(internal_format); |
glTexImage2D(target, 0, internal_format, 1, 1, 0, format, type, nullptr); |
Ken Russell (switch to Gerrit)
2017/04/28 19:04:25
Can you think of any way to add a TexImage2DHelper
yizhou.jiang
2017/06/09 07:58:15
Done.
|
texture_zero_level_set = true; |
@@ -6324,6 +6350,8 @@ void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { |
// This may have some unwanted side effects, but we expect command buffer |
// validation to prevent you from doing anything weird with the texture |
// after this, like calling texSubImage2D sucessfully. |
+ ScopedTextureBaseLevelResetter baseLevelResetter( |
+ base_level, workarounds().reset_teximage2d_base_level); |
glTexImage2D(target, 0, internal_format, 0, 0, 0, format, type, nullptr); |
} |
@@ -13761,6 +13789,8 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage( |
} |
state_.PushTextureDecompressionUnpackState(); |
if (dimension == ContextState::k2D) { |
+ ScopedTextureBaseLevelResetter baseLevelResetter( |
+ texture->base_level(), workarounds().reset_teximage2d_base_level); |
glTexImage2D(target, level, format_info->decompressed_internal_format, |
width, height, border, format_info->decompressed_format, |
format_info->decompressed_type, decompressed_data.get()); |
@@ -14402,6 +14432,9 @@ void GLES2DecoderImpl::DoCopyTexImage2D( |
std::unique_ptr<char[]> zero(new char[pixels_size]); |
memset(zero.get(), 0, pixels_size); |
+ |
+ ScopedTextureBaseLevelResetter baseLevelResetter( |
+ texture->base_level(), workarounds().reset_teximage2d_base_level); |
glTexImage2D(target, level, final_internal_format, width, height, border, |
format, type, zero.get()); |
} |
@@ -16878,6 +16911,8 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
// Ensure that the glTexImage2D succeeds. |
LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName); |
glBindTexture(dest_binding_target, dest_texture->service_id()); |
+ ScopedTextureBaseLevelResetter baseLevelResetter( |
+ dest_texture->base_level(), workarounds().reset_teximage2d_base_level); |
glTexImage2D(dest_target, dest_level, |
TextureManager::AdjustTexInternalFormat(feature_info_.get(), |
internal_format), |
@@ -17325,8 +17360,12 @@ void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLuint source_id, |
// As a fallback, copy into a non-compressed GL_RGBA texture. |
LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName); |
- glTexImage2D(dest_texture->target(), 0, GL_RGBA, source_width, source_height, |
- 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
+ { |
+ ScopedTextureBaseLevelResetter baseLevelResetter( |
+ dest_texture->base_level(), workarounds().reset_teximage2d_base_level); |
+ glTexImage2D(dest_texture->target(), 0, GL_RGBA, source_width, |
+ source_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
+ } |
GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName); |
if (error != GL_NO_ERROR) { |
RestoreCurrentTextureBindings(&state_, dest_texture->target()); |