Commit fd79169d authored by yunchao.he's avatar yunchao.he Committed by Commit bot

[Command Buffer] emulate SRGB color format for BlitFramebuffer in OpenGL.

In Desktop OGLs whose version < 4.4, they maybe don't enable srgb conversion
between srgb color format and linear color format. This change can emulate
srgb and do the conversion for machines with these OGL profiles.

BUG=634525
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel

Review-Url: https://codereview.chromium.org/2286593002
Cr-Commit-Position: refs/heads/master@{#419396}
parent 8aa28163
......@@ -181,38 +181,14 @@ class WebGL2ConformanceExpectations(WebGLConformanceExpectations):
self.Fail('deqp/functional/gles3/fbomultisample*',
['mac', 'nvidia'], bug=641209)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_04.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_07.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_08.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_10.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_11.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_12.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_13.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_18.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_25.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_28.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_29.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_30.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_31.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_32.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_33.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_34.html',
['mac'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/' +
'default_framebuffer_*.html',
['mac'], bug=483282)
......@@ -232,6 +208,32 @@ class WebGL2ConformanceExpectations(WebGLConformanceExpectations):
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('conformance2/textures/misc/tex-input-validation.html',
['mac', ('nvidia', 0xfe9), 'no_angle'], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_04.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_07.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_08.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_10.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_11.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_12.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_13.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_18.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_25.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_29.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_32.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_34.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/pixelbufferobject.html',
['mac', ('nvidia', 0xfe9)], bug=483282)
self.Fail('deqp/functional/gles3/negativevertexarrayapi.html',
......@@ -500,38 +502,6 @@ class WebGL2ConformanceExpectations(WebGLConformanceExpectations):
# The Intel Mesa driver only supports sRGB encoding in ES 3.x, see
# https://patchwork.freedesktop.org/patch/76903
# So these tests fail on core profile.
self.Fail('deqp/functional/gles3/framebufferblit/conversion_04.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_07.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_08.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_10.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_11.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_12.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_13.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_18.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_25.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_28.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_29.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_30.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_31.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_32.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_33.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/conversion_34.html',
['linux', 'intel'], bug=598902)
self.Fail('deqp/functional/gles3/framebufferblit/' +
'default_framebuffer_00.html',
['linux', 'intel'], bug=598902)
......
......@@ -77,6 +77,8 @@ target(link_target_type, "service_sources") {
"gles2_cmd_decoder_passthrough_doers.cc",
"gles2_cmd_decoder_passthrough_handlers.cc",
"gles2_cmd_decoder_passthrough_handlers_autogen.cc",
"gles2_cmd_srgb_converter.cc",
"gles2_cmd_srgb_converter.h",
"gles2_cmd_validation.cc",
"gles2_cmd_validation.h",
"gles2_cmd_validation_autogen.h",
......
......@@ -41,7 +41,7 @@ void CopyTexImageResourceManager::Initialize(
blit_program_ = glCreateProgram();
// Compile the fragment shader
// Compile the vertex shader
const char* vs_source =
"#version 150\n"
"out vec2 v_texcoord;\n"
......@@ -69,7 +69,7 @@ void CopyTexImageResourceManager::Initialize(
glAttachShader(blit_program_, vs);
glDeleteShader(vs);
// Compile the vertex shader
// Compile the fragment shader
const char* fs_source =
"#version 150\n"
"uniform sampler2D u_source_texture;\n"
......
......@@ -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"
......@@ -813,10 +814,14 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
// or regular back buffer).
gfx::Size GetBoundReadFramebufferSize();
// Get the service side ID for the bound read frame buffer.
// Get the service side ID for the bound read framebuffer.
// If it's back buffer, 0 is returned.
GLuint GetBoundReadFramebufferServiceId();
// Get the service side ID for the bound draw framebuffer.
// If it's back buffer, 0 is returned.
GLuint GetBoundDrawFramebufferServiceId();
// Get the format/type of the currently bound frame buffer (either FBO or
// regular back buffer).
// If the color image is a renderbuffer, returns 0 for type.
......@@ -2060,6 +2065,7 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
bool InitializeCopyTexImageBlitter(const char* function_name);
bool InitializeCopyTextureCHROMIUM(const char* function_name);
bool InitializeSRGBConverter(const char* function_name);
// Generate a member function prototype for each command in an automated and
// typesafe way.
#define GLES2_CMD_OP(name) \
......@@ -2252,6 +2258,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.
......@@ -4236,14 +4243,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;
}
......@@ -4309,6 +4308,21 @@ GLuint GLES2DecoderImpl::GetBoundReadFramebufferServiceId() {
return 0;
}
GLuint GLES2DecoderImpl::GetBoundDrawFramebufferServiceId() {
Framebuffer* framebuffer =
GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
if (framebuffer) {
return framebuffer->service_id();
}
if (offscreen_target_frame_buffer_.get()) {
return offscreen_target_frame_buffer_->id();
}
if (surface_.get()) {
return surface_->GetBackingFramebufferObject();
}
return 0;
}
GLenum GLES2DecoderImpl::GetBoundReadFramebufferTextureType() {
Framebuffer* framebuffer =
GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
......@@ -4545,6 +4559,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()) {
......@@ -4642,6 +4661,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()) {
......@@ -7595,12 +7615,17 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
}
}
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) {
......@@ -7610,7 +7635,7 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
}
GLenum src_sized_format =
GLES2Util::ConvertToSizedFormat(src_format, src_type);
GLES2Util::ConvertToSizedFormat(src_internal_format, src_type);
DCHECK(read_framebuffer || (is_feedback_loop != FeedbackLoopUnknown));
const Framebuffer::Attachment* read_buffer =
is_feedback_loop == FeedbackLoopUnknown ?
......@@ -7621,6 +7646,8 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
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))) {
......@@ -7676,11 +7703,65 @@ 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) &&
((mask & GL_COLOR_BUFFER_BIT) != 0);
bool encode_srgb_only =
(draw_buffers_has_srgb && !read_buffer_has_srgb) &&
((mask & GL_COLOR_BUFFER_BIT) != 0);
// TODO(yunchao) Need to revisit here if the read buffer is a multi-sampled
// renderbuffer.
if (!enable_srgb ||
read_buffer_samples > 0 ||
!feature_info_->feature_flags().desktop_srgb_support ||
gl_version_info().IsAtLeastGL(4, 4) ||
(gl_version_info().IsAtLeastGL(4, 2) && encode_srgb_only)) {
if (enable_srgb && gl_version_info().IsAtLeastGL(4, 2)) {
state_.EnableDisableFramebufferSRGB(enable_srgb);
}
// TODO(yunchao) Need to revisit here. In GLES spec, blitFramebuffer
// should do scissor test per fragment operation.
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 images.
// The others are not.
state_.EnableDisableFramebufferSRGB(true);
if (!InitializeSRGBConverter(func_name)) {
return;
}
GLenum src_format =
TextureManager::ExtractFormatFromStorageFormat(src_internal_format);
srgb_converter_->Blit(this, srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1,
mask, filter,
GetBoundReadFramebufferSize(),
GetBoundReadFramebufferServiceId(),
src_internal_format, src_format, src_type,
GetBoundDrawFramebufferServiceId(),
read_buffer_has_srgb, draw_buffers_has_srgb);
}
bool GLES2DecoderImpl::InitializeSRGBConverter(
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_->InitializeSRGBConverter(this);
if (LOCAL_PEEK_GL_ERROR(function_name) != GL_NO_ERROR) {
return false;
}
}
return true;
}
void GLES2DecoderImpl::EnsureRenderbufferBound() {
......
This diff is collapsed.
// Copyright (c) 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_SRGB_CONVERTER_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_SRGB_CONVERTER_H_
#include <array>
#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/gpu_export.h"
namespace gpu {
namespace gles2 {
class GLES2Decoder;
// This class encapsulates the resources required to implement the
// glBlitFramebuffer command, which somtimes requires to convert sRGB
// to linear (RGBA) color format, or vice versa.
class GPU_EXPORT SRGBConverter {
public:
explicit SRGBConverter(const gles2::FeatureInfo* feature_info);
~SRGBConverter();
void InitializeSRGBConverter(const gles2::GLES2Decoder* decoder);
void Destroy();
void Blit(
const gles2::GLES2Decoder* decoder,
GLint srcX0,
GLint srcY0,
GLint srcX1,
GLint srcY1,
GLint dstX0,
GLint dstY0,
GLint dstX1,
GLint dstY1,
GLbitfield mask,
GLenum filter,
const gfx::Size& framebuffer_size,
GLuint src_framebuffer,
GLenum src_framebuffer_internal_format,
GLenum src_framebuffer_format,
GLenum src_framebuffer_type,
GLuint dst_framebuffer,
bool decode,
bool encode);
private:
void InitializeSRGBConverterProgram();
scoped_refptr<const gles2::FeatureInfo> feature_info_;
bool srgb_converter_initialized_ = false;
GLuint srgb_converter_program_ = 0;
std::array<GLuint, 2> srgb_converter_textures_ = {{0, 0}};
GLuint srgb_decoder_fbo_ = 0;
GLuint srgb_encoder_fbo_ = 0;
GLuint srgb_converter_vao_ = 0;
DISALLOW_COPY_AND_ASSIGN(SRGBConverter);
};
} // namespace gles2.
} // namespace gpu.
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_SRGB_CONVERTER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment