Accessing VolatileImage via Java native interface

Hello,

I currently try to integrate our high performance 2D drawing engine, which is based on X11, into a lightweight Java SWING container.

My first approach was to make usage of shared memory X11 pixmap within our drawing engine

and to transfer the rendering result via a memcpy into a MemoryImageSource, which is drawn

via Java 2D API.

This solution works fine, hower, especiially when using high resolutions of 2k x 2k, the copying

operation are not fast enough.

Therefore I think of a solution, which should be based on a VolatileImage and a direct copy

operation from an X11 pixmap into that VolatileImage. However, up to now I have not found

any interface to retrieve the internal pixmap ID of the VolatileImage (even the AWT native interface does not seem to work in this case) ,

Any help on this topic is appreciated.

Thanks in advance,

Oliver

[935 byte] By [ok1a] at [2007-10-3 7:33:43]
# 1

Unfortunately there's no way to access VolatileImage's underlying pixmap.

(In some cases it may not even be a pixmap)

Have you tried using BufferedImage instead of MemoryImageSource?

You can get the data buffer of the BI, and then get the data array,

pass it to the native code and put your pixels into the array using JNI.

Then you can either copy this buffered image to the Swing's backbuffer directly or first copy it to another VolatileImage , and then to the backbuffer.

The latter would be useful if you want to cache the rendered data (that is, if you don't re-render the data on each Swing's repaint).

I've seen folks using this strategy successfully for video, may work for

you as well.

Thanks,

Dmitri

Java2D Team

dmitri_trembovetskia at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 2

Another thought: rendering to a shared memory pixmap will most likely be

unaccelerated by the X server, so you'll be using X11's software renderer

with system memory destination, so I wonder if you could try using directly

Java2D instead of your native renderer in the first place? May be it will

be more performant than your current approach.

Thanks,

Dmitri

dmitri_trembovetskia at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 3
In principle we perform exactly the same operations like you suggested with the MemoryImageSource and we are also using the animation and refresh feature. What should be the advantage of using a BufferedImage ?Thanks,Oliver
ok1a at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 4

Sorry, using Java2D directly is not a feasible option for the moment, but

might be an option for the future.

However, as far as I know the X11 rendering within Java2D has JNI overhead for

each call to any X11 draw request. Furthermore there are no advanced optimization

strategies which can be used for drawing of highly dynamic al objects in order to reduce

the necessary redraws.

Therefore I am still searching for a high performance solution based on the Pixmap approach as the interface between the two worlds (Java + external rendering engine).

Meanwhile, I had a look to the Java sources and found a way to retrieve the drawable

from the VolatileImage without the need to modify the Java sources.

However, my C/C++ code relies on some internal data structures of the Java sources

and is therefore not very compatible regarding different versions of the virtual machine.

Therefore it would be nice if the Java Native Interface for AWT could be extended by

the missing functionality. This would make life much easier to integrate native

rendering engines into the Java AWT/SWING environment.

Thanks,

Oliver

ok1a at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 5

> However, my C/C++ code relies on some internal data structures of the Java sources

and is therefore not very compatible regarding different versions of the virtual machine.

Yes, your code will be highly incompatible (we may change the implementation any time) and I would advise you against doing it.

Also, there's a potential for race conditions (our access to x11 display is synchronized).

> This would make life much easier to integrate native rendering engines into the Java AWT/SWING environment.

While I agree that it would, I believe it would be better if we addressed the issue of having the need for native renderers - whatever performance problems you have with our current X11 renderer should be solved instead..

Also, have you tried the OpenGL pipeline? It has much lower JNI overhead.

Thanks,

Dmitri

dmitri_trembovetskia at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 6
> What should be the advantage of using a BufferedImage ?We go through less hoops for rendering BufferedImages, so the overhead should be lower.Thanks, Dmitri
dmitri_trembovetskia at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 7
>> What should be the advantage of using a BufferedImage ?> We go through less hoops for rendering BufferedImages, so the overhead should be lower.Sounds good, so I will try it out and I'm curious about it.Thanks,Oliver
ok1a at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 8

>> However, my C/C++ code relies on some internal data structures of the Java sources

and is therefore not very compatible regarding different versions of the virtual machine.

>Yes, your code will be highly incompatible (we may change the implementation any time) and I would advise you against doing it.

You are right, maybe we will use the optimized solution only in rare cases as an

acceleration option and fallback to the BufferedImage solution in general.

>> This would make life much easier to integrate native rendering engines into the Java AWT/SWING environment.

>While I agree that it would, I believe it would be better if we addressed the issue of having the need for native renderers - whatever performance problems you have with our current X11 renderer should be solved instead..

In general your are right, but in our market it is important to have a drawing engine which

is highly optimized for a large number of dynamic/moving objects and to fullfill

operational display requirements. Therefore I cannot see a possibility to move to Java

rendering at the moment.

Maybe, I can find an alternative solution based on the ideas I got from the

accelerated implementation of GLJPanel from the JOGL project.

In combination with the latest GLX extension "EXT_texture_from_pixmap" it would

be possible to access an X11 pixmap as a texture and then make usage

of the Java2D/JOGLE bridge.

Thanks,

Oliver

ok1a at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 9
Looks like you're on the right track.Dmitri
dmitri_trembovetskia at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 10

Hello Dmitri,

currently I try to implement your proposed BufferedImage solution and

I am having problems to get the data array from the BufferedImage

in an efficient way. Furthermore, it seems to be the case that I always get

a copy of the DataBuffer and therefore I do not know how to refresh the

BufferedImage based on the modified DataBuffer.

It would be fine, if you could give me some more hints.

Thanks,

Oliver

ok1a at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 11

Hmm. You should be getting the same databuffer (and not a copy) if you're using the same BufferedImage and not creating a new one on every

refresh.

You don't have to "refresh" the BufferedImage since it just uses the DataBuffer as the storage for pixels - so whatever changes you make to the DB are immediately "available" to the BufferedImage.

Also, take a look at this thread:

http://www.javagaming.org/forums/index.php?topic=12453.0

It may give you a more clear idea on the approach.

Specifically, see this post for some flags:

http://www.javagaming.org/forums/index.php?topic=12453.msg100335#msg100335

These two flags from this post may help you a bit:

// magic passes

System.setProperty("sun.java2d.accthreshold", "0");

System.setProperty("sun.java2d.allowrastersteal", "true");

Basically, they mean "attempt to cache BufferedImages in a

Pixmap on a first copy", and "do not disable acceleration for

images for which the application got direct access to the pixels".

This will only be helpful if you do not intend to update the

BufferedImage with your renderer's output on every screen update -

which means that we could use the cached copy for at least

some of the updates.

However, if you use the "allowrastersteal" flag, you'll need to let us

know that the image changed by rendering to it (like do a single pixel fillRect):

// somewhere..

BufferedImage bi = ... // say it's an IntRgb image - create the image once

System.setProperty("sun.java2d.allowrastersteal", "true");

System.setProperty("sun.java2d.accthreshold", "0");

void render(Graphics backBufferG) {

DataBufferInt dbi = ...;

int[] data = dbi.getData();

if (nativeUpdatePending) {

// now update the pixels from the native code if there's update pending

updateDataBufferWithDataFromNative(data);

// now let 2d know that the pixels changed by touching the image:

Graphics g = bi.getGraphics();

g.setColor(TranparentColor);

g.fillRect(0,0,1,1);

}

// now copy the image to the backbuffer:

backBufferG.drawImage(bi, ..);

}

Or, alternatively, forget about the flags and do what other folks

were doing in that thread (note that the d3d and ddraw-related

flags obviously won't work for you, but the opengl one might).

Hopefully I didn't confuse you completely.

Thanks,

Dmitri

dmitri_trembovetskia at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...
# 12

Hi, Dmitri

i have seen the examples you suggested, but i still have a little confused, if i get the databuffer in my native function, yes it's not a copy, but if i have to fill the databuffer by setting every pixel, like:

for(int i = 0; i < length; i++)

{

buffer[i] = RGB(255, 0, 255);

}

it would be very inefficient, because the length of databuffer is very large, is there any way to copy the entire array of pixels directly into databuffer? usually, i use bitmap to draw graphics on dc.

thanks a lot.

angelswingadama at 2007-7-15 2:33:39 > top of Java-index,Security,Cryptography...