-
Bug
-
Resolution: Fixed
-
P3
-
1.4.0
-
beta3
-
x86
-
windows_98, windows_2000
Name: bsC130419 Date: 05/31/2001
java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)
VolatileImages are wonderful once if they have simple content, but creating and
drawing on them using certain Graphics2D facilities can incur a hefty
performance penalty that makes them unusuable in certain important cases. When
testing the JDK1.4, I discovered a major performance drop in an application of
mine that makes extensive use of double buffering. After recoding to take
advantage of VolatileImages, the performance was even worse, which was
certainly not what I expected.
The problem is I draw extensively with AlphaComposites so that users can drag
objects over a background and still see the background beneath the dragged
objects. This is an important GUI idiom which Java really should not make
impossible to implement.
To determine where the problem lies, I wrote a short program that draws 1200
colored rectangles (200x200) into a normal BufferedImage created by
Component.createImage(w,h) and into a VolatileImage returned by
Component.createVolatileImage(w,h). I did this twice, once with a standard
solid color and once with a composite.
The results (in milliseconds) are listed below for my Windows 2000 475MHz
laptop:
Times measured for drawing rectangles on top of each other using a
SOLID color:
standard image: 1102
volatile image: 30
Times measured for drawing rectangles on top of each other using a
COMPOSITE (AlphaComposite) color:
standard image: 5097
volatile image: 21271 (!!!)
As happy as I am about the speed up with the solid colors, the VolatileImage
consistently takes 4 times as long as the BufferedImage when an AlphaComposite
is used, which is bad, especially when the area of the rectangle gets larger.
The (quickly and badly written) program that produced these results follows. I
put the test in the paintComponent method so you can causing the window to draw
itself runs the tests:
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class TestImageTypes {
public static void main(String args[]) {
JFrame app = new JFrame("Image Type Tester");
boolean f = true;
if (args.length>0 && args[0].equals("-solid")) f = false;
else System.out.println("Testing composite color speeds.\n(java
TestImageTypes -solid to test solid color speeds.)\n");
app.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
app.getContentPane().add(new Tester(f));
app.pack();
app.setVisible(true);
}
}
class Tester extends JPanel {
static AlphaComposite myAlpha = AlphaComposite.getInstance
(AlphaComposite.SRC_OVER, 0.65f);
static Color myColor = new Color(124,23,188);
Image im;
VolatileImage vi;
Graphics2D g1, g2;
boolean flag;
public Tester(boolean f) {
flag = f;
}
public void createImages() {
vi = this.createVolatileImage(200,200);
g2 = (Graphics2D)vi.getGraphics();
im = this.createImage(200,200);
g1 = (Graphics2D)im.getGraphics();
}
private void recreateImage() {
GraphicsConfiguration gc = this.getGraphicsConfiguration();
if ((vi.validate(gc)) == VolatileImage.IMAGE_INCOMPATIBLE) {
g2.dispose();
vi = this.createVolatileImage(200,200);
}
}
public void paintIt(Graphics2D g) {
g.setColor(Color.white);
g.fillRect(0,0,200,200);
if (flag) g.setComposite(myAlpha);
g.setColor(myColor);
for (int x = 0; x<100; x++) {
g.fillRect(x,0,100,200);
}
if (flag) g.setComposite(AlphaComposite.SrcOver);
}
public Dimension getPreferredSize() {
return new Dimension(200,200);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (vi == null) createImages();
int i;
long s = System.currentTimeMillis();
for (i = 0; i<12; i++) {
paintIt(g1);
}
System.out.println("standard image: "+(System.currentTimeMillis() - s));
recreateImage();
s = System.currentTimeMillis();
for (i = 0; i<12; i++) {
paintIt(g2);
}
System.out.println("volatile image: "+(System.currentTimeMillis() - s));
g.drawImage(im, 0, 0, this);
}
}
(Review ID: 125368)
======================================================================
This is also affecting performance of Swing apps that use translucency effects
(e.g., the calendar demo of JavaOne 2001).
------------------
Updated the synopsis to reflect that this problem also affects scaling to
a VolatileImage object, as described in bug 4504148.
###@###.### 2001-09-20
- duplicates
-
JDK-4504148 Massive performance drop in Graphics.drawImage()
-
- Closed
-