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 a5946fab874cafdcba455ea0d5bcfa4bb081ef31..3cebd8e74a15846f6800061c7ec1daf1d7ac69e4 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
@@ -889,6 +889,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient { |
const void* data, |
ContextState::Dimension dimension); |
+ bool ValidateCopyTexFormatHelper(GLenum internal_format, GLenum read_format, |
+ GLenum read_type, std::string& err_msg); |
// Validate if |format| is valid for CopyTex{Sub}Image functions. |
// If not, generate a GL error and return false. |
bool ValidateCopyTexFormat(const char* func_name, GLenum internal_format, |
@@ -13697,12 +13699,10 @@ error::Error GLES2DecoderImpl::DoCompressedTexSubImage( |
return error::kNoError; |
} |
-bool GLES2DecoderImpl::ValidateCopyTexFormat( |
- const char* func_name, GLenum internal_format, |
- GLenum read_format, GLenum read_type) { |
+bool GLES2DecoderImpl::ValidateCopyTexFormatHelper(GLenum internal_format, |
+ GLenum read_format, GLenum read_type, std::string& err_msg) { |
Zhenyao Mo
2016/11/03 22:55:35
This is against coding style: https://google.githu
|
if (read_format == 0) { |
- LOCAL_SET_GL_ERROR( |
- GL_INVALID_OPERATION, func_name, "no valid color image"); |
+ err_msg = std::string("no valid color image"); |
return false; |
} |
// Check we have compatible formats. |
@@ -13710,8 +13710,7 @@ bool GLES2DecoderImpl::ValidateCopyTexFormat( |
uint32_t channels_needed = GLES2Util::GetChannelsForFormat(internal_format); |
if (!channels_needed || |
(channels_needed & channels_exist) != channels_needed) { |
- LOCAL_SET_GL_ERROR( |
- GL_INVALID_OPERATION, func_name, "incompatible format"); |
+ err_msg = std::string("incompatible format"); |
return false; |
} |
if (feature_info_->IsWebGL2OrES3Context()) { |
@@ -13722,15 +13721,12 @@ bool GLES2DecoderImpl::ValidateCopyTexFormat( |
GLES2Util::IsSignedIntegerFormat(read_format)) || |
(GLES2Util::IsUnsignedIntegerFormat(internal_format) != |
GLES2Util::IsUnsignedIntegerFormat(read_format))) { |
- LOCAL_SET_GL_ERROR( |
- GL_INVALID_OPERATION, func_name, "incompatible format"); |
+ err_msg = std::string("incompatible format"); |
return false; |
} |
} |
if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { |
- LOCAL_SET_GL_ERROR( |
- GL_INVALID_OPERATION, |
- func_name, "can not be used with depth or stencil textures"); |
+ err_msg = std::string("can not be used with depth or stencil textures"); |
return false; |
} |
if (feature_info_->IsWebGL2OrES3Context()) { |
@@ -13747,9 +13743,7 @@ bool GLES2DecoderImpl::ValidateCopyTexFormat( |
(dg > 0 && sg != dg) || |
(db > 0 && sb != db) || |
(da > 0 && sa != da)) { |
- LOCAL_SET_GL_ERROR( |
- GL_INVALID_OPERATION, |
- func_name, "incompatible color component sizes"); |
+ err_msg = std::string("incompatible color component sizes"); |
return false; |
} |
} |
@@ -13757,6 +13751,18 @@ bool GLES2DecoderImpl::ValidateCopyTexFormat( |
return true; |
} |
+bool GLES2DecoderImpl::ValidateCopyTexFormat( |
+ const char* func_name, GLenum internal_format, |
+ GLenum read_format, GLenum read_type) { |
+ std::string err_msg; |
+ if (!ValidateCopyTexFormatHelper(internal_format, read_format, |
+ read_type, err_msg)) { |
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, err_msg.c_str()); |
+ return false; |
+ } |
+ return true; |
+} |
+ |
void GLES2DecoderImpl::DoCopyTexImage2D( |
GLenum target, |
GLint level, |
@@ -15961,17 +15967,9 @@ bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats( |
source_internal_format == GL_RGB_YCBCR_420V_CHROMIUM || |
source_internal_format == GL_RGB_YCBCR_422_CHROMIUM; |
if (!valid_source_format) { |
- std::string msg = "invalid source internal format " + |
- GLES2Util::GetStringEnum(source_internal_format); |
- LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, |
- msg.c_str()); |
return false; |
} |
if (!valid_dest_format) { |
- std::string msg = "invalid dest internal format " + |
- GLES2Util::GetStringEnum(dest_internal_format); |
- LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, |
- msg.c_str()); |
return false; |
} |
return true; |
@@ -16038,25 +16036,47 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
TextureRef* source_texture_ref = GetTexture(source_id); |
TextureRef* dest_texture_ref = GetTexture(dest_id); |
- if (!texture_manager()->ValidateTextureParameters( |
- GetErrorState(), kFunctionName, true, internal_format, dest_type, |
- internal_format, 0)) |
- return; |
- |
if (!ValidateCopyTextureCHROMIUMTextures(kFunctionName, source_texture_ref, |
dest_texture_ref)) { |
return; |
} |
- if (!ValidateCopyTextureCHROMIUMInternalFormats( |
- kFunctionName, source_texture_ref, internal_format)) { |
- return; |
- } |
- |
Texture* source_texture = source_texture_ref->texture(); |
Texture* dest_texture = dest_texture_ref->texture(); |
GLenum source_target = source_texture->target(); |
GLenum dest_target = dest_texture->target(); |
+ |
+ GLenum source_type = 0; |
+ GLenum source_internal_format = 0; |
+ source_texture->GetLevelType(source_target, 0, &source_type, |
+ &source_internal_format); |
+ GLenum format = TextureManager::ExtractFormatFromStorageFormat( |
+ internal_format); |
+ if (!texture_manager()->ValidateTextureParameters( |
+ GetErrorState(), kFunctionName, true, format, dest_type, |
+ internal_format, 0)) |
+ return; |
+ |
+ bool legacy_format_valid = ValidateCopyTextureCHROMIUMInternalFormats( |
Zhenyao Mo
2016/11/03 22:55:35
I think you should expand this function to handle
|
+ kFunctionName, source_texture_ref, internal_format); |
+ bool source_format_color_renderable = Texture::ColorRenderable( |
+ GetFeatureInfo(), source_internal_format, source_texture->IsImmutable()); |
+ std::string err_msg; |
+ bool copy_tex_image_format_valid = source_format_color_renderable && |
+ source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D && |
+ ValidateCopyTexFormatHelper(internal_format, |
+ source_internal_format, source_type, err_msg); |
+ if (!legacy_format_valid && !copy_tex_image_format_valid) { |
+ std::string msg = "source internal format(" + |
+ GLES2Util::GetStringEnum(source_internal_format) + |
+ ") and destination internal format(" + |
+ GLES2Util::GetStringEnum(internal_format) + |
+ ") combination is invalid."; |
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
+ msg.c_str()); |
+ return; |
+ } |
+ |
int source_width = 0; |
int source_height = 0; |
gl::GLImage* image = |
@@ -16088,11 +16108,6 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
} |
} |
- GLenum source_type = 0; |
- GLenum source_internal_format = 0; |
- source_texture->GetLevelType(source_target, 0, &source_type, |
- &source_internal_format); |
- |
if (dest_texture->IsImmutable()) { |
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
"texture is immutable"); |
@@ -16133,7 +16148,7 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
dest_target, 0, TextureManager::AdjustTexInternalFormat( |
feature_info_.get(), internal_format), |
source_width, source_height, 0, |
- TextureManager::AdjustTexFormat(feature_info_.get(), internal_format), |
+ TextureManager::AdjustTexFormat(feature_info_.get(), format), |
dest_type, NULL); |
GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName); |
if (error != GL_NO_ERROR) { |
@@ -16143,12 +16158,11 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
texture_manager()->SetLevelInfo( |
dest_texture_ref, dest_target, 0, internal_format, source_width, |
- source_height, 1, 0, internal_format, dest_type, |
+ source_height, 1, 0, format, dest_type, |
gfx::Rect(source_width, source_height)); |
dest_texture->ApplyFormatWorkarounds(feature_info_.get()); |
} else { |
- texture_manager()->SetLevelCleared(dest_texture_ref, dest_target, 0, |
- true); |
+ texture_manager()->SetLevelCleared(dest_texture_ref, dest_target, 0, true); |
} |
// Try using GLImage::CopyTexImage when possible. |
@@ -16178,11 +16192,21 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
return; |
} |
} |
- copy_texture_CHROMIUM_->DoCopyTexture( |
- this, source_target, source_texture->service_id(), source_internal_format, |
- dest_target, dest_texture->service_id(), internal_format, source_width, |
- source_height, unpack_flip_y == GL_TRUE, |
- unpack_premultiply_alpha == GL_TRUE, unpack_unmultiply_alpha == GL_TRUE); |
+ if (legacy_format_valid) { |
+ copy_texture_CHROMIUM_->DoCopyTexture( |
+ this, source_target, source_texture->service_id(), |
+ source_internal_format, dest_target, dest_texture->service_id(), |
+ internal_format, source_width, source_height, unpack_flip_y == GL_TRUE, |
+ unpack_premultiply_alpha == GL_TRUE, |
+ unpack_unmultiply_alpha == GL_TRUE); |
+ } else if (copy_tex_image_format_valid) { |
+ copy_texture_CHROMIUM_->DoCopyTexImage2D( |
+ this, source_target, source_texture->service_id(), |
+ dest_target, dest_texture->service_id(), |
+ internal_format, source_width, source_height); |
+ } else { |
+ NOTIMPLEMENTED(); |
+ } |
} |
void GLES2DecoderImpl::DoCopySubTextureCHROMIUM( |
@@ -16284,8 +16308,23 @@ void GLES2DecoderImpl::DoCopySubTextureCHROMIUM( |
return; |
} |
- if (!ValidateCopyTextureCHROMIUMInternalFormats( |
- kFunctionName, source_texture_ref, dest_internal_format)) { |
+ bool legacy_format_valid = ValidateCopyTextureCHROMIUMInternalFormats( |
+ kFunctionName, source_texture_ref, dest_internal_format); |
+ bool source_format_color_renderable = Texture::ColorRenderable( |
+ GetFeatureInfo(), source_internal_format, source_texture->IsImmutable()); |
+ std::string err_msg; |
+ bool copy_tex_image_format_valid = source_format_color_renderable && |
+ source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D && |
+ ValidateCopyTexFormatHelper(dest_internal_format, |
+ source_internal_format, source_type, err_msg); |
+ if (!legacy_format_valid && !copy_tex_image_format_valid) { |
+ std::string msg = "source internal format(" + |
+ GLES2Util::GetStringEnum(source_internal_format) + |
+ ") and destination internal format(" + |
+ GLES2Util::GetStringEnum(dest_internal_format) + |
+ ") combination is invalid."; |
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, |
+ msg.c_str()); |
return; |
} |
@@ -16362,12 +16401,23 @@ void GLES2DecoderImpl::DoCopySubTextureCHROMIUM( |
return; |
} |
} |
- copy_texture_CHROMIUM_->DoCopySubTexture( |
- this, source_target, source_texture->service_id(), source_internal_format, |
- dest_target, dest_texture->service_id(), dest_internal_format, xoffset, |
- yoffset, x, y, width, height, dest_width, dest_height, source_width, |
- source_height, unpack_flip_y == GL_TRUE, |
- unpack_premultiply_alpha == GL_TRUE, unpack_unmultiply_alpha == GL_TRUE); |
+ if (legacy_format_valid) { |
+ copy_texture_CHROMIUM_->DoCopySubTexture( |
+ this, source_target, source_texture->service_id(), |
+ source_internal_format, dest_target, dest_texture->service_id(), |
+ dest_internal_format, xoffset, yoffset, x, y, width, height, |
+ dest_width, dest_height, source_width, |
+ source_height, unpack_flip_y == GL_TRUE, |
+ unpack_premultiply_alpha == GL_TRUE, |
+ unpack_unmultiply_alpha == GL_TRUE); |
+ } else if (copy_tex_image_format_valid) { |
+ copy_texture_CHROMIUM_->DoCopyTexSubImage2D( |
+ this, source_target, source_texture->service_id(), |
+ dest_target, dest_texture->service_id(), |
+ xoffset, yoffset, x, y, width, height); |
+ } else { |
+ NOTIMPLEMENTED(); |
+ } |
} |
bool GLES2DecoderImpl::InitializeCopyTexImageBlitter( |