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. (cherry picked from commit 03d7eaa)
This commit is contained in:
parent
69b72201ac
commit
cec90d7f48
|
@ -1098,4 +1098,10 @@ public class FMLClientHandler implements IFMLSidedHandler
|
|||
{
|
||||
return (CompoundDataFixer)this.client.getDataFixer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplayVSyncForced()
|
||||
{
|
||||
return SplashProgress.isDisplayVSyncForced;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,10 @@ public class SplashProgress
|
|||
private static int memoryLowColor;
|
||||
private static float memoryColorPercent;
|
||||
private static long memoryColorChangeTime;
|
||||
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)
|
||||
|
@ -254,7 +258,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();
|
||||
|
@ -266,6 +271,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())
|
||||
|
@ -371,17 +377,41 @@ 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();
|
||||
}
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
|
|
@ -757,4 +757,6 @@ public class FMLCommonHandler
|
|||
{
|
||||
return (CompoundDataFixer)sidedDelegate.getDataFixer();
|
||||
}
|
||||
|
||||
public boolean isDisplayVSyncForced() { return sidedDelegate.isDisplayVSyncForced(); }
|
||||
}
|
||||
|
|
|
@ -80,4 +80,6 @@ public interface IFMLSidedHandler
|
|||
void fireSidedRegistryEvents();
|
||||
|
||||
CompoundDataFixer getDataFixer();
|
||||
|
||||
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.
|
||||
|
|
|
@ -349,4 +349,10 @@ public class FMLServerHandler implements IFMLSidedHandler
|
|||
{
|
||||
return (CompoundDataFixer)this.server.getDataFixer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplayVSyncForced()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue