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 fd688cf290519a478f28d15c2dc0bf35f6d9152e..9ba55270759de29280b7fe4b380add2d22ba0e9c 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -1260,6 +1260,15 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
| int height) override; |
| // overridden from GLES2Decoder |
| + bool ClearCompressedTextureLevel(Texture* texture, |
| + unsigned target, |
| + int level, |
| + unsigned format, |
| + int width, |
| + int height) override; |
| + bool IsCompressedTextureFormat(unsigned format) override; |
| + |
| + // overridden from GLES2Decoder |
| bool ClearLevel3D(Texture* texture, |
| unsigned target, |
| int level, |
| @@ -10525,6 +10534,52 @@ bool GLES2DecoderImpl::ClearLevel(Texture* texture, |
| return true; |
| } |
| +bool GLES2DecoderImpl::ClearCompressedTextureLevel(Texture* texture, |
| + unsigned target, |
| + int level, |
| + unsigned format, |
| + int width, |
| + int height) { |
| + DCHECK(target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY); |
| + // This code path can only be called if the texture was originally |
| + // allocated via TexStorage2D. Note that TexStorage2D is exposed |
| + // internally for ES 2.0 contexts, but compressed texture support is |
| + // not part of that exposure. |
| + DCHECK(feature_info_->IsES3Enabled()); |
| + |
| + GLsizei bytes_required = 0; |
| + if (!GetCompressedTexSizeInBytes( |
| + "ClearCompressedTextureLevel", width, height, 1, format, |
| + &bytes_required)) { |
| + return false; |
| + } |
| + |
| + TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearCompressedTextureLevel", |
| + "bytes_required", bytes_required); |
| + |
| + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| + std::unique_ptr<char[]> zero(new char[bytes_required]); |
| + memset(zero.get(), 0, bytes_required); |
| + glBindTexture(texture->target(), texture->service_id()); |
| + glCompressedTexSubImage2D( |
| + target, level, 0, 0, width, height, format, bytes_required, zero.get()); |
| + TextureRef* bound_texture = |
| + texture_manager()->GetTextureInfoForTarget(&state_, texture->target()); |
| + glBindTexture(texture->target(), |
| + bound_texture ? bound_texture->service_id() : 0); |
| + Buffer* bound_buffer = buffer_manager()->GetBufferInfoForTarget( |
| + &state_, GL_PIXEL_UNPACK_BUFFER); |
| + if (bound_buffer) { |
| + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
|
Zhenyao Mo
2016/04/29 17:15:16
This should be bound_buffer->service_id()
Ken Russell (switch to Gerrit)
2016/05/02 20:50:55
Thank you for catching that and apologies for not
|
| + } |
| + return true; |
| +} |
| + |
| +bool GLES2DecoderImpl::IsCompressedTextureFormat(unsigned format) { |
| + return feature_info_->validators()->compressed_texture_format.IsValid( |
| + format); |
| +} |
| + |
| bool GLES2DecoderImpl::ClearLevel3D(Texture* texture, |
| unsigned target, |
| int level, |
| @@ -11741,11 +11796,24 @@ void GLES2DecoderImpl::DoCompressedTexSubImage2D( |
| return; |
| } |
| + if (!texture->IsLevelCleared(target, level)) { |
| + // This can only happen if the compressed texture was allocated |
| + // using TexStorage2D. |
| + DCHECK(texture->IsImmutable()); |
| + GLsizei level_width = 0, level_height = 0; |
| + bool success = texture->GetLevelSize( |
| + target, level, &level_width, &level_height, nullptr); |
| + DCHECK(success); |
| + // We can skip the clear if we're uploading the entire level. |
| + if (xoffset == 0 && yoffset == 0 && |
| + width == level_width && height == level_height) { |
| + texture_manager()->SetLevelCleared(texture_ref, target, level, true); |
| + } else { |
| + texture_manager()->ClearTextureLevel(this, texture_ref, target, level); |
| + } |
| + DCHECK(texture->IsLevelCleared(target, level)); |
| + } |
| - // Note: There is no need to deal with texture cleared tracking here |
| - // because the validation above means you can only get here if the level |
| - // is already a matching compressed format and in that case |
| - // CompressedTexImage2D already cleared the texture. |
| glCompressedTexSubImage2D( |
| target, level, xoffset, yoffset, width, height, format, image_size, data); |
| @@ -14446,28 +14514,11 @@ void GLES2DecoderImpl::TexStorageImpl( |
| function_name, internal_format, "internal_format"); |
| return; |
| } |
| - bool is_compressed_format; |
| - switch (internal_format) { |
| - case GL_COMPRESSED_R11_EAC: |
| - case GL_COMPRESSED_SIGNED_R11_EAC: |
| - case GL_COMPRESSED_RG11_EAC: |
| - case GL_COMPRESSED_SIGNED_RG11_EAC: |
| - case GL_COMPRESSED_RGB8_ETC2: |
| - case GL_COMPRESSED_SRGB8_ETC2: |
| - case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
| - case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
| - case GL_COMPRESSED_RGBA8_ETC2_EAC: |
| - case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: |
| - is_compressed_format = true; |
| - if (target == GL_TEXTURE_3D) { |
| - LOCAL_SET_GL_ERROR( |
| - GL_INVALID_OPERATION, function_name, "target invalid for format"); |
| - return; |
| - } |
| - break; |
| - default: |
| - is_compressed_format = false; |
| - break; |
| + bool is_compressed_format = IsCompressedTextureFormat(internal_format); |
| + if (is_compressed_format && target == GL_TEXTURE_3D) { |
| + LOCAL_SET_GL_ERROR( |
| + GL_INVALID_OPERATION, function_name, "target invalid for format"); |
| + return; |
| } |
| if (!texture_manager()->ValidForTarget(target, 0, width, height, depth) || |
| TextureManager::ComputeMipMapCount( |