OSDN Git Service

Better error checking on GLFrames.
authorMarius Renn <renn@google.com>
Tue, 19 Jul 2011 22:20:25 +0000 (15:20 -0700)
committerMarius Renn <renn@google.com>
Tue, 19 Jul 2011 22:20:25 +0000 (15:20 -0700)
Also includes another bugfix when switching between surfaces.

Change-Id: Ieb1ccc59dd4d1bffb92a766372238799f7ba7cfe

mca/filterfw/java/android/filterfw/core/GLEnvironment.java
mca/filterfw/java/android/filterfw/core/GLFrame.java
mca/filterfw/jni/jni_gl_environment.cpp
mca/filterfw/jni/jni_gl_environment.h
mca/filterfw/native/core/gl_env.cpp
mca/filterfw/native/core/gl_env.h

index cd7fc98..0675637 100644 (file)
@@ -58,6 +58,14 @@ public class GLEnvironment {
         return nativeIsActive();
     }
 
+    public boolean isContextActive() {
+        return nativeIsContextActive();
+    }
+
+    public static boolean isAnyContextActive() {
+        return nativeIsAnyContextActive();
+    }
+
     public void activate() {
         if (Looper.myLooper() != null && Looper.myLooper().equals(Looper.getMainLooper())) {
             Log.e("GLEnvironment", "Activating GL context in UI thread!");
@@ -123,6 +131,10 @@ public class GLEnvironment {
 
     private native boolean nativeIsActive();
 
+    private native boolean nativeIsContextActive();
+
+    private static native boolean nativeIsAnyContextActive();
+
     private native boolean nativeActivate();
 
     private native boolean nativeDeactivate();
index 8f5b401..e775773 100644 (file)
@@ -152,12 +152,14 @@ public class GLFrame extends Frame {
 
     @Override
     public Object getObjectValue() {
+        assertGLEnvValid();
         return ByteBuffer.wrap(getNativeData());
     }
 
     @Override
     public void setInts(int[] ints) {
         assertFrameMutable();
+        assertGLEnvValid();
         if (!setNativeInts(ints)) {
             throw new RuntimeException("Could not set int values for GL frame!");
         }
@@ -165,6 +167,7 @@ public class GLFrame extends Frame {
 
     @Override
     public int[] getInts() {
+        assertGLEnvValid();
         flushGPU("getInts");
         return getNativeInts();
     }
@@ -172,6 +175,7 @@ public class GLFrame extends Frame {
     @Override
     public void setFloats(float[] floats) {
         assertFrameMutable();
+        assertGLEnvValid();
         if (!setNativeFloats(floats)) {
             throw new RuntimeException("Could not set int values for GL frame!");
         }
@@ -179,6 +183,7 @@ public class GLFrame extends Frame {
 
     @Override
     public float[] getFloats() {
+        assertGLEnvValid();
         flushGPU("getFloats");
         return getNativeFloats();
     }
@@ -186,6 +191,7 @@ public class GLFrame extends Frame {
     @Override
     public void setData(ByteBuffer buffer, int offset, int length) {
         assertFrameMutable();
+        assertGLEnvValid();
         byte[] bytes = buffer.array();
         if (getFormat().getSize() != bytes.length) {
             throw new RuntimeException("Data size in setData does not match GL frame size!");
@@ -196,6 +202,7 @@ public class GLFrame extends Frame {
 
     @Override
     public ByteBuffer getData() {
+        assertGLEnvValid();
         flushGPU("getData");
         return ByteBuffer.wrap(getNativeData());
     }
@@ -203,6 +210,7 @@ public class GLFrame extends Frame {
     @Override
     public void setBitmap(Bitmap bitmap) {
         assertFrameMutable();
+        assertGLEnvValid();
         if (getFormat().getWidth()  != bitmap.getWidth() ||
             getFormat().getHeight() != bitmap.getHeight()) {
             throw new RuntimeException("Bitmap dimensions do not match GL frame dimensions!");
@@ -216,6 +224,7 @@ public class GLFrame extends Frame {
 
     @Override
     public Bitmap getBitmap() {
+        assertGLEnvValid();
         flushGPU("getBitmap");
         Bitmap result = Bitmap.createBitmap(getFormat().getWidth(),
                                             getFormat().getHeight(),
@@ -228,6 +237,8 @@ public class GLFrame extends Frame {
 
     @Override
     public void setDataFromFrame(Frame frame) {
+        assertGLEnvValid();
+
         // Make sure frame fits
         if (getFormat().getSize() < frame.getFormat().getSize()) {
             throw new RuntimeException(
@@ -259,6 +270,7 @@ public class GLFrame extends Frame {
 
     public void generateMipMap() {
         assertFrameMutable();
+        assertGLEnvValid();
         if (!generateNativeMipMap()) {
             throw new RuntimeException("Could not generate mip-map for GL frame!");
         }
@@ -266,6 +278,7 @@ public class GLFrame extends Frame {
 
     public void setTextureParameter(int param, int value) {
         assertFrameMutable();
+        assertGLEnvValid();
         if (!setNativeTextureParam(param, value)) {
             throw new RuntimeException("Could not set texture value " + param + " = " + value + " " +
                                        "for GLFrame!");
@@ -292,6 +305,18 @@ public class GLFrame extends Frame {
             + ", FBO ID " + getFboId();
     }
 
+    private void assertGLEnvValid() {
+        if (!mGLEnvironment.isContextActive()) {
+            if (GLEnvironment.isAnyContextActive()) {
+                throw new RuntimeException("Attempting to access " + this + " with foreign GL " +
+                    "context active!");
+            } else {
+                throw new RuntimeException("Attempting to access " + this + " with no GL context " +
+                    " active!");
+            }
+        }
+    }
+
     static {
         System.loadLibrary("filterfw");
     }
index f7ccc71..e41f35c 100644 (file)
@@ -75,6 +75,16 @@ jboolean Java_android_filterfw_core_GLEnvironment_nativeIsActive(JNIEnv* env, jo
   return gl_env ? ToJBool(gl_env->IsActive()) : JNI_FALSE;
 }
 
+jboolean Java_android_filterfw_core_GLEnvironment_nativeIsContextActive(JNIEnv* env, jobject thiz) {
+  GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
+  return gl_env ? ToJBool(gl_env->IsContextActive()) : JNI_FALSE;
+}
+
+jboolean Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* env,
+                                                                           jclass clazz) {
+  return ToJBool(GLEnv::IsAnyContextActive());
+}
+
 jboolean Java_android_filterfw_core_GLEnvironment_nativeActivate(JNIEnv* env, jobject thiz) {
   GLEnv* gl_env = ConvertFromJava<GLEnv>(env, thiz);
   return gl_env ? ToJBool(gl_env->Activate()) : JNI_FALSE;
index 9c46c6a..2af970f 100644 (file)
@@ -39,6 +39,12 @@ JNIEXPORT jboolean JNICALL
 Java_android_filterfw_core_GLEnvironment_nativeIsActive(JNIEnv* env, jobject thiz);
 
 JNIEXPORT jboolean JNICALL
+Java_android_filterfw_core_GLEnvironment_nativeIsContextActive(JNIEnv* env, jobject thiz);
+
+JNIEXPORT jboolean JNICALL
+Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* env, jclass clazz);
+
+JNIEXPORT jboolean JNICALL
 Java_android_filterfw_core_GLEnvironment_nativeActivate(JNIEnv* env, jobject thiz);
 
 JNIEXPORT jboolean JNICALL
index a55823a..e771e3e 100644 (file)
@@ -173,6 +173,14 @@ bool GLEnv::IsActive() const {
     &&   surface() == eglGetCurrentSurface(EGL_DRAW);
 }
 
+bool GLEnv::IsContextActive() const {
+  return context() == eglGetCurrentContext();
+}
+
+bool GLEnv::IsAnyContextActive() {
+  return eglGetCurrentContext() != EGL_NO_CONTEXT;
+}
+
 int GLEnv::AddWindowSurface(const EGLSurface& surface, WindowHandle* window_handle) {
   const int id = ++max_surface_id_;
   surfaces_[id] = SurfaceWindowPair(surface, window_handle);
@@ -184,15 +192,16 @@ int GLEnv::AddSurface(const EGLSurface& surface) {
 }
 
 bool GLEnv::SwitchToSurfaceId(int surface_id) {
-  const SurfaceWindowPair* surface = FindOrNull(surfaces_, surface_id);
-  if (surface) {
-    if (surface_id_ != surface_id) {
+  if (surface_id_ != surface_id) {
+    const SurfaceWindowPair* surface = FindOrNull(surfaces_, surface_id);
+    if (surface) {
+      bool wasActive = IsActive();
       surface_id_ = surface_id;
-      return Activate();
+      return wasActive ? Activate() : true;
     }
-    return true;
+    return false;
   }
-  return false;
+  return true;
 }
 
 bool GLEnv::ReleaseSurfaceId(int surface_id) {
index 4b6344a..e3c699b 100644 (file)
@@ -160,6 +160,13 @@ class GLEnv {
     // Returns true if the environment is active in the current thread.
     bool IsActive() const;
 
+    // Returns true if the environment's context is active in the curent thread.
+    bool IsContextActive() const;
+
+    // Returns true if there is any EGL context active in the current thread.
+    // This need not be a context created by a GLEnv instance.
+    static bool IsAnyContextActive();
+
     // Attaching GL objects ////////////////////////////////////////////////////
 
     // Attach a shader to the environment. The environment takes ownership of