Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (603)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Awesome Speeds With VolatileImage  (Read 11085 times)
0 Members and 1 Guest are viewing this topic.
Offline orogamo
« Posted 2012-09-18 08:52:49 »

I am in the making of this game in java,
It runs at 30fps(capped).

As a benchmark, I removed the cap and got 92-97fps...
This was with a BufferedImage...
Then i changed it to VolatileImage, it now runs at 192-197fps...
That was a 100fps increase, that's just badass Cheesy

So i have added the following code at the beginning of the rendering code to initialize the BufferGraphics:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
if(vBuffer == null && useGPU) {
   vBuffer = RandomRPG.GamePanel.createVolatileImage(800, 600);
   BufferGraphics = vBuffer.createGraphics();
   BufferGraphics.setBackground(Color.BLACK);
   BufferGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
} else if(Buffer == null && !useGPU) {
   Buffer = new BufferedImage(800, 600, 2);
   BufferGraphics = Buffer.createGraphics();
   BufferGraphics.setBackground(Color.BLACK);
   BufferGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
}


, and at the end:
1  
2  
3  
4  
5  
6  
7  
8  
if(useGPU) {
   g.drawImage(vBuffer, 0, 0, RandomRPG.GamePanel.getPreferredSize().width, RandomRPG.GamePanel.getPreferredSize().height, null);
   vBuffer.flush();
} else {
   g.drawImage(Buffer, 0, 0, RandomRPG.GamePanel.getPreferredSize().width, RandomRPG.GamePanel.getPreferredSize().height, null);
   Buffer.flush();
}
Toolkit.getDefaultToolkit().sync();


This way i can choose either to use the GPU or not...

PS:
CPU Usage was around 17-20% on an Intel Core i5-2540M 2.6GHz 2-Core, 4-Logical Processors
when i used the BufferedImage...
But when i used the VolatileImage, this sank to about 6-7%..
That is because now the GPU is used to take the load of the CPU.
Now i can have lots more stuff in the GameLoop Tongue
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #1 - Posted 2012-09-18 09:28:36 »

...I thought Java2D could never take advantage of the GPU. Are you sure that is what's actually happening?
Simply changing to a volatile image shouldn't make that kind of difference...unless I've totally missed something

- Jonas
Offline princec

« JGO Spiffy Duke »


Medals: 434
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #2 - Posted 2012-09-18 09:38:48 »

Yes it should - VolatileImage is backed directly by Direct3d or OpenGL textures. It's almost as fast at drawing as pure OpenGL is for various ordinary operations.

Cas Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline orogamo
« Reply #3 - Posted 2012-09-18 10:16:46 »

Doesn't it just use VRAM.
BufferedImages uses normal RAM,
and VolatileImages uses VRAM.
So with Volatile the GPU reads VRAM direcly which is faster than reading RAM.
Correct me if I'm wrong
Offline princec

« JGO Spiffy Duke »


Medals: 434
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #4 - Posted 2012-09-18 11:02:16 »

That's right. Though I think since JDK1.5 BufferedImage converts to VolatileImage under-the-hood when it can.

Cas Smiley

Offline orogamo
« Reply #5 - Posted 2012-09-18 11:19:48 »

I also did a smaller benchmark with one image. Drew 5000 frames to buffer then to screen, with both:
VolatileImage: 7 seconds
BufferedImage: 25 seconds

So VolatileImage used 18 seconds less time than the BufferedImage...
VolatileImage is 350% more efficient than BufferedImage.
Offline Oskuro

JGO Knight


Medals: 40
Exp: 6 years


Coding in Style


« Reply #6 - Posted 2012-09-18 11:33:32 »

Drawbacks? When I read up on Volatile Images I remember there were a few drawbacks that required caution.

I don't have the book on hand right now, I'll check it when I get back home.

Offline Cero
« Reply #7 - Posted 2012-09-18 12:13:54 »

Drawbacks? When I read up on Volatile Images I remember there were a few drawbacks that required caution.

I don't have the book on hand right now, I'll check it when I get back home.

Indeed. Volatiles can be unloaded and disappear (artifact) at any moment.

Offline StumpyStrust
« Reply #8 - Posted 2012-09-18 16:37:01 »

Yes since java 1.5 all images loaded will try and become manged images if they can.

The major thing that volatile can do better than bufferedImages is acting like a backbuffer.

volatileImage.getGraphics() /BufferedImage.getGraphics()

draw...draw...draw....


BufferedImages are slow for this but for just using BufferedStrategy and g2d.drawImage there is no difference and you really get no speed boost for using a volatile image as a back buffer instead of a BufferedStrategy

Offline nsigma
« Reply #9 - Posted 2012-09-18 18:27:38 »

That's right. Though I think since JDK1.5 BufferedImage converts to VolatileImage under-the-hood when it can.

Not quite accurate.  A managed BufferedImage can automatically cache the data in the graphics hardware for rendering from, but all rendering to it happens in software.  A VolatileImage can be rendered to by the hardware pipeline.  BufferedImage is more akin to texture, VolatileImage to FBO - in fact, from recollection that's how they're done in the OpenGL pipeline.

you really get no speed boost for using a volatile image as a back buffer instead of a BufferedStrategy

As I recall BufferStrategy uses VolatileImage under the hood anyway, and it's easier to use.  VolatileImage is best used in the same places you'd use render-to-texture (composite sprites, etc.)

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline StumpyStrust
« Reply #10 - Posted 2012-09-18 19:02:57 »

Just ran some tests and without any transparency, volatileimages are much faster then most bufferedimages. With transparency, they are 10-15% slower.

Basically Alphacomp will give you a huge slow down (8300 sprites) 80fps to 8fps when using volatileimages. So anything that does not need to fade or have any transparency should be a volatileimage (backgrounds and stuff);

Offline nsigma
« Reply #11 - Posted 2012-09-18 19:29:01 »

Just ran some tests and without any transparency, volatileimages are much faster then most bufferedimages. With transparency, they are 10-15% slower.

What OS / pipeline?

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline StumpyStrust
« Reply #12 - Posted 2012-09-18 22:51:52 »

Hehe win 7 d3d and I just ran it under opengl pipeline and buffered images were as good as volatile and they can load transparent images where volatile cannot....well I have never gotten them to. And opengl flag also boosts alphacomp performances as well...

Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #13 - Posted 2012-10-01 02:21:13 »

Sorry for reviving an old thread, but BufferStrategy uses VolatileImage underneath, so use that instead of VI directly.

Offline nsigma
« Reply #14 - Posted 2012-10-01 12:30:46 »

Sorry for reviving an old thread, but BufferStrategy uses VolatileImage underneath, so use that instead of VI directly.

Woot!  ra4king's back!!!  And reviving old threads to repeat what's already been said!  Tongue  I'm getting that cage prepared as I type ...  Wink

To be pedantic, while BufferStrategy uses VolatileImage under the covers, it does not therefore follow that all uses of VolatileImage can be replaced by BufferStrategy.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #15 - Posted 2012-10-01 15:22:34 »

Right, but for basic rendering like the one portrayed by the OP, it should be used.

And what's already been said? *searches older posts again* .... oh I thought it wasn't mentioned Sad

Offline Kerai

Junior Devvie


Medals: 4



« Reply #16 - Posted 2012-10-06 10:14:43 »

Sorry I dig out an old thread, but it is not "ended" with proper information.

Java2D can be accelerated (mostly defaultly it is) by Direct3D or OpenGL.

http://docs.oracle.com/javase/1.5.0/docs/guide/2d/flags.html - here you can set some flags to force acceleration (usefult to force direct3d on windows and opengl everywhere else)

BufferedImage when loaded from resources may be INCOMPATIBLE ... there are several types of BufferedImage (depending on layout of pixeldata inside)
For maximum performance, you can create compatible BufferedImage with GraphicsConfiguration
http://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsConfiguration.html#createCompatibleImage%28int,%20int,%20int%29

Java2D tries to cache BufferedImage as texture whenever possible, so drawing it anywhere is as fast as drawing texture.

problem is.. drawing ON BufferedImage is performed in software, while drawing ON VolatileImage is (if possible) on GPU.

so its only faster to use VolatileImage if you want to draw ON IT, otherwise its better to use compatible BufferedImage.

Here is some more info on OpenGL acceleration in Java2D:
http://today.java.net/pub/a/today/2004/11/12/graphics2d.html#Image_Rendering

Direct3D pipeline is very similiar.
Online Riven
« League of Dukes »

« JGO Overlord »


Medals: 840
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #17 - Posted 2012-10-06 10:30:20 »

What you say was true in 2004 / Java 5 (as the links imply) indeed. Drawing ON a BufferedImage is often hardware accelerated now.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social
Offline Linuxhippy

Senior Devvie


Medals: 1


Java games rock!


« Reply #18 - Posted 2012-10-07 11:20:09 »

What you say was true in 2004 / Java 5 (as the links imply) indeed. Drawing ON a BufferedImage is often hardware accelerated now.

Nope, drawing ON BufferedImages is never accelerated - its just modern CPUs got quite fast Wink

orogamo:
Try to only make the Buffer a VolatieImage, and use BufferedImage for your sprites.
It should give similar or even better throughput.
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #19 - Posted 2012-10-07 18:41:32 »

Nope, drawing ON BufferedImages is never accelerated - its just modern CPUs got quite fast Wink
Wrong. BufferedImages *are* accelerated now. Look into "managed images".

Offline Linuxhippy

Senior Devvie


Medals: 1


Java games rock!


« Reply #20 - Posted 2012-10-07 19:24:55 »

Wrong. BufferedImages *are* accelerated now. Look into "managed images".

Managed BIs are accelerated when used as source, when used as destination ("drawing on bufferedimages"), they are strictly CPU only.
I did the new xrender java2d pipeline thats in jdk7, I know its the same for the opengl pipeline and thinking about the java2d-internals I really doubt the d3d pipeline accelerates rendering TO BIs.

So the code posted compares software-only rendering with hw-accelerated rendering, but by using a BufferedImage as buffer (=destination) it doesn't give "image management" even a chance.

Basically Kerai summed it up quite nicely:
Quote
Java2D tries to cache BufferedImage as texture whenever possible, so drawing it anywhere is as fast as drawing texture.
problem is.. drawing ON BufferedImage is performed in software, while drawing ON VolatileImage is (if possible) on GPU.
so its only faster to use VolatileImage if you want to draw ON IT, otherwise its better to use compatible BufferedImage.
Offline StumpyStrust
« Reply #21 - Posted 2012-10-07 21:25:29 »

I have no real proof other then that fact that when I try drawing onto a bufferedimage I get 1-2fps.

You can draw onto a volatile image and then call getSnapShot() which will return a bufferedImage of that volatile image so you can do stuff to the pixels.

I should write a detailed tut on how to get java2d to run fast and exactly what you can expect to get out of it performance wise. Also, go into detail on what the typical bottle necks are.

For example, you will almost never have a bottle neck with, fill/blending/alpha/scaling it is almost always the draw call count. And almost all images you create start out managed.

Offline Regenuluz
« Reply #22 - Posted 2012-10-08 08:02:30 »

Yes, yes you should. I'd be reading it, for sure! Smiley
Offline nsigma
« Reply #23 - Posted 2012-10-08 09:29:52 »

Wrong. BufferedImages *are* accelerated now. Look into "managed images".

Ah, t'is the audacity of youth to be so sure about being wrong!  Tongue

Thanks Linuxhippy for backing up Kerai and my points about this earlier.  I think this is now the third or fourth thread recently I've picked up ra4king on this.  Roll Eyes

As Riven correctly pointed out (pity about the second sentence!  Wink ) Kerai's information is somewhat old.  There is no need to use a compatible image for it to be managed since Java 5.  In fact, I've generally found createCompatibleImage(..) to be more trouble than it's worth, particularly on Linux in the past - YMMV.

I should write a detailed tut on how to get java2d to run fast and exactly what you can expect to get out of it performance wise.

Sounds like a good idea.  See if you can bug Linuxhippy into proofing it - he's probably the person with the most knowledge of the Java2D back-end around here!

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #24 - Posted 2012-10-08 23:35:54 »

I think this is now the third or fourth thread recently I've picked up ra4king on this.  Roll Eyes
Whoa really?

Emo Cry Emo Cry Emo Cry Emo Cry Emo Cry Emo Cry

Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 139
Projects: 4
Exp: 3 years



« Reply #25 - Posted 2012-10-09 03:51:43 »

I think this is now the third or fourth thread recently I've picked up ra4king on this.  Roll Eyes
Whoa really?

Emo Cry Emo Cry Emo Cry Emo Cry Emo Cry Emo Cry
What's the score
Offline Oskuro

JGO Knight


Medals: 40
Exp: 6 years


Coding in Style


« Reply #26 - Posted 2012-10-27 10:40:02 »

NO thread, you're not dying just yet...

I'm working on my rendering classes now, and from what I've gathered from the java API, one thing that forces an image to Software mode is exposing the underlying data structure as a Java type (For example, a int array of RGBA values).

This is a problem for me, as I intended to expose said data structure to be able to operate directly on a per-pixel basis. This is how I get said structure:


1  
2  
3  
4  
5  
6  
7  
8  
9  
java.awt.image.BufferedImage bufferImage = null;
int[] exposedDataBuffer = null;

bufferImage = new java.awt.image.BufferedImage(
                           renderResolutionWidth,
                           rederResolutionHeight,
                           java.awt.image.BufferedImage.TYPE_INT_RGB );

exposedDataBuffer = ((java.awt.image.DataBufferInt) bufferImage.getRaster().getDataBuffer()).getData();


And when drawing a frame:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
// Get Buffer Strategy Context
java.awt.Graphics strategyGraphicsContext = bufferStrategy.getDrawGraphics();

// Clear
strategyGraphicsContext.fillRect(0, 0, frameWidht, frameHeight);

// Draw
strategyGraphicsContext.drawImage(
                     bufferImage, // Image Source
                     0,                // Destination Rectangle 1st Corner X Coord
                     0,                // Destination Rectangle 1st Corner Y Coord
                     frameWidth,  // Destination Rectangle 2nd Corner X Coord
                     frameHeight, // Destination Rectangle 2nd Corner Y Coord
                     0,                // Source Rectangle 1st Corner X Coord
                     0,                // Source Rectangle 1st Corner Y Coord
                     bufferWidth,  // Source Rectangle 2nd Corner X Coord
                     bufferHeight, // Source Rectangle 2nd Corner Y Coord
                     null     );      // Observer
                                                       

// Dispose of Context
strategyGraphicsContext.dispose();

// Flip Buffers
bufferStrategy.show();


The question then is... How to do this (per-pixel manipulation) while still retaining the capability to use Accelerated graphics?

And yes, using AWT, still not looking into better libraries. I'm really trying to get a better understanding of the basic operation of Java graphics before delegating. Smiley

Offline nsigma
« Reply #27 - Posted 2012-10-27 12:14:55 »

Are you updating the array every frame and only drawing once?  If you update a BufferedImage every time before you draw it, through the array or Graphics2D, then it won't be accelerated anyway.

If you update the image then draw it many times, either draw it into a second BufferedImage or a VolatileImage and draw from that.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline Oskuro

JGO Knight


Medals: 40
Exp: 6 years


Coding in Style


« Reply #28 - Posted 2012-10-27 12:32:19 »

I'm not sure I follow.

Right now yes, it is a 1:1 process, each frame is drawn before showing, but that's just because it's still under development.

My first idea is to decouple the rendering process from the drawing process, so frames are only sent to the drawing surface once they are complete (not sure if this would help).

Then, to further save on processing, split the frame into layers to be assembled, reusing those that need not be updated as often (for example, backgrounds).

Thing is, in the test I have now, I'm applying a full-screen static filter (Made by randomizing the lightness value on a per-pixel basis), so I don't see how can I break such a thing down so as not to need to update the pixel buffer each time.

Keep in mind I'm a graphics pipeline noob here, bashing my head in an effort to learn! Smiley

Offline nsigma
« Reply #29 - Posted 2012-10-27 13:05:40 »

Keep in mind I'm a graphics pipeline noob here, bashing my head in an effort to learn! Smiley

OK.  Though I'm not sure I can explain it any simpler, apart from to just say not to worry about software mode / acceleration.  From what I read you're doing now, it won't make any difference!  Smiley

Thing is, in the test I have now, I'm applying a full-screen static filter (Made by randomizing the lightness value on a per-pixel basis), so I don't see how can I break such a thing down so as not to need to update the pixel buffer each time.

If you're manipulating the whole image array each time before you draw it, it will never be accelerated.  You're processing it in software!

Then, to further save on processing, split the frame into layers to be assembled, reusing those that need not be updated as often (for example, backgrounds).

This is the only scenario where it may be worth worrying that an image is forced to unmanaged (software only) mode.  If you manipulate the pixel array of a background image, then draw it to the screen 10, 100, 1000 ... times, consider drawing it to another BufferedImage (that you haven't grabbed the array of!) first.  This will mean the image can be cached on the graphics card and so faster to draw to the screen.

A BufferedImage is always stored and manipulated in software - the pixels are stored in Java memory.  What "managed image" means is that when you draw the image more than once to the screen, Java2D will try to cache a copy of the image on the graphics card rather than uploading the pixels each time.  Each time you draw on a BufferedImage, the cached copy is invalidated and drawing the image will not be accelerated again at least the second time you draw it to the screen.  Grabbing the pixel array means the image is never cached on the graphics card.

Therefore, to put it simply, unless you draw an image more than once to the screen before you modify it again, it is pointless to worry about grabbing the pixel array.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (30 views)
2014-12-15 09:26:44

Mr.CodeIt (23 views)
2014-12-14 19:50:38

BurntPizza (50 views)
2014-12-09 22:41:13

BurntPizza (84 views)
2014-12-08 04:46:31

JscottyBieshaar (45 views)
2014-12-05 12:39:02

SHC (59 views)
2014-12-03 16:27:13

CopyableCougar4 (57 views)
2014-11-29 21:32:03

toopeicgaming1999 (123 views)
2014-11-26 15:22:04

toopeicgaming1999 (113 views)
2014-11-26 15:20:36

toopeicgaming1999 (32 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!