Volatile/Buffered Images
I'm drawing my screen background on a BufferedImage, and then copying it over to a VolatileImage, which is then drawn to the screen.
My problem is... when I first render the BufferedImage, it whips right through... No problem whatsoever. But when I write over the data, it's painfully slow. Any ideas why this might be?
[334 byte] By [
cbisbee] at [2007-9-27 16:45:41]

Thanks for the tip... But it didn't fix anything. I've also posted a similar message on those boards, but I'll put my code up here too.
From my PiratesMap class:
public void paintComponent(Graphics g){
Graphics2D g2=(Graphics2D)g;
//find the x-y coordinates of the ship, make them positive, and find the upper left corner of the
// display screen
xco=32767+myShip.getSp().getXco()-d.width/2;
yco=32767+myShip.getSp().getYco()-d.height/2;
//determine the number of pixels wide the top and left boxes need to be
int xoffset=-Math.abs(xco%squarewidth);
int yoffset=-Math.abs(yco%squareheight);
//find which 32x32 megapixel is in the top left corner
int xsquare=(xco%3072)/squarewidth+16;
int ysquare=(yco%3072)/squareheight+16;
paintToScreen(g2, xsquare, ysquare, NumVisCols, NumVisRows, xoffset, yoffset);
g2.dispose();
}
void paintToScreen(Graphics2D g2, int x, int y, int w, int h, int xoff, int yoff){
//paints the background map to the screen
g2.drawImage(((BufferedImage)mapimage).getSubimage(x , y, w, h),
new AffineTransform(32,0,0,32,xoff,yoff),null);
}
void copyMaps(MapLoader ml){
mapimage=gc.createCompatibleImage(160, 160);
Graphics2D g2=(Graphics2D)mapimage.getGraphics();
g2.drawImage(ml.getMapimage(),0,0,null);
g2.dispose();
System.out.println("Should've copied");
}
And from my MapLoader class:
private void copyMap(){
//draw the map data to an image
Graphics2D g=(Graphics2D)holderimage.getGraphics();
for(int x=0;x<112;x++){
for(int y=0;y<112;y++){
g.setPaint(c[map[0].xy[x][y]]);
System.out.println(x+" "+y);
g.draw(new Rectangle2D.Double(x,y,1,1));
}
}
for(int x=0;x<48;x++){
for(int y=0;y<112;y++){
g.setPaint(c[map[2].xy[x+16][y]]);
g.draw(new Rectangle2D.Double(x+112,y,1,1));
}
}
for(int x=0;x<112;x++){
for(int y=0;y<48;y++){
g.setPaint(c[map[1].xy[x][y+16]]);
g.draw(new Rectangle2D.Double(x,y+112,1,1));
}
}
for(int x=0;x<48;x++){
for(int y=0;y<48;y++){
g.setPaint(c[map[3].xy[x+16][y+16]]);
g.draw(new Rectangle2D.Double(x+112,y+112,1,1));
}
}
System.out.println("ending draw");
g.dispose();
}
public Image getMapimage(){
//return the map
ready=false;
loading=false;
return holderimage;
}
You may note the printlns in my copyMap method... These are for debugging, and they're telling me what my problem is... The first map I draw is no problem, it whips right through. But on the second drawing of the map (when mapimage is written over by copyMap), it's PAINFULLY slow.
So I have two questions:
A) My theory is that somehow the second writing of the map is somehow going into vram, or some other similarly slow writing technique. How do I fix this, or if I'm wrong, what is the problem?
B) Am I totally on the wrong track here? Is there a better way to do this?
Hmmm. Im wondering if you are running into the situation outlined in the following javagaming.org thread:
http://www.javagaming.org/discus/messages/27/1608.html?1030358070
To summarize, mapimage is being created in the "eden" space, but since it is not nulled before the second image is assigned to mapimage, the old image gets moved to the survivor generation (an expensive operation) since both images cannot fit into the eden space. This is just a theory of course, and I could be wrong. The way to test would be to either increase the size of the eden space using the -Xmn command line option, or adding something like the following to your code:
mapimage=null; // allow for the old image to be garbage collected
mapimage=gc.createCompatibleImage(160, 160);
You might also want to run with the -verbose:gc command to see if garbage collection is slowing you down.
Also, if this theory is correct, then your image creation should speed up again over time, since hotspot is supposed to dynamically resize the eden space.