Skip to main content

Alpha blending performance

3 replies [Last post]
dolda2000
Offline
Joined: 2008-02-13

I'm having some serious trouble with the performance of alpha blending in Java -- so serious that I suspect that I'm doing something wrong. I don't know what I'm doing wrong, though, so I'm hoping someone might be able to tell me. Here follows the results of some experiments I've been doing.

First of all, I'm trying to draw BufferedImages with an alpha channel directly onto a window. I'm using Java 1.6 all the time. I'm trying to draw a number of 50x50 images onto the window at 16 FPS, and performance seems to scale linearly with around 6% CPU per images (so at 4 images, it consumes ~24% CPU, at 8 images ~50% CPU, and at around 15 or more images the framerate starts to drop). I also tried to draw one 800x600 image onto a window, and it takes around 400 ms. Performance in this test seems to be about the same on both Linux and Windows, by the way.

Second, I'm trying to use VolatileImages to draw the images onto the window (using GraphicsConfiguration.createCompatibleVolatileImage()). However, that doesn't work at all, because Java2D will only give me opaque VolatileImages. It doesn't return VolatileImages with either 1-bit or alpha transparency, on either Linux or Windows. It may be worth mentioning that I have direct rendering working on the Linux system.

Third, I tried to use the Direct3D rendering pipeline by setting sun.java2d.d3d=true. That actually works fairly well, and I seem to be able to draw alpha transparent images at about the same rate as normal images, and opaque images are drawn faster as well. However, it obviously only works on Windows, so I'd very much prefer not use it. A weird thing I noticed is that I still don't get accelerated VolatileImages for translucent images. Should it be like that?

Fourth, I tried to use the OpenGL rendering pipeline by setting sun.java2d.opengl=true, which is a very mixed blessing. because performance became definitely wonderful on Windows. All draw operations dropped to hardly measurable times. However, it doesn't seem to work at all on Linux, because performance wasn't affected at atll, and when setting sun.java2d.trace=count, it indicates that it's still using the normal XPM drawing routines. There also seems to be a fairly serious bug when using it on Windows, because when drawing newly created BufferedImages, the result is some weird monochrome blue drawing. As long as the BufferedImages weren't created recently, they are drawn as they should. Am I doing something weird to cause this behavior? Oh, and by the way, I'm still not getting accelerated VolatileImages, which I find weird.

Also, I'm wondering about the usage of the alternate pipelines as such. It seems to be working fairly OK for stand-alone programs, but what about applets? Is it at all possible to use the alternate pipelines when writing an applet? Even if I can somehow get permission to change system properties within an applet, AWT has already been started and set up its pipelines by that time, right?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Dmitri Trembovetski

Hello,

just curious, why would you want to draw translucent images
directly to the screen?

Drawing translucent images to an opaque window sounds
strange to me. Wouldn't you get artifacts with partial
repaints and stuff? If you do clear the window before
rendering your image, then it's no different from
just rendering to an opaque image filled with the background
color.

Typically one would have an opaque back buffer, and render
everything into there, then present it. It is highly recommended
to use the BufferStrategy API for your double-buffering
implementation.

Another questions is which java version have you tried?
Have you tried 6uN (dev. builds available at http://jdk6.dev.java.net)

java2d@JAVADESKTOP.ORG wrote:
> I'm having some serious trouble with the performance of alpha blending in Java -- so serious that I suspect that I'm doing something wrong. I don't know what I'm doing wrong, though, so I'm hoping someone might be able to tell me. Here follows the results of some experiments I've been doing.
>
> First of all, I'm trying to draw BufferedImages with an alpha channel directly onto a window. I'm using Java 1.6 all the time. I'm trying to draw a number of 50x50 images onto the window at 16 FPS, and performance seems to scale linearly with around 6% CPU per images (so at 4 images, it consumes ~24% CPU, at 8 images ~50% CPU, and at around 15 or more images the framerate starts to drop). I also tried to draw one 800x600 image onto a window, and it takes around 400 ms. Performance in this test seems to be about the same on both Linux and Windows, by the way.

Yeah, that wouldn't work too well.

> Second, I'm trying to use VolatileImages to draw the images onto the window (using GraphicsConfiguration.createCompatibleVolatileImage()). However, that doesn't work at all, because Java2D will only give me opaque VolatileImages. It doesn't return VolatileImages with either 1-bit or alpha transparency, on either Linux or Windows. It may be worth mentioning that I have direct rendering working on the Linux system.

Translucent VIs are only available with opengl pipeline
(since 1.5, and depending on your configuration) and the new
d3d pipeline in 6uN.

> Third, I tried to use the Direct3D rendering pipeline by setting sun.java2d.d3d=true. That actually works fairly well, and I seem to be able to draw alpha transparent images at about the same rate as normal images, and opaque images are drawn faster as well. However, it obviously only works on Windows, so I'd very much prefer not use it. A weird thing I noticed is that I still don't get accelerated VolatileImages for translucent images. Should it be like that?

Yeah, see above. The new d3d pipeline is enabled by default, and
it does support accelerated translucent VIs.

> Fourth, I tried to use the OpenGL rendering pipeline by setting sun.java2d.opengl=true, which is a very mixed blessing. because performance became definitely wonderful on Windows. All draw operations dropped to hardly measurable times. However, it doesn't seem to work at all on Linux, because performance wasn't affected at atll, and when setting sun.java2d.trace=count, it indicates that it's still using the normal XPM drawing routines. There also seems to be a fairly serious bug when using it on Windows, because when drawing newly created BufferedImages, the result is some weird monochrome blue drawing. As long as the BufferedImages weren't created recently, they are drawn as they should. Am I doing something weird to cause this behavior? Oh, and by the way, I'm still not getting accelerated VolatileImages, which I find weird.
>

What is your video board? Could you please provide output with
J2D_TRACE_LEVEL=4 env. variable set?

If you try the 6uN build, could you please provide output
from that as well (on windows, too).

> Also, I'm wondering about the usage of the alternate pipelines as such. It seems to be working fairly OK for stand-alone programs, but what about applets? Is it at all possible to use the alternate pipelines when writing an applet? Even if I can somehow get permission to change system properties within an applet, AWT has already been started and set up its pipelines by that time, right?
> [Message sent by forum member 'dolda2000' (dolda2000)]

With the new Java plugin in 6u10 you will be able to specify
vm parameters (and a separate vm will be started).
Although I would suggest against enabling the
opengl pipeline unconditionally. It could be better to provide
separate links for "accelerated" and sw-rendering.

The new d3d pipeline is enabled by default, so you don't need
to provide any flags.

Thanks,
Dmitri
Java2D Team

===========================================================================
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".

dolda2000
Offline
Joined: 2008-02-13

Thanks for your prompt response. Please allow me to reply to a few specific points:

> Hello,
> just curious, why would you want to draw translucent
> images directly to the screen?
> Drawing translucent images to an opaque window sounds
> strange to me. Wouldn't you get artifacts with partial
> repaints and stuff? If you do clear the window before
> rendering your image, then it's no different from
> just rendering to an opaque image filled with the background color.
> Typically one would have an opaque back buffer, and render
> everything into there, then present it. It is highly recommended
> to use the BufferStrategy API for your double-buffering implementation.

Of course, I'm already using the BufferStrategy API, but I forgot about it when I wrote my first post. Sorry about the confusion.

> Another questions is which java version have you
> tried?
> Have you tried 6uN (dev. builds available at
> http://jdk6.dev.java.net)

I'm only using the standard Java 6 JRE from Sun. I'd very much like not to depend on non-standard Java distributions, since I'd like people to use my code without any weird requirements, so if at all possible, I'd like not to depend on APIs or characteristics of particular JREs.
> [...]
>> Performance in this test seems to be about
>> the same on both Linux and Windows, by the way.
>
> Yeah, that wouldn't work too well.

Really? Why is that? Is it because I fooled you into thinking that I wasn't using a BufferStrategy, or is there something inherently slow with drawing alpha translucent images in Java2D?

> [...]
> Translucent VIs are only available with opengl
> pipeline
> (since 1.5, and depending on your configuration)

I see. That explains a lot. :)

> [...]
> However, it
> doesn't seem to work at all on Linux, because
> performance wasn't affected at atll, and when
> setting sun.java2d.trace=count, it indicates that
> it's still using the normal XPM drawing routines.
> There also seems to be a fairly serious bug when
> using it on Windows, because when drawing newly
> created BufferedImages, the result is some weird
> monochrome blue drawing. As long as the
> BufferedImages weren't created recently, they are
> drawn as they should. Am I doing something weird to
> cause this behavior? Oh, and by the way, I'm still
> not getting accelerated VolatileImages, which I find
> weird.
>
> What is your video board? Could you please provide
> output with
> J2D_TRACE_LEVEL=4 env. variable set?

Sure! My video board is (according to lspci on Linux) a "ATI Technologies Inc M22 [Mobility Radeon X300]". The output is as follows:
[I] GLXGC_FindBestVisual: scn=0
[I] GLXGC_InitGLX
[I] OGLFuncs_OpenLibrary
[I] OGLFuncs_InitPlatformFuncs
[I] OGLFuncs_InitBaseFuncs
[I] OGLFuncs_InitExtFuncs
[I] GLXGC_InitGLX: client GLX version=1.4
[I] GLXGC_InitFBConfig: scn=0 vis=0x0
[V] candidate fbconfigs:
[V] id=0x28 db=0 alpha=8 depth=24 stencil=0 valid=false (bad match)
[V] id=0x30 db=0 alpha=8 depth=24 stencil=0 valid=false (bad match)
[V] id=0x27 db=0 alpha=8 depth=24 stencil=8 valid=false (bad match)
[V] id=0x2f db=0 alpha=8 depth=24 stencil=8 valid=false (bad match)
[V] id=0x24 db=1 alpha=8 depth=24 stencil=0 valid=false (bad match)
[V] id=0x2c db=1 alpha=8 depth=24 stencil=0 valid=false (bad match)
[V] id=0x23 db=1 alpha=8 depth=24 stencil=8 valid=false (bad match)
[V] id=0x2b db=1 alpha=8 depth=24 stencil=8 valid=false (bad match)
[E] GLXGC_InitFBConfig: could not find an appropriate fbconfig
[E] GLXGC_FindBestVisual: could not find best visual
[I] GLXGraphicsConfig_getGLXConfigInfo
[I] GLXGC_InitFBConfig: scn=0 vis=0x23
[V] candidate fbconfigs:
[V] id=0x23 db=1 alpha=8 depth=24 stencil=8 valid=false (bad match)
[E] GLXGC_InitFBConfig: could not find an appropriate fbconfig
[E] GLXGraphicsConfig_getGLXConfigInfo: could not create fbconfig

I seem to be able to infer from this that the OpenGL pipeline doesn't find a visual that it is content with, but what is it looking for?

> If you try the 6uN build, could you please provide
> output
> from that as well (on windows, too).

I'd like to, but the Windows system isn't mine, unfortunately, and I have no Windows systems of my own. I'll try to get hold of it again, and get back with the output from it if I can.

> With the new Java plugin in 6u10 you will be able
> to specify
> vm parameters (and a separate vm will be started).
> Although I would suggest against enabling the
> opengl pipeline unconditionally. It could be better
> to provide
> separate links for "accelerated" and sw-rendering.
> The new d3d pipeline is enabled by default, so you
> don't need
> to provide any flags.

Do you have any idea when this JRE is going to released? As I mentioned above, I'd very much like to not use any features that people won't commonly have access to.

Again, thanks very much for your prompt response!

Fredrik Tolf

Dmitri Trembovetski

Hello,

java2d@JAVADESKTOP.ORG wrote:
>> Another questions is which java version have you
>> tried?
>> Have you tried 6uN (dev. builds available at
>> http://jdk6.dev.java.net)
>
> I'm only using the standard Java 6 JRE from Sun. I'd very much like not to depend on non-standard Java distributions, since I'd like people to use my code without any weird requirements, so if at all possible, I'd like not to depend on APIs or characteristics of particular JREs.

This "non-standard" distribution will become "standard"
in the near future, so I suggest that you at least
try and see how your application behaves on it.

>> [...]
>>> Performance in this test seems to be about
>>> the same on both Linux and Windows, by the way.
>> Yeah, that wouldn't work too well.
>
> Really? Why is that? Is it because I fooled you into thinking that I wasn't using a BufferStrategy, or is there something inherently slow with drawing alpha translucent images in Java2D?

That really depends on the source and
destination - what kind of image you render and where
you render it to.

If you're rendering a translucent BufferedImage
into another BufferedImage, it'd be done in software
but it will be reasonably fast because both source and
destination pixels reside in system memory.

If you're trying to render a translucent BI into
an hw accelerated surface (like VI or screen), then
the destination pixels live in VRAM (or in case of
X11, on the X server), so they will need to be
first pulled into system memory so that the software
loops can perform alpha compositing. This pulling
pixels off VRAM or the X server (and then putting
the composited pixels back) is a very slow operation.

The best case is where your source translucent image
is hw-accelerated itself and sits in VRAM - for
that you'd either need a translucent VI,
or a translucent managed image (a BI is a managed
image), and your destination is also in VRAM.
In that case the compositing is done using
video hardware and is very fast.

As I mentioned, translucent managed images
will only become available (by default on windows) in the
upcoming 6uN. In previous releases they were
only accelerated if a non-default Java2D
rendering pipeline is used (either OpenGL or
Direct3D - enabled via flags). In the current
Java 6 release the D3D pipeline is also enabled
in the full-screen mode.

The hw accelerated translucent VIs will be available
in 6uN on Windows by default, and with optional
OpenGL pipeline on X11 or windows (still enabled
via flags).

Does this make it more clear?

>> What is your video board? Could you please provide
>> output with
>> J2D_TRACE_LEVEL=4 env. variable set?
>
> Sure! My video board is (according to lspci on Linux) a "ATI Technologies Inc M22 [Mobility Radeon X300]". The output is as follows:
> [I] GLXGC_FindBestVisual: scn=0
> [I] GLXGC_InitGLX
> [I] OGLFuncs_OpenLibrary
> [I] OGLFuncs_InitPlatformFuncs
> [I] OGLFuncs_InitBaseFuncs
> [I] OGLFuncs_InitExtFuncs
> [I] GLXGC_InitGLX: client GLX version=1.4
> [I] GLXGC_InitFBConfig: scn=0 vis=0x0
> [V] candidate fbconfigs:
> [V] id=0x28 db=0 alpha=8 depth=24 stencil=0 valid=false (bad match)
> [V] id=0x30 db=0 alpha=8 depth=24 stencil=0 valid=false (bad match)
> [V] id=0x27 db=0 alpha=8 depth=24 stencil=8 valid=false (bad match)
> [V] id=0x2f db=0 alpha=8 depth=24 stencil=8 valid=false (bad match)
> [V] id=0x24 db=1 alpha=8 depth=24 stencil=0 valid=false (bad match)
> [V] id=0x2c db=1 alpha=8 depth=24 stencil=0 valid=false (bad match)
> [V] id=0x23 db=1 alpha=8 depth=24 stencil=8 valid=false (bad match)
> [V] id=0x2b db=1 alpha=8 depth=24 stencil=8 valid=false (bad match)
> [E] GLXGC_InitFBConfig: could not find an appropriate fbconfig
> [E] GLXGC_FindBestVisual: could not find best visual
> [I] GLXGraphicsConfig_getGLXConfigInfo
> [I] GLXGC_InitFBConfig: scn=0 vis=0x23
> [V] candidate fbconfigs:
> [V] id=0x23 db=1 alpha=8 depth=24 stencil=8 valid=false (bad match)
> [E] GLXGC_InitFBConfig: could not find an appropriate fbconfig
> [E] GLXGraphicsConfig_getGLXConfigInfo: could not create fbconfig
>
> I seem to be able to infer from this that the OpenGL pipeline doesn't find a visual that it is content with, but what is it looking for?

That I'm not sure - Chris would know.

>> If you try the 6uN build, could you please provide
>> output
>> from that as well (on windows, too).
>
> I'd like to, but the Windows system isn't mine, unfortunately, and I have no Windows systems of my own. I'll try to get hold of it again, and get back with the output from it if I can.
>
>> With the new Java plugin in 6u10 you will be able
>> to specify
>> vm parameters (and a separate vm will be started).
>> Although I would suggest against enabling the
>> opengl pipeline unconditionally. It could be better
>> to provide
>> separate links for "accelerated" and sw-rendering.
>> The new d3d pipeline is enabled by default, so you
>> don't need
>> to provide any flags.
>
> Do you have any idea when this JRE is going to released? As I mentioned above, I'd very much like to not use any features that people won't commonly have access to.

I can only say - sometime later this year.

Thanks,
Dmitri

===========================================================================
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".