[OpenJDK 2D-Dev] MaskFill incorrect gamma correction (sRGB != linear RGB)
bourges.laurent at gmail.com
Fri Aug 29 06:39:24 UTC 2014
Could anybody answer my questions ?
I really want to improve java2d rendering quality (gamma, colors...)
Le 20 août 2014 11:05, "Laurent Bourgès" <bourges.laurent at gmail.com> a
> 2014-08-14 22:09 GMT+02:00 Jim Graham <james.graham at oracle.com>:
>> Hi Laurent,
>> Java2D has color correction code in it, but it is only really hooked up
to the specific color correction classes so it pretty much has to be
manually invoked. The rendering pipeline usually punts on issues like
color space other than if you specify an alternate color space for a
BufferedImage then it may classify the image as "Custom" and use a lot of
really slow custom rendering pipelines (as in, "I have no idea how colors
are stored there so let's make method calls per pixel to read and write
> Great, but how are color blended ? I tried the CS_Linear_RGB color space
and it gave me the same 'wrong' image. I suspect that pixels are converted
in sRGB via getRGB() / setRGB() methods that means that color blending
always happen in sRGB !
> If not, could you give me an example with a custom color space ? I would
like to try color blending in the CIE-lch color space.
>> By default it assumes that sRGB is a close enough approximation for any
screen output device and just does pretty straightforward math on the pixel
values and pretends that it is doing it all "in sRGB space". In reality,
it is doing it all in "just computing with the color components" space and
assuming that since the output is a screen then it is essentially "sort of
playing in sRGB space". The assumption works fine for GUI and casual
rendering, but more deliberate treatment of color spaces would really be
needed for things like pre-press.
> Exactly: in my case, I would like to choose between speed of quality
rendering for my image outputs (user defined).
> As there are many rendering hints in Graphics2D (quality over speed), it
could be used to use different color blending approachs.
> Moreover, is there any mean to provide custom java classes to perform the
mask fill or color blending ?
> I hacked the GeneralComposite class (missing alpha coverage values) to
perform mine (slow but more accurate).
> Is it possible to add such feature in JDK9 ?
>> In particular, it does no gamma correction except in the LCD text loops
- those are so finicky when it comes to getting the AA just right in terms
of quality that they really required us to do gamma corrected blending or
the results just wouldn't be readable. But, all other AA rendering (and
alpha rendering) is done just linearly in the space of the component values.
> It means blending in the sRGB color space ?
> I looked a bit at the gamma correction on text but what does mean the
contrast ratio setting (140 by default) ?
> Could you explain me in details ? does it modify the alpha coverage value
> I tried in marlin but it seems to me visually not better.
>> Note that to do the gamma correction for LCD text in the hw accelerated
pipelines we have to read back the screen so that we can convert them into
gamma space and back again. This greatly increases the cost of the
rendering and if we did the same thing for regular shape rendering then
there would be a significant performance hit.
> Ok, slower but accurate: exactly what I want.
> How much slower ? Does it depend on the GPU or API (d3d, opengl ...) ?
> Maybe OpenCL could help for such intensive computing tasks but it is
another story ?
>> I believe that future versions of D3D and OpenGL will eventually support
gamma corrected blending natively, but for now the gamma decorrection on
the destination has to be implemented with manual computations in a
shader. If you combine that with the fact that shaders cannot access the
output pixel then there is no way to do that correction without reading
back from the screen and providing those pixel values as a secondary input
to the shader. Note that you can't simply bind the output surface as an
input texture because neither API allows a texture to be bound as both the
input and output of the same operation - so a readback has to be done.
> It is not obvious to me. I read several web pages describing gamma
correction in D3D or opengl extensions. Maybe GPU drivers are not
supporting them but it seems that in 2014 the API are able to perform sRGB
<=> linear RGB conversions on the fly. If not it is possible to provide a
pixel shader for that purpose.
> To be investigated in depth ...
>> Another possibility is to store all pixel values internally in a linear
sRGB space and to de/re-gamma them as we copy them to the screen, then we
could avoid the readback in most cases at the cost of a single gamma
conversion on the final blit, but that would take a serious overhaul to the
rendering pipelines to accomplish and we haven't even prototyped something
like that. Rendering directly to the screen via "Window.getGraphics()",
though, would need to do the readback for every render operation...
> I think there is two use case:
> - direct rendering: it seems difficult (or to be fixed) to apply sRGB <=>
linear RGB conversions on the fly !
> - image rendering: often the software pipeline is used (antialiasing for
example) and the mask fill / color blending is performed by the software
pipeline (C code): in that case, it seems possible to fix that code to
handle the gamma correction (quality setting).
> If I can create a BufferedImage with Linear RGB, I expect the color
blending to use directly this data format (avoid sRGB conversions). Of
course if the image is drawn on the screen, it will require a conversion to
> I would prefer this last solution as it will provide the best quality
(less conversion errors).
> Ideally color blending should be made using 16bits linear components like
> Anybody has other ideas ? opinions ?
> Laurent Bourgès
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the 2d-dev