Hi,

Now that Norman's paperwork has been filed I can commit his FillRect paint performance patch. Let's run this demo before every release so that we can track AWT painting performance.

Tom

2006-05-25  Thomas Fitzsimmons  <[EMAIL PROTECTED]>

        * examples/gnu/classpath/examples/swing/Demo.java: Add FillRect
        paint performance demo.
        * examples/gnu/classpath/examples/swing/FillRect.java: New file.
Index: examples/gnu/classpath/examples/swing/Demo.java
===================================================================
RCS file: /sources/classpath/classpath/examples/gnu/classpath/examples/swing/Demo.java,v
retrieving revision 1.45
diff -u -r1.45 Demo.java
--- examples/gnu/classpath/examples/swing/Demo.java	18 Apr 2006 20:53:34 -0000	1.45
+++ examples/gnu/classpath/examples/swing/Demo.java	25 May 2006 20:36:57 -0000
@@ -156,7 +156,10 @@
 
     examples.add(new JMenuItem(new PopupAction("NavigationFilter",
                                                NavigationFilterDemo.createDemoFactory())));
-    
+    examples.add(new JMenuItem(new PopupAction("Paint Performance",
+                                               FillRect.createDemoFactory())));
+
+
     final JMenuItem vmMenu;
     
     help.add(new JMenuItem("just play with the widgets"));
@@ -543,7 +546,10 @@
     panel.add(new JButton(new PopupAction("Tree",
                                           TreeDemo.createDemoFactory())));
     panel.add(new JButton(new PopupAction("Theme Editor",
-                                       MetalThemeEditor.createDemoFactory())));
+                                      MetalThemeEditor.createDemoFactory())));
+    panel.add(new JButton(new PopupAction("Paint Performance",
+                                          FillRect.createDemoFactory())));
+
     JButton exitDisposer = mkDisposerButton(frame);
     panel.add(exitDisposer);
     
Index: examples/gnu/classpath/examples/swing/FillRect.java
===================================================================
RCS file: examples/gnu/classpath/examples/swing/FillRect.java
diff -N examples/gnu/classpath/examples/swing/FillRect.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ examples/gnu/classpath/examples/swing/FillRect.java	25 May 2006 20:36:57 -0000
@@ -0,0 +1,301 @@
+/* FillRect.java - demonstrator for classpath/gcj fillrect performance issue
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath examples.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA. */
+
+package gnu.classpath.examples.swing;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+/** 
+ * @author Norman Hendrich
+ */
+public class FillRect
+  extends JPanel
+  implements ActionListener 
+{
+
+  static FillRect fillRectDemo;
+
+  LCDCanvas lcd;
+  Worker worker;
+  JLabel label;
+
+  int     nx = 64;
+  int     ny = 64;
+  int     matrix[][], future[][];
+  int     generation = 0;
+
+  // 20 msec, or 50 repaints per sec (theoretically)
+  int     sleepMillis = 20;
+  long    lastMillis = System.currentTimeMillis();
+
+  boolean enableRepaints = true;
+
+  public void actionPerformed(ActionEvent e) 
+  {
+    if (e.getActionCommand().equals("CLOSE"))
+    {
+      System.exit(0);
+    }
+  }
+
+  public FillRect()
+  {
+    setSize(64, 64);
+    createContent();
+  }
+
+  public void createContent()
+  {
+    setLayout(new BorderLayout());
+
+    JPanel p = new JPanel(new BorderLayout());
+    lcd   = new LCDCanvas();
+    label = new JLabel();
+    label.setText("paintComponent took 00 msec. (00000 fillRect calls)");
+    p.add(lcd, BorderLayout.CENTER);
+    p.add(label, BorderLayout.SOUTH);
+    add(p);
+  }
+
+  public void setSize(int _nx,int _ny )
+  {
+    nx = _nx;
+    ny = _ny;
+    matrix = new int[nx][ny];
+    future = new int[nx][ny];
+  }
+
+  public void initFrameContent()
+  {
+    JPanel closePanel = new JPanel();
+    JButton closeButton = new JButton("Close");
+    closeButton.setActionCommand("CLOSE");
+    closeButton.addActionListener(this);
+    closePanel.add(closeButton);
+    add(closePanel, BorderLayout.SOUTH);
+  }
+
+  public void setSleepMillis(int millis)
+  {
+    sleepMillis = millis;
+  }
+
+  public class LCDCanvas extends JPanel
+  {
+    private int   sx, sy;
+    private Color activePixel  = new Color(30, 30, 40);
+    private Color passivePixel = new Color(200, 180, 240);
+    private Color gridPixel    = new Color(255, 240, 240);
+
+    public LCDCanvas()
+    {
+      super();
+      sx = 4 * nx;
+      sy = 4 * ny;
+    }
+
+    public void paintComponent(Graphics g)
+    {
+      // for buffered drawing - not used atm
+      // g.drawImage( buffer, 0, 0, null );
+      long t1 = System.currentTimeMillis();
+
+      g.setColor(gridPixel);
+      g.fillRect(0, 0, sx, sy);
+
+      Color pixelColor = null;
+      for (int ix = 0; ix < nx; ix++)
+        {
+          for (int iy = 0; iy < ny; iy++)
+            {
+              if (matrix[ix][iy] != 0)
+                pixelColor = activePixel;
+              else
+                pixelColor = passivePixel;
+
+              g.setColor(pixelColor);
+              g.fillRect(4 * ix, 4 * iy, 3, 3);
+            }
+        }
+
+      long t2 = System.currentTimeMillis();
+
+      label.setText("paintComponent took " + (t2 - t1) + " msec. "
+                    +  "(" + (nx * ny + 1) + " fillRect calls)");
+    }
+
+    public Dimension getPreferredSize()
+    {
+      return new Dimension(sx,sy);
+    }
+
+    public Dimension getMinimumSize()
+    {
+      return new Dimension(sx,sy);
+    }
+  }
+
+  public class Worker extends Thread
+  {
+    public void run()
+    {
+      boolean running = true;
+      while(running)
+        {
+          iteration();
+
+          if (enableRepaints)
+            display();
+
+          if (sleepMillis > 0)
+            {
+              try
+                {
+                  Thread.sleep( sleepMillis );
+                }
+              catch(InterruptedException ie)
+                {
+                  running = false;
+                }
+            }
+        }
+    }
+  }
+
+  /** 
+   * stupid animation algorithm: show binary representation of current
+   * iteration.
+   */
+  public void iteration()
+  {
+    generation++;
+
+    for (int i = 0; i < nx; i++)
+      {
+        long tmp1 = 1L << i;
+        for (int j = 0; j < ny; j++)
+          {
+            // count neighbors
+            long tmp2 = (1L << j);
+
+        
+            long tmp3 = generation & tmp1 & tmp2;
+            if (tmp3 != 0) 
+              matrix[i][j] = 1;
+            else
+              matrix[i][j] = 0;
+          }
+    }
+
+    if ((generation % 100) == 0)
+      {
+        long t = System.currentTimeMillis();
+        //        System.out.println(
+        //           " generation= " + generation +
+        //           " iterations/sec= " + 100.0*1000/(t-lastMillis) );
+        lastMillis = t;
+      }
+  }
+
+  public void display()
+  {
+    lcd.repaint();
+  }
+
+  public static void usage()
+  {
+    System.out.println( 
+      "Usage: <java> FillRect2 [-sleep <millis>] [-size <int>] [-nopaint]\n"
+    + "Example: jamvm FillRect2 -sleep 10 -size 100\n"
+    );
+    System.exit(0);
+  }
+
+  public static void main(String args[])
+    throws Exception
+  {
+    fillRectDemo = new FillRect();
+    for (int i = 0; i < args.length; i++)
+      {
+        if ("-help".equals(args[i]))
+          {
+            usage();
+          }
+        if ("-sleep".equals(args[i]))
+          {
+            fillRectDemo.setSleepMillis( Integer.parseInt(args[i + 1]));
+            i++;
+          }
+        if ("-size".equals(args[i]))
+          {
+            int size = Integer.parseInt(args[i + 1]);
+            fillRectDemo.setSize(size, size);
+            i++;
+          }
+        if ("-nopaint".equals(args[i]))
+          {
+            fillRectDemo.enableRepaints = false; 
+          }
+      }
+
+    SwingUtilities.invokeLater (new Runnable()
+     {
+       public void run()
+       {
+
+         fillRectDemo.initFrameContent();
+         JFrame frame = new JFrame("FillRect performance test");
+         frame.getContentPane().add(fillRectDemo);
+         frame.pack();
+         frame.show();
+         fillRectDemo.worker = fillRectDemo.new Worker();
+         fillRectDemo.worker.start();
+       }
+      });
+  }
+
+  /**
+   * Returns a DemoFactory that creates a SliderDemo.
+   *
+   * @return a DemoFactory that creates a SliderDemo
+   */
+  public static DemoFactory createDemoFactory()
+  {    
+    return new DemoFactory()
+    {
+      public JComponent createDemo()
+      {
+        fillRectDemo = new FillRect();
+        SwingUtilities.invokeLater
+        (new Runnable()
+         {
+           public void run()
+           {
+             fillRectDemo.worker = fillRectDemo.new Worker();
+             fillRectDemo.worker.start();
+           }
+         });
+        return fillRectDemo;
+      }
+    };
+  }
+}

Reply via email to