JDK-4323072 : Graphics2D vector rendering causes 100% cpu for high magnification
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.3.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_nt
  • CPU: x86
  • Submitted: 2000-03-18
  • Updated: 2001-08-01
  • Resolved: 2001-08-01
Related Reports
Duplicate :  
Description

Name: skT88420			Date: 03/18/2000


java version "1.3.0rc1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0rc1-T)
Java HotSpot(TM) Client VM (build 1.3.0rc1-S, mixed mode)

also

java version "1.2.2"
Classic VM (build JDK-1.2.2-004, native threads, symcjit)


Please compile and run the following application.  The app displays a simple
polygon object in a canvas, and has a zoom button.  When you click the button,
you zoom 2 times closer to the object.  Each time you zoom, the app displays
the current zoom factor and the time in milliseconds that it took on the
console.  First few
times to draw are less than 50 milliseconds on my machine, a pentium III
laptop.  By the time you zoom 128 times, the time is 130 ms, for 256 times it
is 240 ms, and for 512 times the system hangs, never returns in my
low-tolerance timeframe, and sends the cpu into 100%.

Though you may think this frivolous, it is a vast simplification of a very
realistic process that occurs in mapping - having background objects that are
frequently shown at all magnification levels.  This problem impacts very
heavily when an end-user chooses to zoom way into a map, perhaps because
other data only becomes visible at that magnification.  Please, please, please
fix it, or find us a workaround!
==========================================================
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

public class Frame extends JFrame
{
	private MyCanvas _canvas;

    public static void main(String args[]) {
        new Frame().setVisible(true);
    }


	public Frame()
	{
	    setSize(410,360);
	    addWindowListener(new MyWindowListener());
	    getContentPane().setLayout(new BorderLayout());
	    _canvas = new MyCanvas();
	    getContentPane().add(_canvas, BorderLayout.CENTER);
	    getContentPane().add(new MyButton(), BorderLayout.NORTH);
	}

	private class MyWindowListener extends WindowAdapter {
	    public void windowClosing(WindowEvent event) {
	        setVisible(false);
    		dispose();
    		System.exit(0);
	    }
	}
	
	private class MyActionListener implements ActionListener {
	    public void actionPerformed(ActionEvent event) {
	        _canvas.zoom();
	    }
	}
	
	private class MyButton extends JButton {
	    MyButton() {
	        super("Zoom");
	        addActionListener(new MyActionListener());
	    }
	}
	
    class MyCanvas extends JComponent {
        private AffineTransform transform = new AffineTransform();
        private int xpts[] = { 100, 300, 400, 250, 200, 150, 0, 100 };
        private int ypts[] = { 0, 0, 200, 300, 150, 300, 200, 0 };
        private int npts = 8;
        private Polygon polygon = new Polygon(xpts, ypts, npts);
        private Point2D.Double src = new Point2D.Double();
        private Point2D.Double dst = new Point2D.Double();
        
        private final double zoomFactor = 2.0;
        private final double centreX = 200.0;
        private final double centreY = 150.0;
        private final double transformX = -centreX *0.5;
        private final double transformY = -centreY *0.5;
    
        void zoom() {
            transform.scale(zoomFactor,zoomFactor);
            transform.translate(transformX, transformY);
            repaint();
        }
        
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            transformPolygon();
            long t0 = System.currentTimeMillis();
            drawPolygon((Graphics2D)g);
            showInfo(System.currentTimeMillis()-t0);
        }
        
        void showInfo(long time) {
            System.out.println("zoom="+transform.getScaleX()+"  time="+time);
        }
        
        private void drawPolygon(Graphics2D g2) {
            g2.setColor(Color.cyan);
            g2.fillPolygon(polygon);
            g2.setColor(Color.red);
            g2.drawPolygon(polygon);
        }
    
        private void transformPolygon() {
            polygon = new Polygon();
            for (int i = 0; i < npts; i++) {
                src.setLocation((double)xpts[i], (double)ypts[i]);
                transform.transform(src,dst);
                polygon.addPoint((int)dst.x, (int)dst.y);
            }
        }
    }
}
(Review ID: 101797) 
======================================================================

Comments
EVALUATION This was caused by integer overflow in the line clipping calculations and is a duplicate of bug 4376103. jim.graham@Eng 2001-07-31
31-07-2001