Skip to content

Commit

Permalink
Add UnpremultiplyAndDitherCopyCHROMIUM extension
Browse files Browse the repository at this point in the history
This change adds a new GL command (intended for use via the
RasterInterface) which copies data from a normal-bit-depth (8888)
texture to a low-bit-depth (4444) texture, performing an unpremultiply
and a dither in the process.

This is a pretty special-case extension designed to address the
speicific issues that:
- GPU raster output is currently not dithered, leading to banding in
   some cases
- Dithering premultiplied output does not alleviate all banding.
- Storing premultiplied ouptut in 4444 textures can lead to artifacts
   even if dithered.

This extension will be used when Chrome rasterizes to 4444 textures on
low-end devices.

To achieve this behavior, we add a "dither" parameter to the
CopyTextureCHROMIUMResourceManager, allowing it to perform a dither
while copying. The new extension leverages this existing class.

The actual dither code is the same logic used internally in Skia, and
has been tested there for performance. The only difference is that in
our case we dither alpha as well.

Bug: 789153
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;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
Change-Id: Ibce954f90eb7c461e127c5eb8bcf3ad9799bfe20
Reviewed-on: https://chromium-review.googlesource.com/899664
Commit-Queue: Eric Karl <ericrk@chromium.org>
Reviewed-by: Will Harris <wfh@chromium.org>
Reviewed-by: Antoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537884}
  • Loading branch information
Eric Karl authored and Commit Bot committed Feb 20, 2018
1 parent 729d39e commit 0d482c5
Show file tree
Hide file tree
Showing 43 changed files with 996 additions and 139 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
Name

CHROMIUM_unpremultiply_and_dither_copy

Name Strings

GL_CHROMIUM_unpremultiply_and_dither_copy

Version

Last Modifed Date: Feb 01, 2018

Dependencies

OpenGL ES 2.0 or OpenGL ES 3.0 is required.

EXT_texture_format_BGRA8888 affects the definition of this extension.

Overview

This extension performs a copy from one texture to a second texture,
unpremultiplying and dithering the texture in the process. Additionally,
it allows a subrect to be specified for the copy.

Both textures:
- Must be the same size
- Have the same subrect

The source texture:
- Must be RGBA. If EXT_texture_format_BGRA8888 or GLES3 is available,
the texture may be BGRA
- Will have data copied from level 0

The dest texture:
- Must be RGBA
- Must have type GL_UNSIGNED_SHORT_4_4_4_4
- Will have data copied to level 0

In addition to the above, this extension inherits all source/dest
limitations from CHROMIUM_copy_texture.

New Procedures and Functions

void UnpremultiplyAndDitherCopyCHROMIUM(uint sourceId,
uint destId,
int x,
int y,
sizei width,
sizei height)

Additions to the OpenGL ES 2.0 Specification

The command

UnpremultiplyAndDitherCopyCHROMIUM

Copies the contents of level 0 of <sourceId> texture to level 0 and of
<destId> texture, performing an unpremultiply and dither during the copy.

<destId> must be initialized and have:
- a target of TEXTURE_2D, TEXTURE_RECTANGLE_ARB.
- a format of GL_RGBA, or GL_BGRA if EXT_texture_format_BGRA8888
or GLES3 is available.
- a data type of GL_UNSIGNED_SHORT_4_4_4_4.

<sourceId> must be initialized and have:
- a target of TEXTURE_2D, TEXTURE_RECTANGLE_ARB, TEXTURE_EXTERNAL_OES.
- a format of GL_RGBA, or GL_BGRA if EXT_texture_format_BGRA8888
or GLES3 is available.

INVALID_OPERATION is generated if any of the above requirements is not met,
or if the source / dest combination violates any requirements of
CHROMIUM_copy_texture.

Errors

None.

New Tokens

None.

New State

None.

Revision History

02/01/2018 Documented the extension
2 changes: 2 additions & 0 deletions gpu/GLES2/gl2chromium_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@
GLES2_GET_FUN(GenUnverifiedSyncTokenCHROMIUM)
#define glVerifySyncTokensCHROMIUM GLES2_GET_FUN(VerifySyncTokensCHROMIUM)
#define glWaitSyncTokenCHROMIUM GLES2_GET_FUN(WaitSyncTokenCHROMIUM)
#define glUnpremultiplyAndDitherCopyCHROMIUM \
GLES2_GET_FUN(UnpremultiplyAndDitherCopyCHROMIUM)
#define glDrawBuffersEXT GLES2_GET_FUN(DrawBuffersEXT)
#define glDiscardBackbufferCHROMIUM GLES2_GET_FUN(DiscardBackbufferCHROMIUM)
#define glScheduleOverlayPlaneCHROMIUM \
Expand Down
22 changes: 22 additions & 0 deletions gpu/GLES2/gl2extchromium.h
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,28 @@ typedef void(GL_APIENTRYP PFNGLSETCOLORSPACEMETADATACHROMIUM)(
GLColorSpace color_space);
#endif /* GL_CHROMIUM_color_space_metadata */

/* GL_CHROMIUM_dither_and_premultiply_copy */
#ifndef GL_CHROMIUM_unpremultiply_and_dither_copy
#define GL_CHROMIUM_unpremultiply_and_dither_copy 1

#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY
glUnpremultiplyAndDitherCopyCHROMIUM(GLenum source_id,
GLenum dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height);
#endif
typedef void(GL_APIENTRYP PFNGLUNPREMULTIPLYANDDITHERCOPYCHROMIUMPROC)(
GLenum source_id,
GLenum dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height);
#endif /* GL_CHROMIUM_unpremultiply_and_dither_copy */

#ifdef __cplusplus
}
#endif
Expand Down
10 changes: 10 additions & 0 deletions gpu/command_buffer/build_gles2_cmd_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4636,6 +4636,16 @@
'extension': 'CHROMIUM_gpu_fence',
'extension_flag': 'chromium_gpu_fence',
},
'UnpremultiplyAndDitherCopyCHROMIUM': {
'decoder_func': 'DoUnpremultiplyAndDitherCopyCHROMIUM',
'cmd_args': 'GLuint source_id, GLuint dest_id, GLint x, GLint y, '
'GLsizei width, GLsizei height',
'client_test': False,
'unit_test': False,
'impl_func': True,
'extension': 'CHROMIUM_unpremultiply_and_dither_copy',
'extension_flag': 'unpremultiply_and_dither_copy',
}
}


Expand Down
10 changes: 10 additions & 0 deletions gpu/command_buffer/build_raster_cmd_buffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,16 @@
'unit_test': False,
'extension': True,
},
'UnpremultiplyAndDitherCopyCHROMIUM': {
'decoder_func': 'DoUnpremultiplyAndDitherCopyCHROMIUM',
'cmd_args': 'GLuint source_id, GLuint dest_id, GLint x, GLint y, '
'GLsizei width, GLsizei height',
'client_test': False,
'unit_test': False,
'impl_func': True,
'extension': 'CHROMIUM_unpremultiply_and_dither_copy',
'extension_flag': 'unpremultiply_and_dither_copy',
}
}


Expand Down
14 changes: 14 additions & 0 deletions gpu/command_buffer/client/gles2_c_lib_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,15 @@ void GL_APIENTRY GLES2VerifySyncTokensCHROMIUM(GLbyte** sync_tokens,
void GL_APIENTRY GLES2WaitSyncTokenCHROMIUM(const GLbyte* sync_token) {
gles2::GetGLContext()->WaitSyncTokenCHROMIUM(sync_token);
}
void GL_APIENTRY GLES2UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) {
gles2::GetGLContext()->UnpremultiplyAndDitherCopyCHROMIUM(
source_id, dest_id, x, y, width, height);
}
void GL_APIENTRY GLES2DrawBuffersEXT(GLsizei count, const GLenum* bufs) {
gles2::GetGLContext()->DrawBuffersEXT(count, bufs);
}
Expand Down Expand Up @@ -2909,6 +2918,11 @@ extern const NameToFunc g_gles2_function_table[] = {
"glWaitSyncTokenCHROMIUM",
reinterpret_cast<GLES2FunctionPointer>(glWaitSyncTokenCHROMIUM),
},
{
"glUnpremultiplyAndDitherCopyCHROMIUM",
reinterpret_cast<GLES2FunctionPointer>(
glUnpremultiplyAndDitherCopyCHROMIUM),
},
{
"glDrawBuffersEXT",
reinterpret_cast<GLES2FunctionPointer>(glDrawBuffersEXT),
Expand Down
13 changes: 13 additions & 0 deletions gpu/command_buffer/client/gles2_cmd_helper_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -2701,6 +2701,19 @@ void WaitSyncTokenCHROMIUM(GLint namespace_id,
}
}

void UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) {
gles2::cmds::UnpremultiplyAndDitherCopyCHROMIUM* c =
GetCmdSpace<gles2::cmds::UnpremultiplyAndDitherCopyCHROMIUM>();
if (c) {
c->Init(source_id, dest_id, x, y, width, height);
}
}

void DrawBuffersEXTImmediate(GLsizei count, const GLenum* bufs) {
const uint32_t size =
gles2::cmds::DrawBuffersEXTImmediate::ComputeSize(count);
Expand Down
7 changes: 7 additions & 0 deletions gpu/command_buffer/client/gles2_implementation_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,13 @@ void VerifySyncTokensCHROMIUM(GLbyte** sync_tokens, GLsizei count) override;

void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override;

void UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) override;

void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;

void DiscardBackbufferCHROMIUM() override;
Expand Down
26 changes: 26 additions & 0 deletions gpu/command_buffer/client/gles2_implementation_impl_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -3249,6 +3249,32 @@ void GLES2Implementation::LoseContextCHROMIUM(GLenum current, GLenum other) {
CheckGLError();
}

void GLES2Implementation::UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix()
<< "] glUnpremultiplyAndDitherCopyCHROMIUM(" << source_id
<< ", " << dest_id << ", " << x << ", " << y << ", "
<< width << ", " << height << ")");
if (width < 0) {
SetGLError(GL_INVALID_VALUE, "glUnpremultiplyAndDitherCopyCHROMIUM",
"width < 0");
return;
}
if (height < 0) {
SetGLError(GL_INVALID_VALUE, "glUnpremultiplyAndDitherCopyCHROMIUM",
"height < 0");
return;
}
helper_->UnpremultiplyAndDitherCopyCHROMIUM(source_id, dest_id, x, y, width,
height);
CheckGLError();
}

void GLES2Implementation::DrawBuffersEXT(GLsizei count, const GLenum* bufs) {
GPU_CLIENT_SINGLE_THREAD_CHECK();
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDrawBuffersEXT(" << count << ", "
Expand Down
6 changes: 6 additions & 0 deletions gpu/command_buffer/client/gles2_interface_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,12 @@ virtual void GenSyncTokenCHROMIUM(GLbyte* sync_token) = 0;
virtual void GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) = 0;
virtual void VerifySyncTokensCHROMIUM(GLbyte** sync_tokens, GLsizei count) = 0;
virtual void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) = 0;
virtual void UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) = 0;
virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) = 0;
virtual void DiscardBackbufferCHROMIUM() = 0;
virtual void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
Expand Down
6 changes: 6 additions & 0 deletions gpu/command_buffer/client/gles2_interface_stub_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,12 @@ void GenSyncTokenCHROMIUM(GLbyte* sync_token) override;
void GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) override;
void VerifySyncTokensCHROMIUM(GLbyte** sync_tokens, GLsizei count) override;
void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override;
void UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) override;
void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;
void DiscardBackbufferCHROMIUM() override;
void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
Expand Down
7 changes: 7 additions & 0 deletions gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,13 @@ void GLES2InterfaceStub::VerifySyncTokensCHROMIUM(GLbyte** /* sync_tokens */,
GLsizei /* count */) {}
void GLES2InterfaceStub::WaitSyncTokenCHROMIUM(const GLbyte* /* sync_token */) {
}
void GLES2InterfaceStub::UnpremultiplyAndDitherCopyCHROMIUM(
GLuint /* source_id */,
GLuint /* dest_id */,
GLint /* x */,
GLint /* y */,
GLsizei /* width */,
GLsizei /* height */) {}
void GLES2InterfaceStub::DrawBuffersEXT(GLsizei /* count */,
const GLenum* /* bufs */) {}
void GLES2InterfaceStub::DiscardBackbufferCHROMIUM() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,12 @@ void GenSyncTokenCHROMIUM(GLbyte* sync_token) override;
void GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) override;
void VerifySyncTokensCHROMIUM(GLbyte** sync_tokens, GLsizei count) override;
void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override;
void UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) override;
void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;
void DiscardBackbufferCHROMIUM() override;
void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2105,6 +2105,19 @@ void GLES2TraceImplementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) {
gl_->WaitSyncTokenCHROMIUM(sync_token);
}

void GLES2TraceImplementation::UnpremultiplyAndDitherCopyCHROMIUM(
GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) {
TRACE_EVENT_BINARY_EFFICIENT0(
"gpu", "GLES2Trace::UnpremultiplyAndDitherCopyCHROMIUM");
gl_->UnpremultiplyAndDitherCopyCHROMIUM(source_id, dest_id, x, y, width,
height);
}

void GLES2TraceImplementation::DrawBuffersEXT(GLsizei count,
const GLenum* bufs) {
TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DrawBuffersEXT");
Expand Down
11 changes: 11 additions & 0 deletions gpu/command_buffer/client/raster_implementation_gles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,17 @@ void RasterImplementationGLES::CompressedTexImage2D(GLenum target,
border, imageSize, data);
}

void RasterImplementationGLES::UnpremultiplyAndDitherCopyCHROMIUM(
GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) {
gl_->UnpremultiplyAndDitherCopyCHROMIUM(source_id, dest_id, x, y, width,
height);
}

void RasterImplementationGLES::TexStorageForRaster(
GLenum target,
viz::ResourceFormat format,
Expand Down
6 changes: 6 additions & 0 deletions gpu/command_buffer/client/raster_implementation_gles.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ class RASTER_EXPORT RasterImplementationGLES : public RasterInterface {
GLboolean unpack_premultiply_alpha,
GLboolean unpack_unmultiply_alpha) override;
void CompressedCopyTextureCHROMIUM(GLuint source_id, GLuint dest_id) override;
void UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) override;

// Discardable textures.
void InitializeDiscardableTextureCHROMIUM(GLuint texture_id) override;
Expand Down
6 changes: 6 additions & 0 deletions gpu/command_buffer/client/raster_interface_autogen.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ virtual void GenSyncTokenCHROMIUM(GLbyte* sync_token) = 0;
virtual void GenUnverifiedSyncTokenCHROMIUM(GLbyte* sync_token) = 0;
virtual void VerifySyncTokensCHROMIUM(GLbyte** sync_tokens, GLsizei count) = 0;
virtual void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) = 0;
virtual void UnpremultiplyAndDitherCopyCHROMIUM(GLuint source_id,
GLuint dest_id,
GLint x,
GLint y,
GLsizei width,
GLsizei height) = 0;
virtual GLenum GetGraphicsResetStatusKHR() = 0;
virtual void InitializeDiscardableTextureCHROMIUM(GLuint texture_id) = 0;
virtual void UnlockDiscardableTextureCHROMIUM(GLuint texture_id) = 0;
Expand Down
2 changes: 2 additions & 0 deletions gpu/command_buffer/common/capabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ struct GPU_EXPORT Capabilities {

bool chromium_gpu_fence = false;

bool unpremultiply_and_dither_copy = false;

int major_version = 2;
int minor_version = 0;

Expand Down
Loading

0 comments on commit 0d482c5

Please sign in to comment.