summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNao Pross <naopross@thearcway.org>2018-12-03 01:04:32 +0100
committerNao Pross <naopross@thearcway.org>2018-12-03 01:04:32 +0100
commite3902f015dcb4612ad72e77337cedc8a88ee94a3 (patch)
treef99baed4c2edf22c4b878f71280b1186494b1e53
parentUpdate Scene thread pause to use a higher level interface (diff)
downloadSubconscious-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.java63
-rw-r--r--src/subconscious/graphics/widget/ActorInfo.java2
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;
}