Skip to main content

java2d Compositing -> OpenGL fragment shaders

5 replies [Last post]
Anonymous

----- Original Message -----
From: "Michele Puccini"
To:
Sent: Wednesday, February 21, 2007 7:41 PM
Subject: java2d Compositing -> OpenGL fragment shaders

A little followup..

the fragment shader code of my previous email was bloody wrong as the docs
say:

"Notice that the fragment shader has no access to the frame buffer. This
implies that operations such as blending occur only after the fragment
shader has run."

The big mistake is that I was thinking of reading the framebuffer contents
with gl_FragColor.. :(

Mmmh.. maybe I could implement my blending by binding a pbuffer object to a
texture (or even a FBO) and then access the dest pixels from there, right ?

But, anyway, the idea of using shaders in the java2d/opengl codepath could
still be valid.

Cheers,

Mik
============================================================================
> ClassX Development Italy Via Francesca, 368/I I-56030 S.M. a Monte (PI) <
> Tel.(+39)-0587-705153 Fax.(+39)-0587-705153 WEB: http://www.classx.it <
============================================================================

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
tarbo
Offline
Joined: 2006-12-18

Michele, you may wish to try turning on OpenGL extension limits in your nVidia Control Panel. I've found that my particular JRE (6.0) acts a little funky when given free reins with extension limits, and it works like a charm when the setting is changed from the default.

I'm not sure it will help in your case, but it doesn't hurt to try.

mikofclassx
Offline
Joined: 2003-07-02

I tried but nothing special happened, at least with my small test code.

Cheers,

Mik.

Chris Campbell

Hi Mik,

On Feb 22, 2007, at 2:11 AM, Michele Puccini wrote:
> A little followup..
>
> the fragment shader code of my previous email was bloody wrong as
> the docs
> say:
>
> "Notice that the fragment shader has no access to the frame buffer.
> This
> implies that operations such as blending occur only after the fragment
> shader has run."
>
> The big mistake is that I was thinking of reading the framebuffer
> contents
> with gl_FragColor.. :(
>

Yep, the fact that you can't access destination pixels is about the
only downside of working with fragment shaders.

> Mmmh.. maybe I could implement my blending by binding a pbuffer
> object to a
> texture (or even a FBO) and then access the dest pixels from there,
> right ?
>

If one really needs access to destination pixels from a fragment
shader, the typical approach is to copy a chunk of the destination
into a texture, and then read that from the shader. This can get
tricky, but it is exactly the technique we use in our LCD-optimzed
text shader for the OGL pipeline, and it works great.

> But, anyway, the idea of using shaders in the java2d/opengl
> codepath could
> still be valid.

Well, this is a timely discussion. As you may already know, our
first use of fragment shaders to accelerate Java 2D operations was in
JDK 6 when I added the fragment shader (mentioned above) that handles
LCD-optimized text on the GPU, currently only for the OGL pipeline.
But that was just the beginning.

In JDK 7-b08, I checked in a chunk of code that uses fragment shaders
to accelerate ConvolveOp, RescaleOp, and LookupOp on the GPU (again,
currently only for the OGL pipeline). You can download b08 today
from jdk7.dev.java.net and give it a try. On your board (Nvidia
GeForce 7600GT), it should scream. You can get a taste by maximizing
Java2Demo and trying out the ImageOps demo (moving the sliders
around). The screen refreshes should happen in a fraction of the
time that they did in JDK 6, all while using close to 0% CPU. I
won't go into more details because I have a blog forthcoming on this
subject, with performance charts and whatnot, but if you're really
curious in the meantime you can read this bug report:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6514990

I've also just checked in code that uses fragment shaders to
accelerate the new LinearGradientPaint and RadialGradientPaint
classes that were added in JDK 6. This should appear in a public JDK
7 build sometime around b09 or b10. There is some chance that we
could backport these fixes to a JDK 6 update release, once they've
been proven in JDK 7 for some time. Again, I'll have a blog entry
that discusses this work, but in the meantime:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6521533

There are still more operations that we plan to accelerate via
fragment shaders in the OGL pipeline, so stay tuned. Also, although
I've mentioned that these ops are currently only accelerated via the
OGL pipeline, there is work being done to completely rework the D3D
pipeline on Windows so that it shares a lot of the same code and
structure of the OGL pipeline. I'm hoping that these shader-based
optimizations should be portable to the new D3D pipeline when it's
ready.

Anyway, back to your original question about using shaders to
accelerate premultiplication. As you've found, it can be quite
complicated, but really it's only applicable in a very small set of
situations. In most cases, incoming pixel data is already in a
premultiplied format, so there's nothing special we have to do in the
OGL pipeline. The only case where we convert in software is when
rendering a non-premultiplied TYPE_INT_ARGB or similar image, but
this conversion step rarely is a problem for performance. What would
have helped in this case was 3Dlabs proposal for programmable pixel
packing/unpacking, in which case we could convert from non-premult
data to premult data on-the-fly using OpenGL, but that never saw the
light of day.

But again, for most cases this isn't a concern. If your image can be
"managed" by Java 2D, then you only incur the conversion once when
the BufferedImage is cached as a (premultiplied) OpenGL texture.
Unless you really need to use TYPE_INT_ARGB images, I'd recommend (as
always) to use createCompatibleImage() to construct your images, as
this is guaranteed to return the fastest image type for the
particular screen/pipeline. For the OGL pipeline, this will return a
premultiplied image format, which means you will avoid the minor
conversions described above.

BTW:
> That's probably because the Porter and Duff compositing rules "work
> better" with premultiplied data ;)

It's not just "work better"; premultiplied data is a requirement for
making the math work out correctly.

I'll send an email to the list once those blog entries are published.

Thanks,
Chris

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Michele Puccini

Hi Chris,

that's fantastic news indeed. I'll check the new jdk7 as soon as b10 is
released.

While waiting for your blogs, I have a story for you.

Some time ago I was forced to use LWJGL in order to write an
OpenGL/Graphics2D wrapper (not as complete as the real thing, but it works
very well for images, clipping, some kind of vectors). That's why when I
started with the java2d-ogl it was "too fresh" to be stable and fast. It was
jdk 1.4.x time, if I don't mistake.

Then time passed and now we have jdk6 (and this is GOOD). Sadly all my
experiments to update my code in order to take advantage of the new
jav2d-ogl failed again because of the number of crashes or unexpected
behaviors experienced even with very simple test code.

Driver issues, one might say. Bad test code ? Not likely, maybe... But it's
all very discouraging for me.

By the time I'm writing this email I'm also testing some
"deeply-raw-five-min-dev-time" code in order to see how the jav2d-ogl
impacts the speed of antialiased drawLine()s.

- The test itself hangs on jdk6 but runs on jdk5.
- I see no speed increases by turning on/off opengl.
- I usually get a crash in NVOpenGLPbuffer on jdk6 when resizing the jframe.

Other problem: when I turn on "sun.java2d.opengl" also the gui becomes
accelerated, but this could also be the source of repaint problems and other
odd driver/config dependent issues. Result: I can't ship my apps with opengl
enabled by default. I would opt for the possibility to have the choiche to
not accelerate Swing.

So, jav2d-ogl is a wicked good idea. We all wanted it. But.. how can I make
real-world use of it ?

Cheers,

Mik
============================================================================
> ClassX Development Italy Via Francesca, 368/I I-56030 S.M. a Monte (PI) <
> Tel.(+39)-0587-705153 Fax.(+39)-0587-705153 WEB: http://www.classx.it <
============================================================================

----- Original Message -----
From: "Chris Campbell"
To:
Sent: Thursday, February 22, 2007 6:46 PM
Subject: Re: [JAVA2D] java2d Compositing -> OpenGL fragment shaders

> Hi Mik,
>
> On Feb 22, 2007, at 2:11 AM, Michele Puccini wrote:
>> A little followup..
>>

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Chris Campbell

Hi Mik,

All I can do is reiterate what I've said before... Our OGL pipeline
is only as good as the underlying drivers. We've done a ton of work
with Nvidia and ATI to get them to fix the remaining driver bugs, and
those efforts have been mostly successful. Lately we've been waiting
on both companies to release new drivers that contain fixes for some
really annoying crash/artifact bugs that cropped up recently. Both
Nvidia and ATI have a large testsuite that exercises Java 2D's OGL
pipeline, and this has helped prevent driver regression bugs, but
unfortunately it hasn't completely eliminated the problem. All we
can do is continue to keep the pressure on those companies so that
they don't release buggy drivers.

Please, if you've seen any bugs or performance issues in the OGL
pipeline, even if you think they're just driver bugs (and they
probably are), submit a bug report! Don't assume that we already
know about the problem! We can't fix problems that we don't know
about! And be as specific as possible about the problem (OS,
graphics board(s), exact driver version(s)) and include a testcase.

We all want developers to be able to consistently rely on the OGL
pipeline; the only way to get there is for developers like yourself
to help us stamp out the remaining bugs and keep the graphics vendors
on their toes.

Chris

On Feb 23, 2007, at 2:22 AM, Michele Puccini wrote:
> Hi Chris,
>
> that's fantastic news indeed. I'll check the new jdk7 as soon as
> b10 is released.
>
> While waiting for your blogs, I have a story for you.
>
> Some time ago I was forced to use LWJGL in order to write an OpenGL/
> Graphics2D wrapper (not as complete as the real thing, but it works
> very well for images, clipping, some kind of vectors). That's why
> when I started with the java2d-ogl it was "too fresh" to be stable
> and fast. It was jdk 1.4.x time, if I don't mistake.
>
> Then time passed and now we have jdk6 (and this is GOOD). Sadly all
> my experiments to update my code in order to take advantage of the
> new jav2d-ogl failed again because of the number of crashes or
> unexpected behaviors experienced even with very simple test code.
>
> Driver issues, one might say. Bad test code ? Not likely, maybe...
> But it's all very discouraging for me.
>
> By the time I'm writing this email I'm also testing some "deeply-
> raw-five-min-dev-time" code in order to see how the jav2d-ogl
> impacts the speed of antialiased drawLine()s.
>
> - The test itself hangs on jdk6 but runs on jdk5.
> - I see no speed increases by turning on/off opengl.
> - I usually get a crash in NVOpenGLPbuffer on jdk6 when resizing
> the jframe.
>
> Other problem: when I turn on "sun.java2d.opengl" also the gui
> becomes accelerated, but this could also be the source of repaint
> problems and other odd driver/config dependent issues. Result: I
> can't ship my apps with opengl enabled by default. I would opt for
> the possibility to have the choiche to not accelerate Swing.
>
> So, jav2d-ogl is a wicked good idea. We all wanted it. But.. how
> can I make real-world use of it ?
>
> Cheers,
>
> Mik
> ======================================================================
> ======
>> ClassX Development Italy Via Francesca, 368/I I-56030 S.M. a
>> Monte (PI) <
>> Tel.(+39)-0587-705153 Fax.(+39)-0587-705153 WEB: http://
>> www.classx.it <
> ======================================================================
> ======
>
>
>
> ----- Original Message ----- From: "Chris Campbell"
>
> To:
> Sent: Thursday, February 22, 2007 6:46 PM
> Subject: Re: [JAVA2D] java2d Compositing -> OpenGL fragment shaders
>
>
>> Hi Mik,
>>
>> On Feb 22, 2007, at 2:11 AM, Michele Puccini wrote:
>>> A little followup..
>>>
>

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".