United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 4615589 copyArea very slow with VolatileImage
4615589 : copyArea very slow with VolatileImage

Details
Type:
Bug
Submit Date:
2001-12-18
Status:
Closed
Updated Date:
2004-08-10
Project Name:
JDK
Resolved Date:
2004-08-10
Component:
client-libs
OS:
windows_xp
Sub-Component:
2d
CPU:
x86
Priority:
P4
Resolution:
Not an Issue
Affected Versions:
1.4.0
Fixed Versions:

Related Reports

Sub Tasks

Description

Name: gm110360			Date: 12/18/2001


java version "1.4.0-beta3"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)

java version "1.4.0-beta3"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)

I want to develop smooth (and fast) scrolling for my game, which uses a
VolatileImage as backbuffer for double buffering.
  To do this i wanted to use copyArea(x,y,width,height,dx,dy) on this
VolatileImage,but the problem is that copyArea
works very!!!! slow with 0<dx<10 & dy=0 and slow with 0<dy<10. In all other
cases it works great .
(This Bug is very  similar to id 4392912)

I have wrote a small testprogramm  (which copies an 800*600 Image 100 times)
with these results ( AMD Duron 800 mHz ,Geforce2 mx):
  
dx=1 , dy=0:
VolatileImage: 6369 ms

dx=-1 , dy=0:
VolatileImage: 0 ms

dx=0 , dy=1:
VolatileImage: 431 ms

dx=0 , dy=-1:
VolatileImage: 0 ms

dx=1 , dy=1:
VolatileImage: 431 ms

dx=-1 , dy=-1:
VolatileImage: 0 ms

dx=1 , dy=-1:
VolatileImage: 10 ms

dx=-1 , dy=1:
VolatileImage: 431 ms

-----------------------------------

dx=5 , dy=0:
VolatileImage: 1272 ms

dx=-5 , dy=0:
VolatileImage: 0 ms

dx=0 , dy=5:
VolatileImage: 240 ms

dx=0 , dy=-5:
VolatileImage: 0 ms

dx=5 , dy=5:
VolatileImage: 280 ms

dx=-5 , dy=-5:
VolatileImage: 0 ms

dx=5 , dy=-5:
VolatileImage: 0 ms

dx=-5 , dy=5:
VolatileImage: 280 ms


The TestProgramm:

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;

public class CopyAreaTest extends JFrame
{
  BufferedImage offScr1;
  Graphics2D offScrG_1;
  VolatileImage offScr2;
  Graphics2D offScrG_2;
  int width=800;
  int height=600;

  public CopyAreaTest()
  {
    this.setSize(width,height);
    this.setVisible(true);

    offScr1=new BufferedImage(this.getWidth(),this.getHeight
(),BufferedImage.TYPE_INT_RGB);
    offScrG_1=offScr1.createGraphics();

    offScr2=createVolatileImage(getWidth(),getHeight());
    offScrG_2=offScr2.createGraphics();
  }


  public void performeTest(int dx,int dy)
  {
    System.out.println("dx="+dx+ " , dy="+dy+":");

    long t=System.currentTimeMillis();
    for (int i=0;i<100;i++)
    {
      offScrG_1.copyArea(0,0,width,height,dx,dy);
    }
    System.out.println("BufferedImage: "+(System.currentTimeMillis()-t )+ "
ms");
    t=System.currentTimeMillis();

    for (int i=0;i<100;i++)
    {
      offScrG_2.copyArea(0,0,width,height,dx,dy);
    }
    System.out.println("VolatileImage: "+(System.currentTimeMillis()-t )+ "
ms");

    System.out.println();

  }

  public static void main(String args[])
  {
    CopyAreaTest test=new CopyAreaTest();

    test.performeTest(1,0);
    test.performeTest(-1,0);
    test.performeTest(0,1);
    test.performeTest(0,-1);
    test.performeTest(1,1);
    test.performeTest(-1,-1);
    test.performeTest(1,-1);
    test.performeTest(-1,1);

    System.out.println("-----------------------------------");
    System.out.println();

    test.performeTest(5,0);
    test.performeTest(-5,0);
    test.performeTest(0,5);
    test.performeTest(0,-5);
    test.performeTest(5,5);
    test.performeTest(-5,-5);
    test.performeTest(5,-5);
    test.performeTest(-5,5);

    test.dispose();
  }
}
(Review ID: 136927) 
======================================================================

                                    

Comments
EVALUATION

Given the differences we are seeing on different platforms, this seems to be a symptom of how the hardware or drivers choose to accelerate this surface->surface Blt operation.  All we do is to call the ddraw function to schedule the Blt on the surface behind the VolatileImage; how that Blt occurs is up to the hardware and driver.  It could be that some hardware is doing some operations in suboptimal ways, such as reading surfaces out of VRAM to do the operation, or making temporary copies in hardware, or whatever; obviously the direction of the copy has a lot to do with how optimal the operation is performed.

If the speed of this particular operation is objectionable to a user, there are other workarounds that may be more appropriate.  For example, instead of operating directly on a buffer, an application could simply copy a background image in from some other buffer.  In the side-scroller case, don't scroll directly on the back buffer (if the speed is not sufficient for your purposes), but instead copy in from surfaces that contain the background image appropriate;
since these surfaces shoudl all  be in VRAM and the copies happen at hardware speeds, these are pretty fast operations.

Closing this as "Not a Bug"; this is not a problem in Java2D, but in the way that some hardware chooses to implement hardware-accelerated features.

###@###.### 2004-08-10
                                     
2004-08-10
WORK AROUND

Keep the background image in a different buffer and copy it into the back buffer appropriate on each frame; if the hardware is not doing a scroll operation efficiently, then work around the issue by just copying the bits onto the buffer every frame instead of scrolling.

###@###.### 2004-08-10
                                     
2004-08-10



Hardware and Software, Engineered to Work Together