Here’s that long-time-ago promised information on some of “hidden” features in 1.4.1_02.
In 1.4.1_02, we’ve implemented a number of features
mostly dealing with acceleration of translucent
images in hardware using Direct3D. Unfortunately we
didn’t have enough time to test them appropriately,
so we had to disable them by default for now.
Please note that flags mentioned here are ‘for educational purposes
only’, and can (and most likely will) be changed in the future
releases.
Note: Always make sure you have the latest video drivers installed.
Also, we recommend at least DirectX 7 to be installed.
- Acceleration of translucent images
Images created with- GraphicsConfiguration.createCompatibleImage(w,h, Transparency.TRANSLUCENT),
- Toolkit images (those loaded with Toolkit.getImage()) with
translucent color model
will be attempted to be accelerated in vram.
Disabled by default, enabled via flag:
-Dsun.java2d.translaccel=true
You will also need to set the following flag:
-Dsun.java2d.ddforcevram=true
With this flag set Java2D will attempt to put images created as
mentioned above into vram, and use D3D for rendering (compositing)
them to the screen or to a VolatileImage.
Currently only translation transforms are supported (no rotation,
scaling, etc).
The following code fragment illustrates the use of accelerated
images. The fragment assumes that backBuffer is a VolatileImage.
BufferStrategy can be used as well.
Image translucentImage = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
//...
Graphics2D g2 = (Grahics2D)backBuffer.getGraphics();
g2.drawImage(translucentImage, x, y, null);
Compositing with extra alpha with SRC_OVER rule (which is
the default Graphics2D compositing rule) is accelerated, so the
following code will allow the use of hardware for compositing:
Image translucentImage = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
// ...
float ea = 0.5;
Graphics2D g2 = (Grahics2D)backBuffer.getGraphics();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ea));
g2.drawImage(translucentImage, x, y, null);
- 16-bit 4444 image format support.
2.1. Software loops support:
4444 image format is 16-bit per pixel image format, ARGB.
It’s useful if you’re trying to save some memory, as it takes half
as much memory as TYPE_INT_ARGB.
One can create an Argb 4444 BufferedImage like this:
private static final int DCM_4444_RED_MASK = 0x0f00;
private static final int DCM_4444_GRN_MASK = 0x00f0;
private static final int DCM_4444_BLU_MASK = 0x000f;
private static final int DCM_4444_ALP_MASK = 0xf000;
static ColorModel translucentCM = null;
public static ColorModel getTranslucentColorModel() {
if (translucentCM == null) {
translucentCM = new DirectColorModel(16,
DCM_4444_RED_MASK,
DCM_4444_GRN_MASK,
DCM_4444_BLU_MASK,
DCM_4444_ALP_MASK);
}
return translucentCM;
}
and then:
// ...
ColorModel cmSw = getTranslucentColorModel();
wr = cmSw.createCompatibleWritableRaster(mWidth, mHeight);
BufferedImage image = new BufferedImage(cmSw, wr, cmSw.isAlphaPremultiplied(), null);
Then the buffered image can be used like any other
BufferedImage. Note that it won't be accelerated, but
we've added some optimized software loops for this image format.
2.2 Acceleration of 4444 images:
When enabled, forces the accelerated surfaces for
managed images, created with
GraphicsConfiguratio.createCompatibleImage(w,h, TRANSLUCENT)
or translucent images loaded with Toolkit.getImage
to be in 4444 format, saving vram and system memory. The system
memory surface for these images will be in 4444 format as well.
Disabled by default, enabled via flag:
-Dsun.java2d.d3dtexbpp=16
This option is useful when you have lots of images to be stored in
vram. The downside is poorer quality.
Note that some videoboards (for example, 3dfx Voodoo3) do not
support 32-bit textures, which are attempted to be used by defaul,
so this flag must be set in order to get
acceleration of translucent images.
- Changing acceleration threshold
Acceleration threshold controls how many copies from managed images
will occur before we create a vram version of the image.
If the number is ‘0’, the accelerated surface is created during
image initialization.
The default threshold is 1.
A new threshold can be set via flag:
-Dsun.java2d.accthreshold=N (where N>=0)
If the threshold is set to 0, all the vram surfaces
for all managed images will be created at the image
creation time, and updated during the first copy from image.
This flag can be used to eliminate the initial delay in rendering
when the images are being copied to the vram after the first few
copies. Instead, the delay is effectively shifted to the image
creation time.
This could be useful behavior when you know that your application
will be able to take advantage of image management; just get the
overhead of the copy over with at the start instead of incurring some
number of slower copies to begin with and then having the copy overhead
at some later time.
- How to check if the acceleration works in your configuration.
Compile and run the following test:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class Test extends JFrame implements ActionListener {
Image img = null;
public Test() {
setLocation(200, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setSize(170, 200);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
img = gc.createCompatibleImage(100, 100, Transparency.TRANSLUCENT);
Graphics g = img.getGraphics();
g.setColor(new Color(255, 0, 0, 128));
g.fillRect(0, 0, 99, 99);
getContentPane().add("Center", new JComponent() {
public void paintComponent(Graphics g) {
float ea = (float)extraAlpha/255f;
((Graphics2D)g).setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ea));
g.drawImage(img, 30, 30, null);
}
});
new javax.swing.Timer(50, this).start();
}
int extraAlpha = 1;
int alphaStep = 10;
public void actionPerformed(ActionEvent e) {
extraAlpha += alphaStep;
if (extraAlpha < 0 || extraAlpha > 255) {
alphaStep = -alphaStep;
extraAlpha += alphaStep;
}
repaint();
}
public static void main(String argv[]) {
try {
System.setProperty("sun.java2d.translaccel", "true");
System.setProperty("sun.java2d.ddforcevram", "true");
System.setProperty("sun.java2d.trace", "count");
System.setProperty("sun.java2d.accthreshold", "0");
if (argv != null && argv.length > 0 && argv[0].equals("-16")) {
System.setProperty("sun.java2d.d3dtexbpp", "16");
}
} catch (Exception e) {
System.err.println("Can't set properties: " + e);
}
new Test().setVisible(true);
}
}
After you quit it, it’ll print out the trace information about the
loops which have been used. If you see a line there similar to:
xxxx calls to sun.awt.windows.D3DBlitLoops::Blit(“Integer ARGB D3D with translucency”, SrcOver, “Short 565 RGB DirectDraw”)
or, if the test run with ‘-16’ parameter to force 16-bit textures,
xxxx calls to sun.awt.windows.D3DBlitLoops::Blit(“UShort 4444 ARGB D3D with translucency”, SrcOver, “Short 565 RGB DirectDraw”)
it means that the acceleration works on your configuration.
- Known issues
- Rendering accelerated translucent images to the screen
is not clipped. While blasting your rendering through
all windows covering your window certainly looks cool, you should
be using double buffering anyway
(either through BufferStrategy, Swing back-buffer or an
app-managed VolatileImage back-buffer). - Sometimes the contents of the translucent managed images
are not restored properly after the display change - still no translucent VolatileImages, as it requires new API,
which we cannot introduce in a dot (maintenance) release.
We hope to have it in 1.5. - managed translucent images may take up more vram than
their size, because the textures are allocated
with sizes of power of two. So, for example,
a 33x33 image will actually take as much vram as 64x64 one. - there’s no way to automatically choose between 16- and 32-
bit textures on the fly depending on the desktop bit depth,
for example. You can sort of workaround it as shown in
the test app above. - on some hardware (like ATI Radeon) the performance depends on the
display mode depth your app is running at. For some reason it
works much faster if the display mode depth is 16 bit,
no matter what depth the textures (manaded images) are.
-
Some other useful flags:
-Dsun.java2d.ddscale=true - turns on hardware scaling support -
Feedback
We post this solely to get your feedback on the features we’ve
already implemented and are yet to implement in future releases.
Please send us your comments, either on this forum,
or directly on java2d-comments@sun.com - this alias goes directly to the
development team.