Aha! I think I have it (a little sample code goes a long way here…)
I got your app running here and I think I know what’s going on. In particular, I know why you’re seeing differences between 1.4.0 and 1.4.2 and between ddraw and noddraw.
it’s all because of the cursor flicker…
From jdk1.2 up through 1.4.0, we used ddraw when we needed to copy bits from some system memory surface (a non-ddraw/VRAM image) to the screen. We would lock the screen, copy the bits, and unlock the screen. This performed better than non-ddraw approaches, but had the side-effect of sometimes causing flashing on the desktop. this got particularly annoying with win2k and XP, where things like translucent fading menus and non-hw cursors (due to translucent drop shadows and color cursors) would flicker when we did our stuff (because they would disappear during the lock and reappear after we unlocked).
In 1.4.1, we found a way around this problem. By using GDI, we would (mostly, except for Matrox; I’ve still seen some cursor flickering artifacts there, but I’ve seen it with many other apps on those boards as well) avoid the flicker. And by cleverly arranging the GDI copy routine, we would be able to retain most of the performance of our ddraw copies as well. I say mostly because it can perform almost as fast as ddraw in some situations, but in others it can be significantly slower (10, 20, 30%, whatever). But we decided to take that hit for these copies because:
- the flicker was pretty horrid and lots of people were complaining about it
- with the advent of VolatileImage and other images being cached in VRAM and copied using ddraw blits, the amount of screen-lock situations was hugely decreased.
Your app is running into this issue. I don’t know what numbers you are seeing, but when I ran the app on my desktop system here (XP with a Matrox g550 card), I got about 1800 ms for the vanilla app and about 1400 when I re-enabled ddraw screen locking.
(Note: if you want to make this work on your system, the 2 flags to use are:
-Dsun.java2d.ddlock=true
-Dsun.java2d.gdiblit=false
)
So I believe that this is the performance difference you are seeing between 1.4 and 142.
The other question here is: why aren’t you getting hw-accelerated images? There are a couple of reasons for this:
-
You are creating ARGB images. This means that unless you enable d3d translucency (as of 141_02 and 142 via the -Dsun.java2d.translaccel flag) you will never see this type of image hw-accelerated. Even though the images only contain bitmask-transparent data (from the duke.gif image), we still see them as fully-translucent images and they fall into our translucent-copy routines.
If all you want is transparent-background (vs translucent) images, then either use the image you created to begin with (from the duke.gif image) or call GraphicsConfig.createCompatibleImage(w,h,Transparency.BITMASK)
to get a transparent image. We should be able to cache that image as a ddraw/VRAM image and accelerate it.
-
Even if you do enable hw acceleration for translucency, you’re still out of luck here. This is because your are copying the images directly to the screen. D3d has this lovely delusion that it owns the screen. so now matter what you tell DirectX about a window, the clip region of the desktop, etc., d3d will blast its bits wherever it wants to. So if we enabled d3d-texture ops to the screen you could, for example, copy your sprites all over any overlapping windows on the desktop. That didn’t seem very professional, so we only enable d3d operations if you tell us to (using the flag) AND if you are copying to an accelerated offscreen image (ala the Swing back buffer). So in this case, you might want to create a VolatileImage back buffer (or use the BufferStrategy buffer) and draw the sprites to that buffer before then copying the buffer to the screen. (Just one more caveat: some translucency operations can cause us to punt an offscreen ddraw surface out of vram and mess up this d3d acceleration scheme; if you enable d3d acceleration, also us the -Dsun.java2d.ddforcevram=true flag to tell us to leave the back buffer in vram no matter what).
Make sense?
Good luck,
Chet.