|
Quick Lists
|
|
Bug ID:
|
4835595
|
|
Votes
|
12
|
|
Synopsis
|
PixelGrabber.grabPixels runs up to 600 times slower on JDK1.4.1 than on JDK1.3.1
|
|
Category
|
java:classes_2d
|
|
Reported Against
|
rc
, 1.4.1
, tiger-beta2
|
|
Release Fixed
|
6u10(b26)
|
|
State
|
10-Fix Delivered,
Verified,
bug
|
|
Priority:
|
3-Medium
|
|
Related Bugs
|
6307181
,
6309072
,
4915527
,
6409688
,
5079092
,
6205557
|
|
Submit Date
|
20-MAR-2003
|
|
Description
|
FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
versus
java version "1.3.1_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_03-b03)
Java HotSpot(TM) Client VM (build 1.3.1_03-b03, mixed mode)
FULL OS VERSION :
xxxxx OS trust 5.8 Generic_108528-18 sun4u sparc xxxxx W, xxxxx -Blade-100
EXTRA RELEVANT SYSTEM CONFIGURATION :
24-bit color
A DESCRIPTION OF THE PROBLEM :
The sample program below takes about 93 seconds to execute the grabPixels() call under JDK 1.4.1 on a Solaris 8, Blade 100. It takes 0.16 seconds
under JDK 1.3.1. (For systems with 8-bit color, the time is about 0.1 seconds under both JDKs.)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the code on a 24-bit color Blade 100, Solaris 8 under JDK1.4.1 and JDK1.3.1. The output to standard out shows the times for the grabPixels call
EXPECTED VERSUS ACTUAL BEHAVIOR :
execution time of about 200 milliseconds in all cases
JDK 1.4.1 output is about 93000 milliseconds
JDK 1.3.1 output is about 160 millseconds
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class Pixel implements ActionListener {
private JButton b;
private JFrame f;
public Pixel () {
f = new JFrame("Copy Frame");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(700,500);
Container cp = f.getContentPane();
JPanel p = new JPanel();
cp.add(p);
b = new JButton("Copy It");
b.addActionListener (this);
p.add(b);
f.setVisible( true);
}
public void actionPerformed (ActionEvent e) {
if (e.getSource() == b) {
Dimension size = f.getSize();
Image customer = f.createImage(size.width,size.height);
Graphics gr = customer .getGraphics();
f.printAll(gr);
int [] pixels = new int[size.width*size.height];
PixelGrabber pg = new PixelGrabber ( customer , 0, 0,
size.width, size.height, pixels, 0, size.width);
try {
long start = System.currentTimeMillis();
System.out.println("starting");
pg.grabPixels();
long end = System.currentTimeMillis();
System.out.println("end after "+ (end-start) + " ms");
} catch (InterruptedException ie) {
System.out.println("grab exception="+ie);
}
}
}
public static void main (String[] args) {
new Pixel();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Replace
Image customer = f.createImage(size.width,size.height);
with
BufferedImage customer = new BufferedImage(size.width,size.height, BufferedImage.TYPE_INT_RGB);
(Review ID: 182843)
======================================================================
FULL PRODUCT VERSION :
java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)
FULL OPERATING SYSTEM VERSION :
xxxxx OS brooke 5.9 Generic_112233-01 sun4u sparc xxxxx W,Ultra-1
ADDITIONAL OPERATING SYSTEMS :
Linux gescher 2.4.19-PMC-SMP #3 SMP Mon Sep 9 22:33:11 CEST 2002 i686 unknown
A DESCRIPTION OF THE PROBLEM :
PixelGrabber + setenv DISPLAY slower in java 1.4
PixelGrabber is too slow in version 1.4 when I'm running a program in a remote machine but displaying the windows in my workstation
REGRESSION. Last worked in version 1.3
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Log in on another machine; setenv DISPLAY to the machine you are
2. Run the given program (on the machine you've just logged in) with java 1.2/1.3 and 1.4.
EXPECTED VERSUS ACTUAL BEHAVIOR :
PixelGrabber should be so fast as in version 1.3.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
output, v.1.3.0:
Starting
9
output, v.1.4.1:
Starting
27074
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.image.*;
public class Foo {
public static void main(String[] args) throws Exception {
String s = "DonaudampfschifffahrtsgesellschaftskapitM-^OÀ»n";
Frame f = new Frame();
f.setSize(300, 300);
f.show();
Thread.sleep(1500);
Font font = f.getFont();
FontMetrics fm = f.getFontMetrics(font);
int h = fm.getMaxAscent() + fm.getMaxDescent() + 2;
long sum = 0;
for(int i = 0; i < 10; i++) {
int w = fm.stringWidth(s) + 2;
PixelGrabber pg = new PixelGrabber(f.createImage(w, h), 0, 0, w, h, new int[w*h], 0, w);
long start = System.currentTimeMillis();
pg.grabPixels();
long end = System.currentTimeMillis();
sum += end - start;
}
System.out.println(sum);
System.exit(0);
}
}
---------- END SOURCE ----------
(Review ID: 166897)
======================================================================
Posted Date : 2006-05-31 21:11:23.0
|
|
Work Around
|
N/A
|
|
Evaluation
|
Image processing is generally handled by 2D.
xxxxx@xxxxx 2003-03-20
Can't reproduce this on my Solaris 7 box. Times with 1.4.2, 1.4.1, 1.4, 1.3.1
are all about .3 ms.
xxxxx@xxxxx 2003-03-20
I am able to reproduce this bug:
1. Ultra-5_10 witch M640
jdk1.4.1 332196 ms
jdk1.5.0b02 296381 ms
jdk1.3.1 306 ms
2. Ultra-5_10 withc Raptor GFX:
jdk1.4.1 135474 ms
jdk1.5.0b02 122419 ms
jdk1.3.1 238 ms
xxxxx@xxxxx 2003-03-21
I am able to reproduce this on my system (Solaris 8, running through VNC) and
see something like:
jdk1.3.1 181 ms
jdk1.5 16 seconds
The key here is our use of pixmaps, starting in the 1.4 release. For example, if I run with pixmaps disabled (-Dsun.java2d.pmoffscreen=false), then I see something more like
jdk1.5 243 ms
While still slower than 1.3.1, this obviously represents much greater performance than with pixmaps enabled....
The different numbers above are probably due to running on configurations that do or do not have DGA enabled; when DGA is enabled, we use DGA instead of pixmaps (and thus the user would not see the problem there).
Presumably, we are getting bottlenecked in per-pixel transactions through X asking for the pixel values, whereas we used to simply run through cached memory reading the pixel values (in 1.3.1, or in a DGA-enabled system).
The fix would seem to be either doing block transfers of the pixels from pixmaps to avoid the per-pixel overhead, or possibly punting a pixmap image into a faster memory location when this type of read operation is detected.
xxxxx@xxxxx 2003-09-30
There are several reasons for the slowdown.
The main is, of course, getting each pixel through X via XGetImage(1x1)
request (DataBufferNative.getElem).
Even though we notice the read operations and punt a Pixmap
to a shared memory pixmap, it's still very slow. On a remote display it'd be
even slower, since we won't be able to punt, and the pixels will have
to get over the wire.
So, on my system:
jdk1.3.1 30ms
jdk1.5 3418ms // 100x slowdown
jdk1.5 J2D_PIXMAPS=server 23406ms // 800x slowdown: worst case, no punting (server pixmaps forced)
jdk1.5 J2D_PIXMAPS=shared 625ms // 20x slowdown: by eliminating X overhead (forcing shared memory pixmaps)
jdk1.5 return from native getElem 325ms // 10x slowdown: immediate return from native getElem, no X or JNI calls
jdk1.5 return from java getElem 85ms // 3x slowdown: immediate return from DBN.getElem in java
This means that we have 300ms in JNI-only overhead, which is the main concern
of another bug (4740695), then we have ~50ms of what appears to be a new
pipeline overhead.
But we spend the most time dealing with X11. We can probably eliminate some of it
with more aggressive punting strategy (punt to a shared memory pixmap earlier, or
if we notice that there's a lot of single-pixel reads), but this still won't
address the remote-X case, where we really want to have the pixels locally.
Another approach is, as mentioned above, to attempt block transfers,and cache
the pixels at native level (too much trouble to do it in java, say,
CachingDataBufferNative class, since it'll be hard to to detect if the cache
has been invalidated by other thread's writing to the image).
Will need further investigation.
xxxxx@xxxxx 2003-11-10
This bug is mostly addressed in JDK7, since with the fix for
data buffer tracking we no longer put "component" images
(those created with GC.createCompatibleImage and Component.createImage)
into the pixmaps.
We could do similar "fix" in some 6ux release.
Posted Date : 2007-06-29 20:17:20.0
We will do the work around for this release: do not
put images created with createImage or createCompatibleImage into
Pixmaps.
Originally these images were created in Pixmaps to help applications
which do double buffering using createImage - mostly Swing
apps. Since then Swing's painting mechanism changed to use BufferStrategy
or VolatileImage as back-buffer, so it is not as important to create
these images in Pixmaps.
Note that the managed images will continue to be cached in pixmaps.
Posted Date : 2008-05-23 01:23:27.0
|
|
Comments
|
Submitted On 22-OCT-2003
ewanmellor
I am experiencing the same problem with Intel P3 500, Linux 2.4.18,
XFree86 4.1.0.1, 24 bpp, Matrox Millenium G200. I am running locally (no
VNC or remote X involved).
The problem affects
Java HotSpot(TM) Client VM (build 1.4.2_01-b06, mixed mode)
Java HotSpot(TM) Client VM (build Blackdown-1.4.1-01, mixed mode)
but does not affect
Java HotSpot(TM) Client VM (build Blackdown-1.3.1-FCS, mixed mode)
The workaround mentioned (-Dsun.java2d.pmoffscreen=false) is effective,
though like the Solaris tests does not restore performance to JDK 1.3
levels.
Using the Pixel benchmark above:
JDK 1.4.2: 12428 msec.
JDK 1.4.2, with -D workaround: 204 msec.
JDK 1.3.1: 178 msec.
xdpyinfo reports:
supported pixmap formats:
depth 1, bits_per_pixel 1, scanline_pad 32
depth 4, bits_per_pixel 8, scanline_pad 32
depth 8, bits_per_pixel 8, scanline_pad 32
depth 15, bits_per_pixel 16, scanline_pad 32
depth 16, bits_per_pixel 16, scanline_pad 32
depth 24, bits_per_pixel 32, scanline_pad 32
depth 32, bits_per_pixel 32, scanline_pad 32
It also reports the presence of the XFree86-DGA extension, though I think
that it's not being used.
Submitted On 10-SEP-2004
E.Preuss
Hi, is there a workaround for applets in a browser, that doesn't use BufferedImage? I need to code java1.1 compliant in my project...
Submitted On 13-SEP-2004
dmitri_trembovetski
Unfortunately I can't think of anything you can do in 1.1.x api to work around this problem programmaticaly.
You can try to make sure your users somehow set the -Dsun.java2d.pmoffscreen=false flag - either in the plugin control panel, or by setting _JAVA_OPTIONS="-Dsun.java2d.pmoffscreen=false" env. variable.
Dmitri Trembovetski
Java2D Team
Submitted On 16-SEP-2004
xjzhuqiang
zhuqing xjzhuqiang@sohu.com
Submitted On 08-AUG-2007
In relation to this I was trying to get the pixels of a ROI within the large image and using PixelGrabber with x, y, w, h offsets took enormous time for grabPixel to work (almost 780 msecs). Instead just by getting the subImage from the original image and grabbing all pixels dramatically reduced the time to 30 msecs a factor of 25.
Submitted On 03-FEB-2009
Can you backport this bug fix to 1.5? We are experiencing it on customer environments but cannot upgrade to any JDK that is later than 1.5.
Submitted On 23-FEB-2009
dmitri_trembovetski
if you want this to be back-ported to 5, buy a support contract for java5 (http://developers.sun.com/services/).
Dmitri
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |