You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(134) |
Sep
(52) |
Oct
(13) |
Nov
(342) |
Dec
(163) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(44) |
Feb
(62) |
Mar
(158) |
Apr
(38) |
May
(70) |
Jun
(58) |
Jul
(104) |
Aug
(207) |
Sep
(83) |
Oct
(122) |
Nov
(23) |
Dec
(49) |
| 2004 |
Jan
(119) |
Feb
(132) |
Mar
(192) |
Apr
(140) |
May
(77) |
Jun
(74) |
Jul
(201) |
Aug
(63) |
Sep
(102) |
Oct
(70) |
Nov
(173) |
Dec
(78) |
| 2005 |
Jan
(174) |
Feb
(197) |
Mar
(105) |
Apr
(59) |
May
(77) |
Jun
(43) |
Jul
(21) |
Aug
(18) |
Sep
(47) |
Oct
(37) |
Nov
(74) |
Dec
(50) |
| 2006 |
Jan
(44) |
Feb
(19) |
Mar
(32) |
Apr
(24) |
May
(31) |
Jun
(55) |
Jul
(138) |
Aug
(28) |
Sep
(12) |
Oct
(41) |
Nov
(58) |
Dec
(24) |
| 2007 |
Jan
(28) |
Feb
(14) |
Mar
(10) |
Apr
(68) |
May
(30) |
Jun
(26) |
Jul
(18) |
Aug
(63) |
Sep
(19) |
Oct
(29) |
Nov
(20) |
Dec
(10) |
| 2008 |
Jan
(38) |
Feb
(7) |
Mar
(37) |
Apr
(120) |
May
(41) |
Jun
(36) |
Jul
(39) |
Aug
(24) |
Sep
(28) |
Oct
(30) |
Nov
(36) |
Dec
(75) |
| 2009 |
Jan
(46) |
Feb
(22) |
Mar
(50) |
Apr
(70) |
May
(134) |
Jun
(105) |
Jul
(75) |
Aug
(34) |
Sep
(38) |
Oct
(34) |
Nov
(19) |
Dec
(20) |
| 2010 |
Jan
(11) |
Feb
(20) |
Mar
(65) |
Apr
(83) |
May
(104) |
Jun
(73) |
Jul
(78) |
Aug
(57) |
Sep
(43) |
Oct
(35) |
Nov
(9) |
Dec
(4) |
| 2011 |
Jan
(21) |
Feb
(11) |
Mar
(18) |
Apr
(10) |
May
(18) |
Jun
(15) |
Jul
(48) |
Aug
(25) |
Sep
(17) |
Oct
(45) |
Nov
(15) |
Dec
(12) |
| 2012 |
Jan
(21) |
Feb
(9) |
Mar
(12) |
Apr
(9) |
May
(9) |
Jun
(5) |
Jul
(1) |
Aug
(10) |
Sep
(12) |
Oct
(1) |
Nov
(28) |
Dec
(5) |
| 2013 |
Jan
(4) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2014 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
|
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
| 2015 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
|
| 2016 |
Jan
(2) |
Feb
(1) |
Mar
(1) |
Apr
(1) |
May
(2) |
Jun
|
Jul
(1) |
Aug
(2) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2017 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
1
(2) |
2
|
3
|
4
|
|
5
|
6
(2) |
7
|
8
|
9
|
10
|
11
|
|
12
|
13
|
14
|
15
|
16
|
17
|
18
(3) |
|
19
|
20
|
21
|
22
|
23
|
24
|
25
|
|
26
|
27
|
28
(1) |
29
(1) |
|
|
|
|
From: <ka...@us...> - 2012-02-29 23:18:43
|
Revision: 3746
http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3746&view=rev
Author: kappa1
Date: 2012-02-29 23:18:35 +0000 (Wed, 29 Feb 2012)
Log Message:
-----------
Implement a much more accurate Display.sync() method that auto adapts to the systems timer resolution and load.
Modified Paths:
--------------
trunk/LWJGL/src/java/org/lwjgl/opengl/Display.java
Modified: trunk/LWJGL/src/java/org/lwjgl/opengl/Display.java
===================================================================
--- trunk/LWJGL/src/java/org/lwjgl/opengl/Display.java 2012-02-28 18:18:06 UTC (rev 3745)
+++ trunk/LWJGL/src/java/org/lwjgl/opengl/Display.java 2012-02-29 23:18:35 UTC (rev 3746)
@@ -79,9 +79,15 @@
/** The current display mode, if created */
private static DisplayMode current_mode;
- /** Timer for sync() */
- private static long timeThen;
+ /** time at last sync() */
+ private static long lastTime;
+ /** Whether the sync() method has been initiated */
+ private static boolean syncInitiated;
+
+ /** adaptive time to yield instead of sleeping in sync()*/
+ private static long adaptiveYieldTime = 1000*1000;
+
/** X coordinate of the window */
private static int x = -1;
@@ -401,41 +407,84 @@
}
}
- private static long timeLate;
-
/**
- * Best sync method that works reliably.
- *
+ * An accurate sync method that adapts automatically
+ * to the system it runs on to provide reliable results.
+ *
* @param fps The desired frame rate, in frames per second
*/
public static void sync(int fps) {
- long timeNow;
- long gapTo;
- long savedTimeLate;
- synchronized ( GlobalLock.lock ) {
- gapTo = Sys.getTimerResolution() / fps + timeThen;
- timeNow = Sys.getTime();
- savedTimeLate = timeLate;
- }
-
+ if (fps <= 0) return;
+ if (!syncInitiated) initiateSyncTimer();
+
+ long sleepTime = 1000000000 / fps; // nanoseconds to sleep this frame
+ // adaptiveYieldTime + remainder micro & nano seconds if smaller than sleepTime
+ long yieldTime = Math.min(sleepTime, adaptiveYieldTime + sleepTime % (1000*1000));
+ long overSleep = 0; // time the sync goes over by
+
try {
- while ( gapTo > timeNow + savedTimeLate ) {
- Thread.sleep(1);
- timeNow = Sys.getTime();
+ while (true) {
+ long t = getTime() - lastTime;
+
+ if (t < sleepTime - yieldTime) {
+ Thread.sleep(1);
+ }
+ else if (t < sleepTime) {
+ // burn the last few CPU cycles to ensure accuracy
+ Thread.yield();
+ }
+ else {
+ overSleep = t - sleepTime;
+ break; // exit while loop
+ }
}
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
+ } catch (InterruptedException e) {}
+
+ lastTime = getTime() - Math.min(overSleep, sleepTime);
+
+ // auto tune the amount of time to yield
+ if (overSleep > adaptiveYieldTime) {
+ // increase by 500 microseconds (half a ms)
+ adaptiveYieldTime = Math.min(adaptiveYieldTime + 500*1000, sleepTime);
}
-
- synchronized ( GlobalLock.lock ) {
- if ( gapTo < timeNow )
- timeLate = timeNow - gapTo;
- else
- timeLate = 0;
-
- timeThen = timeNow;
+ else if (overSleep < adaptiveYieldTime - 1000*1000) {
+ // decrease by 5 microseconds
+ adaptiveYieldTime = Math.max(adaptiveYieldTime - 5*1000, 1000*1000);
}
}
+
+ /**
+ * Get System Nano Time
+ * @return will return the current time in nano's
+ */
+ private static long getTime() {
+ return (Sys.getTime() * 1000000000) / Sys.getTimerResolution();
+ }
+
+ /**
+ * On windows the sleep functions can be highly inaccurate by
+ * over 10ms making in unusable. However it can be forced to
+ * be a bit more accurate by running a separate sleeping daemon
+ * thread.
+ */
+ private static void initiateSyncTimer() {
+ syncInitiated = true;
+
+ if (!System.getProperty("os.name").startsWith("Win")) {
+ return;
+ }
+
+ Thread timerAccuracyThread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(Long.MAX_VALUE);
+ } catch (Exception e) {}
+ }
+ });
+
+ timerAccuracyThread.setDaemon(true);
+ timerAccuracyThread.start();
+ }
/** @return the title of the window */
public static String getTitle() {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|