mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-31 14:15:30 +00:00
Bug 844275 - Move the GfxInfoThread so that it is guaranteed to run to completion before compositor creation. r=Cwiiis
This commit is contained in:
parent
8c5695896a
commit
f519ef0fcb
@ -156,8 +156,6 @@ public class GeckoAppShell
|
||||
|
||||
private static Handler sGeckoHandler;
|
||||
|
||||
public static GfxInfoThread sGfxInfoThread = null;
|
||||
|
||||
static ActivityHandlerHelper sActivityHelper = new ActivityHandlerHelper();
|
||||
|
||||
/* The Android-side API: API methods that Android calls */
|
||||
@ -2176,9 +2174,7 @@ public class GeckoAppShell
|
||||
}
|
||||
|
||||
public static String getGfxInfoData() {
|
||||
String data = sGfxInfoThread.getData();
|
||||
sGfxInfoThread = null;
|
||||
return data;
|
||||
return GfxInfoThread.getData();
|
||||
}
|
||||
|
||||
public static void registerSurfaceTextureFrameListener(Object surfaceTexture, final int id) {
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.gfx.GfxInfoThread;
|
||||
import org.mozilla.gecko.mozglue.GeckoLoader;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
|
||||
@ -92,15 +91,6 @@ public class GeckoThread extends Thread implements GeckoEventListener {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Here we start the GfxInfo thread, which will query OpenGL
|
||||
// system information for Gecko. This must be done early enough that the data will be
|
||||
// ready by the time it's needed to initialize the LayerManager (it takes about 100 ms
|
||||
// to obtain). Doing it here seems to have no negative effect on startup time. See bug 766251.
|
||||
// Starting the GfxInfoThread here from the GeckoThread, ensures that
|
||||
// the Gecko thread is started first, adding some determinism there.
|
||||
GeckoAppShell.sGfxInfoThread = new GfxInfoThread();
|
||||
GeckoAppShell.sGfxInfoThread.start();
|
||||
|
||||
String path = initGeckoEnvironment();
|
||||
|
||||
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - runGecko");
|
||||
|
@ -59,6 +59,11 @@ public class GLController {
|
||||
};
|
||||
|
||||
private GLController() {
|
||||
// Here we start the GfxInfo thread, which will query OpenGL
|
||||
// system information for Gecko. This must be done early enough that the data will be
|
||||
// ready by the time it's needed to initialize the compositor (it takes about 100 ms
|
||||
// to obtain).
|
||||
GfxInfoThread.startThread();
|
||||
}
|
||||
|
||||
static GLController getInstance(LayerView view) {
|
||||
@ -115,6 +120,17 @@ public class GLController {
|
||||
|
||||
mView.post(new Runnable() {
|
||||
public void run() {
|
||||
// If we haven't yet created the compositor, and the GfxInfoThread
|
||||
// isn't done it's data gathering activities, then postpone creating
|
||||
// the compositor a little bit more. Don't block though, since this is
|
||||
// the UI thread we're running on. This conditional also ensures that
|
||||
// we don't call GfxInfoThread.hasData() once we have created the
|
||||
// compositor, as that is not allowed (see GfxInfoThread).
|
||||
if (!mCompositorCreated && !GfxInfoThread.hasData()) {
|
||||
mView.postDelayed(this, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Re-check mSurfaceValid in case the surface was destroyed between
|
||||
// where we set it to true above and this runnable getting run.
|
||||
|
@ -17,45 +17,66 @@ import javax.microedition.khronos.egl.EGLDisplay;
|
||||
import javax.microedition.khronos.egl.EGLSurface;
|
||||
|
||||
public class GfxInfoThread extends Thread {
|
||||
|
||||
private static final String LOGTAG = "GfxInfoThread";
|
||||
|
||||
private SynchronousQueue<String> mDataQueue;
|
||||
private static GfxInfoThread sInstance;
|
||||
private String mData;
|
||||
|
||||
public GfxInfoThread() {
|
||||
mDataQueue = new SynchronousQueue<String>();
|
||||
private GfxInfoThread() {
|
||||
}
|
||||
|
||||
private void error(String msg) {
|
||||
Log.e(LOGTAG, msg);
|
||||
try {
|
||||
mDataQueue.put("ERROR\n" + msg + "\n");
|
||||
} catch (InterruptedException e) {
|
||||
Log.w(LOGTAG, "Thread interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
public static void startThread() {
|
||||
if (sInstance == null) {
|
||||
sInstance = new GfxInfoThread();
|
||||
sInstance.start();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasData() {
|
||||
// This should never be called before startThread() or after getData()
|
||||
// so we know sInstance will be non-null here
|
||||
synchronized (sInstance) {
|
||||
return sInstance.mData != null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getData() {
|
||||
// This should be called exactly once after startThread(), so we
|
||||
// know sInstance will be non-null here
|
||||
String data = sInstance.getDataImpl();
|
||||
sInstance = null;
|
||||
return data;
|
||||
}
|
||||
|
||||
private synchronized void error(String msg) {
|
||||
Log.e(LOGTAG, msg);
|
||||
mData = "ERROR\n" + msg + "\n";
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
private void eglError(EGL10 egl, String msg) {
|
||||
error(msg + " (EGL error " + Integer.toHexString(egl.eglGetError()) + ")");
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
String data = mDataQueue.poll();
|
||||
if (data != null)
|
||||
return data;
|
||||
private synchronized String getDataImpl() {
|
||||
if (mData != null) {
|
||||
return mData;
|
||||
}
|
||||
|
||||
Log.w(LOGTAG, "We need the GfxInfo data, but it is not yet available. " +
|
||||
"We have to wait for it, so expect abnormally long startup times. " +
|
||||
"Please report a Mozilla bug.");
|
||||
|
||||
try {
|
||||
data = mDataQueue.take();
|
||||
while (mData == null) {
|
||||
wait();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Log.w(LOGTAG, "Thread interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
Log.i(LOGTAG, "GfxInfo data is finally available.");
|
||||
return data;
|
||||
return mData;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -183,11 +204,9 @@ public class GfxInfoThread extends Thread {
|
||||
|
||||
// finally send the data. Notice that we've already freed the EGL resources, so that they don't
|
||||
// remain there until the data is read.
|
||||
try {
|
||||
mDataQueue.put(data);
|
||||
} catch (InterruptedException e) {
|
||||
Log.w(LOGTAG, "Thread interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
synchronized (this) {
|
||||
mData = data;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user