blob: efa57d2a36fe4ff31c19bfa5283f85553d61210b [file] [log] [blame]
/* JNIOverhead.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.java2d;
import gnu.classpath.examples.swing.DemoFactory;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* @author Norman Hendrich
*/
public class JNIOverhead
extends JPanel
implements ActionListener
{
static JNIOverhead fillRectDemo;
LCDCanvas lcd;
Worker worker;
JLabel label;
JCheckBox translate;
JCheckBox lines;
int nx = 128;
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;
/**
* If true, test translation.
*/
boolean testTranslation = false;
/**
* If true, paint lines rather than rectangles
*/
boolean paintLines;
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("CLOSE"))
{
System.exit(0);
}
}
public JNIOverhead()
{
setSize(nx, ny);
createContent();
}
public void createContent()
{
setLayout(new BorderLayout());
JPanel p = new JPanel(new BorderLayout());
lcd = new LCDCanvas();
label = new JLabel();
label.setText("not running");
translate = new JCheckBox("translate");
translate.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
testTranslation = translate.isSelected();
}
});
lines = new JCheckBox("lines");
lines.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
paintLines = lines.isSelected();
}
});
JPanel bottom = new JPanel();
bottom.add(lines);
bottom.add(translate);
p.add(lcd, BorderLayout.CENTER);
p.add(bottom, BorderLayout.SOUTH);
p.add(label, BorderLayout.NORTH);
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;
int dx, dy;
if (paintLines)
{
for (int ix = 0; ix < nx; ix++)
for (int iy = 0; iy < ny; iy++)
{
if (matrix[ix][iy] != 0)
pixelColor = activePixel;
else
pixelColor = passivePixel;
dx = 4 * ix;
dy = 4 * iy;
g.setColor(pixelColor);
if (testTranslation)
{
g.translate(dx, dy);
g.drawLine(0, 0, 5, 5);
g.translate(- dx, - dy);
}
else
g.drawLine(dx, dy, dx + 5, dy + 5);
}
}
else
for (int ix = 0; ix < nx; ix++)
{
for (int iy = 0; iy < ny; iy++)
{
if (matrix[ix][iy] != 0)
pixelColor = activePixel;
else
pixelColor = passivePixel;
dx = 4 * ix;
dy = 4 * iy;
g.setColor(pixelColor);
if (testTranslation)
{
g.translate(dx, dy);
g.fillRect(0, 0, 3, 3);
g.translate(- dx, - dy);
}
else
g.fillRect(dx, dy, 3, 3);
}
}
long t2 = System.currentTimeMillis();
label.setText("paintComponent took " + (t2 - t1) + " msec. " + "("
+ (nx * ny + 1) + " "
+ (paintLines ? "drawLine" : "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 JNIOverhead();
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 JNIOverhead();
SwingUtilities.invokeLater
(new Runnable()
{
public void run()
{
fillRectDemo.worker = fillRectDemo.new Worker();
fillRectDemo.worker.start();
}
});
return fillRectDemo;
}
};
}
}