summaryrefslogtreecommitdiffstats
path: root/opengl/java
diff options
context:
space:
mode:
Diffstat (limited to 'opengl/java')
-rw-r--r--opengl/java/android/opengl/GLSurfaceView.java91
1 files changed, 71 insertions, 20 deletions
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 952eff2..cbe5be4 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -18,7 +18,6 @@ package android.opengl;
import java.io.Writer;
import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
@@ -30,6 +29,8 @@ import javax.microedition.khronos.opengles.GL;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
+import android.content.pm.ConfigurationInfo;
+import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
@@ -682,7 +683,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
}
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] num_config = new int[1];
- egl.eglChooseConfig(display, mConfigSpec, null, 0, num_config);
+ if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,
+ num_config)) {
+ throw new IllegalArgumentException("eglChooseConfig failed");
+ }
int numConfigs = num_config[0];
@@ -692,8 +696,10 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
}
EGLConfig[] configs = new EGLConfig[numConfigs];
- egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
- num_config);
+ if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
+ num_config)) {
+ throw new IllegalArgumentException("eglChooseConfig#2 failed");
+ }
EGLConfig config = chooseConfig(egl, display, configs);
if (config == null) {
throw new IllegalArgumentException("No config chosen");
@@ -818,11 +824,17 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
*/
mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+ if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
+ throw new RuntimeException("eglGetDisplay failed");
+ }
+
/*
* We can now initialize EGL for that display
*/
int[] version = new int[2];
- mEgl.eglInitialize(mEglDisplay, version);
+ if(!mEgl.eglInitialize(mEglDisplay, version)) {
+ throw new RuntimeException("eglInitialize failed");
+ }
mEglConfig = mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
/*
@@ -1059,6 +1071,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
}
if (changed) {
gl = (GL10) mEglHelper.createSurface(getHolder());
+ sGLThreadManager.checkGLDriver(gl);
tellRendererSurfaceChanged = true;
}
if (tellRendererSurfaceCreated) {
@@ -1272,37 +1285,75 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
}
}
- static class GLThreadManager {
- public boolean shouldQuit(GLThread thread) {
- synchronized(this) {
- return thread != mMostRecentGLThread;
- }
- }
+ private static class GLThreadManager {
public void start(GLThread thread) throws InterruptedException {
+ if (! mGLESVersionCheckComplete) {
+ mGLESVersion = SystemProperties.getInt(
+ "ro.opengles.version",
+ ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
+ if (mGLESVersion >= kGLES_20) {
+ mMultipleGLESContextsAllowed = true;
+ }
+ mGLESVersionCheckComplete = true;
+ }
+
GLThread oldThread = null;
synchronized(this) {
mMostRecentGLThread = thread;
oldThread = mMostRecentGLThread;
+
+ while ((! mMultipleGLESContextsAllowed)
+ && mGLContextCount > 0) {
+ wait();
+ }
+
+ mGLContextCount++;
}
- if (oldThread != null) {
+
+ if (oldThread != null && ! mMultipleGLESContextsAllowed) {
synchronized(oldThread) {
oldThread.notifyAll();
}
}
- sEglSemaphore.acquire();
}
- public void end(GLThread thread) {
- sEglSemaphore.release();
- synchronized(this) {
- if (mMostRecentGLThread == thread) {
- mMostRecentGLThread = null;
+
+ public synchronized void end(GLThread thread) {
+ mGLContextCount--;
+ notifyAll();
+ if (mMostRecentGLThread == thread) {
+ mMostRecentGLThread = null;
+ }
+ }
+
+ public synchronized void checkGLDriver(GL10 gl) {
+ if (! mGLESDriverCheckComplete) {
+ if (mGLESVersion < kGLES_20) {
+ String renderer = gl.glGetString(GL10.GL_RENDERER);
+ mMultipleGLESContextsAllowed =
+ ! renderer.startsWith(kMSM7K_RENDERER_PREFIX);
+ notifyAll();
}
+ mGLESDriverCheckComplete = true;
}
}
+
+ public boolean shouldQuit(GLThread thread) {
+ synchronized(this) {
+ return thread != mMostRecentGLThread;
+ }
+ }
+
+ private boolean mGLESVersionCheckComplete;
+ private int mGLESVersion;
private GLThread mMostRecentGLThread;
- }
+ private boolean mGLESDriverCheckComplete;
+ private boolean mMultipleGLESContextsAllowed;
+ private int mGLContextCount;
+ private static final int kGLES_20 = 0x20000;
+ private static final String kMSM7K_RENDERER_PREFIX =
+ "Q3Dimension MSM7500 ";
+ };
- private static final Semaphore sEglSemaphore = new Semaphore(1);
private static final GLThreadManager sGLThreadManager = new GLThreadManager();
private boolean mSizeChanged = true;