Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (552)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Size matters? A managed image problem...  (Read 2641 times)
0 Members and 1 Guest are viewing this topic.
Offline barfy

Junior Member




The evidence of things not seen


« Posted 2004-04-30 12:31:09 »

Hi all,

I'm aware that all managed images will be accelerated with no size constraints according to this thread by trembovetski:

http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=2D;action=display;num=1065777178;start=1#1.

Assuming of course that there is enough VRAM available.

Then I'm puzzled as to why this BufferedImage with BITMASK transparency created using this piece of code doesn't seem to get accelerated:

Quote
squareBuffer = Globals.GC.createCompatibleImage(playerBounds.width, playerBounds.height, Transparency.BITMASK);


The width of that image created is 364 px, and the height is 700 px.

How I tell that it ISN'T accelerated is by using JProfiler to trace method invocations made by sun.java2d.SurfaceData.getSurfaceDataFromImage, and it calls sun.awt.image.BufImgSurfaceData.createData. If it was accelerated with BITMASK transparency, it should be calling sun.awt.image.AcceleratedOffScreenImage.getSourceSurfaceData instead.

Information on the environment I'm runnng in:

Quote

Java VM: 1.4.2_04

Property Flags:
  • System.setProperty("sun.java2d.accthreshold", "1");
  • System.setProperty("sun.java2d.translaccel", "true");
  • System.setProperty("sun.java2d.opengl", "true");

Available Accelerated Memory: 237684704 (so I've ruled out insufficient VRAM)


This WORKS however:

Quote
squareBuffer = Globals.GC.createCompatibleImage(playerBounds.width / 10, playerBounds.height / 10, Transparency.BITMASK);


I've got translucent acceleration enabled and this WORKS:

Quote
squareBuffer = Globals.GC.createCompatibleImage(playerBounds.width, playerBounds.height, Transparency.TRANSLUCENT);


And this too:

Quote
squareBuffer = Globals.GC.createCompatibleImage(playerBounds.width, playerBounds.height, Transparency.OPAQUE);
     

So, does size actually matter with regards to BITMASK transparency managed images? Or did I miss something?

I'd appreciate it if someone could clarify. Thanks.
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #1 - Posted 2004-04-30 12:39:49 »

No idea,
but try setting sun.java2d.accthreshold=0, rather than 1.
or try sun.java2d.forceddvram=true

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

Junior Member




The evidence of things not seen


« Reply #2 - Posted 2004-04-30 12:42:14 »

Quote
No idea,
but try setting sun.java2d.accthreshold=0, rather than 1.
or try sun.java2d.forceddvram=true


Whoa, that response was quick!  Smiley
I've tried enabling and disabling them both already though, doesn't help...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #3 - Posted 2004-04-30 12:47:10 »

Quote


Whoa, that response was quick!  Smiley


Fast, but absolutely useless to you Wink

Try iterating through a variety of widths/heights for your bitmask image.
Find out at exactly what resolution the image stops being managed. It maybe some 'clever' code deeming your image too large to be managed. (though I don't see how exactly that could be considered clever ^_^)

also, I was under the impression images larger than the display resolution may *not* be accelerated (driver issues and the like).
Have you changed the DisplayMode to something with a height < 700?

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

Junior Member




The evidence of things not seen


« Reply #4 - Posted 2004-04-30 13:10:12 »

Quote


Fast, but absolutely useless to you Wink


Heh Smiley. Any response is good I say.

Quote

Try iterating through a variety of widths/heights for your bitmask image.
Find out at exactly what resolution the image stops being managed. It maybe some 'clever' code deeming your image too large to be managed. (though I don't see how exactly that could be considered clever ^_^)
also, I was under the impression images larger than the display resolution may *not* be accelerated (driver issues and the like).
Have you changed the DisplayMode to something with a height < 700?


I'm running the app in windowed mode and I'm not using BufferStrategy for my back buffer, so it shouldn't be a DisplayMode quirk. The "squareBuffer" BufferedImage is just a 368 * 700 size image I'm using to render square tiles on occasionally, but it is imperative that it is accelerated since it gets copied from every animation cycle . If i reduce the size to say a 10th, it works as intended.

Btw, my desktop is set at 1280 x 1024 at 32 bpp if that makes a difference.

Appreciate your responses Smiley.


Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #5 - Posted 2004-04-30 13:46:46 »

You are aware that each time you draw a tile to the BufferedImage, it will lose its vram cached version?

For that situation(an intermediary buffer), VolatileImage is a better solution.
Ofcourse, you need a BITMASK volatile image, which is impossible pre-1.5, so ignore what I just said Wink

Either way, I can't see why an OPAQUE image would be accelerated, and a BITMASK not :S very confusing.

You are using windowed mode, but not using BufferStrategy.
What *are* you using for your back buffer? a VolatileImage?
What size is the window?

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

JGO Coder


Medals: 2


pixels! :x


« Reply #6 - Posted 2004-04-30 13:55:58 »

>just a 368 * 700 size image

Next power of 2 combo would be 512x1024.

Try breaking it up that it fits in 512x512 or 256x256 tiles. It should work better then. 2 or 4 blits instead of one, but that doesnt really matter.

It could be that your graphics card doesnt support textures that big or (wich I don't know exactly) that the maximum is either 512x512 or 256x256 (might have been a compatibility decision).

弾幕 ☆ @mahonnaiseblog
Offline barfy

Junior Member




The evidence of things not seen


« Reply #7 - Posted 2004-04-30 13:58:26 »

Can anyone else running JVM 1.4.2_04 on Windows XP confirm having the same problem with BITMASK Managed Images larger than 364 * 700 size?
Offline barfy

Junior Member




The evidence of things not seen


« Reply #8 - Posted 2004-04-30 14:08:42 »

Quote
You are aware that each time you draw a tile to the BufferedImage, it will lose its vram cached version?

For that situation(an intermediary buffer), VolatileImage is a better solution.
Ofcourse, you need a BITMASK volatile image, which is impossible pre-1.5, so ignore what I just said Wink


I'm aware of that, but I can't have it any other way since VolatileImages are only OPAQUE. Next best option would be to use TRANSLUCENT BufferedImages, but that would be wasteful since I don't need that many levels of transparency.

Quote
Either way, I can't see why an OPAQUE image would be accelerated, and a BITMASK not :S very confusing.


Exactly. Could be a bug.

Quote

You are using windowed mode, but not using BufferStrategy.
What *are* you using for your back buffer? a VolatileImage?
What size is the window?


Yes, a VolatileImage for my back buffer. The window is sized at 1024 x 768.

Quote
It could be that your graphics card doesnt support textures that big or (wich I don't know exactly) that the maximum is either 512x512 or 256x256 (might have been a compatibility decision).


Hmm. IMO, unlikely since even larger TRANSLUCENT and OPAQUE images are accelerated.
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #9 - Posted 2004-04-30 14:58:08 »

Quote

Hmm. IMO, unlikely since even larger TRANSLUCENT and OPAQUE images are accelerated.


Ok this is entirely guess work - but.... because you have transaccel enabled, TRANSLUCENT and OPAQUE images maybe created as D3D surfaces, but BITMASK may still be created as DirectDraw surfaces.
Try disabling transaccel, and see if the OPAQUE 364x700 image is still accelerated.

Can you put together a simple test case that we can all run to establish if its a Java problem, or driver 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 barfy

Junior Member




The evidence of things not seen


« Reply #10 - Posted 2004-04-30 16:13:30 »

Quote


Ok this is entirely guess work - but.... because you have transaccel enabled, TRANSLUCENT and OPAQUE images maybe created as D3D surfaces, but BITMASK may still be created as DirectDraw surfaces.
Try disabling transaccel, and see if the OPAQUE 364x700 image is still accelerated.


Tried that too. Doesn't work.

Quote

Can you put together a simple test case that we can all run to establish if its a Java problem, or driver problem.


Done!  Wink
The code is listed below. Just cut and paste:
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  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.*;
import java.util.Random;

public class ImageTest extends JFrame implements Runnable
{
      Image bb;
      BufferedImage bitmaskImage;
      long elapsedTime;
      int delayToUpdate = 100;
     
      final int numOfDraws = 400; // Modify this to change the number of times the BITMASK image is drawn onto the volatile buffer
                                            // A larger number stresses the rendering pipeling
                                           
      /* NOTE: if the width and height is set to 256, it should be accelerated.
       *             If either one is increased by 1, then the image should not be accelerated
       *             Check the FPS to confirm
       */
                               
      final int bitmaskWidth = 256; // Modify this to change the width of the BITMASK image
     final int bitmaskHeight = 256; // Modify this to change the height of the BITMASK image
     
      public static void main(String[] args)
      {
            ImageTest bitmaskImageTest = new ImageTest();
            Thread start = new Thread(bitmaskImageTest);
            start.start();
      }
     
      public ImageTest()
      {
            setIgnoreRepaint(true);
        getContentPane().setLayout(null);
        setBounds(new Rectangle(0, 0, 1024, 768));        
            setVisible(true);
           
            bitmaskImage = getGraphicsConfiguration().createCompatibleImage(bitmaskWidth, bitmaskHeight, Transparency.BITMASK);          
           
            Graphics2D g = bitmaskImage.createGraphics();
            g.setColor(Color.GREEN);
            g.fillRect(0, 0, bitmaskImage.getWidth(null), bitmaskImage.getHeight(null));
            g.dispose();
           
            bb = getGraphicsConfiguration().createCompatibleVolatileImage(1024, 768);
           
            elapsedTime = 0;
           
            // Add window listener.
       this.addWindowListener
        (
            new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            }
        );
        }
       
       public void run()
       {
             int counter = 0;
             Random rand = new Random();
             while(true)
             {
                   long startTime = System.currentTimeMillis();
                   
                   if(counter == delayToUpdate)
                   {
                         Graphics2D bitmaskG = bitmaskImage.createGraphics();
                         bitmaskG.setColor(Color.GREEN);
                         bitmaskG.fillRect(0, 0, bitmaskImage.getWidth(null), bitmaskImage.getHeight(null));
                         bitmaskG.setColor(Color.BLUE);
                         for(int i=0; i < 10; i++)
                               bitmaskG.fillOval(rand.nextInt(1024), rand.nextInt(768), 50, 50);
                         bitmaskG.dispose();
                         counter = 0;
                   }      
                         
                   Graphics g = bb.getGraphics();
                  for(int i=0; i < numOfDraws; i++)
                        g.drawImage(bitmaskImage, (bb.getWidth(null) - bitmaskImage.getWidth(null))/2, (bb.getHeight(null) - bitmaskImage.getHeight(null))/2, null);
                 
                  g.setColor(Color.RED);
                  String FPS = new String("FPS: " + ((float)1000)/elapsedTime);
                  g.drawString(FPS, (1024 >> 1) - 50,
                                            768 >> 1);
                  g.dispose();
                 
                  g = getGraphics();
                  g.drawImage(bb, 0, 0, null);
                  g.dispose();
                     
                     counter++;              
                  elapsedTime = System.currentTimeMillis() - startTime;
            }      
      }
}


Do try it and see if you can get hardware accelerated BITMASK images greater than 256 x 256.

Thanks.
Offline barfy

Junior Member




The evidence of things not seen


« Reply #11 - Posted 2004-04-30 16:16:51 »

Oh, and btw, on my P4 3.0ghz and ATI RADEON 9800 running the latest catalyst drivers, I get:

7-8 fps with 257 x 256 sized image and 33+ fps using a 256 x 256 sized image with the default parameters.

It clearly shows that a 257 x 256 image isn't accelerated.



Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #12 - Posted 2004-04-30 17:58:24 »

If the drivers require square power of 2 textures, 257x256 would round to 512x512.
That is 4 times as much work as 256x256, which would explain the drop from 33fps to 7-8fps.

What fps do you get with 512x512? is it the same 7-8fps?

btw, Is there a reason you arn't using BufferStrategy?

oh, I took the opportunity to tweak your code a litte, hope you don't mind (your fps calcing was abit poo Wink)

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  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.util.Random;
     
public class ImageTest extends JFrame implements Runnable
{
      Image      bb;
      BufferedImage bitmaskImage;
     
      static final boolean      BUFFER_STRATEGY =      true;
     
      static final int BITMASK_BLITS_PER_FRAME = 400;
     
      static final int WINDOW_WIDTH      = 800, WINDOW_HEIGHT      = 600;
      static final int BITMASK_WIDTH =      256, BITMASK_HEIGHT = 256;
     
      public static void main(String[]      args)
      {
            System.setProperty("sun.java2d.accthreshold", "0");
            Thread t      = new      Thread(new ImageTest());
            t.setPriority(Thread.MIN_PRIORITY);                  
            t.start();
      }
           
      public ImageTest()
      {
            setIgnoreRepaint(true);
            getContentPane().setLayout(null);
            setBounds(new Rectangle(0,      0,      WINDOW_WIDTH, WINDOW_HEIGHT));            
            setVisible(true);
     
            bitmaskImage =      getGraphicsConfiguration().createCompatibleImage(BITMASK_WIDTH, BITMASK_HEIGHT, Transparency.OPAQUE);                  
     
            Graphics2D g =      bitmaskImage.createGraphics();
            g.setColor(Color.GREEN);
      g.fillRect(0, 0, BITMASK_WIDTH, BITMASK_HEIGHT);
            g.dispose();
     
            if(BUFFER_STRATEGY)
            {
                  createBufferStrategy(2);
            }
            else
            {
                  bb      = getGraphicsConfiguration().createCompatibleVolatileImage(WINDOW_WIDTH, WINDOW_HEIGHT);
            }
     
            setDefaultCloseOperation(EXIT_ON_CLOSE);
      }
     
      public void      run()
      {
            Random rand      = new      Random();
            long lastTime = System.currentTimeMillis();
            int frameCount      = 0;
            String fps = "n/a";
            while(true)
            {
                  frameCount++;
                 
                  long time =      System.currentTimeMillis();
                  if(time-lastTime > 1000) //once a second
                 {
                        //update      the fps counter
                       fps =      Integer.toString(frameCount);
                        frameCount=0;
                        lastTime+=1000;
                       
                       
                        Graphics2D bitmaskG = bitmaskImage.createGraphics(); //and alter the      bitmask image
                       bitmaskG.setColor(Color.GREEN);
            bitmaskG.fillRect(0, 0, BITMASK_WIDTH, BITMASK_HEIGHT);
                        bitmaskG.setColor(Color.BLUE);
                        for(int i=0; i      < 10;      i++)
                        {
                              bitmaskG.fillOval(rand.nextInt(BITMASK_WIDTH-25), rand.nextInt(BITMASK_HEIGHT-25), 50,      50);
                        }
                        bitmaskG.dispose();
                  }      
                 
                  Graphics      bg      = BUFFER_STRATEGY?getBufferStrategy().getDrawGraphics():bb.getGraphics(); //buffers      Graphics
                 
                  for(int i=0; i      < BITMASK_BLITS_PER_FRAME;      i++)
                  {
                        bg.drawImage(bitmaskImage,      (WINDOW_WIDTH - BITMASK_WIDTH)/2, (WINDOW_HEIGHT- BITMASK_HEIGHT)/2,      null);
                  }
           
                  bg.setColor(Color.RED);
                  bg.drawString(fps, WINDOW_WIDTH/2 -      50, WINDOW_HEIGHT/2);
                  bg.dispose();
                 
                  if(BUFFER_STRATEGY)
                  {
                        getBufferStrategy().show();
                  }
                  else
                  {
                        Graphics      g = getGraphics();
                        g.drawImage(bb, 0, 0, null);
                        g.dispose();
                  }
                  Thread.yield();
            }      
      }      
}


Btw, with this code I get 15-16fps using a 256x256 image.
With a 257x257 image I get the same 15-16fps.
With a 512x512 image I get 4-5fps.

(Athlon1.33gig 512ddr GF2gts 32mb)

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

Junior Member




The evidence of things not seen


« Reply #13 - Posted 2004-05-01 01:37:11 »

Quote
If the drivers require square power of 2 textures, 257x256 would round to 512x512.
That is 4 times as much work as 256x256, which would explain the drop from 33fps to 7-8fps.

What fps do you get with 512x512? is it the same 7-8fps?

btw, Is there a reason you arn't using BufferStrategy?

oh, I took the opportunity to tweak your code a litte, hope you don't mind (your fps calcing was abit poo Wink)

Btw, with this code I get 15-16fps using a 256x256 image.
With a 257x257 image I get the same 15-16fps.
With a 512x512 image I get 4-5fps.

(Athlon1.33gig 512ddr GF2gts 32mb)


Yes, it's scaling down nicely in your case. Were you using BITMASK transparency?

Here's what I got:
Quote

Settings:
BUFFER_STRATEGY = true
BITMASK_BLITS_PER_FRAME = 400
WINDOW_WIDTH = 800 WINDOW_HEIGHT = 600

Transparency.BITMASK
BITMASK_WIDTH = 256, BITMASK_HEIGHT = 256
FPS: 36 - 37

BITMASK_WIDTH = 257 BITMASK_HEIGHT = 256
FPS: 8 - 9

BITMASK_WIDTH = 256 BITMASK_HEIGHT = 257
FPS: 8 - 9

BITMASK_WIDTH = 257 BITMASK_HEIGHT = 257
FPS: 8 - 9

BITMASK_WIDTH = 512 BITMASK_HEIGHT = 512
FPS: 2 - 3

Transparency.OPAQUE
BITMASK_WIDTH = 256, BITMASK_HEIGHT = 256
FPS: 36 - 37

BITMASK_WIDTH = 257 BITMASK_HEIGHT = 256
FPS: 28 - 29 Huh Does it warrant such a drastic decrease compared to 256 x 257?

BITMASK_WIDTH = 256 BITMASK_HEIGHT = 257
FPS: 36 - 37

BITMASK_WIDTH = 257 BITMASK_HEIGHT = 257
FPS: 28 - 29 Huh

BITMASK_WIDTH = 512 BITMASK_HEIGHT = 512
FPS: 7 - 8


You can tell that there's a noticable difference in the frame rates for the OPAQUE images as compared to the BITMASK ones, which proves that the OPAQUE images are accelerated in all cases and in only 1 case for the BITMASK images.

And even then there's a drastic decrease in 8-9 fps for a 1px increase in the width from 256 to 257 in the OPAQUE image.

What do you think is the problem? Driver issue?

Thanks Abuse, you've been really helpful btw Smiley




Offline barfy

Junior Member




The evidence of things not seen


« Reply #14 - Posted 2004-05-01 02:02:17 »

And here are the results for TRANSLUCENT images with acceleration enabled:

Transparecy.TRANSLUCENT

BUFFER_STRATEGY = true;
BITMASK_BLITS_PER_FRAME = 400;
WINDOW_WIDTH = 800 WINDOW_HEIGHT = 600

Quote
BITMASK_WIDTH = 256 BITMASK_HEIGHT = 256
FPS: 42 - 43

BITMASK_WIDTH = 257 BITMASK_HEIGHT = 256
FPS: 37 - 38

BITMASK_WIDTH = 256 BITMASK_HEIGHT = 257
FPS: 39 - 40

BITMASK_WIDTH = 257 BITMASK_HEIGHT = 257
FPS: 33 - 34 Drastic drop compared to 256 x 256

BITMASK_WIDTH = 512 BITMASK_HEIGHT = 512
FPS: 12 - 13


Again, it shows that OPAQUE and TRANSLUCENT images are accelerated while BITMASK images aren't.

Also, TRANSLUCENT images outperform OPAQUE images with acceleration enable. Probably because of D3D vs DirectDraw...


Offline trembovetski

Senior Member




If only I knew what I'm talking about!


« Reply #15 - Posted 2004-05-01 04:52:06 »

This one is easy: we have this limit (which we often forget about ourselves) for bitmask images on windows, the size (w * h) must be less than 65536 in order for image to get accelerated. This is because of the way we accelerate bitmask images with DirectX pipeline.

This won't be a problem with opengl pipelines on either windows or unix.

[edit]
Quote
trembovetski:  All of the sprites will be attempted to get accelerated. Size doesn't matter.

Mwahaha! And you believed me! Size always matters!
Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #16 - Posted 2004-05-01 05:43:12 »

Nyah! Guessed right Smiley

256x256 would have worked Tongue

弾幕 ☆ @mahonnaiseblog
Offline barfy

Junior Member




The evidence of things not seen


« Reply #17 - Posted 2004-05-01 06:04:01 »

Quote
This one is easy: we have this limit (which we often forget about ourselves) for bitmask images on windows, the size (w * h) must be less than 65536 in order for image to get accelerated. This is because of the way we accelerate bitmask images with DirectX pipeline.


Ohhhh. Roll Eyes

That explains my situation. But how come Abuse got accelerated BITMASK images with the test program we ran?

Quote

This won't be a problem with opengl pipelines on either windows or unix.


And is this opengl pipeline available on 1.4.2 on windows? How would I use/enable it if it is?

Failing that, my next best option is to chop up the image into smaller chunks like Onyx said. But that is exactly what I want to avoid since I want to incur as little overhead as possible with fewer drawImage() calls.

Quote

Mwahaha! And you believed me! Size always matters!


Bah.  :-/
Offline oNyx

JGO Coder


Medals: 2


pixels! :x


« Reply #18 - Posted 2004-05-01 06:12:47 »

>I want to avoid since I want to incur as little overhead as
>possible with fewer drawImage() calls.

Won't make a difference. More accelerated calls will be faster than one non-accelerated call. Also 600 blits aren't a big deal @60fps (even on rather old hardware).

So don't mind that and just try it Smiley

If you can use dirty rectangles, you could even split it into even smaler tiles like 32x32 and only redraw those who needs to be redrawn. That will give you a nice performance boost compared to draw the whole thing each time.

弾幕 ☆ @mahonnaiseblog
Offline barfy

Junior Member




The evidence of things not seen


« Reply #19 - Posted 2004-05-01 08:18:16 »

Quote

More accelerated calls will be faster than one non-accelerated call.


Generally true. That's why I mentioned earlier that this "squareBuffer" image I'm using has to be accelerated even though it gets written TO occasionally.

Quote

Also 600 blits aren't a big deal @60fps (even on rather old hardware).


I'm not so sure about this. In fact, the test program I ran shows that the overhead involved in calling drawImage() is very significant. For example, all other things being equal, I compared blitting on screen a 16 x 16 sized accelerated BITMASK image 256 times to blitting a 256 x 256 sized accelerated BITMASK image 1 time.

FPS, 16 x 16, 256 times: ~280
FPS, 256 x 256, 1 time: ~1778+, 6x faster

Drastic frame rate difference. But the large overhead could be local to my hardware  :-/. If you want to try it yourself, the code for the test program is listed on the previous page.

Quote

If you can use dirty rectangles, you could even split it into even smaler tiles like 32x32 and only redraw those who needs to be redrawn. That will give you a nice performance boost compared to draw the whole thing each time.


In the worst case however, when all rectangles are dirty, performance will suffer. Even when not all rectangles are dirty, the added complexities/overhead with using such a scheme and the additional drawImage calls might make it a less viable option.



Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #20 - Posted 2004-05-01 09:01:40 »

Quote

But how come Abuse got accelerated BITMASK images with the test program we ran?  


hahahahaha, /me is an idiot.

I was indeed running with OPAQUEs not BITMASKs, well noticed.

With it set to BITMASK i get results similar to yours, and consistent with trembovetski bad news Sad

Quote

FPS, 16 x 16, 256 times: ~280
FPS, 256 x 256, 1 time: ~1778+, 6x faster


I get slightly closer results :-

16x16 256 times ~360
256x256 1 time ~750

I guess its driver/hardware related. (though it is disturbing a machine almost 3 times faster can't blit 16x16 as fast; have you got a crappy gfx card in it?)

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

Junior Member




The evidence of things not seen


« Reply #21 - Posted 2004-05-01 14:33:53 »

Quote


hahahahaha, /me is an idiot.

I was indeed running with OPAQUEs not BITMASKs, well noticed.

With it set to BITMASK i get results similar to yours, and consistent with trembovetski bad news Sad  


Okay, so it is official then  Tongue. Someone should put this ommision in the docs.  

Quote

(though it is disturbing a machine almost 3 times faster can't blit 16x16 as fast; have you got a crappy gfx card in it?)


Not exactly. I've got an ATI Radeon 9800 pro with the latest catalyst 4.4 drivers. This IS disturbing...

Are you sure you are running your test with the same variables set? This is the exact code I tested with (basically the same as your modified version except that it now erases the fps text and avoids a divide by 0 error), running on JVM 1.4.2_04:

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  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
import javax.swing.*; 
import java.awt.*;
import java.awt.image.*;
import java.util.Random;
 
public class ImageTest2 extends JFrame implements Runnable
{
 Image bb;
 BufferedImage bitmaskImage;
 
 static final boolean BUFFER_STRATEGY = true;
 
 static final int BITMASK_BLITS_PER_FRAME = 256;
 
 static final int WINDOW_WIDTH = 800, WINDOW_HEIGHT = 600;
 static final int BITMASK_WIDTH = 16, BITMASK_HEIGHT = 16;
 
 public static void main(String[] args)
 {
  System.setProperty("sun.java2d.accthreshold", "0");
  System.setProperty("sun.java2d.translaccel", "true");
  Thread t = new Thread(new ImageTest2());
  t.setPriority(Thread.MIN_PRIORITY);    
  t.start();
 }
   
 public ImageTest2()
 {
  setIgnoreRepaint(true);
  getContentPane().setLayout(null);
  setBounds(new Rectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT));  
  setVisible(true);
 
  bitmaskImage = getGraphicsConfiguration().createCompatibleImage(BITMASK_WIDTH, BITMASK_HEIGHT, Transparency.BITMASK);    
 
  Graphics2D g = bitmaskImage.createGraphics();
  g.setColor(Color.GREEN);
 g.fillRect(0, 0, BITMASK_WIDTH, BITMASK_HEIGHT);
  g.dispose();
 
  if(BUFFER_STRATEGY)
  {
   createBufferStrategy(2);
  }
  else
  {
   bb = getGraphicsConfiguration().createCompatibleVolatileImage(WINDOW_WIDTH, WINDOW_HEIGHT);
  }
 
  setDefaultCloseOperation(EXIT_ON_CLOSE);
 }
 
 public void run()
 {
  Random rand = new Random();
  long lastTime = System.currentTimeMillis();
  int frameCount = 0;
  String fps = "n/a";
  while(true)
  {
   frameCount++;
   
   long time = System.currentTimeMillis();
   if(time-lastTime > 1000) //once a second
  {
    //update the fps counter
   fps = Integer.toString(frameCount);
    frameCount=0;
    lastTime+=1000;
     
     
    Graphics2D bitmaskG = bitmaskImage.createGraphics(); //and alter the bitmask image so it isn't accelerated for awhile
   bitmaskG.setColor(Color.GREEN);
    bitmaskG.fillRect(0, 0, BITMASK_WIDTH, BITMASK_HEIGHT);
    bitmaskG.setColor(Color.BLUE);
    for(int i=0; i < 10; i++)
    {
          if((BITMASK_WIDTH-25) <= 0)
                break;
     bitmaskG.fillOval(rand.nextInt(BITMASK_WIDTH-25), rand.nextInt(BITMASK_HEIGHT-25), 50, 50);
    }
    bitmaskG.dispose();
   }  
   
   Graphics bg = BUFFER_STRATEGY?getBufferStrategy().getDrawGraphics():bb.getGraphics(); //buffers Graphics
  bg.setColor(Color.WHITE);
   bg.fillRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
   
   for(int i=0; i < BITMASK_BLITS_PER_FRAME; i++)
   {
    bg.drawImage(bitmaskImage, (WINDOW_WIDTH - BITMASK_WIDTH)/2, (WINDOW_HEIGHT- BITMASK_HEIGHT)/2, null);
   }
   
   
   bg.setColor(Color.RED);
   bg.drawString(fps, WINDOW_WIDTH/2 - 50, WINDOW_HEIGHT/2);
   bg.dispose();
   
   if(BUFFER_STRATEGY)
   {
    getBufferStrategy().show();
   }
   else
   {
    Graphics g = getGraphics();
    g.drawImage(bb, 0, 0, null);
    g.dispose();
   }
   Thread.yield();
   
   }  
 }  
}




Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #22 - Posted 2004-05-01 15:25:36 »

That code gives :-

16x16 256 times = 370 to 400
256x256 1 time = 490 to 530

The reduced fps on the 256x256x1 is due to the clearing of the background. (removing it gives the 700fps I got earlier)

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

JGO Coder


Medals: 2


pixels! :x


« Reply #23 - Posted 2004-05-01 15:33:05 »

16x16 256 times
256x256 1 time

Hm... you could try 32x32 (64 times - should be a good trade-off). Heh wait a minute... I suggested 32x32 in first place Tongue

弾幕 ☆ @mahonnaiseblog
Offline trembovetski

Senior Member




If only I knew what I'm talking about!


« Reply #24 - Posted 2004-05-02 05:28:50 »

Remember that after we decide to accelerate the image for the first time, a lot of stuff has to be done: we need to process the image and find an unused color to be used as color key in ddraw blit operation, then the image needs to be transferred from system memory to VRAM, and only after that the HW handles the blit from the new accelerated surface to the destination.

For larger images this overhead is, of course, higher.
BTW, this process has to be repeated each time after you render to that image.

But once the image gets accelerated, the speed of the  consequent copies should be comparable for 32x32 and 256x256 images.
Offline trembovetski

Senior Member




If only I knew what I'm talking about!


« Reply #25 - Posted 2004-05-02 05:33:53 »

Quote
And is this opengl pipeline available on 1.4.2 on windows? How would I use/enable it if it is?


The opengl pipeline will be available in release 1.5 (beta1 is out now - with opengl pipeline implemented on Linux/Solaris only - see the release notes for requirements, or search the forum for sun.java2d.opengl property). Beta2 is coming out soon, and it'll have ogl on windows.
Offline barfy

Junior Member




The evidence of things not seen


« Reply #26 - Posted 2004-05-02 12:17:38 »

Quote
Remember that after we decide to accelerate the image for the first time, a lot of stuff has to be done: we need to process the image and find an unused color to be used as color key in ddraw blit operation, then the image needs to be transferred from system memory to VRAM, and only after that the HW handles the blit from the new accelerated surface to the destination.

For larger images this overhead is, of course, higher.
BTW, this process has to be repeated each time after you render to that image.

But once the image gets accelerated, the speed of the  consequent copies should be comparable for 32x32 and 256x256 images.


What I was trying to demonstrate was that the overhead in calling drawImage() for an already HW accelerated image is quite hefty.

For example, if we imagined a single 256 x 256 image as the equivalent of 256 16 x 16 portions, and tried to blit the whole image onto the screen in a single frame, using the test I mentioned in a previous post, we get the following FPS:

For a P4 3.0ghz with ATI Radeon 9800 PRO,

16 x 16, 256 drawImage() per frame: 280+ FPS
256 x 256, 1 drawImage() per frame: 1700+ FPS

For a Athlon 1.33ghz with GF2,

16 x 16, 256 drawImage() per frame: 360+ FPS
256 x 256, 1 drawImage() per frame: 750+ FPS

For the first case, the difference is 6x (why so large? Hardware issue?). For the second, 2x.

So, for the most part, I would rather blit entire images on screen in a single drawImage() call rather than use multiple drawImage() calls with "dirty rectangles".





Offline trembovetski

Senior Member




If only I knew what I'm talking about!


« Reply #27 - Posted 2004-05-02 16:06:27 »

Aha, I see what you mean it now.

Yes, we're aware that the overhead of a blit call is pretty high, unfortunately. Part of it is JNI overhead, which is surprisingly high, and the rest is our pipelines.

One of the goals we have for our next release is to reduce the pipeline overhead (the time it takes from java render call to the time we issue the command to hw), and make sure the vm team works on JNI's.
Pages: [1]
  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.

CopyableCougar4 (23 views)
2014-08-22 19:31:30

atombrot (34 views)
2014-08-19 09:29:53

Tekkerue (30 views)
2014-08-16 06:45:27

Tekkerue (28 views)
2014-08-16 06:22:17

Tekkerue (18 views)
2014-08-16 06:20:21

Tekkerue (27 views)
2014-08-16 06:12:11

Rayexar (65 views)
2014-08-11 02:49:23

BurntPizza (41 views)
2014-08-09 21:09:32

BurntPizza (31 views)
2014-08-08 02:01:56

Norakomi (41 views)
2014-08-06 19:49:38
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!