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(), |