Fastest pixel by pixel operation

A

André Wagner

Hello!

I'm writing a videogame emulator that'll run in a java web applet.
Which is the best way to access the graphics, considering that:

1. The only way that I'll access the graphics will be pixel by pixel.
2. It needs to be ridiculously fast.
3. Since it'll run in a applet, it can only access the basic java API.

Thank you in advance.

André
 
A

Andrew Thompson

I'm writing a videogame emulator ..

Cool. How about an Amiga emulator (maybe for your
next project - I have a lot of cool old Amiga games
that I prefer to current day rubbish - but anyway..)?
..that'll run in a java webapplet.

Why? Not "Why Web?" but "Why Applet?".

Once you have a working prog. it is simpler to
deploy using webstart, which offers a free floating
app. with splash screens and desktop integration (if
either makes any sense for the deployment).
Which is the best way to access the graphics,

I'll leave the bit twiddling to others better at it..
3. Since it'll run in aapplet, it can only access the basic java API.

..but that is not the case.
A sandboxed applet (or webstart launched applet or
application, for that matter) can use the sandboxed
jar's of other API's (e.g. JFreeChart) just fine.
If you wanted to offer the user the ability to *save*
the generated chart to disk as an image, that would
require either signed/trusted code in the applet/webstart
app, or a sandboxed webstart app. that uses the JNLP
API to access to local disks.

In fact, once it comes to webstart, you can deploy
a *sandboxed* app. that refers to the Java3D webstart
extension* that has its own splash and is *all
permissions* because it uses natives to achieve
what it does.

* <http://download.java.net/media/java3d/webstart/release/java3d-1.5-
latest.jnlp>

Using the Java3D extension we** (the deployers) get
to deploy our part of the app. without signing it,
yet can still take advantage of the power of J3D
using natives.

** Hypothetically, I have deployed things using a
number of JNLP (webstart) extensions, including
JOGL renderings, but cannot quite recall if I've
ever used the J3D extn.

Just a few thoughts for you..
 
A

André Wagner

..that'll run in a java webapplet.
Why?  Not "Why Web?" but "Why Applet?".

It really needs to be an applet because I'll make use of communication
with the webpage (javascript).

Regards,

André
 
L

Larry A Barowski

Roedy Green said:
I suspect VolatileImage is the way to fly with a video card with
enough VRAM to wash your feet in.

That will be fast to display, but slow to get the pixel-by-pixel
data into the image. Depending on how much writing there is,
it may be faster to use a BufferedImage where the image type
matches the "screen type". You can get this by using
GraphicsConfiguration.createCompatibleImage(int, int). You
would of course want to bail out on screens that used packed
image types.

I'm not sure if you can get the default GraphicsEnvironment ->
GraphicsDevice -> GraphicsConfiguration in an unsigned
applet though. If not, there is probably some other way to
find the desired image type.
 
R

Roedy Green

That will be fast to display, but slow to get the pixel-by-pixel
data into the image.

The trick is you try to get all the application data inside the card,
including currently non visible data. The card itself in very good at
copying bits about, much better than an ordinary CPU and RAM. It
typically has bit addressibility or an approximation thereto, and a
very wide data path.
 
L

Larry A Barowski

Roedy Green said:
The trick is you try to get all the application data inside the card,
including currently non visible data. The card itself in very good at
copying bits about, much better than an ordinary CPU and RAM. It
typically has bit addressibility or an approximation thereto, and a
very wide data path.

The OP will be accessing individual pixels. Can that be done
efficiently through a VolatileImage?

On my system, setting a pixel through Graphics.drawLine with a
zero-size line on a Graphics from a VolatileImage has a speed of
about 6,000 pixels/second. WritableRaster.setDataElements() on
a BufferedImage has a speed of about 10,000,000 pixels/second.
 
A

André Wagner

On my system, setting a pixel through Graphics.drawLine with a
zero-size line on a Graphics from a VolatileImage has a speed of
about 6,000 pixels/second. WritableRaster.setDataElements() on
a BufferedImage has a speed of about 10,000,000 pixels/second.

Thank you for this info. Do you have any documentation or know about
any webpage that discuss fast pixel by pixel access? I'd really
appretiate that!

Regards.
 
L

Larry A Barowski

André Wagner said:
Thank you for this info. Do you have any documentation or know about
any webpage that discuss fast pixel by pixel access? I'd really
appretiate that!

Nope, I'm just experimenting. By the way, the speed I reported
above is incorrect. It was 100,000,000 pixels/second. By using
DataBuffer.setElem(), that increases to about 133,000,000
pixels/second. So we're talking about 1/4 of the frame time for
a 1000x1000 image at 30fps. My next thought would be to use
reflection to get access to the array in the DataBuffer and write
to it directly, which should give you a bit more speed.

How is the pixel data represented/accessed in your emulator?
 
R

Roedy Green

The OP will be accessing individual pixels. Can that be done
efficiently through a VolatileImage?

Painting a bit at a time won't buy you much with VolatileImage, but
you might be able to manufacture an array of pixels then use
MemoryImageSource to blast a batch of them through into the REGEN at
once.
 
R

Roedy Green

Thank you for this info. Do you have any documentation or know about
any webpage that discuss fast pixel by pixel access? I'd really
appretiate that!

See http://mindprod.com/jgloss/image.html

Sorry I don't have sample code, however I do outline the various
classes and what they are for. What you might do is use a
WriteableRaster to build a BufferedImage constructed in RAM, then
blast the constructed portions onto a VolatileImage with drawImage,
and from VolatileImage to the Graphics object passed to you in your
paintComponent.
 
A

André Wagner

Nope, I'm just experimenting. By the way, the speed I reported
above is incorrect. It was 100,000,000 pixels/second. By using
DataBuffer.setElem(), that increases to about 133,000,000
pixels/second. So we're talking about 1/4 of the frame time for
a 1000x1000 image at 30fps. My next thought would be to use
reflection to get access to the array in the DataBuffer and write
to it directly, which should give you a bit more speed.

That is a great info! Thank you!
How is the pixel data represented/accessed in your emulator?

My video memory (the whole RAM, in fact) is a array of shorts. But I
can easily change for something different for the video memory.

Regards,

André
 
L

Larry A Barowski

André Wagner said:
My video memory (the whole RAM, in fact) is a array of shorts. But I
can easily change for something different for the video memory.

I'm thinking the fastest thing would be to create a BufferedImage
that is compatible with the screen, as above, and write directly to
the pixel array in its DataBuffer. I just tried it and it is about six
times faster than going through DataBuffer.setElem(). You could
also create your own DataBuffer and WritableRaster subclasses
(and use the BufferedImage constructor that takes a
WritableRaster) to give you "legitimate" direct access to the pixel
array. There may be "behind the scenes" blitting optimizations
that you will miss that way, but you could try it to find out. Either
doing that or using reflection to get the pixel array from the
DataBuffer of a compatible BufferedImage, it would be fairly
straightforward to handle all the single-band, non-packed screen
types, and you could also do multi-band non-packed types if
necessary - I'm not sure how common those are. Most likely no
one is going to be using a videogame emulator on a green-screen
or 8-color screen, so you don't have to worry about the packed
screen types.

Of course you could also try a MemoryImageSource as Roedy
suggested and see if it is fast enough. That might be simpler
to start with.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top