Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4234728

Graphics2D.setClip(Area) causes poor performance for drawPolyline()

XMLWordPrintable

    • 2d
    • x86
    • windows_nt



      Name: dbT83986 Date: 05/01/99


      specifying a Rectangle as parameter to Graphics2D.setClip()
      causes virtually no performance difference compared with no
      clip at all. But, the exact same Rectangle, converted into a
      java.awt.geom.Area, causes a 10x performance degradation.

      Curiously, the main hit is on Graphics.drawPolyline() whereas
      Graphics.fillPolygon() is also affected but not nearly as much.

      This performance hit forces me to use rectangular clip areas.
      I would have preferred to use non-rectangular clip.
      --------------------------------------------------------------
      D:\Russell\projects\test\PolygonClipProblem>java -version
      java version "1.2.1"
      HotSpot VM (1.0rc2, mixed mode, build E)

      D:\Russell\projects\test\PolygonClipProblem>java -fullversion
      java full version "JDK-1.2.1-K"
      --------------------------------------------------------------
      compile and run the following app. click anywhere in the circles
      to cause a redraw. Select "rectangle" to see there is little
      difference in draw time. Select "area" to see a 10 times performance
      degradation.

      Repeat after de-selecting "fillPolygon" then repeat once more
      after de-selecting "drawPolyline". The draw time for all redraws
      is shown in the display. Notice that an Area clip is about 4x worse
      for drawPolyline compared with fillPolygon.
      --------------------------------------------------------------
      public class PolygonClipProblem extends javax.swing.JFrame {
      private javax.swing.JPanel _topPanel;
      private javax.swing.JRadioButton _useRectangle;
      private javax.swing.JRadioButton _useArea;
      private javax.swing.JRadioButton _useNone;
      private javax.swing.JRadioButton _doLine;
      private javax.swing.JRadioButton _doFill;
      private MyCanvas _canvas;

      final static int CircleCount = 37;
      final static int VertexCount = 200;
      final static int InitialRadius = 200;
      final static int RadiusChange = -5;
      final static int InitialX = 205;
      final static int InitialY = 205;
      final static int XChange = 8;
      final static int YChange = 1;
      Circle _circles[];

      final java.awt.Color _colors[] = {
      java.awt.Color.red.darker(),
      java.awt.Color.green.darker(),
      java.awt.Color.blue.darker(),
      java.awt.Color.yellow.darker(),
      java.awt.Color.cyan.darker(),
      java.awt.Color.magenta.darker()
      };
      int _nextColor = _colors.length;

      public PolygonClipProblem() {
      super("Polygon clip problem");

      _topPanel = new javax.swing.JPanel();
      _useRectangle = new javax.swing.JRadioButton("Rectangle");
      _useArea = new javax.swing.JRadioButton("Area");
      _useNone = new javax.swing.JRadioButton("No Clip");
      _doLine = new javax.swing.JRadioButton("DrawPolyline");
      _doFill = new javax.swing.JRadioButton("FillPolygon");
      _canvas = new MyCanvas();

      setSize(600,500);
      addWindowListener(
      new java.awt.event.WindowAdapter() {
      public void windowClosing(java.awt.event.WindowEvent event) {
      setVisible(false);
      dispose();
      System.exit(0);
      }
      }
      );
      _canvas.addMouseListener(
      new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent e) {
      _canvas.repaint();
      }
      }
      );

      javax.swing.ButtonGroup group = new javax.swing.ButtonGroup();
      group.add(_useRectangle);
      group.add(_useArea);
      group.add(_useNone);

      getContentPane().setLayout(new java.awt.BorderLayout());
      _topPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT,5,5));
      _topPanel.add(_useNone);
      _topPanel.add(_useRectangle);
      _topPanel.add(_useArea);
      javax.swing.JPanel filler = new javax.swing.JPanel();
      filler.setPreferredSize(new java.awt.Dimension(100,20));
      _topPanel.add(filler);
      _topPanel.add(_doLine);
      _topPanel.add(_doFill);
      getContentPane().add(_topPanel,java.awt.BorderLayout.NORTH);
      getContentPane().add(_canvas,java.awt.BorderLayout.CENTER);

      createCircles();
      _useNone.doClick();
      _doLine.doClick();
      _doFill.doClick();
      }

      private final void createCircles() {
      _circles = new Circle[CircleCount];
      for (int i = 0; i < CircleCount; i++) {
      _circles[i] = new Circle(InitialX+i*XChange, InitialY+i*YChange, InitialRadius+i*RadiusChange, VertexCount);
      }
      }

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

      private final class Circle {
      int _x[];
      int _y[];
      Circle(int x0, int y0, int radius, int count) {
      _x = new int[count];
      _y = new int[count];
      double drad = (double)radius;
      double xc = (double)x0;
      double yc = (double)y0;
      int count1 = count-1;
      double angle = 2.0*Math.PI/(double)(count1);
      for (int i = 0; i < count1; i++) {
      _x[i] = (int)(xc + drad*Math.cos(angle*(double)i));
      _y[i] = (int)(yc + drad*Math.sin(angle*(double)i));
      }
      _x[count1] = _x[0];
      _y[count1] = _y[0];
      }
      int[] getX() { return _x; }
      int[] getY() { return _y; }
      }

      java.awt.Color nextColor() {
      _nextColor--;
      if (_nextColor < 0) _nextColor = _colors.length - 1;
      return _colors[_nextColor];
      }

      private final class MyCanvas extends javax.swing.JComponent {
      java.awt.Rectangle _clipRect;
      java.awt.geom.Area _clipArea;

      MyCanvas() {
      this.addComponentListener(
      new java.awt.event.ComponentAdapter() {
      public void componentResized(java.awt.event.ComponentEvent e) {
      setClipGeometry();
      }
      }
      );
      setClipGeometry();
      }

      private final void setClipGeometry() {
      _clipRect = this.getBounds();
      _clipRect.setLocation(0,0);
      _clipRect.grow(-50,-50);
      _clipArea = new java.awt.geom.Area(_clipRect);
      }
      public void paintComponent(java.awt.Graphics g) {
      java.awt.Graphics2D g2 = (java.awt.Graphics2D)g;

      g2.setColor(this.getBackground());
      g2.fillRect(0,0,this.getWidth()-1,this.getHeight()-1);
      g2.draw3DRect(2,2,this.getWidth()-2,this.getHeight()-2,false);

      if (_useRectangle.isSelected()) {
      g2.setClip(_clipRect);
      }
      else if (_useArea.isSelected()) {
      g2.setClip(_clipArea);
      }

      g2.setColor(java.awt.Color.white);
      g2.fillRect(0,0,this.getWidth()-1,this.getHeight()-1);

      long tm = System.currentTimeMillis();

      for (int i = 0; i < CircleCount; i++) {
      Circle circle = _circles[i];
      if (_doFill.isSelected()) {
      g2.setColor(nextColor());
      g2.fillPolygon(circle.getX(), circle.getY(), circle.getX().length);
      }
      if (_doLine.isSelected()) {
      g2.setColor(nextColor());
      g2.drawPolyline(circle.getX(), circle.getY(), circle.getX().length);
      }
      }

      tm = System.currentTimeMillis() - tm;

      g2.setColor(this.getBackground());
      g2.draw3DRect(2,2,this.getWidth()-2,this.getHeight()-2,false);

      StringBuffer sb = new StringBuffer();
      sb.append(tm);
      sb.append(" ms");
      g2.setColor(this.getForeground());
      g2.setFont(this.getFont());
      g2.drawString(sb.toString(), 55, this.getHeight() - 55);
      }
      }
      }
      (Review ID: 57717)
      ======================================================================

            chegar Chris Hegarty
            dblairsunw Dave Blair (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: