Tuning VolatileImage for software-accelerated graphics

Hi!
It’s been a while since Sun announced graphics acceleration input for their Java platform. It’s “true”, graphics are used as data buffers rendered to the graphics card output throughout various call-backs, such as RenderedImage’s or VolatileImage’s. Indeed OpenGL buffers provided the most of soft- and hard-ware acceleration for high-end graphics.
BUT the problem arises when the native librairies don’t load on all system’s or have to be disabled (e.g. the JAI codecsLib is disabled for Windows) or the System graphics layer are system-dependent (e.g. Apple’s Quartz or M’soft DirectX or the open library OpenGL). Sun Java dev’s released their Java 6th edition to provide more compatibility with the recent graphics cards buffers and routines, which has still some enhancements to be made till 7th edition.
One of the more accessible solution is to convert RenderedImage to VolatileImage instances to enter up into the VRAM buffers. Heading to this way, we face an uneasy situation where the VolatileImage is known to be instanciated OPAQUE. Now how to provide the same TRANSPARENCY and easiness of the RenderedImage’s ?? The solution has become real (since 5th edition )with the VolatileImage TRANSLUCENT parameter. Well, this is not sufficient, the background of VolatileImage is still filled with some WHITE-COLOR that renders opaque. So here’s the way to render ALL YOUR VOLATILE IMAGES W/ FULL TRANSPARENCY AS BACKGROUND :


/**
     * Instances a new VolatileImage from an image object.
     * @param size dimensions
     * @return VolatileImage created
     * @see java.awt.image.VolatileImage
     */
    public static VolatileImage createVolatileImage(Dimension size) {
        VolatileImage vdata = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleVolatileImage(size.width, size.height, VolatileImage.TRANSLUCENT);
        Graphics2D g = vdata.createGraphics();
        Composite cps = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f);
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, 0.0f));
        g.fillRect(0,0, size.width, size.height);
        g.setComposite(cps);
        return vdata;
    }

As you can see, the VolatileImage is given the TRANSLUCENT parameter and then Graphics are realized once to fill them with the AlphaComposite DST_IN and the alpha value to a floating zero. THIS CHANGES A LOT THE RENDERING SPEED. :wink:
::slight_smile: ::slight_smile: ::slight_smile:

EDIT : it should be reset back to the default Composite, which must be opaque SRC_OVER.

one snap shot of the accelerated screen. ALL SPRITES ARE VOLATILE :o

http://sourceforge.net/dbimage.php?id=163387

I wonder why you don’t simply use BufferedImages for your sprites, if they are read-only?
This is what BufferedImages have been designed for (since 1.5), e.g. I know about my old GeForce488Go which has quite a high per-primitive overhead for each rendered VI, whereas thousands of BIs are no problem at all. (I guess the pbuffer state changes are killing it)

lg Clemens

indeed BufferedImage’s are the most compatible. They are also known as RenderedImage in a 2D context. But they’re not as fast as VolatileImage instances because each render cycle has to fetch pixels data from a RAM allocated buffer, unlike Volatile buffer which are known to solely use the VRAM allocation. That is like looking data into the harddisk compared to fetching “living” data into the RAM memory; i.e. your Graphics Card CPU would look directly into its VRAM buffer in a Volatile context where he could find valid Image’s.
:slight_smile:
further benchmarking are made with the BufferStrategy “pBuffer” and the usual JFC double-buffering, The “full-screen exclusive” mode can create 2+ Volatile buffers that are flipped or swapped as the render cycle processes graphics contents which is much faster.

I thought BufferedImages were backed by a Texture+FBO and a VolatileImage was backed by a PBuffer…

I never heard of that reading from RAM into vRAM each ‘render cycle’. When all your drawing-operations are accelerated, there would be no need to sync with RAM.

Sorry but thats not true. BufferedImages are, if accalerated, copied to VRAM and when blitted to another GPU resource the vram-copy is used.

lg Clemens

you don’t even know what you’re talking about…

This is why I gave up on Java2D about… hm… seven years ago now.

Cas :slight_smile:

[quote]you don’t even know what you’re talking about…
[/quote]
Riven and Linuxhippy are right, check the source to Sun’s implementation of the BufferedImage class if you don’t take us on our word :s

Edit:
Unless you’re doing direct modifications to the underlying pixelbuffer, which causes the BufferedImage to get unaccelerated… which implies sysmem -> gpumem copies

Sorry but I know what I am talking about. If you’re not modyfing your VolatielImages your work is completly useless - BufferedImages provide excatly the same functionality without the risk of loosing their content.

Because BufferedImages are accalerated :wink: ?

lg Clemens

Nah, coz fiddling round with all the arcane runes and intoning the riddle of the bones to get consistent working performance just irked me too much…

Cas :slight_smile:

And we’re all very grateful that it made you develop LWJGL !