Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (498)
Games in Android Showcase (117)
games submitted by our members
Games in WIP (563)
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  
  minimizing image bit depth and resolution for better performance?  (Read 5160 times)
0 Members and 1 Guest are viewing this topic.
Offline No_Germs

Junior Member





« Posted 2005-09-05 13:56:04 »

my game's running at 25 Frames per second now. i'm using 24 bit images.
a thought occured to me-an image with a smaller bit depth or with a samller resolution can improve performance. should i go to such extent?
Offline Ask_Hjorth_Larsen

Junior Member




Java games rock!


« Reply #1 - Posted 2005-09-05 21:14:08 »

Do you create your images using GraphicsConfiguration.createCompatibleImage(..)? Because I've heard that this will match the image bit depth to that of the screen, making some things faster. Also it should be good for "managed images", meaning it might substantially increase the efficiency (so much, in my experience,  that maybe you won't have to bother about further optimizations).

I normally read an image from a file using ImageIO, then draw it onto another image which has been created by graphicsConfiguration.createCompatibleImage(...), but I've also heard that in newer versions of java, some of these things should be taken care of automatically.
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #2 - Posted 2005-09-06 00:21:07 »

indeed.

If you are :-
a) using Java1.4 or 1.5
b) running on Windows
c) have fairly uptodate hardware.
c) doing everything correctly & optimally (not doing any silly effects that rely on unaccelerated functionality)

Then reaching the refreshrate of your monitor (60+ fps) should not be a problem.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline No_Germs

Junior Member





« Reply #3 - Posted 2005-09-06 03:08:24 »

hmmm...
i do get my BufferedImage the correct you pointed out, so that's not the problem.

and i do have all the features mentioned in a),b) and c), so i guess i don't do d) correctly.
what do you mean by "not doing any silly effects that rely on unaccelerated functionality"?
i do use affine transforms alot...
here's some code, maybe i'm doing something wrong:
class Body//this represents every drawable item
{
    private float X;
    private float Y;
    private BufferedImage theImage;
    private float Angle;
    //some initialization code and other stuff here...
    public void Draw(Graphics2D g)
    {
        AffineTransform OriginalTrans=g.getTransform();
        g.translate(X,Y);
        g.rotate(Angle);
        g.drawImage(theImage,-theImage.getWidth()/2,-theImage.getHeight()/2,null);
        g.setTransform(OriginalTrans);
    }
}
class MyApp extends JApplet
{
    private BufferedImage BackBuffer;
    private Graphics2D BackGraphics;
    private Graphics AppGraphics;
    private Body[] theArray;
     //...
    public void paint()
    {
        for(int i=0;i<theArray.length;i++)
        {
             theArray.Draw(BackGraphics);
        }
        AppGraphics.drawImage(BackBuffer,0,0,null);
    }
   
}
Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #4 - Posted 2005-09-06 06:48:34 »

"i do use affine transforms alot..."

Thats the reason. Consider switching to lwjgl or jogl. Over there it will be even nicely filtered... for free.

弾幕 ☆ @mahonnaiseblog
Offline No_Germs

Junior Member





« Reply #5 - Posted 2005-09-06 07:27:02 »

i thought that the 2d api uses the opengl pipeline, and hence trasnforming and rotating are supported by opengl. am i wrong?
Offline weston

Junior Member





« Reply #6 - Posted 2005-09-06 08:06:23 »

not everything supported by opengl is supported by the opengl pipeline.

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
Offline Linuxhippy

Senior Member


Medals: 1


Java games rock!


« Reply #7 - Posted 2005-09-06 09:35:22 »

not everything supported by opengl is supported by the opengl pipeline.

Transformation and Rotation are. Indeed almost everything useful which supported by OpenGL is used to accalerate the OGL-Pipeline as far as possible.

lg Clemens
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #8 - Posted 2005-09-06 11:18:09 »

*but* the opengl pipeline is not enabled by default.

Add "-Dsun.java2d.opengl=True" on the command-line, or set the property through code (before any awt components are initialized).

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline No_Germs

Junior Member





« Reply #9 - Posted 2005-09-06 11:53:00 »

ok,
1. first of all i've tried disabling all the affinetransform related operations (not that the code has any meaning without it, but just to check things out), and the time improvement was about 5 miliseconds, so i don't think that's the problem...
2. silly me, forgot to tell you i'm not running in full screen mode and am not using bufferstrategy (for the meantime i prefer the game to be windowed). do you think that can make 25 milisec diffrerence?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline No_Germs

Junior Member





« Reply #10 - Posted 2005-09-06 15:36:33 »

i've tried moving to full screen double buffering (using the info in this link: http://javaalmanac.com/egs/java.awt/screen_Flip.html), and it just slowed me down...
Offline Linuxhippy

Senior Member


Medals: 1


Java games rock!


« Reply #11 - Posted 2005-09-06 19:51:10 »

Could you re-run your game with the system-property:
-Dsun.java2d.trace=count

and post the output here?

Thank you in advance, lg Clemens
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #12 - Posted 2005-09-06 23:56:13 »

Using BufferStrategy (or manually using a VolatileImage for a backbuffer) is the *only* way to get your blits hardware accelerated.

It doesn't matter if you want your game to be windowed, or fullscreen.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline No_Germs

Junior Member





« Reply #13 - Posted 2005-09-07 05:27:39 »

Could you re-run your game with the system-property:
-Dsun.java2d.trace=count

and post the output here?

Thank you in advance, lg Clemens

thank me? no no, thank you :-)

here's the output

36 calls to sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, AnyAlpha, IntArgbBm)
26 calls to sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntArgb, SrcOverNoEa, IntArgb)
2670 calls to sun.java2d.loops.MaskFill::MaskFill(AnyColor, SrcOver, IntRgb)
692 calls to sun.java2d.loops.Blit::Blit(IntRgb, SrcNoEa, IntArgb)
660704 calls to sun.java2d.loops.Blit::Blit(IntArgbBm, SrcOverNoEa, IntRgb)
26 calls to sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, IntArgb)
50 calls to sun.java2d.loops.DrawGlyphList::DrawGlyphList(OpaqueColor, SrcNoEa, AnyInt)
35 calls to D3DDrawRect
15659 calls to sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntArgb, SrcOverNoEa, "D3D texture destination")
20976 calls to sun.java2d.loops.MaskBlit$General::MaskBlit(IntArgbBm, SrcOverNoEa, "D3D texture destination")
5 calls to GDIFillRect
36 calls to sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntRgb, SrcNoEa, IntArgbBm)
1344416 calls to sun.java2d.loops.MaskFill::MaskFill(AnyColor, Src, IntRgb)
1268 calls to DDFillRect
36 calls to sun.java2d.loops.MaskBlit$General::MaskBlit(IntRgb, SrcNoEa, IntArgbBm)
14 calls to sun.java2d.loops.Blit::Blit(IntRgb, SrcNoEa, IntRgb)
36635 calls to sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, IntRgb)
20976 calls to sun.java2d.loops.Blit::Blit(IntArgbBm, SrcNoEa, IntArgb)
33 calls to sun.awt.windows.Win32BlitLoops::Blit("Integer RGB DirectDraw", SrcNoEa, "Integer RGB DirectDraw")
406 calls to sun.java2d.loops.MaskBlit::MaskBlit(IntRgb, AnyAlpha, IntArgb)
561 calls to sun.java2d.loops.MaskFill::MaskFill(AnyColor, Src, IntArgb)
2105260 total calls to 21 different primitives
Offline trembovetski

Senior Member




If only I knew what I'm talking about!


« Reply #14 - Posted 2005-09-07 05:53:59 »

The problem is that your backbuffer appears to be a BufferedImage. Rendering to BI is done via the
software loops. If you want to have acceleration, you'll need to either have
VolaileImage as your backbuffer, or use BufferStrategy. You don't have to be in fullscreen
mode  to get the acceleration (assuming you've enabled it via -Dsun.java2d.opengl=true or
-Dsun.java2d.d3d=true).

Thanks,
  Dmitri
Java2D
Offline No_Germs

Junior Member





« Reply #15 - Posted 2005-09-07 06:03:29 »

The problem is that your backbuffer appears to be a BufferedImage.
how did you reach that conclusion?

edit:
anyway, i've run ImageCapabilities.isAccelerated() and ImageCapabilities. isTrueVolatile() and they both return true, so i guess you we're wrong.
anyway,
if i enable -Dsun.java2d.d3d=true, i don't see any improvment,

and if enable -Dsun.java2d.opengl=true(of course, after disabling d3d), i get the following exception:

Exception in thread "main" java.lang.IllegalArgumentException: Width (0) and height (0) cannot be <= 0
at java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown Source)
at sun.awt.image.SunVolatileImage.getBackupImage(Unknown Source)
at sun.awt.image.VolatileSurfaceManager.getBackupSurface(Unknown Source)
at sun.awt.image.VolatileSurfaceManager.initialize(Unknown Source)
at sun.awt.image.SunVolatileImage.<init>(Unknown Source)
at sun.awt.image.SunVolatileImage.<init>(Unknown Source)
at sun.awt.image.SunVolatileImage.<init>(Unknown Source)
at sun.awt.image.SunVolatileImage.<init>(Unknown Source)
at sun.awt.windows.WComponentPeer.createVolatileImage(Unknown Source)
at java.awt.Component.createVolatileImage(Unknown Source)
at java.awt.Component$BltBufferStrategy.createBackBuffers(Unknown Source)
at java.awt.Component$BltBufferStrategy.revalidate(Unknown Source)
at java.awt.Component$BltBufferStrategy.getDrawGraphics(Unknown Source)

Offline Linuxhippy

Senior Member


Medals: 1


Java games rock!


« Reply #16 - Posted 2005-09-07 09:54:31 »

The problem is that your backbuffer appears to be a BufferedImage.
how did you reach that conclusion?

Because all your rendering is done in plain software (have a look at the java2d.loops.* innvocations) which explains why its so damn slow.
Which grapiccard do you sue?

lg Clemens
Offline No_Germs

Junior Member





« Reply #17 - Posted 2005-09-07 10:10:02 »

 
Because all your rendering is done in plain software (have a look at the java2d.loops.* innvocations)
lg Clemens

so why do the calls "ImageCapabilities.isAccelerated()" and "ImageCapabilities. isTrueVolatile()" both return true?

anyway my graphics card's an old one- nvidia geforce 2 mx/mx 400

and why does the initialization fail when i enable opengl?
Offline Ask_Hjorth_Larsen

Junior Member




Java games rock!


« Reply #18 - Posted 2005-09-07 12:55:06 »

I think the explanation is that the rendering TO the image is done in software, whereas rendering the image to the screen would be accelerated.If this is the case, every time you draw onto the image, a lot of software stuff occurs. When that is finished, taking horribly long time, the image is transferred via the bus to the graphics card, taking awfully long time, and then, at last, the accelerated image is rendered to the screen as fast as lightning!

As I understand this, the way to overcome this is to let the BufferStrategy take care of the stuff, such that the operations you specify are somehow given to the graphics card which will execute them quickly. So: no drawing onto BufferedImages if you want them accelerated. If you draw once (generate the image or rarely add some damage while the program is running) it probably wouldn't matter that much, but drawing onto the image every frame is deadly.

That's my suggestion to what's going on, I hope it's correct.
Offline No_Germs

Junior Member





« Reply #19 - Posted 2005-09-07 13:04:00 »

well, that's a good advice, but i have already implemented it a month ago. currently, i don't do any drawing to a buffered image. the only drawing that occures is the drawing of the buffered images on to the screen...

besides, that's not my question Smiley

Offline trembovetski

Senior Member




If only I knew what I'm talking about!


« Reply #20 - Posted 2005-09-08 05:15:26 »

well, that's a good advice, but i have already implemented it a month ago. currently, i don't do any drawing to a buffered image. the only drawing that occures is the drawing of the buffered images on to the screen...

besides, that's not my question Smiley



But according to the code you've posted you do render to a BufferedImage.
Quote
class Body//this represents every drawable item
{
    private float X;
    private float Y;
    private BufferedImage theImage;
    private float Angle;
    //some initialization code and other stuff here...
    public void Draw(Graphics2D g)
    {
        AffineTransform OriginalTrans=g.getTransform();
        g.translate(X,Y);
        g.rotate(Angle);
        g.drawImage(theImage,-theImage.getWidth()/2,-theImage.getHeight()/2,null);
        g.setTransform(OriginalTrans);
    }
}
class MyApp extends JApplet
{
    private BufferedImage BackBuffer;
    private Graphics2D BackGraphics;
    private Graphics AppGraphics;
    private Body[] theArray;
     //...
    public void paint()
    {
        for(int i=0;i<theArray.length;i++)
        {
             theArray.Draw(BackGraphics);
        }
        AppGraphics.drawImage(BackBuffer,0,0,null);
    }
   
}

The BackBuffer is defined as BufferedImage. Am I missing something? Or this piece of code
is some old version?

What image did you get the ImageCapabilities from?

Dmitri
Java2D Team
Offline trembovetski

Senior Member




If only I knew what I'm talking about!


« Reply #21 - Posted 2005-09-08 05:26:17 »

a thought occured to me-an image with a smaller bit depth or with a samller resolution can improve performance. should i go to such extent?


Just to answer the original question: if everything is setup correctly and we can accelerate
your image, the cached copy will be kept in vram in the best format possible, it doesn't matter
what bit depth the original image was in.

Suppose you have a 24-bit opaque image, but the current display mode is 16-bit. The vram-cached image
will be in 16-bit format. There are some details specific to the pipelines, but in general you
can't affect what format the image will be accelerated in.

But you can save some heap space if you use a smaller bit depth for your artwork.

If we can't for some reason use the hw acceleration (like it appears to be in your case),
we'll use our software loops. For those the pixel size that matters but whether
or not we have a specific loop for the particular image format. Or, should I say,
it matters more than the pixel size.

Dmitri
Java2D Team

Offline No_Germs

Junior Member





« Reply #22 - Posted 2005-09-08 07:54:19 »

But according to the code you've posted you do render to a BufferedImage.
The BackBuffer is defined as BufferedImage. Am I missing something? Or this piece of code
is some old version?

What image did you get the ImageCapabilities from?

Dmitri
Java2D Team
indeed, it's an old version. i've moved to double buffering using buffer strategy somewhere in the middle of this post Smiley
Offline rickyhaggett

Junior Newbie





« Reply #23 - Posted 2005-09-13 00:13:45 »

Hey folks,

In this thread, a few people (Abuse and Dmitri) seem to imply that it's possible to get hardware acceleration using a BufferStrategy in Windowed Mode (good for debug)..

I'm trying to do this, and I get a runtime Exception:

java.lang.IllegalStateException: Component must have a valid peer
   at java.awt.Component$FlipBufferStrategy.createBuffers(Component.java:3023)
   at java.awt.Component$FlipBufferStrategy.<init>(Component.java:2998)
   at java.awt.Component.createBufferStrategy(Component.java:2925)
   at java.awt.Window.createBufferStrategy(Window.java:2041)
   at java.awt.Component.createBufferStrategy(Component.java:2857)
   at java.awt.Window.createBufferStrategy(Window.java:2016)

The fullscreen code I have that works is:

            mainFrame = new JFrame(gc);
            mainFrame.setUndecorated(true);
            mainFrame.setIgnoreRepaint(true);
            device.setFullScreenWindow(mainFrame);
            if (device.isDisplayChangeSupported())
            {
                chooseBestDisplayMode(device);
            }
           
            mainFrame.createBufferStrategy(2);
            bufferStrategy = mainFrame.getBufferStrategy();

.. and the windowed code that doesn't is:


            mainFrame = new JFrame("title");
            mainFrame.createBufferStrategy(2);
            bufferStrategy = mainFrame.getBufferStrategy(); 

.. and it throws the Exception on the second line (mainFrame.createBufferStrategy(2)Wink

I remember reading somewhere that the frame the BufferStrategy is created from needs to be 'undecorated', but if I call mainFrame.setUndecorated(true) after I construct it, it doesn't seem to make any difference.

Any ideas?

Cheers,

Ricky

Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #24 - Posted 2005-09-13 00:52:11 »

isDisplayable() must return true, i.e. the Frame must be attached to a native screen resource.
You achieve this by simply making the Frame visible i.e. setVisible(true).

The reason your fullscreen code worked, is because setFullscreenWindow(...) itself makes the Frame displayable.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline rickyhaggett

Junior Newbie





« Reply #25 - Posted 2005-09-13 01:45:27 »

Ah cool - that works!

I now have:

            mainFrame = new JFrame("title");
            mainFrame.setVisible(true);
            mainFrame.setIgnoreRepaint(true);           
            mainFrame.createBufferStrategy(2);
            bufferStrategy = mainFrame.getBufferStrategy();
           

I get only about half the FPS running in windowed mode, versus fullscreen mode (~20 a second versus ~ 40). Does this sound normal?
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #26 - Posted 2005-09-13 09:07:16 »

I wouldn't expect that much of a performance hit, no.

The only reason Windowed should be slower than fullscreen, is because blitting will be used instead of page flipping to transfer data to the front buffer.

Unless you have a very poor graphics card, the difference between these 2 methods is small.

Ofcourse, there maybe other things happening in the background - something on your desktop or taskbar continually updating for instance can completely kill windowed performance, (I believe because of the context switching between GDI<->DirectDraw?)

Only 40 fps in fullscreen? your game must be doing quite alot of rendering & game logic to kick the framerate so low :S

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline rickyhaggett

Junior Newbie





« Reply #27 - Posted 2005-09-13 09:52:22 »

Hmm, no, I didn't think so.

My card is a Radeon9800, so perhaps background tasks are hurting me, yes

Also, I'm running it through Eclipse. I'll have to kill as much as I can and see how it does then.

As for my fullscreen framerate, that was actually my next point of investigation last night. I have a bunch of objects (well, okay, they're caterpillars), crawing along an undulating 2D landscape made of straight line segments. In their paint method, I call g.rotate(angle) ... paint ... g.rotate(-angle), to paint the caterpillars rotated to the angle of the line they're currently on.

The totally weird thing is that if I have only one caterpillar, I get 60fps a lot of the time, *until* he hits particular line segments, and thus his angle is set to certain  values (seemingly greater than 6 radians, and less than 0.5 radians). Then, with these angles,  the framerate falls to more like 30-40fps (so when I have a bunch of caterpillars, the chances are the framerate stays low most of the time).

Even weirder - this still happens even if I don't paint anything of the caterpillar, i.e.

g.translate(catx, caty);
g.rotate(angle);

// nothing here..

g.rotate(-angle);
g.translate(-catx, -caty);


Oh, and I'm calling g.rotate all over the place elsewhere in my game, and it seems to cope fine with all those cases - it's just this one that causes the drop.

I realise that this is perhaps too weird to get a simple answer for. I'll have to try to isolate it as a test case, but my concern is that maybe it's happening only in combination with all the other stuff I'm painting - kind of a final-straw scenario.

Any wild speculation folks have would be appreciated anyway!

Cheers,

Ricky

Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #28 - Posted 2005-09-13 12:23:43 »

[broken record]
blits that have a Transform other than translate will not be accelerated unless you enable the opengl pipeline.
[/broken record]

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline rickyhaggett

Junior Newbie





« Reply #29 - Posted 2005-09-13 14:34:56 »

Well, I'm doing this in Eclipse's 'VM arguments' :

-Dsun.java2d.opengl=true

(And I've also tried -Dsun.java2d.d3d=true)

Does that not enable the gl pipe?

Like I say, I'm doing g.rotate all over the shop, without any framerate dropout - it's just this one instance that causes problems, and even then only with certain angles.

And it still slows down even if I *don't* blit (just rotate).

I'll try to isolate it as some test code if possible.
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.

radar3301 (12 views)
2014-09-21 23:33:17

BurntPizza (31 views)
2014-09-21 02:42:18

BurntPizza (22 views)
2014-09-21 01:30:30

moogie (20 views)
2014-09-21 00:26:15

UprightPath (29 views)
2014-09-20 20:14:06

BurntPizza (33 views)
2014-09-19 03:14:18

Dwinin (48 views)
2014-09-12 09:08:26

Norakomi (74 views)
2014-09-10 13:57:51

TehJavaDev (103 views)
2014-09-10 06:39:09

Tekkerue (51 views)
2014-09-09 02:24:56
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

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!