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();
|
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 int memoryLowColor;
|
||||||
private static float memoryColorPercent;
|
private static float memoryColorPercent;
|
||||||
private static long memoryColorChangeTime;
|
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);
|
static final Semaphore mutex = new Semaphore(1);
|
||||||
|
|
||||||
private static String getString(String name, String def)
|
private static String getString(String name, String def)
|
||||||
|
@ -254,7 +258,8 @@ public class SplashProgress
|
||||||
private final int barHeight = 20;
|
private final int barHeight = 20;
|
||||||
private final int textHeight2 = 20;
|
private final int textHeight2 = 20;
|
||||||
private final int barOffset = 55;
|
private final int barOffset = 55;
|
||||||
|
private long updateTiming;
|
||||||
|
private long framecount;
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
setGL();
|
setGL();
|
||||||
|
@ -266,6 +271,7 @@ public class SplashProgress
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
while(!done)
|
while(!done)
|
||||||
{
|
{
|
||||||
|
framecount++;
|
||||||
ProgressBar first = null, penult = null, last = null;
|
ProgressBar first = null, penult = null, last = null;
|
||||||
Iterator<ProgressBar> i = ProgressManager.barIterator();
|
Iterator<ProgressBar> i = ProgressManager.barIterator();
|
||||||
while(i.hasNext())
|
while(i.hasNext())
|
||||||
|
@ -371,16 +377,40 @@ public class SplashProgress
|
||||||
// is trying to impose a framerate or other thing is occurring. Without the mutex, the main
|
// 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
|
// thread would delay waiting for the same global display lock
|
||||||
mutex.acquireUninterruptibly();
|
mutex.acquireUninterruptibly();
|
||||||
|
long updateStart = System.nanoTime();
|
||||||
Display.update();
|
Display.update();
|
||||||
// As soon as we're done, we release the mutex. The other thread can now ping the processmessages
|
// 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
|
// 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();
|
mutex.release();
|
||||||
if(pause)
|
if(pause)
|
||||||
{
|
{
|
||||||
clearGL();
|
clearGL();
|
||||||
setGL();
|
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();
|
clearGL();
|
||||||
}
|
}
|
||||||
|
@ -464,7 +494,7 @@ public class SplashProgress
|
||||||
memoryColorChangeTime = time;
|
memoryColorChangeTime = time;
|
||||||
memoryColorPercent = usedMemoryPercent;
|
memoryColorPercent = usedMemoryPercent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int memoryBarColor;
|
int memoryBarColor;
|
||||||
if (memoryColorPercent < 0.75f)
|
if (memoryColorPercent < 0.75f)
|
||||||
{
|
{
|
||||||
|
|
|
@ -757,4 +757,6 @@ public class FMLCommonHandler
|
||||||
{
|
{
|
||||||
return (CompoundDataFixer)sidedDelegate.getDataFixer();
|
return (CompoundDataFixer)sidedDelegate.getDataFixer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDisplayVSyncForced() { return sidedDelegate.isDisplayVSyncForced(); }
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,4 +80,6 @@ public interface IFMLSidedHandler
|
||||||
void fireSidedRegistryEvents();
|
void fireSidedRegistryEvents();
|
||||||
|
|
||||||
CompoundDataFixer getDataFixer();
|
CompoundDataFixer getDataFixer();
|
||||||
|
|
||||||
|
boolean isDisplayVSyncForced();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import com.google.common.base.Joiner;
|
||||||
public class ProgressManager
|
public class ProgressManager
|
||||||
{
|
{
|
||||||
private static final List<ProgressBar> bars = new CopyOnWriteArrayList<ProgressBar>();
|
private static final List<ProgressBar> bars = new CopyOnWriteArrayList<ProgressBar>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not a fully fleshed out API, may change in future MC versions.
|
* Not a fully fleshed out API, may change in future MC versions.
|
||||||
* However feel free to use and suggest additions.
|
* However feel free to use and suggest additions.
|
||||||
|
@ -57,7 +56,9 @@ public class ProgressManager
|
||||||
return bar;
|
return bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isDisplayVSyncForced() {
|
||||||
|
return FMLCommonHandler.instance().isDisplayVSyncForced();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Not a fully fleshed out API, may change in future MC versions.
|
* Not a fully fleshed out API, may change in future MC versions.
|
||||||
* However feel free to use and suggest additions.
|
* However feel free to use and suggest additions.
|
||||||
|
|
|
@ -349,4 +349,10 @@ public class FMLServerHandler implements IFMLSidedHandler
|
||||||
{
|
{
|
||||||
return (CompoundDataFixer)this.server.getDataFixer();
|
return (CompoundDataFixer)this.server.getDataFixer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDisplayVSyncForced()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue