Add in a check to the splash screen. If the Display.update call takes

too long on average (over first 200 frames) we'll use a sleep based
timer to allow mods doing splash screen work some time on the
LWJGL global lock.
This commit is contained in:
cpw committed 2017-03-06 17:31:26 -05:00
1 parent 1be1bb59c5
commit 03d7eaae23
6 files changed
+51 -4

No files matched your search

@@ -1056,4 +1056,10 @@ public class FMLClientHandler implements IFMLSidedHandler
{
MinecraftForge.EVENT_BUS.post(new ModelRegistryEvent());
}
@Override
public boolean isDisplayVSyncForced()
{
return SplashProgress.isDisplayVSyncForced;
}
}
@@ -106,6 +106,10 @@ public class SplashProgress
private static int barBorderColor;
private static int barColor;
private static int barBackgroundColor;
static boolean isDisplayVSyncForced = false;
private static final int TIMING_FRAME_COUNT = 200;
private static final int TIMING_FRAME_THRESHOLD = TIMING_FRAME_COUNT * 5 * 1000000; // 5 ms per frame, scaled to nanos
static final Semaphore mutex = new Semaphore(1);
private static String getString(String name, String def)
@@ -240,7 +244,8 @@ public class SplashProgress
private final int barHeight = 20;
private final int textHeight2 = 20;
private final int barOffset = 55;
private long updateTiming;
private long framecount;
public void run()
{
setGL();
@@ -252,6 +257,7 @@ public class SplashProgress
glDisable(GL_TEXTURE_2D);
while(!done)
{
framecount++;
ProgressBar first = null, penult = null, last = null;
Iterator<ProgressBar> i = ProgressManager.barIterator();
while(i.hasNext())
@@ -348,16 +354,40 @@ public class SplashProgress
// is trying to impose a framerate or other thing is occurring. Without the mutex, the main
// thread would delay waiting for the same global display lock
mutex.acquireUninterruptibly();
long updateStart = System.nanoTime();
Display.update();
// As soon as we're done, we release the mutex. The other thread can now ping the processmessages
// call as often as it wants until we get get back here again
long dur = System.nanoTime() - updateStart;
if (framecount < TIMING_FRAME_COUNT) {
updateTiming += dur;
}
mutex.release();
if(pause)
{
clearGL();
setGL();
}
Display.sync(100);
// Such a hack - if the time taken is greater than 10 milliseconds, we're gonna guess that we're on a
// system where vsync is forced through the swapBuffers call - so we have to force a sleep and let the
// loading thread have a turn - some badly designed mods access Keyboard and therefore GlobalLock.lock
// during splash screen, and mutex against the above Display.update call as a result.
// 4 milliseconds is a guess - but it should be enough to trigger in most circumstances. (Maybe if
// 240FPS is possible, this won't fire?)
if (framecount >= TIMING_FRAME_COUNT && updateTiming > TIMING_FRAME_THRESHOLD) {
if (!isDisplayVSyncForced)
{
isDisplayVSyncForced = true;
FMLLog.log(Level.INFO, "Using alternative sync timing : %d frames of Display.update took %d nanos", TIMING_FRAME_COUNT, updateTiming);
}
try { Thread.sleep(16); } catch (InterruptedException ie) {}
} else
{
if (framecount ==TIMING_FRAME_COUNT) {
FMLLog.log(Level.INFO, "Using sync timing. %d frames of Display.update took %d nanos", TIMING_FRAME_COUNT, updateTiming);
}
Display.sync(100);
}
}
clearGL();
}
@@ -751,4 +751,6 @@ public class FMLCommonHandler
{
sidedDelegate.fireSidedRegistryEvents();
}
public boolean isDisplayVSyncForced() { return sidedDelegate.isDisplayVSyncForced(); }
}
@@ -77,4 +77,6 @@ public interface IFMLSidedHandler
void reloadRenderers();
void fireSidedRegistryEvents();
boolean isDisplayVSyncForced();
}
@@ -32,7 +32,6 @@ import com.google.common.base.Joiner;
public class ProgressManager
{
private static final List<ProgressBar> bars = new CopyOnWriteArrayList<ProgressBar>();
/**
* Not a fully fleshed out API, may change in future MC versions.
* However feel free to use and suggest additions.
@@ -57,7 +56,9 @@ public class ProgressManager
return bar;
}
public static boolean isDisplayVSyncForced() {
return FMLCommonHandler.instance().isDisplayVSyncForced();
}
/**
* Not a fully fleshed out API, may change in future MC versions.
* However feel free to use and suggest additions.
@@ -332,4 +332,10 @@ public class FMLServerHandler implements IFMLSidedHandler
{
// NOOP
}
@Override
public boolean isDisplayVSyncForced()
{
return false;
}
}