[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-2d-dev
Subject:    Re: [OpenJDK 2D-Dev] MaskFill incorrect gamma correction (sRGB != linear RGB)
From:       Laurent_Bourgès <bourges.laurent () gmail ! com>
Date:       2014-08-29 6:39:24
Message-ID: CAKjRUT6pLh_PWpni7s5O_jfbbyBOku1v1f7jPXve9SuCpaBVng () mail ! gmail ! com
[Download RAW message or body]

Hi,

Could anybody answer my questions ?
I really want to improve java2d rendering quality (gamma, colors...)

Laurent

Le 20 août 2014 11:05, "Laurent Bourgès" <bourges.laurent@gmail.com> a
écrit :
>
> Jim,
>
> 2014-08-14 22:09 GMT+02:00 Jim Graham <james.graham@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
them").
>
>
> 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.
(Grrr)
>
>
> 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.
>
>
http://www.geeks3d.com/20101001/tutorial-gamma-correction-a-story-of-linearity/
> http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_sRGB.txt
>
> 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
sRGB.
> 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
scRGB: http://en.wikipedia.org/wiki/ScRGB
>
>
> Anybody has other ideas ? opinions ?
>
> Regards,
> Laurent Bourgès

[Attachment #3 (text/html)]

<p dir="ltr">Hi,</p>
<p dir="ltr">Could anybody answer my questions ?<br>
I really want to improve java2d rendering quality (gamma, colors...)</p>
<p dir="ltr">Laurent</p>
<p dir="ltr">Le 20 août 2014 11:05, &quot;Laurent Bourgès&quot; &lt;<a \
href="mailto:bourges.laurent@gmail.com">bourges.laurent@gmail.com</a>&gt; a écrit \
:<br> &gt;<br>
&gt; Jim,<br>
&gt;<br>
&gt; 2014-08-14 22:09 GMT+02:00 Jim Graham &lt;<a \
href="mailto:james.graham@oracle.com">james.graham@oracle.com</a>&gt;:<br> &gt;<br>
&gt;&gt; Hi Laurent,<br>
&gt;&gt;<br>
&gt;&gt; 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 &quot;Custom&quot; and use a lot of really slow custom rendering pipelines (as in, \
&quot;I have no idea how colors are stored there so let&#39;s make method calls per \
pixel to read and write them&quot;).<br>

&gt;<br>
&gt;<br>
&gt; Great, but how are color blended ? I tried the CS_Linear_RGB color space and it \
gave me the same &#39;wrong&#39; image. I suspect that pixels are converted in sRGB \
via getRGB() / setRGB() methods that means that color blending always happen in sRGB \
!<br>

&gt; 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.<br> &gt;  <br>
&gt;&gt;<br>
&gt;&gt; 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 &quot;in sRGB space&quot;.  In reality, it is \
doing it all in &quot;just computing with the color components&quot; space and \
assuming that since the output is a screen then it is essentially &quot;sort of \
playing in sRGB space&quot;.  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.<br>

&gt;<br>
&gt;<br>
&gt; Exactly: in my case, I would like to choose between speed of quality rendering \
for my image outputs (user defined).<br> &gt; As there are many rendering hints in \
Graphics2D (quality over speed), it could be used to use different color blending \
approachs.<br> &gt;<br>
&gt; Moreover, is there any mean to provide custom java classes to perform the mask \
fill or color blending ? <br> &gt; I hacked the GeneralComposite class (missing alpha \
coverage values) to perform mine (slow but more accurate). <br> &gt; Is it possible \
to add such feature in JDK9 ?<br> &gt;<br>
&gt;&gt; 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&#39;t be readable.  But, all other AA rendering (and alpha rendering) is done \
just linearly in the space of the component values.<br>

&gt;<br>
&gt;<br>
&gt; It means blending in the sRGB color space ?<br>
&gt; I looked a bit at the gamma correction on text but what does mean the contrast \
ratio setting (140 by default) ? <br> &gt; Could you explain me in details ? does it \
modify the alpha coverage value ?<br> &gt; I tried in marlin but it seems to me \
visually not better.<br> &gt;  <br>
&gt;&gt;<br>
&gt;&gt; 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. <br>

&gt;<br>
&gt;<br>
&gt; Ok, slower but accurate: exactly what I want. <br>
&gt; How much slower ? Does it depend on the GPU or API (d3d, opengl ...) ?<br>
&gt; Maybe OpenCL could help for such intensive computing tasks but it is another \
story ? <br> &gt;  <br>
&gt;&gt;<br>
&gt;&gt; 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&#39;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. (Grrr)<br>

&gt;<br>
&gt;<br>
&gt; 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 &lt;=&gt; linear RGB conversions on the fly. \
If not it is possible to provide a pixel shader for that purpose.<br>

&gt;<br>
&gt; <a href="http://www.geeks3d.com/20101001/tutorial-gamma-correction-a-story-of-lin \
earity/">http://www.geeks3d.com/20101001/tutorial-gamma-correction-a-story-of-linearity/</a><br>
 &gt; <a href="http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_sRGB.txt">http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_sRGB.txt</a><br>
 &gt;<br>
&gt; To be investigated in depth ...<br>
&gt;  <br>
&gt;&gt;<br>
&gt;&gt; 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&#39;t even prototyped something like that.  Rendering directly to the screen \
via &quot;Window.getGraphics()&quot;, though, would need to do the readback for every \
render operation...<br>

&gt;<br>
&gt;<br>
&gt; I think there is two use case:<br>
&gt; - direct rendering: it seems difficult (or to be fixed) to apply sRGB &lt;=&gt; \
linear RGB conversions on the fly !<br> &gt; - 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).<br>

&gt;<br>
&gt; 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 sRGB.<br>

&gt; I would prefer this last solution as it will provide the best quality (less \
conversion errors). <br> &gt;<br>
&gt; Ideally color blending should be made using 16bits linear components like scRGB: \
<a href="http://en.wikipedia.org/wiki/ScRGB">http://en.wikipedia.org/wiki/ScRGB</a><br>
 &gt;<br>
&gt;<br>
&gt; Anybody has other ideas ? opinions ?<br>
&gt;<br>
&gt; Regards,<br>
&gt; Laurent Bourgès</p>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic