mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 08:17:35 +00:00
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:
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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user