-
Bug
-
Resolution: Unresolved
-
P4
-
5.0
-
itanium
-
linux
FULL PRODUCT VERSION :
java version "1.5.0_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_03-b07)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_03-b07, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux mordor 2.6.11.4-21.7-default #1 Thu Jun 2 14:23:14 UTC 2005 x86_64 x86_64 x86_64 GNU/Linux
EXTRA RELEVANT SYSTEM CONFIGURATION :
AMD-64 3200+
1Gb OCZ RAM
ATI x700 RADEON video card
A DESCRIPTION OF THE PROBLEM :
A simple application, consisting fo a background and a thread which
moves a window with a gif image over the background is eight times slower
on Gtk than on Windows! The redrawing in terms of rectangles etc seems
ok ...
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the program that is pasted or downloaded it from http://www.geocities.com/free_bridge/animation.zip,
javac *.java
java AnimationFrame
then select File-->Animate, after the animation finishes a number is printed on the screen. On windows it's les than a second, while in linux it's 8 secs.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
i would expect such a simple animation to performa reasonably well, I don't think that the speed is satisfactory neither in windows nor in linux.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Besides the files below there is another file, 03d.gif. You can get it from http://www.geocities.com/free_bridge/animation.zip, or just use any small gif.
AnimationFrame.java:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.UIManager;
/**
* Created on Apr 23, 2005
*
* @author popivan
*/
public class AnimationFrame extends JFrame implements ActionListener
{
private JMenuItem menuItemFileAnimate_;
private JMenuItem menuItemFileExit_;
private View view_ = null;
AnimationFrame( String title )
{
super( title );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
JPanel content = ( JPanel )getContentPane( );
content.setOpaque( true );
content.setLayout( new BorderLayout( ) );
createMenu( );
view_ = new View( );
content.add( view_, BorderLayout.NORTH );
pack( );
}
private void createMenu( )
{
JMenuBar menuBar;
JMenu menu;
menuBar = new JMenuBar( );
menu = new JMenu( "File" );
menu.setMnemonic( KeyEvent.VK_F );
menuBar.add( menu );
menuItemFileAnimate_ = new JMenuItem( "Animate" );
menuItemFileAnimate_.addActionListener( this );
menu.add( menuItemFileAnimate_ );
menu.addSeparator( );
menuItemFileExit_ = new JMenuItem( "Exit" );
menuItemFileExit_.addActionListener( this );
menu.add( menuItemFileExit_ );
menuBar.setBorder( BorderFactory.createEmptyBorder( ) );
setJMenuBar( menuBar );
}
private static void runGUI( )
{
try
{
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName( ) );
}
catch( Exception e )
{
}
AnimationFrame frame = new AnimationFrame( "Animation" );
frame.setVisible( true );
}
public static void main( String [ ] args )
{
// System.setProperty( "sun.java2d.noddraw", "false" );
// System.setProperty( "sun.java2d.ddscale","true" );
// System.setProperty( "sun.java2d.ddforcevram", "true" );
javax.swing.SwingUtilities.invokeLater( new Runnable( ) {
public void run( ) {
runGUI( );
}
});
}
public void actionPerformed( ActionEvent e )
{
if( e.getSource( ) == menuItemFileAnimate_ )
{
view_.animate( );
}
else if( e.getSource( ) == menuItemFileExit_ )
{
processEvent( new WindowEvent( this, WindowEvent.WINDOW_CLOSING ) );
}
}
}
CardView.java:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class CardView extends JPanel
{
private BufferedImage image_ = null;
private int width_ = -1;
private int height_ = -1;
CardView( )
{
setBorder( null );
setOpaque( false );
File file = new File( "03d.gif" );
try
{
image_ = ImageIO.read( file );
width_ = image_.getWidth( );
height_ = image_.getHeight( );
setSize( new Dimension( width_, height_ ) );
}
catch( Exception e )
{
image_ = null;
width_ = -1;
height_ = -1;
}
}
public void paintComponent( Graphics g )
{
/*
System.out.print( "CardView: " );
System.out.print( getBounds( ) );
System.out.print( ": " );
System.out.print( g.getClipBounds( ) );
System.out.print( ": " );
System.out.println( getLocation( ) );
*/
g.drawImage( image_, 0, 0, width_, height_, null );
}
}
View.java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class View extends JPanel implements Runnable
{
private static final int AnimationSteps = 1;
private static final int AnimationDelay = 1;
private Point current_ = new Point( 0, 0 );
private ArrayList pointList_ = null;
private BufferedImage image_ = null;
private int width_ = -1;
private int height_ = -1;
CardView card_ = null;
private boolean animationFlag_ = false;
private int painted_ = 0;
private int index_;
View( )
{
setPreferredSize( new Dimension( 928, 500 ) );
File file = new File( "03d.gif" );
try
{
image_ = ImageIO.read( file );
width_ = image_.getWidth( );
height_ = image_.getHeight( );
setSize( new Dimension( width_, height_ ) );
}
catch( Exception e )
{
image_ = null;
width_ = -1;
height_ = -1;
}
}
public void paintComponent( Graphics g )
{
g.setColor( new Color( 0, 0, 130 ) );
Rectangle bounds = g.getClipBounds( );
g.fillRect( bounds.x, bounds.y, bounds.width, bounds.height );
// System.out.print( "View: " );
// System.out.println( bounds );
// g.drawImage( image_, current_.x, current_.y, width_, height_, null );
}
public void animate( )
{
card_ = new CardView( );
Rectangle rect = getBounds( );
Point from = new Point( 0, 0 );
Point to = new Point( rect.width - card_.getWidth( ), rect.height - card_.getHeight( ) );
calcLine( from, to );
// current_.setLocation( from );
card_.setLocation( from.x, from.y );
add( card_ );
painted_ = 0;
Thread thread = new Thread( this );
thread.start( );
// card.setLocation( from.x, from.y );
// add( card );
// Timer timer = new Timer( );
// AnimationTask animeTask = new AnimationTask( timer, this, card, from, to, current_ );
// timer.schedule( animeTask, 0, 1 );
}
public void run( )
{
long time = System.currentTimeMillis( );
double begTime = time;
for( ;; )
{
Point pt = ( Point )pointList_.get( index_ );
card_.setLocation( pt );
if( index_ < pointList_.size( ) - 1 )
{
index_ += AnimationSteps;
if( index_ >= pointList_.size( ) )
{
index_ = pointList_.size( ) - 1;
}
}
else
{
index_ += AnimationSteps;
}
if( index_ >= pointList_.size( ) )
{
break;
}
time += AnimationDelay;
try
{
Thread.sleep( Math.max( 0, time - System.currentTimeMillis( ) ) );
}
catch( InterruptedException e )
{
e.printStackTrace();
}
}
double endTime = System.currentTimeMillis( );
System.out.println( "time elapsed: " + String.valueOf( ( endTime - begTime ) / 1000.0 ) + " secs" );
}
private void calcLine( Point from, Point to )
{
Point pt = new Point( from );
pointList_ = new ArrayList( );
int dx = StrictMath.abs( to.x - from.x );
int dy = StrictMath.abs( to.y - from.y );
int incrX, incrY;
if( from.x > to.x )
{
incrX = -1;
}
else
{
incrX = 1;
}
if( from.y > to.y )
{
incrY = -1;
}
else
{
incrY = 1;
}
if( dx >= dy )
{
//
// x is the independent variable
//
// amount to increment decision if right is chosen (always)
int pr = 2*dy;
//
// amount to increment decision if up is chosen
int pru = pr - 2*dx;
//
// decision variable start value
int p = pr - dx;
for( ; dx >= 0; --dx )
{
//
// process each point in the line one at a time (just use dX)
pointList_.add( new Point( pt ) );
if( p > 0)
{
//
// is the pixel going right AND up?
pt.x += incrX; // increment independent variable
pt.y += incrY; // increment dependent variable
p += pru; // increment decision (for up)
}
else
{
//
// is the pixel just going right?
pt.x += incrX; // increment independent variable
p += pr; // increment decision (for right)
}
}
}
else
{
//
// y is the independent variable
//
// amount to increment decision if right is chosen (always)
int pr = 2*dx;
//
// amount to increment decision if up is chosen
int pru = pr - 2*dy;
//
// decision variable start value
int p = pr - dy;
for( ; dy >= 0; --dy )
{
//
// process each point in the line one at a time (just use dY)
pointList_.add( new Point( pt ) );
if( p > 0 )
{
//
// is the pixel going up AND right?
pt.x += incrX; // increment dependent variable
pt.y += incrY; // increment independent variable
p += pru; // increment decision (for up)
}
else
{
//
// is the pixel just going up?
pt.y += incrY; // increment independent variable
p += pr; // increment decision (for right)
}
}
}
}
}
---------- END SOURCE ----------
###@###.### 2005-07-13 17:46:16 GMT
java version "1.5.0_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_03-b07)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_03-b07, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux mordor 2.6.11.4-21.7-default #1 Thu Jun 2 14:23:14 UTC 2005 x86_64 x86_64 x86_64 GNU/Linux
EXTRA RELEVANT SYSTEM CONFIGURATION :
AMD-64 3200+
1Gb OCZ RAM
ATI x700 RADEON video card
A DESCRIPTION OF THE PROBLEM :
A simple application, consisting fo a background and a thread which
moves a window with a gif image over the background is eight times slower
on Gtk than on Windows! The redrawing in terms of rectangles etc seems
ok ...
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the program that is pasted or downloaded it from http://www.geocities.com/free_bridge/animation.zip,
javac *.java
java AnimationFrame
then select File-->Animate, after the animation finishes a number is printed on the screen. On windows it's les than a second, while in linux it's 8 secs.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
i would expect such a simple animation to performa reasonably well, I don't think that the speed is satisfactory neither in windows nor in linux.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Besides the files below there is another file, 03d.gif. You can get it from http://www.geocities.com/free_bridge/animation.zip, or just use any small gif.
AnimationFrame.java:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.UIManager;
/**
* Created on Apr 23, 2005
*
* @author popivan
*/
public class AnimationFrame extends JFrame implements ActionListener
{
private JMenuItem menuItemFileAnimate_;
private JMenuItem menuItemFileExit_;
private View view_ = null;
AnimationFrame( String title )
{
super( title );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
JPanel content = ( JPanel )getContentPane( );
content.setOpaque( true );
content.setLayout( new BorderLayout( ) );
createMenu( );
view_ = new View( );
content.add( view_, BorderLayout.NORTH );
pack( );
}
private void createMenu( )
{
JMenuBar menuBar;
JMenu menu;
menuBar = new JMenuBar( );
menu = new JMenu( "File" );
menu.setMnemonic( KeyEvent.VK_F );
menuBar.add( menu );
menuItemFileAnimate_ = new JMenuItem( "Animate" );
menuItemFileAnimate_.addActionListener( this );
menu.add( menuItemFileAnimate_ );
menu.addSeparator( );
menuItemFileExit_ = new JMenuItem( "Exit" );
menuItemFileExit_.addActionListener( this );
menu.add( menuItemFileExit_ );
menuBar.setBorder( BorderFactory.createEmptyBorder( ) );
setJMenuBar( menuBar );
}
private static void runGUI( )
{
try
{
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName( ) );
}
catch( Exception e )
{
}
AnimationFrame frame = new AnimationFrame( "Animation" );
frame.setVisible( true );
}
public static void main( String [ ] args )
{
// System.setProperty( "sun.java2d.noddraw", "false" );
// System.setProperty( "sun.java2d.ddscale","true" );
// System.setProperty( "sun.java2d.ddforcevram", "true" );
javax.swing.SwingUtilities.invokeLater( new Runnable( ) {
public void run( ) {
runGUI( );
}
});
}
public void actionPerformed( ActionEvent e )
{
if( e.getSource( ) == menuItemFileAnimate_ )
{
view_.animate( );
}
else if( e.getSource( ) == menuItemFileExit_ )
{
processEvent( new WindowEvent( this, WindowEvent.WINDOW_CLOSING ) );
}
}
}
CardView.java:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class CardView extends JPanel
{
private BufferedImage image_ = null;
private int width_ = -1;
private int height_ = -1;
CardView( )
{
setBorder( null );
setOpaque( false );
File file = new File( "03d.gif" );
try
{
image_ = ImageIO.read( file );
width_ = image_.getWidth( );
height_ = image_.getHeight( );
setSize( new Dimension( width_, height_ ) );
}
catch( Exception e )
{
image_ = null;
width_ = -1;
height_ = -1;
}
}
public void paintComponent( Graphics g )
{
/*
System.out.print( "CardView: " );
System.out.print( getBounds( ) );
System.out.print( ": " );
System.out.print( g.getClipBounds( ) );
System.out.print( ": " );
System.out.println( getLocation( ) );
*/
g.drawImage( image_, 0, 0, width_, height_, null );
}
}
View.java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class View extends JPanel implements Runnable
{
private static final int AnimationSteps = 1;
private static final int AnimationDelay = 1;
private Point current_ = new Point( 0, 0 );
private ArrayList pointList_ = null;
private BufferedImage image_ = null;
private int width_ = -1;
private int height_ = -1;
CardView card_ = null;
private boolean animationFlag_ = false;
private int painted_ = 0;
private int index_;
View( )
{
setPreferredSize( new Dimension( 928, 500 ) );
File file = new File( "03d.gif" );
try
{
image_ = ImageIO.read( file );
width_ = image_.getWidth( );
height_ = image_.getHeight( );
setSize( new Dimension( width_, height_ ) );
}
catch( Exception e )
{
image_ = null;
width_ = -1;
height_ = -1;
}
}
public void paintComponent( Graphics g )
{
g.setColor( new Color( 0, 0, 130 ) );
Rectangle bounds = g.getClipBounds( );
g.fillRect( bounds.x, bounds.y, bounds.width, bounds.height );
// System.out.print( "View: " );
// System.out.println( bounds );
// g.drawImage( image_, current_.x, current_.y, width_, height_, null );
}
public void animate( )
{
card_ = new CardView( );
Rectangle rect = getBounds( );
Point from = new Point( 0, 0 );
Point to = new Point( rect.width - card_.getWidth( ), rect.height - card_.getHeight( ) );
calcLine( from, to );
// current_.setLocation( from );
card_.setLocation( from.x, from.y );
add( card_ );
painted_ = 0;
Thread thread = new Thread( this );
thread.start( );
// card.setLocation( from.x, from.y );
// add( card );
// Timer timer = new Timer( );
// AnimationTask animeTask = new AnimationTask( timer, this, card, from, to, current_ );
// timer.schedule( animeTask, 0, 1 );
}
public void run( )
{
long time = System.currentTimeMillis( );
double begTime = time;
for( ;; )
{
Point pt = ( Point )pointList_.get( index_ );
card_.setLocation( pt );
if( index_ < pointList_.size( ) - 1 )
{
index_ += AnimationSteps;
if( index_ >= pointList_.size( ) )
{
index_ = pointList_.size( ) - 1;
}
}
else
{
index_ += AnimationSteps;
}
if( index_ >= pointList_.size( ) )
{
break;
}
time += AnimationDelay;
try
{
Thread.sleep( Math.max( 0, time - System.currentTimeMillis( ) ) );
}
catch( InterruptedException e )
{
e.printStackTrace();
}
}
double endTime = System.currentTimeMillis( );
System.out.println( "time elapsed: " + String.valueOf( ( endTime - begTime ) / 1000.0 ) + " secs" );
}
private void calcLine( Point from, Point to )
{
Point pt = new Point( from );
pointList_ = new ArrayList( );
int dx = StrictMath.abs( to.x - from.x );
int dy = StrictMath.abs( to.y - from.y );
int incrX, incrY;
if( from.x > to.x )
{
incrX = -1;
}
else
{
incrX = 1;
}
if( from.y > to.y )
{
incrY = -1;
}
else
{
incrY = 1;
}
if( dx >= dy )
{
//
// x is the independent variable
//
// amount to increment decision if right is chosen (always)
int pr = 2*dy;
//
// amount to increment decision if up is chosen
int pru = pr - 2*dx;
//
// decision variable start value
int p = pr - dx;
for( ; dx >= 0; --dx )
{
//
// process each point in the line one at a time (just use dX)
pointList_.add( new Point( pt ) );
if( p > 0)
{
//
// is the pixel going right AND up?
pt.x += incrX; // increment independent variable
pt.y += incrY; // increment dependent variable
p += pru; // increment decision (for up)
}
else
{
//
// is the pixel just going right?
pt.x += incrX; // increment independent variable
p += pr; // increment decision (for right)
}
}
}
else
{
//
// y is the independent variable
//
// amount to increment decision if right is chosen (always)
int pr = 2*dx;
//
// amount to increment decision if up is chosen
int pru = pr - 2*dy;
//
// decision variable start value
int p = pr - dy;
for( ; dy >= 0; --dy )
{
//
// process each point in the line one at a time (just use dY)
pointList_.add( new Point( pt ) );
if( p > 0 )
{
//
// is the pixel going up AND right?
pt.x += incrX; // increment dependent variable
pt.y += incrY; // increment independent variable
p += pru; // increment decision (for up)
}
else
{
//
// is the pixel just going up?
pt.y += incrY; // increment independent variable
p += pr; // increment decision (for right)
}
}
}
}
}
---------- END SOURCE ----------
###@###.### 2005-07-13 17:46:16 GMT