Chromium Code Reviews| 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 db2c9d22c142c3fa90d8e93ba069e37e30e79b9b..671a37a5d4b22a1285b514defb07ab686f33ea57 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -322,6 +322,21 @@ class ScopedResolvedFramebufferBinder { |
| DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFramebufferBinder); |
| }; |
| +// Reset a texture's base level and restore it after calling |
| +// texImage2D |
|
qiankun
2017/04/26 04:16:20
Merge line 325 and 326.
yizhou.jiang
2017/04/27 04:23:22
Done.
|
| +class ScopedTextureBaseLevelResetter { |
| + public: |
| + explicit ScopedTextureBaseLevelResetter( |
| + TextureRef* texture_ref, |
| + scoped_refptr<gpu::gles2::FeatureInfo> feature_info); |
| + ~ScopedTextureBaseLevelResetter(); |
| + |
| + private: |
| + TextureRef* texture_ref_; |
| + scoped_refptr<gpu::gles2::FeatureInfo> feature_info_; |
| + DISALLOW_COPY_AND_ASSIGN(ScopedTextureBaseLevelResetter); |
| +}; |
| + |
| // Encapsulates an OpenGL texture. |
| class BackTexture { |
| public: |
| @@ -667,6 +682,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; |
| @@ -2586,6 +2602,25 @@ ScopedFramebufferBinder::~ScopedFramebufferBinder() { |
| decoder_->RestoreCurrentFramebufferBindings(); |
| } |
| +ScopedTextureBaseLevelResetter::ScopedTextureBaseLevelResetter( |
| + TextureRef* texture_ref, |
| + scoped_refptr<gpu::gles2::FeatureInfo> feature_info) |
| + : texture_ref_(texture_ref), feature_info_(feature_info) { |
| + if (texture_ref_ && |
|
qiankun
2017/04/26 04:16:19
Isn't texture_ref_ always non-null? You can just p
yizhou.jiang
2017/04/27 04:23:22
Done.
|
| + feature_info_->workarounds().reset_teximage2d_base_level) { |
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); |
| + } |
| +} |
| + |
| +ScopedTextureBaseLevelResetter::~ScopedTextureBaseLevelResetter() { |
| + if (texture_ref_ && |
| + feature_info_->workarounds().reset_teximage2d_base_level) { |
| + Texture* texture = texture_ref_->texture(); |
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, |
| + texture->base_level()); |
| + } |
| +} |
| + |
| ScopedResolvedFramebufferBinder::ScopedResolvedFramebufferBinder( |
| GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal) |
| : decoder_(decoder) { |
| @@ -6289,6 +6324,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(texture_ref, |
| + feature_info_); |
| format = TextureManager::ExtractFormatFromStorageFormat(internal_format); |
| glTexImage2D(target, 0, internal_format, 1, 1, 0, format, type, nullptr); |
| texture_zero_level_set = true; |
| @@ -6324,6 +6361,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(texture_ref, |
| + feature_info_); |
| glTexImage2D(target, 0, internal_format, 0, 0, 0, format, type, nullptr); |
| } |
| @@ -13761,6 +13800,8 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage( |
| } |
| state_.PushTextureDecompressionUnpackState(); |
| if (dimension == ContextState::k2D) { |
| + ScopedTextureBaseLevelResetter baseLevelResetter(texture_ref, |
| + feature_info_); |
| glTexImage2D(target, level, format_info->decompressed_internal_format, |
| width, height, border, format_info->decompressed_format, |
| format_info->decompressed_type, decompressed_data.get()); |
| @@ -14402,6 +14443,9 @@ void GLES2DecoderImpl::DoCopyTexImage2D( |
| std::unique_ptr<char[]> zero(new char[pixels_size]); |
| memset(zero.get(), 0, pixels_size); |
| + |
| + ScopedTextureBaseLevelResetter baseLevelResetter(texture_ref, |
| + feature_info_); |
| glTexImage2D(target, level, final_internal_format, width, height, border, |
| format, type, zero.get()); |
| } |
| @@ -16878,6 +16922,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_ref, |
| + feature_info_); |
| glTexImage2D(dest_target, dest_level, |
| TextureManager::AdjustTexInternalFormat(feature_info_.get(), |
| internal_format), |
| @@ -17325,8 +17371,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_ref, |
| + feature_info_); |
| + 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()); |