Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2479513002: Reland of Extend CopyTextureCHROMIUM to more ES 3.0 texture formats. (Closed)
Patch Set: rebase and minor fix for premultiply and un-premultiply alpha Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 3c0f126881452c0bd00de777adffe0901a3d2aa6..70d1b6260526a1e49d4a022be3308c492db8af30 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -889,6 +889,10 @@ 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* output_error_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,
@@ -2002,7 +2006,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
bool ValidateCopyTextureCHROMIUMTextures(const char* function_name,
TextureRef* source_texture_ref,
TextureRef* dest_texture_ref);
- bool ValidateCopyTextureCHROMIUMInternalFormats(
+ SupportedCopyMethodByFormat ValidateCopyTextureCHROMIUMInternalFormats(
const char* function_name,
TextureRef* source_texture_ref,
GLenum dest_internal_format);
@@ -13738,12 +13742,13 @@ 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* output_error_msg) {
if (read_format == 0) {
Zhenyao Mo 2016/11/19 00:42:33 Can we DCHECK(output_error_msg)?
qiankun 2016/11/21 16:01:50 Done.
- LOCAL_SET_GL_ERROR(
- GL_INVALID_OPERATION, func_name, "no valid color image");
+ *output_error_msg = std::string("no valid color image");
return false;
}
// Check we have compatible formats.
@@ -13751,8 +13756,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");
+ *output_error_msg = std::string("incompatible format");
return false;
}
if (feature_info_->IsWebGL2OrES3Context()) {
@@ -13767,15 +13771,13 @@ 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");
+ *output_error_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");
+ *output_error_msg =
+ std::string("can not be used with depth or stencil textures");
return false;
}
if (feature_info_->IsWebGL2OrES3Context()) {
@@ -13792,9 +13794,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");
+ *output_error_msg = std::string("incompatible color component sizes");
return false;
}
}
@@ -13802,6 +13802,20 @@ bool GLES2DecoderImpl::ValidateCopyTexFormat(
return true;
}
+bool GLES2DecoderImpl::ValidateCopyTexFormat(const char* func_name,
+ GLenum internal_format,
+ GLenum read_format,
+ GLenum read_type) {
+ std::string output_error_msg;
+ if (!ValidateCopyTexFormatHelper(internal_format, read_format, read_type,
+ &output_error_msg)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
+ output_error_msg.c_str());
+ return false;
+ }
+ return true;
+}
+
void GLES2DecoderImpl::DoCopyTexImage2D(
GLenum target,
GLint level,
@@ -16006,7 +16020,8 @@ bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUMTextures(
return true;
}
-bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats(
+SupportedCopyMethodByFormat
+GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats(
const char* function_name,
TextureRef* source_texture_ref,
GLenum dest_internal_format) {
@@ -16016,14 +16031,59 @@ bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats(
source_texture->GetLevelType(source_texture->target(), 0, &source_type,
&source_internal_format);
- // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
- // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
- // renderable on some platforms.
- bool valid_dest_format =
- dest_internal_format == GL_RGB || dest_internal_format == GL_RGBA ||
- dest_internal_format == GL_RGB8 || dest_internal_format == GL_RGBA8 ||
- dest_internal_format == GL_BGRA_EXT ||
- dest_internal_format == GL_BGRA8_EXT;
+ bool valid_dest_format = false;
+ // TODO(qiankun.miao@intel.com): ALPHA and LUMINANCE formats have bug on GL
+ // core profile. See crbug.com/577144. Enable the workaround for
+ // glCopyTexImage and glCopyTexSubImage in gles2_cmd_copy_tex_image.cc for
+ // glCopyTextureCHROMIUM implementation.
+ switch (dest_internal_format) {
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE:
+ case GL_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_RGB8:
+ case GL_RGBA8:
+ valid_dest_format = true;
+ break;
+ case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
+ valid_dest_format = feature_info_->texture_format_bgra8888_available();
+ break;
+ case GL_SRGB_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ valid_dest_format = feature_info_->ext_srgb_available();
+ break;
+ case GL_R8:
+ case GL_R8UI:
+ case GL_RG8:
+ case GL_RG8UI:
+ case GL_SRGB8:
+ case GL_RGB565:
+ case GL_RGB9_E5:
+ case GL_RGB8UI:
+ case GL_SRGB8_ALPHA8:
+ case GL_RGB5_A1:
+ case GL_RGBA4:
+ case GL_RGBA8UI:
+ valid_dest_format = feature_info_->IsWebGL2OrES3Context();
+ break;
+ case GL_R16F:
+ case GL_R32F:
+ case GL_RG16F:
+ case GL_RG32F:
+ case GL_RGB16F:
+ case GL_RGB32F:
+ case GL_RGBA16F:
+ case GL_RGBA32F:
+ case GL_R11F_G11F_B10F:
+ valid_dest_format = feature_info_->ext_color_buffer_float_available();
+ break;
+ default:
+ valid_dest_format = false;
+ break;
+ }
+
bool valid_source_format =
source_internal_format == GL_RED || source_internal_format == GL_ALPHA ||
source_internal_format == GL_RGB || source_internal_format == GL_RGBA ||
@@ -16039,16 +16099,38 @@ bool GLES2DecoderImpl::ValidateCopyTextureCHROMIUMInternalFormats(
GLES2Util::GetStringEnum(source_internal_format);
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
msg.c_str());
- return false;
+ return NONE_COPY;
}
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 NONE_COPY;
}
- return true;
+
+ bool source_format_color_renderable =
+ Texture::ColorRenderable(GetFeatureInfo(), source_internal_format, false);
+ bool dest_format_color_renderable =
+ Texture::ColorRenderable(GetFeatureInfo(), dest_internal_format, false);
+ std::string output_error_msg;
+
+ // CopyTexImage* should not allow internalformat of GL_BGRA_EXT and
+ // GL_BGRA8_EXT. crbug.com/663086.
+ bool copy_tex_image_format_valid =
+ source_internal_format != GL_BGRA_EXT &&
+ dest_internal_format != GL_BGRA_EXT &&
+ source_internal_format != GL_BGRA8_EXT &&
+ dest_internal_format != GL_BGRA8_EXT &&
+ ValidateCopyTexFormatHelper(dest_internal_format, source_internal_format,
+ source_type, &output_error_msg);
+ if (source_format_color_renderable && copy_tex_image_format_valid)
+ return DIRECT_COPY;
+
+ if (dest_format_color_renderable)
+ return DIRECT_DRAW;
+
+ return DRAW_AND_COPY;
}
bool GLES2DecoderImpl::ValidateCompressedCopyTextureCHROMIUM(
@@ -16112,25 +16194,41 @@ 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;
Zhenyao Mo 2016/11/19 00:42:33 nit: {} around return when the condition is multi-
qiankun 2016/11/21 16:01:50 Done.
+
+ SupportedCopyMethodByFormat method =
+ ValidateCopyTextureCHROMIUMInternalFormats(
+ kFunctionName, source_texture_ref, internal_format);
+ if (NONE_COPY == method) {
+ return;
+ }
+
+ if (feature_info_->feature_flags().desktop_srgb_support) {
+ bool enable_framebuffer_srgb =
+ GetColorEncodingFromInternalFormat(source_internal_format) == GL_SRGB ||
+ GetColorEncodingFromInternalFormat(internal_format) == GL_SRGB;
+ state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
+ }
+
int source_width = 0;
int source_height = 0;
gl::GLImage* image =
@@ -16162,11 +16260,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");
@@ -16203,26 +16296,24 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
// Ensure that the glTexImage2D succeeds.
LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(kFunctionName);
glBindTexture(dest_target, dest_texture->service_id());
- glTexImage2D(
- dest_target, 0, TextureManager::AdjustTexInternalFormat(
- feature_info_.get(), internal_format),
- source_width, source_height, 0,
- TextureManager::AdjustTexFormat(feature_info_.get(), internal_format),
- dest_type, NULL);
+ glTexImage2D(dest_target, 0, TextureManager::AdjustTexInternalFormat(
+ feature_info_.get(), internal_format),
+ source_width, source_height, 0,
+ TextureManager::AdjustTexFormat(feature_info_.get(), format),
+ dest_type, NULL);
GLenum error = LOCAL_PEEK_GL_ERROR(kFunctionName);
if (error != GL_NO_ERROR) {
RestoreCurrentTextureBindings(&state_, dest_target);
return;
}
- texture_manager()->SetLevelInfo(
- dest_texture_ref, dest_target, 0, internal_format, source_width,
- source_height, 1, 0, internal_format, dest_type,
- gfx::Rect(source_width, source_height));
+ texture_manager()->SetLevelInfo(dest_texture_ref, dest_target, 0,
+ internal_format, source_width,
+ 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.
@@ -16245,18 +16336,21 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
GLfloat transform_matrix[16];
image->GetTextureMatrix(transform_matrix);
copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
- this, source_target, source_texture->service_id(), dest_target,
- dest_texture->service_id(), source_width, source_height,
+ 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, transform_matrix);
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);
+ unpack_premultiply_alpha == GL_TRUE, unpack_unmultiply_alpha == GL_TRUE,
+ method);
}
void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
@@ -16358,11 +16452,20 @@ void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
return;
}
- if (!ValidateCopyTextureCHROMIUMInternalFormats(
- kFunctionName, source_texture_ref, dest_internal_format)) {
+ SupportedCopyMethodByFormat method =
+ ValidateCopyTextureCHROMIUMInternalFormats(
+ kFunctionName, source_texture_ref, dest_internal_format);
+ if (NONE_COPY == method) {
return;
Zhenyao Mo 2016/11/19 00:42:33 Can you add a comment here that an INVALID_OPERATI
qiankun 2016/11/21 16:01:50 Done.
}
+ if (feature_info_->feature_flags().desktop_srgb_support) {
+ bool enable_framebuffer_srgb =
+ GetColorEncodingFromInternalFormat(source_internal_format) == GL_SRGB ||
+ GetColorEncodingFromInternalFormat(dest_internal_format) == GL_SRGB;
+ state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
+ }
+
// Clear the source texture if necessary.
if (!texture_manager()->ClearTextureLevel(this, source_texture_ref,
source_target, 0)) {
@@ -16441,7 +16544,8 @@ void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
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);
+ unpack_premultiply_alpha == GL_TRUE, unpack_unmultiply_alpha == GL_TRUE,
+ method);
}
bool GLES2DecoderImpl::InitializeCopyTexImageBlitter(
@@ -16616,7 +16720,7 @@ void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLuint source_id,
this, source_texture->target(), source_texture->service_id(),
source_internal_format, dest_texture->target(),
dest_texture->service_id(), GL_RGBA, source_width, source_height, false,
- false, false);
+ false, false, DIRECT_DRAW);
}
void GLES2DecoderImpl::TexStorageImpl(GLenum target,

Powered by Google App Engine
This is Rietveld 408576698