This is fixed in Skia by passing the appropriate flag when the shader is
generated. The fix in HWUI is to reverse the premultiplication and
interpolation steps.
Test: bit CtsUiRenderingTestCases:.testclasses.ShaderTests
Bug: 34323783
Change-Id: I3417141949f62fcc696b6d8213a4b446d7d0cbf8
Frankengradients (linearly interpolated RGB, gamma interpolated alpha) look
fantastic but unfortunately create sligh compatibility issues. For instance,
a gradient from 0xffea1030 to 0x00ea1030 (opaque to alpha, with a single
color) blended on top of 0xff101010 would not look the same as a single
opaque gradient from 0xffea1030 to 0xff101010. The difference is hardly
noticeable on simple gradients but it could cause confusion amongst app
developers. Their life is hard enough as it is, let's be good to them.
My crusade against the gamma world is not over and one day I shall
be the victor. I am patience.
Bug: 35485208
Test: UiRendering.ShaderTests, UiRendering.GradientTests, manual testing
Change-Id: I8204e60cdf0a6b12dfe22638d30ca9622687000e
This is the first step toward interpreting color spaces at render time.
Bug: 32984164
Test: BitmapColorSpaceTest in CtsGraphicsTestCases
Change-Id: I0164a18f1ed74a745874fe5229168042afe27a04
As of O, gradients are interpolated in linear space. This unfortunately
affects applications that were expecting a certain behavior for the
alpha ramp. This change attempts to get the best of both world: better
color interpolation (in linear space) and the old alpha interpolation
(in gamma space). This is achieved by applying the electro-optical
transfer function to the alpha channel; an idea so wrong it would
make any graphics programmer worth his salt weep in disgust.
As abhorrent this idea might be to me, it also acts as a faint
beacon of hope admist the unfathomable darkness that is Android's
color management.
And if you allow me another misguided metaphor, this change
represents the flotsam I can cling onto in the hope to one day
reach the bountiful shores of linear blending and accurate color
management. Would this change not fix the distress caused by its
predecessors, I will have no choice but bow my head in shame until
the day I can finally devise an infallible plan.
Bug: 33010587
Test: CtsUiRenderingTestCases
Change-Id: I5397fefd7944413f2c820e613a5cba50579d4dd5
Alpha pre-multiplication must be done after applying the
opto-electronic transfer function when linear blending is
disabled. The correct way would be to pre-multiply before
gamma encoding but this leads to improper blending which
cannot be corrected without using sRGB frame buffers and
texture sampling.
Bug: 33010587
Test: cts-tradefed run singleCommand cts-dev --module CtsUiRenderingTestCases --test android.uirendering.cts.testclasses.GradientTests
Change-Id: I5f04bda4cb9f63674537aef5931621c14d601884
With linear blending turned off some textures were still
created as sRGB textures instead of linear textures.
Multi-stop gradients were not behaving properly on devices
with no support for float textures.
Gradients are now always interpolated in linear space
even if linear blending is off.
New functions to always force sRGB->linear->sRGB conversions.
Test: Manual testing
Bug: 29940137
Change-Id: Ie2f84ee2a65fd85570e88af813e841e0e625df6c
NOTE: Linear blending is currently disabled in this CL as the
feature is still a work in progress
Android currently performs all blending (any kind of linear math
on colors really) on gamma-encoded colors. Since Android assumes
that the default color space is sRGB, all bitmaps and colors
are encoded with the sRGB Opto-Electronic Conversion Function
(OECF, which can be approximated with a power function). Since
the power curve is not linear, our linear math is incorrect.
The result is that we generate colors that tend to be too dark;
this affects blending but also anti-aliasing, gradients, blurs,
etc.
The solution is to convert gamma-encoded colors back to linear
space before doing any math on them, using the sRGB Electo-Optical
Conversion Function (EOCF). This is achieved in different
ways in different parts of the pipeline:
- Using hardware conversions when sampling from OpenGL textures
or writing into OpenGL frame buffers
- Using software conversion functions, to translate app-supplied
colors to and from sRGB
- Using Skia's color spaces
Any type of processing on colors must roughly ollow these steps:
[sRGB input]->EOCF->[linear data]->[processing]->OECF->[sRGB output]
For the sRGB color space, the conversion functions are defined as
follows:
OECF(linear) :=
linear <= 0.0031308 ? linear * 12.92 : (pow(linear, 1/2.4) * 1.055) - 0.055
EOCF(srgb) :=
srgb <= 0.04045 ? srgb / 12.92 : pow((srgb + 0.055) / 1.055, 2.4)
The EOCF is simply the reciprocal of the OECF.
While it is highly recommended to use the exact sRGB conversion
functions everywhere possible, it is sometimes useful or beneficial
to rely on approximations:
- pow(x,2.2) and pow(x,1/2.2)
- x^2 and sqrt(x)
The latter is particularly useful in fragment shaders (for instance
to apply dithering in sRGB space), especially if the sqrt() can be
replaced with an inversesqrt().
Here is a fairly exhaustive list of modifications implemented
in this CL:
- Set TARGET_ENABLE_LINEAR_BLENDING := false in BoardConfig.mk
to disable linear blending. This is only for GLES 2.0 GPUs
with no hardware sRGB support. This flag is currently assumed
to be false (see note above)
- sRGB writes are disabled when entering a functor (WebView).
This will need to be fixed at some point
- Skia bitmaps are created with the sRGB color space
- Bitmaps using a 565 config are expanded to 888
- Linear blending is disabled when entering a functor
- External textures are not properly sampled (see below)
- Gradients are interpolated in linear space
- Texture-based dithering was replaced with analytical dithering
- Dithering is done in the quantization color space, which is
why we must do EOCF(OECF(color)+dither)
- Text is now gamma corrected differently depending on the luminance
of the source pixel. The asumption is that a bright pixel will be
blended on a dark background and the other way around. The source
alpha is gamma corrected to thicken dark on bright and thin
bright on dark to match the intended design of fonts. This also
matches the behavior of popular design/drawing applications
- Removed the asset atlas. It did not contain anything useful and
could not be sampled in sRGB without a yet-to-be-defined GL
extension
- The last column of color matrices is converted to linear space
because its value are added to linear colors
Missing features:
- Resource qualifier?
- Regeneration of goldeng images for automated tests
- Handle alpha8/grey8 properly
- Disable sRGB write for layers with external textures
Test: Manual testing while work in progress
Bug: 29940137
Change-Id: I6a07b15ab49b554377cd33a36b6d9971a15e9a0b
Bug: 26980851
GL_RGBA16F was being incorrectly calculated
as 4 bpp instead of 16 in Texture's objectSize(),
leading to a mismatch in cache size tracking
in GradientCache
Change-Id: I533c52fcdf9910d7a7d14bbd80965b8cbef8e147
bug:17478770
This removes a lot of redundant property query code, and puts the
queries all in one place, so defining them automatically will be simpler
in the future.
Change-Id: I0428550e6081f07bc6554ffdf73b22284325abb8
Several places were setting GL_UNPACK_ALIGNMENT
unneccessarily, whereas other places were assuming an
unpack alignment of 1. Since we never actually
do explicit row-alignment, set GL_UNPACK_ALIGNMENT
to 1 at context creation time and never change it
Bug: 26584230
Also turns on aggressive glGetError checking to
better catch potential problem zones
Change-Id: I190c8f0f0494a7f046d5ed769405c75d363be59a
Adds remaining missing overrides and nullptr usages, missed due to
an extreme failure in tool usage.
Change-Id: I56abd72975a3999ad13330003c348db40f59aebf
This class can be used to perform occlusion queries. An occlusion query
can be used to test whether an object is entirely hidden or not.
Change-Id: Ida456df81dbe008a64d3ff4cb7879340785c6abf
Bug #9316260
The GL specification indicates that deleting a bound texture has
the side effect of binding the default texture (name=0). This change
replaces all calls to glDeleteTextures() by Caches::deleteTexture()
to properly keep track of texture bindings.
Change-Id: Ifbc60ef433e0f9776a668dd5bd5f0adbc65a77a0
Float textures offer better precision for dithering.
In addition this change removes two uniforms from gradient shaders.
These uniforms were used to dither gradients but their value is
a build time constant. Instead we hardcode the value directly in
the shader source at compile time.
Change-Id: I05e9fd3eef93771843bbd91b453274452dfaefee
Bug #7146141
This change is needed to add a render buffer cache to avoid
creating and destroying stencil buffers on every frame.
This change also allows the renderer to use a 1 bit or 4 bit
stencil buffer whenever possible.
Finally this change fixes a bug introduced by a previous CL
which causes the stencil buffer to not be updated in certain
conditions. The fix relies on a new optional parameter in
drawColorRects() that can be used to avoid performing a
quickReject on rectangles generated by the clip region.
Change-Id: I2f55a8e807009887b276a83cde9f53fd5c01199f
Bug #7728929
The uninitialized variable was taken into account to compute
the hash of gradient cache entries, thus causing cache corruptions
and sometimes infinite loops (it would also cause the cache to fill
up.)
Change-Id: Ic807a9bf901888b121a6a781a81dafc33075ed2a
this introduced a dead lock in GradientCache's ctor.
This reverts commit dfe082f63e94cde9aee271c94d13de5e7217e036.
Bug: 7096001
Change-Id: I57b8bbab11fb7cb502fa58e3bbf5d19864db874f
Compute the size of the backing textures based on the maximum possible
number of shades in the gradient.
Change-Id: I2d7f20477d31b81e9735f2c1d83ebdd0dbcbe340
This change sets textures filtering to GL_NEAREST by default. GL_LINEAR
filtering is only used when textures are transformed with a scale or
a rotation. This helps save a couple of fps on some GPUs.
Change-Id: I1efaa452c2c79905f00238e54d886a37203a2ac1
Bug #3179882
Resources were freed following garbage collections on a worker thread.
This worker thread had no EGL context, which would cause the renderer
to incorrectly assume that the memory was liberated.
Change-Id: Ifdb51f94ddf42641e8654522787bfac532976c7c