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 514925476123ce00ac8dbd6b661badf1f86592a0..2cdfaa89414b002367cdf734cf7fcc84e84e9603 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -324,6 +324,35 @@ class ScopedResolvedFramebufferBinder { |
| DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFramebufferBinder); |
| }; |
| +// Reset the base level of the texture currently bound to the |
| +// texture target and restore it after calling texImage2D. |
| +class ScopedTextureBaseLevelResetter { |
| + public: |
| + explicit ScopedTextureBaseLevelResetter(GLenum target, |
|
Zhenyao Mo
2017/06/09 21:28:06
nit: no need for explicit because you have three a
|
| + GLint base_level, |
| + bool reset_base_level) |
| + : target_(target), |
| + base_level_(base_level), |
| + reset_base_level_(reset_base_level) { |
| + DCHECK(target_ == GL_TEXTURE_2D); |
| + if (reset_base_level_) { |
|
Zhenyao Mo
2017/06/09 21:28:06
&& base_level
|
| + glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL, 0); |
| + } |
| + } |
| + |
| + ~ScopedTextureBaseLevelResetter() { |
| + if (reset_base_level_) { |
|
Zhenyao Mo
2017/06/09 21:28:06
&& base_level
|
| + glTexParameteri(target_, GL_TEXTURE_BASE_LEVEL, base_level_); |
| + } |
| + } |
| + |
| + private: |
| + GLenum target_; |
| + GLint base_level_; |
| + bool reset_base_level_; |
| + DISALLOW_COPY_AND_ASSIGN(ScopedTextureBaseLevelResetter); |
| +}; |
| + |
| // Encapsulates an OpenGL texture. |
| class BackTexture { |
| public: |
| @@ -650,11 +679,24 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| GLbitfield mask, |
| GLenum filter); |
| + void TexImage2DHelper(GLenum target, |
| + GLint level, |
| + GLenum internal_format, |
| + GLsizei width, |
| + GLsizei height, |
| + GLint border, |
| + GLenum format, |
| + GLenum type, |
| + const void* pixels, |
| + GLint base_level, |
| + bool reset_base_level); |
| + |
| PathManager* path_manager() { return group_->path_manager(); } |
| private: |
| friend class ScopedFramebufferBinder; |
| friend class ScopedResolvedFramebufferBinder; |
| + friend class ScopedTextureBaseLevelResetter; |
|
Zhenyao Mo
2017/06/09 21:28:06
Why this needs to be a friend?
|
| friend class BackFramebuffer; |
| friend class BackRenderbuffer; |
| friend class BackTexture; |
| @@ -6244,7 +6286,9 @@ void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { |
| !tex->GetLevelType(target, 0, &type, &internal_format) && |
| tex->GetLevelType(target, tex->base_level(), &type, &internal_format)) { |
| format = TextureManager::ExtractFormatFromStorageFormat(internal_format); |
| - glTexImage2D(target, 0, internal_format, 1, 1, 0, format, type, nullptr); |
| + TexImage2DHelper(target, 0, internal_format, 1, 1, 0, format, type, |
| + nullptr, base_level, |
| + workarounds().reset_teximage2d_base_level); |
| texture_zero_level_set = true; |
| } |
| } |
| @@ -6278,7 +6322,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. |
| - glTexImage2D(target, 0, internal_format, 0, 0, 0, format, type, nullptr); |
| + TexImage2DHelper(target, 0, internal_format, 0, 0, 0, format, type, nullptr, |
| + base_level, workarounds().reset_teximage2d_base_level); |
| } |
| if (workarounds().set_texture_filter_before_generating_mipmap) { |
| @@ -8415,6 +8460,23 @@ void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0, |
| } |
| } |
| +void GLES2DecoderImpl::TexImage2DHelper(GLenum target, |
| + GLint level, |
| + GLenum internal_format, |
| + GLsizei width, |
| + GLsizei height, |
| + GLint border, |
| + GLenum format, |
| + GLenum type, |
| + const void* pixels, |
| + GLint base_level, |
| + bool reset_base_level) { |
| + ScopedTextureBaseLevelResetter baseLevelResetter(target, base_level, |
| + reset_base_level); |
| + glTexImage2D(target, level, internal_format, width, height, 0, format, type, |
| + pixels); |
| +} |
| + |
| bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample( |
| GLsizei samples, |
| GLenum internalformat, |
| @@ -13764,9 +13826,11 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage( |
| } |
| state_.PushTextureDecompressionUnpackState(); |
| if (dimension == ContextState::k2D) { |
| - glTexImage2D(target, level, format_info->decompressed_internal_format, |
| - width, height, border, format_info->decompressed_format, |
| - format_info->decompressed_type, decompressed_data.get()); |
| + TexImage2DHelper(target, level, format_info->decompressed_internal_format, |
| + width, height, border, format_info->decompressed_format, |
| + format_info->decompressed_type, decompressed_data.get(), |
| + texture->base_level(), |
| + workarounds().reset_teximage2d_base_level); |
| } else { |
| glTexImage3D( |
| target, level, format_info->decompressed_internal_format, |
| @@ -14405,8 +14469,9 @@ void GLES2DecoderImpl::DoCopyTexImage2D( |
| std::unique_ptr<char[]> zero(new char[pixels_size]); |
| memset(zero.get(), 0, pixels_size); |
| - glTexImage2D(target, level, final_internal_format, width, height, border, |
| - format, type, zero.get()); |
| + TexImage2DHelper(target, level, final_internal_format, width, height, |
| + border, format, type, zero.get(), texture->base_level(), |
| + workarounds().reset_teximage2d_base_level); |
| } |
| if (!src.IsEmpty()) { |
| @@ -16853,12 +16918,14 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
| // Ensure that the glTexImage2D succeeds. |
| LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName); |
| glBindTexture(dest_binding_target, dest_texture->service_id()); |
| - glTexImage2D(dest_target, dest_level, |
| - TextureManager::AdjustTexInternalFormat(feature_info_.get(), |
| - internal_format), |
| - source_width, source_height, 0, |
| - TextureManager::AdjustTexFormat(feature_info_.get(), format), |
| - dest_type, nullptr); |
| + TexImage2DHelper( |
| + dest_target, dest_level, |
| + TextureManager::AdjustTexInternalFormat(feature_info_.get(), |
| + internal_format), |
| + source_width, source_height, 0, |
| + TextureManager::AdjustTexFormat(feature_info_.get(), format), dest_type, |
| + nullptr, dest_texture->base_level(), |
| + workarounds().reset_teximage2d_base_level); |
| GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName); |
| if (error != GL_NO_ERROR) { |
| RestoreCurrentTextureBindings(&state_, dest_binding_target, |
| @@ -17302,8 +17369,10 @@ 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); |
| + TexImage2DHelper(dest_texture->target(), 0, GL_RGBA, source_width, |
| + source_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, |
| + dest_texture->base_level(), |
| + workarounds().reset_teximage2d_base_level); |
| GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName); |
| if (error != GL_NO_ERROR) { |
| RestoreCurrentTextureBindings(&state_, dest_texture->target(), |