From cbda433bb2a41b2dd9a1cdf31edd8b2ca5f16c30 Mon Sep 17 00:00:00 2001 From: Kimmo Rundelin Date: Tue, 14 Sep 2010 10:49:10 +0000 Subject: [PATCH] Non-locking drawing. Hopefully fixes [3065851] "0.87 Bad performance on windows" --- src/games/stendhal/client/GameScreen.java | 8 +-- .../stendhal/client/StaticGameLayers.java | 22 ++++---- src/games/stendhal/client/StendhalClient.java | 35 ++++++------ src/games/stendhal/client/gui/j2DClient.java | 53 ++++++++----------- 4 files changed, 50 insertions(+), 68 deletions(-) diff --git a/src/games/stendhal/client/GameScreen.java b/src/games/stendhal/client/GameScreen.java index 2c0d170273..a95ffe4808 100644 --- a/src/games/stendhal/client/GameScreen.java +++ b/src/games/stendhal/client/GameScreen.java @@ -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); } } diff --git a/src/games/stendhal/client/StaticGameLayers.java b/src/games/stendhal/client/StaticGameLayers.java index 7636d41568..fa5d9a5647 100644 --- a/src/games/stendhal/client/StaticGameLayers.java +++ b/src/games/stendhal/client/StaticGameLayers.java @@ -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. */ diff --git a/src/games/stendhal/client/StendhalClient.java b/src/games/stendhal/client/StendhalClient.java index 6978179b4c..1c3c3880a9 100644 --- a/src/games/stendhal/client/StendhalClient.java +++ b/src/games/stendhal/client/StendhalClient.java @@ -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 true 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(); - } - - } diff --git a/src/games/stendhal/client/gui/j2DClient.java b/src/games/stendhal/client/gui/j2DClient.java index f28fc07cf2..57993f9d19 100644 --- a/src/games/stendhal/client/gui/j2DClient.java +++ b/src/games/stendhal/client/gui/j2DClient.java @@ -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");