diff options
author | Nao Pross <naopross@thearcway.org> | 2018-12-03 01:04:32 +0100 |
---|---|---|
committer | Nao Pross <naopross@thearcway.org> | 2018-12-03 01:04:32 +0100 |
commit | e3902f015dcb4612ad72e77337cedc8a88ee94a3 (patch) | |
tree | f99baed4c2edf22c4b878f71280b1186494b1e53 | |
parent | Update Scene thread pause to use a higher level interface (diff) | |
download | Subconscious-java-e3902f015dcb4612ad72e77337cedc8a88ee94a3.tar.gz Subconscious-java-e3902f015dcb4612ad72e77337cedc8a88ee94a3.zip |
Refractor sleep in Scene rendering loop for better performance
~10 us improvement
-rw-r--r-- | src/subconscious/graphics/Scene.java | 63 | ||||
-rw-r--r-- | src/subconscious/graphics/widget/ActorInfo.java | 2 |
2 files changed, 37 insertions, 28 deletions
diff --git a/src/subconscious/graphics/Scene.java b/src/subconscious/graphics/Scene.java index 05161d5..c5938f1 100644 --- a/src/subconscious/graphics/Scene.java +++ b/src/subconscious/graphics/Scene.java @@ -8,6 +8,8 @@ import subconscious.graphics.widget.Dynamic; import subconscious.graphics.widget.PerfView; +import java.lang.Thread; + import java.util.ArrayList; import java.util.Map; @@ -58,9 +60,10 @@ public abstract class Scene extends Panel public final String UNIQUE_NAME; private static int absScenesCount = 0; - protected final long DESIRED_FPS = 60; - protected final long DESIRED_DELTA_LOOP = (1000*1000*1000)/DESIRED_FPS; - protected final Map<RenderingHints.Key, ?> RENDERING_HINTS = Map.of( + public static final long DESIRED_FPS = 80; + public static final long DESIRED_DELTA_LOOP_NS = (1000*1000*1000)/DESIRED_FPS; + public static final long NO_DELAYS_PER_YELD = 15; + public static final Map<RenderingHints.Key, ?> RENDERING_HINTS = Map.of( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON, RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON, RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED, @@ -119,7 +122,7 @@ public abstract class Scene extends Panel this.build(); // TODO: this will be controlled in the settings - // this.addWidget(new PerfView("default-perfview", 0, 0)); + this.addWidget(new PerfView("default-perfview", 0, 0)); } public Scene(Game game) { @@ -196,12 +199,9 @@ public abstract class Scene extends Panel /* runnable implementation */ public void run() { - long beginLoopTime; - long endLoopTime; - long currentUpdateTime = System.nanoTime(); - long lastUpdateTime; - long deltaLoop; - long gameDeltaTime; + long beforeTime, afterTime, timeDiff = 0, sleepTime; + long overSleepTime = 0L; + int noDelays = 0; this.running = true; @@ -222,12 +222,13 @@ public abstract class Scene extends Panel } while (running) { - beginLoopTime = System.nanoTime(); + beforeTime = System.nanoTime(); + // render on a double buffer do { do { Graphics2D g = (Graphics2D) this.buffer.getDrawGraphics(); - g.addRenderingHints(this.RENDERING_HINTS); + g.addRenderingHints(Scene.RENDERING_HINTS); g.setFont(Fonts.DEFAULT); this.render(g); this.renderWidgets(g); @@ -245,26 +246,34 @@ public abstract class Scene extends Panel // can be ignored } - lastUpdateTime = currentUpdateTime; - currentUpdateTime = System.nanoTime(); + // update game and widgets + this.update(timeDiff); + this.updateWidgets(timeDiff); + this.game.update(timeDiff); - gameDeltaTime = currentUpdateTime - lastUpdateTime; + afterTime = System.nanoTime(); + timeDiff = afterTime - beforeTime; + sleepTime = (Scene.DESIRED_DELTA_LOOP_NS - timeDiff) - overSleepTime; - // TODO: remove Scene.update? - this.update(gameDeltaTime); - this.updateWidgets(gameDeltaTime); - this.game.update(gameDeltaTime); + // if sleep is needed (too fast) + if (sleepTime > 0) { + try { + Thread.sleep(sleepTime/(1000*1000)); + } catch (InterruptedException ex) { + // ex.printStackTrace(); + } - endLoopTime = System.nanoTime(); - deltaLoop = endLoopTime - beginLoopTime; + overSleepTime = (System.nanoTime() - afterTime) - sleepTime; - if (deltaLoop > this.DESIRED_DELTA_LOOP) { - // TODO: late => skip frame + + // if sleep is not needed (too slow) } else { - try { - Thread.sleep((this.DESIRED_DELTA_LOOP - deltaLoop)/(1000*1000)); - } catch (InterruptedException ex) { - ex.printStackTrace(); + overSleepTime = 0L; + // if the thread has been late for too much time, give up + // the cpu to other threads + if (++noDelays >= Scene.NO_DELAYS_PER_YELD) { + Thread.yield(); + noDelays = 0; } } diff --git a/src/subconscious/graphics/widget/ActorInfo.java b/src/subconscious/graphics/widget/ActorInfo.java index a2b25ad..82aecd4 100644 --- a/src/subconscious/graphics/widget/ActorInfo.java +++ b/src/subconscious/graphics/widget/ActorInfo.java @@ -58,7 +58,7 @@ public class ActorInfo extends Widget { this.observingActor = actor; } - public void unsetActor() { + public synchronized void unsetActor() { this.observingActor = null; } |