Volatile or not ?

Hello ppl,
I am using this method and hoping i am getting Accelerated Images. Before using this method my images were automatic. I went from 30-40 Fps to 30-40Fps !!
Yes, no change ! So i was wondering if my images are accelerated and if i am really supposed to see noticible difference in performance.


    public static BufferedImage getAcceleratedImage(Image source)
    {
        // To ensure that the image has loaded into memory
        MediaTracker md = new MediaTracker(new Frame());
        md.addImage(source,0);
        try
        {
            md.waitForID(0);
        }
        catch(InterruptedException iex)
        {
            iex.printStackTrace();
        }
        int height = source.getHeight(null);
        int width = source.getWidth(null);
        // Create a BufferedImage compatible with Graphics Configuration
        // so that its accelerated; Get Graphics2D of the image and draw
        //onto it the source image.

        GraphicsDevice systemGfx = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        GraphicsConfiguration gc = systemGfx.getDefaultConfiguration();
      BufferedImage acceleratedImage = gc.createCompatibleImage(width,height,Transparency.TRANSLUCENT);
        Graphics2D associatedGraphics = acceleratedImage.createGraphics();
        associatedGraphics.drawImage(source,0,0,null);
        return acceleratedImage;
    }

I have enabled System Properties for Aplha Acceleration and forcing vram (which i suppose is to force images to be stored in vid ram). And also using Buffered Strategy.

Hi

You should try something like this:


ImageCapabilities iCap=backBuffer.getCapabilities();

if(iCap.isTrueVolatile()) System.out.println("buffer is true Volatile!");
if(iCap.isAccelerated()) System.out.println("buffer is true Accelerated!");

Where backBuffer is your Volatile image.

I don’t think you can get accelerated Alpha transparency… I know there’s not a such acceleration on Java2d now.

Your code looks fine (other than creating a new frame for each image).

I assume you have at least DX7 installed - we need it for D3D-accelerated translucency.

Try running your app with graphics primitive tracing turned on and see if you have accelerated blits (that is, if there are any D3DBlitLoops::Blit primitives listed).

To turn tracing on:
java -Dsun.java2d.trace=log App
or
java -Dsun.java2d.trace=count App

use -Dsun.java2d.trace=help for more info.

Make sure you are setting the alpha acceleration properties before any AWT/Swing components are initialised.
Otherwise, they will have no effect.

also, heres a far neater image loader.


import java.awt.*;
import java.awt.image.*;
public class ImageLoader
{
   final GraphicsConfiguration gc;
   public ImageLoader(GraphicsConfiguration gc)
   {
      if(gc==null)
      {
         gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
      }
      this.gc = gc;
   }

   public BufferedImage loadImage(String resource)
   {
      try
      {
         BufferedImage src = javax.imageio.ImageIO.read(getClass().getResource(resource));
         BufferedImage dst = gc.createCompatibleImage(src.getWidth(),src.getHeight(),src.getColorModel().getTransparency());
         Graphics2D g2d = dst.createGraphics();
         g2d.setComposite(AlphaComposite.Src);
         g2d.drawImage(src,0,0,null);
         g2d.dispose();
         return dst;
      }
      catch(java.io.IOException e)
      {
         return null;
      }
   }
}

Okae, my Images are Volatile and Accelerated !!!
And i do see

sun.awt.windows.D3DBlitLoops::Blit(“Integer ARGB D3D with translucency”, SrcOver, “Integer RGB
DirectDraw”)

i was wondering that what effect does the Acceleration Threshold have on Rendering ??
And Thanks Abuse, for telling me that i have to set the properties before i init anything Graphical. No wonder my java -Dsun.java2d.trace=count wasnt working before.

If java2D uses DirectDraw under the hood, why is it still so slow ? I heard that i can see a lot of performance difference if i switch to Lwjgl / jogl etc etc. ?

Hey Abuse does

 g2d.setComposite(AlphaComposite.Src); 

give you translucent images? They are still not hardware accelerated right?

Trembovetsky,

[quote]I assume you have at least DX7 installed - we need it for D3D-accelerated translucency.
[/quote]
So are you saying we can have translucent accelerated images?

[quote]Hey Abuse does

 g2d.setComposite(AlphaComposite.Src); 

give you translucent images? They are still not hardware accelerated right?
[/quote]
no, that line insures the alpha values in the created image are the same as those in the source image.

The code would work fine without that line… on Windows.
This is because blank images created under Windows default to 0x000000 i.e. a totally transparent black pixel.
However on Mac, they default to something different.
Which, without that line of code would result in you losing the alpha channel in the source image.

Kommi: yes, we have acceleration of translucent images on windows since 1.4.1_02, but it’s turned off by default. Do a search for -Dsun.java2d.transaccel=true to find out more.

ranabp: acceleration threshold specifies how many times you need to copy from a yet unaccelerated managed image before we attempt to accelerate it. The default is 1. If you set it to 0, we’ll try to accelerate the image on the first copy.

It’s not clear why your app is running slow. Please run tracing with =count and post the output. Most likely you’re performing one of unaccelerated operations, causing the back-buffer to be punted to system memory.

This is what i get sometimes when i try to enable trace=count

Welcome to AlienAttaX 0.7b
Init - System
Trying to enable Alpha Hardware Acceleration - true
Forcing DirectDraw to Use VRAM - true
DirectDraw surfaces constrained to use vram
New Acceleration Threshold: 1
Acceleration for translucent images is enabled.
Loading Errors ? false
Time constructing GM - 16
java.lang.InternalError: not implemented yet
at sun.awt.windows.Win32OffScreenSurfaceData.getRaster(Win32OffScreenSurfaceData.java:338)
at sun.java2d.loops.OpaqueCopyAnyToArgb.Blit(CustomComponent.java:73)
at sun.java2d.loops.Blit$TraceBlit.Blit(Blit.java:301)
at sun.java2d.loops.GraphicsPrimitive.convertFrom(GraphicsPrimitive.java:525)
at sun.java2d.loops.MaskBlit$General.MaskBlit(MaskBlit.java:186)
at sun.java2d.loops.MaskBlit$TraceMaskBlit.MaskBlit(MaskBlit.java:229)
at sun.java2d.loops.MaskFill$General.MaskFill(MaskFill.java:155)
at sun.java2d.loops.MaskFill$TraceMaskFill.MaskFill(MaskFill.java:185)
at sun.java2d.loops.DrawGlyphList$General.DrawGlyphList(DrawGlyphList.java:109)
at sun.java2d.loops.DrawGlyphList$TraceDrawGlyphList.DrawGlyphList(DrawGlyphList.java:139)
at sun.java2d.pipe.SolidTextRenderer.drawGlyphList(SolidTextRenderer.java:38)
at sun.java2d.pipe.GlyphListPipe.drawString(GlyphListPipe.java:47)
at sun.java2d.pipe.ValidatePipe.drawString(ValidatePipe.java:123)
at sun.java2d.SunGraphics2D.drawString(SunGraphics2D.java:2534)
at GameManager.paint(GameManager.java:535)
at AlienAttaX.render(AlienAttaX.java:69)
at AlienAttaX.run(AlienAttaX.java:79)
at java.lang.Thread.run(Thread.java:534)

Apart from that, when the trace works, i get :
RUNNING IN A WINDOW :: with bufferstrat

6639 calls to sun.java2d.loops.Blit::Blit(IntArgb, Xor, IntRgb)
8912 calls to sun.awt.windows.D3DBlitLoops::Blit(“Integer ARGB D3D with translucency”, SrcOver, “Int
eger RGB DirectDraw”)
191 calls to sun.java2d.loops.Blit::Blit(ByteIndexedBm, SrcOverNoEa, IntArgb)
3264 calls to sun.java2d.loops.DrawGlyphList::DrawGlyphList(OpaqueColor, SrcNoEa, AnyInt)
506 calls to sun.java2d.loops.MaskFill::MaskFill(AnyColor, SrcOver, IntRgb)
1088 calls to sun.awt.windows.Win32BlitLoops::Blit(“Integer RGB DirectDraw”, SrcNoEa, “Integer RGB D
irectDraw”)
15 calls to sun.java2d.loops.Blit::Blit(ByteIndexedBm, SrcOverNoEa, IntRgb)
5 calls to sun.java2d.loops.Blit::Blit(IntRgb, SrcNoEa, IntRgb)
54257 calls to GDIFillShape
107336 calls to sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntArgb, SrcOverNoEa, “Integer RGB Direc
tDraw”)
5 calls to sun.awt.windows.Win32BlitLoops$DelegateBlitBgLoop::BlitBg(Any, SrcNoEa, “Integer RGB Dire
ctDraw with 1 bit transp”)
639 calls to sun.awt.windows.Win32BlitLoops::Blit(“Integer RGB DirectDraw with 1 bit transp”, SrcOve
rNoEa, “Integer RGB DirectDraw”)
888 calls to sun.java2d.loops.MaskFill::MaskFill(AnyColor, Src, IntRgb)
107336 calls to sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, IntRgb)
5 calls to sun.java2d.loops.SetFillRectANY::FillRect(AnyColor, SrcNoEa, Any)
982 calls to DDFillRect
1093 calls to sun.java2d.loops.DrawGlyphList::DrawGlyphList(AnyColor, Xor, AnyInt)
1 call to sun.java2d.loops.ScaledBlit::ScaledBlit(ByteIndexedBm, SrcOverNoEa, IntRgb)
99 calls to sun.java2d.loops.Blit::Blit(IntArgb, SrcNoEa, IntArgb)
981 calls to GDIDrawShape
294251 total calls to 20 different primitives

Running in FullScreen also bufferstrat

5 calls to sun.awt.windows.Win32BlitLoops$DelegateBlitBgLoop::BlitBg(Any, SrcNoEa, “Integer RGB Dire
ctDraw with 1 bit transp”)
36 calls to sun.java2d.loops.Blit::Blit(IntArgb, SrcNoEa, IntArgb)
5 calls to sun.java2d.loops.Blit::Blit(IntRgb, SrcNoEa, IntRgb)
993 calls to sun.java2d.loops.DrawGlyphList::DrawGlyphList(AnyColor, Xor, AnyInt)
150 calls to sun.java2d.loops.Blit::Blit(ByteIndexedBm, SrcOverNoEa, IntArgb)
5643 calls to sun.java2d.loops.Blit::Blit(IntArgb, Xor, IntRgb)
1680 calls to sun.java2d.loops.MaskFill::MaskFill(AnyColor, Src, IntRgb)
15 calls to sun.java2d.loops.Blit::Blit(ByteIndexedBm, SrcOverNoEa, IntRgb)
106415 calls to sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntArgb, SrcOverNoEa, “Integer RGB Direc
tDraw”)
106415 calls to sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, IntRgb)
5 calls to sun.java2d.loops.SetFillRectANY::FillRect(AnyColor, SrcNoEa, Any)
44375 calls to GDIFillShape
6172 calls to sun.awt.windows.D3DBlitLoops::Blit(“Integer ARGB D3D with translucency”, SrcOver, “Int
eger RGB DirectDraw”)
2988 calls to sun.java2d.loops.DrawGlyphList::DrawGlyphList(OpaqueColor, SrcNoEa, AnyInt)
785 calls to DDFillRect
1 call to sun.java2d.loops.ScaledBlit::ScaledBlit(ByteIndexedBm, SrcOverNoEa, IntRgb)
784 calls to GDIDrawShape
675 calls to sun.awt.windows.Win32BlitLoops::Blit(“Integer RGB DirectDraw with 1 bit transp”, SrcOve
rNoEa, “Integer RGB DirectDraw”)
277142 total calls to 18 different primitives

MeThinks that all the trouble is because of GDI - Which i think doesnt use using real directdraw acceleration !!! Since i am a “newless clubie” to the game scene, i dont know much.

[quote]Okae, my Images are Volatile and Accelerated !!!
And i do see

sun.awt.windows.D3DBlitLoops::Blit(“Integer ARGB D3D with translucency”, SrcOver, “Integer RGB
DirectDraw”)
[/quote]
My apps trace log has no sign of the above mentioned D3DBlitLoops. Mine looks more like this:

[quote]sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, Ushort565Rgb)
sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntArgb, SrcOverNoEa, “Short 565 RGB DirectDraw”)
sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, Ushort565Rgb)
sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntArgb, SrcOverNoEa, “Short 565 RGB DirectDraw”)
sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, Ushort565Rgb)
sun.awt.windows.Win32BlitLoops::Blit(“Short 565 RGB DirectDraw”, SrcNoEa, “Short 565 RGB DirectDraw”)
sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntArgb, SrcOverNoEa, “Short 565 RGB DirectDraw”)
sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, Ushort565Rgb)
sun.java2d.loops.MaskFill::MaskFill(AnyColor, Src, Ushort565Rgb)
sun.awt.windows.Win32BlitLoops::Blit(“Short 565 RGB DirectDraw with 1 bit transp”, SrcOverNoEa, “Short 565 RGB DirectDraw”)
[/quote]
Does this mean I don’t have hardware acceleration? :’(

Yes.
It seems that Java is using the portable version (java2d)of graphics function for some reason.

Maybe you are not using VolatileImage when you have to.

Anyway I don’t think that a feature (alpha acceleration) can be useful if to activate it I have to use a command line parameter!

Also if it is present only on windows why we should sacrify portability?

If I want to make a game with alpha transparence for windows I can choose the combo C++/DX, which is faster than NOT ACCELERATED Java version.

[quote]Yes.
It seems that Java is using the portable version (java2d)of graphics function for some reason.
Maybe you are not using VolatileImage when you have to.
[/quote]
I am using managed Images. What else could be wrong?

are you modifying the managed images ever?

[quote]are you modifying the managed images ever?
[/quote]
what do you mean by modify. All I am doing is rendering them to the screen. I really need to fix this and don’t know where to start.

[quote]Yes.

Anyway I don’t think that a feature (alpha acceleration) can be useful if to activate it I have to use a command line parameter!
[/quote]
Maybe not now but I am sure it will be a standard in future versions, so learning it now makes sence.

I undersand what you say, but I have already a sprite library which can do rotations, scaling e transparency, and for now I don’t use any of them.

I agree with you about learning it, but I’ll not use till it will become standard.

I hope it will happen soon…

Yeah max, but aplha acceleration is helpful when u are showing off ur snazzy (or even shabby) game effects.
And u can set the aplha enabler in system properties anywayz !! :slight_smile:

106415 calls to sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntArgb, SrcOverNoEa, “Integer RGB DirectDraw”)
106415 calls to sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, IntRgb)

These are the things that kill your performance. This is a software blit of a translucent buffered image to an accelerated image (backbuffer).

I see a couple of possibilites:

  • you have some sprites as bufferedImages for some reason (so they are not being accelerated)
  • you create more sprites that can fit in vram, some of them get accelerated, but most - don’t
  • you render to your sprites more often than you copy from them

hw accelerated translucecy was not enabled by default because we didn’t have enough time to properly test it. Also, it’s very limited, as you can see: only for certain types of images, one particular compositing rule (SrcOver).

In the next release we’re hoping to have it on by default, and for all images.

krypto, it looks like you have our D3D functionality disabled for some reason: I can see that DDraw works fine (opaque and 1-bit transparent images are accelerated).

I’m assuming you do create translucent images with createCompatibleImage(w,h,Transparency.TRANSLUCENT), and have acceleration enabled with -Dsun.java2d.translaccel=true, right?

If so, check that you don’t disable d3d via command line option or environment variable - a lot of people did that to avoid problems with D3D on Radeon boards with earlier jdk releases.

Another possibility is that your hardware doesn’t support the functionality we need in hardware.