Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
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
  
  Include a link with my name & email   

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