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

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

Issue 2286593002: [Command Buffer] emulate SRGB color format for BlitFramebuffer in OpenGL (Closed)
Patch Set: Addressed zmo@'s feedback Created 4 years, 4 months 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 991d525ff7b79a21c7e6434401e8a9b21c22ed3e..14f63d960e69586e932f62ecad2bfaafa9aefa5b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -44,6 +44,7 @@
#include "gpu/command_buffer/service/gles2_cmd_copy_tex_image.h"
#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h"
+#include "gpu/command_buffer/service/gles2_cmd_srgb_converter.h"
#include "gpu/command_buffer/service/gles2_cmd_validation.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/command_buffer/service/gpu_state_tracer.h"
@@ -2071,6 +2072,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
bool InitializeCopyTexImageBlitter(const char* function_name);
bool InitializeCopyTextureCHROMIUM(const char* function_name);
+ bool InitializeSRGBDecoder(const char* function_name);
+ bool InitializeSRGBEncoder(const char* function_name);
// Generate a member function prototype for each command in an automated and
// typesafe way.
#define GLES2_CMD_OP(name) \
@@ -2262,6 +2265,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
apply_framebuffer_attachment_cmaa_intel_;
std::unique_ptr<CopyTexImageResourceManager> copy_tex_image_blit_;
std::unique_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
+ std::unique_ptr<SRGBConverter> srgb_converter_;
std::unique_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
// Cached values of the currently assigned viewport dimensions.
@@ -4226,14 +4230,6 @@ bool GLES2DecoderImpl::CheckBoundFramebufferValid(const char* func_name) {
Framebuffer* read_framebuffer = GetFramebufferInfoForTarget(target);
valid = valid && CheckFramebufferValid(
read_framebuffer, target, GL_INVALID_FRAMEBUFFER_OPERATION, func_name);
-
- if (valid && feature_info_->feature_flags().desktop_srgb_support) {
- bool enable_framebuffer_srgb =
- (draw_framebuffer && draw_framebuffer->HasSRGBAttachments()) ||
- (read_framebuffer && read_framebuffer->HasSRGBAttachments());
- state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
- }
-
return valid;
}
@@ -4535,6 +4531,11 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
copy_texture_CHROMIUM_.reset();
}
+ if (srgb_converter_.get()) {
+ srgb_converter_->Destroy();
+ srgb_converter_.reset();
+ }
+
clear_framebuffer_blit_.reset();
if (state_.current_program.get()) {
@@ -4627,6 +4628,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) {
apply_framebuffer_attachment_cmaa_intel_.reset();
copy_tex_image_blit_.reset();
copy_texture_CHROMIUM_.reset();
+ srgb_converter_.reset();
clear_framebuffer_blit_.reset();
if (query_manager_.get()) {
@@ -7524,12 +7526,17 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
return;
}
- GLenum src_format = GetBoundReadFramebufferInternalFormat();
+ GLenum src_internal_format = GetBoundReadFramebufferInternalFormat();
GLenum src_type = GetBoundReadFramebufferTextureType();
+ bool read_buffer_has_srgb =
+ GetColorEncodingFromInternalFormat(src_internal_format) == GL_SRGB;
+ bool draw_buffers_has_srgb = false;
if ((mask & GL_COLOR_BUFFER_BIT) != 0) {
- bool is_src_signed_int = GLES2Util::IsSignedIntegerFormat(src_format);
- bool is_src_unsigned_int = GLES2Util::IsUnsignedIntegerFormat(src_format);
+ bool is_src_signed_int =
+ GLES2Util::IsSignedIntegerFormat(src_internal_format);
+ bool is_src_unsigned_int =
+ GLES2Util::IsUnsignedIntegerFormat(src_internal_format);
DCHECK(!is_src_signed_int || !is_src_unsigned_int);
if ((is_src_signed_int || is_src_unsigned_int) && filter == GL_LINEAR) {
@@ -7539,13 +7546,15 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
}
GLenum src_sized_format =
- GLES2Util::ConvertToSizedFormat(src_format, src_type);
+ GLES2Util::ConvertToSizedFormat(src_internal_format, src_type);
for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) {
GLenum dst_format = GetBoundColorDrawBufferInternalFormat(
static_cast<GLint>(ii));
GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii));
if (dst_format == 0)
continue;
+ if (GetColorEncodingFromInternalFormat(dst_format) == GL_SRGB)
+ draw_buffers_has_srgb = true;
if (read_buffer_samples > 0 &&
(src_sized_format !=
GLES2Util::ConvertToSizedFormat(dst_format, dst_type))) {
@@ -7582,11 +7591,95 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
}
}
- state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
- BlitFramebufferHelper(
- srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
- state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
+ bool enable_srgb = read_buffer_has_srgb || draw_buffers_has_srgb;
+ bool same_size = (abs(srcX1 - srcX0) == abs(dstX1 - dstX0)) &&
+ (abs(srcY1 - srcY0) == abs(dstY1 - dstY0));
+ if (!enable_srgb ||
+ !feature_info_->feature_flags().desktop_srgb_support ||
+ (read_buffer_has_srgb && draw_buffers_has_srgb && same_size) ||
+ gl_version_info().IsAtLeastGL(4, 4)) {
+ if (enable_srgb && gl_version_info().IsAtLeastGL(4, 4)) {
+ state_.EnableDisableFramebufferSRGB(enable_srgb);
+ }
+
+ state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
+ BlitFramebufferHelper(
+ srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
state_.enable_flags.scissor_test);
+ return;
+ }
+
+ // emulate srgb for desktop core profile when GL version < 4.4
+ // TODO(yunchao): Need to handle this situation:
+ // There are multiple draw buffers. Some of them are srgb image.
+ // The others are not.
+ GLenum target = features().chromium_framebuffer_multisample ?
+ GL_DRAW_FRAMEBUFFER : GL_FRAMEBUFFER;
+ Framebuffer* draw_framebuffer = GetFramebufferInfoForTarget(target);
+
+ target = features().chromium_framebuffer_multisample ?
+ GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER;
+ Framebuffer* read_framebuffer = GetFramebufferInfoForTarget(target);
+
+ if (read_buffer_has_srgb) {
+ state_.EnableDisableFramebufferSRGB(false);
+ if (!InitializeSRGBDecoder(func_name)) {
+ return;
+ }
+ srgb_converter_->SRGBToLinear(this, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter,
+ GetBoundReadFramebufferSize(),
+ read_framebuffer->service_id(),
+ src_internal_format,
+ draw_framebuffer->service_id(),
+ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
+ }
+
+ if (draw_buffers_has_srgb) {
+ state_.EnableDisableFramebufferSRGB(false);
+ if (!InitializeSRGBEncoder(func_name)) {
+ return;
+ }
+ srgb_converter_->LinearToSRGB(this, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1,
+ mask, filter,
+ GetBoundReadFramebufferSize(),
+ read_framebuffer->service_id(),
+ src_internal_format,
+ draw_framebuffer->service_id(),
+ GL_SRGB8_ALPHA8,
+ GL_RGBA, GL_UNSIGNED_BYTE);
+ }
+}
+
+bool GLES2DecoderImpl::InitializeSRGBDecoder(
+ const char* function_name) {
+ if (!srgb_converter_.get()) {
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
+ srgb_converter_.reset(
+ new SRGBConverter(feature_info_.get()));
+ }
+ srgb_converter_->InitializeSRGBDecoder(this);
+ if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR) {
+ return false;
+ }
+ return true;
+}
+
+bool GLES2DecoderImpl::InitializeSRGBEncoder(
+ const char* function_name) {
+ if (!srgb_converter_.get()) {
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
+ srgb_converter_.reset(
+ new SRGBConverter(feature_info_.get()));
+ }
+ srgb_converter_->InitializeSRGBEncoder(this);
+ if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR) {
+ return false;
+ }
+ return true;
}
void GLES2DecoderImpl::EnsureRenderbufferBound() {

Powered by Google App Engine
This is Rietveld 408576698