Non-locking drawing. Hopefully fixes [3065851] "0.87 Bad performance on windows"

This commit is contained in:
Kimmo Rundelin 2010-09-14 10:49:10 +00:00
parent 8191b96967
commit cbda433bb2
4 changed files with 50 additions and 68 deletions

View file

@ -465,12 +465,8 @@ public class GameScreen extends JComponent implements PositionChangeListener, IG
* so if swing internals change some time in the future, a new solution
* may be needed.
*/
if (StendhalClient.get().tryAcquireDrawingSemaphore()) {
try {
super.paintImmediately(x, y, w, h);
} finally {
StendhalClient.get().releaseDrawingSemaphore();
}
if (!StendhalClient.get().isInBatchUpdate()) {
super.paintImmediately(x, y, w, h);
}
}

View file

@ -75,15 +75,15 @@ public class StaticGameLayers {
private double width;
/** Name of the layers set that we are rendering right now. */
private String area;
private volatile String area;
/** true when the area has been changed. */
private boolean areaChanged;
private volatile boolean areaChanged;
/**
* Whether the internal state is valid.
*/
private boolean isValid;
private volatile boolean isValid;
public StaticGameLayers() {
/*
@ -218,8 +218,10 @@ public class StaticGameLayers {
}
/**
* Set the name of the area to be rendered.
* @param area the areas name
* Set the name of the area to be rendered. This must not be called before
* ll the layer data for the area have been added.
*
* @param area the area name
*/
public void setAreaName(final String area) {
this.area = area;
@ -230,7 +232,7 @@ public class StaticGameLayers {
/**
* Invalidate any cached settings.
*/
public void invalidate() {
private void invalidate() {
isValid = false;
}
@ -239,6 +241,7 @@ public class StaticGameLayers {
return;
}
String area = this.area;
if (area == null) {
height = 0.0;
width = 0.0;
@ -357,13 +360,6 @@ public class StaticGameLayers {
return areaChanged;
}
/**
* marks the area as changed
*/
public void markAreaChanged() {
this.areaChanged = true;
}
/**
* resets the areaChanged flag.
*/

View file

@ -28,7 +28,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Semaphore;
import javax.swing.JOptionPane;
@ -96,8 +95,9 @@ public class StendhalClient extends ClientFramework {
/**
* Whether the client is in a batch update.
*/
private boolean inBatchUpdate = false;
private Semaphore drawingSemaphore = new Semaphore(1);
private volatile boolean inBatchUpdate = false;
/** Name of the current area */
private String areaName;
private final StendhalPerceptionListener stendhalPerceptionListener;
@ -233,7 +233,7 @@ public class StendhalClient extends ClientFramework {
if (inBatchUpdate && (contentToLoad == 0)) {
inBatchUpdate = false;
drawingSemaphore.release();
staticLayers.setAreaName(areaName);
}
}
@ -242,7 +242,6 @@ public class StendhalClient extends ClientFramework {
/*
* A batch update has begun
*/
drawingSemaphore.acquireUninterruptibly();
inBatchUpdate = true;
logger.debug("Batch update started");
@ -263,7 +262,8 @@ public class StendhalClient extends ClientFramework {
return items;
}
staticLayers.setAreaName(name.substring(0, i));
//staticLayers.setAreaName(name.substring(0, i));
areaName = name.substring(0, i);
}
/*
@ -303,6 +303,17 @@ public class StendhalClient extends ClientFramework {
return items;
}
/**
* Check if the client is in the middle of a batch update. A batch update
* starts when a content transfer starts and end on the first perception
* event.
*
* @return <code>true</code> if in a batch update.
*/
public boolean isInBatchUpdate() {
return inBatchUpdate;
}
/**
* Determine if we are in the middle of transfering new content.
@ -338,8 +349,6 @@ public class StendhalClient extends ClientFramework {
logger.error("onTransfer", e);
}
}
staticLayers.markAreaChanged();
contentToLoad -= items.size();
/*
@ -614,14 +623,4 @@ public class StendhalClient extends ClientFramework {
}
return res;
}
public void releaseDrawingSemaphore() {
drawingSemaphore.release();
}
public boolean tryAcquireDrawingSemaphore() {
return drawingSemaphore.tryAcquire();
}
}

View file

@ -518,28 +518,24 @@ public class j2DClient implements UserInterface {
logger.debug("Move objects");
gameObjects.update(delta);
if (gameLayers.isAreaChanged() && client.tryAcquireDrawingSemaphore()) {
try {
/*
* Update the screen
*/
screen.setMaxWorldSize(gameLayers.getWidth(), gameLayers.getHeight());
screen.center();
// [Re]create the map
final CollisionDetection cd = gameLayers.getCollisionDetection();
final CollisionDetection pd = gameLayers.getProtectionDetection();
if (gameLayers.isAreaChanged() && !client.isInBatchUpdate()) {
/*
* Update the screen
*/
screen.setMaxWorldSize(gameLayers.getWidth(), gameLayers.getHeight());
screen.center();
if (cd != null) {
minimap.update(cd, pd,
screen.getGraphicsConfiguration(),
gameLayers.getArea());
}
gameLayers.resetChangedArea();
} finally {
client.releaseDrawingSemaphore();
// [Re]create the map
final CollisionDetection cd = gameLayers.getCollisionDetection();
final CollisionDetection pd = gameLayers.getProtectionDetection();
if (cd != null) {
minimap.update(cd, pd,
screen.getGraphicsConfiguration(),
gameLayers.getArea());
}
gameLayers.resetChangedArea();
}
final User user = User.get();
@ -555,17 +551,12 @@ public class j2DClient implements UserInterface {
lastuser = user;
}
}
if (client.tryAcquireDrawingSemaphore()) {
try {
if (mainFrame.getMainFrame().getState() != Frame.ICONIFIED) {
logger.debug("Draw screen");
screen.draw();
minimap.refresh();
containerPanel.repaintChildren();
}
} finally {
client.releaseDrawingSemaphore();
}
if (mainFrame.getMainFrame().getState() != Frame.ICONIFIED) {
logger.debug("Draw screen");
screen.draw();
minimap.refresh();
containerPanel.repaintChildren();
}
logger.debug("Query network");