SurfaceTexture: Allow creation in detached mode

Adds a constructor that doesn't require a GLES texture name and sets
up the SurfaceTexture in detached mode.

Bug: 15616428
Change-Id: I375495f481bfbe43b3830ab7d124cef8f1be0ac6
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 621534e..eea16f1 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -227,7 +227,7 @@
     }
 }
 
-static void SurfaceTexture_init(JNIEnv* env, jobject thiz,
+static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached,
         jint texName, jboolean singleBufferMode, jobject weakThiz)
 {
     sp<IGraphicBufferProducer> producer;
@@ -239,8 +239,15 @@
         consumer->setDefaultMaxBufferCount(1);
     }
 
-    sp<GLConsumer> surfaceTexture(new GLConsumer(consumer, texName,
-            GL_TEXTURE_EXTERNAL_OES, true, true));
+    sp<GLConsumer> surfaceTexture;
+    if (isDetached) {
+        surfaceTexture = new GLConsumer(consumer, GL_TEXTURE_EXTERNAL_OES,
+                true, true);
+    } else {
+        surfaceTexture = new GLConsumer(consumer, texName,
+                GL_TEXTURE_EXTERNAL_OES, true, true);
+    }
+
     if (surfaceTexture == 0) {
         jniThrowException(env, OutOfResourcesException,
                 "Unable to create native SurfaceTexture");
@@ -338,7 +345,7 @@
 
 static JNINativeMethod gSurfaceTextureMethods[] = {
     {"nativeClassInit",            "()V",   (void*)SurfaceTexture_classInit },
-    {"nativeInit",                 "(IZLjava/lang/ref/WeakReference;)V", (void*)SurfaceTexture_init },
+    {"nativeInit",                 "(ZIZLjava/lang/ref/WeakReference;)V", (void*)SurfaceTexture_init },
     {"nativeFinalize",             "()V",   (void*)SurfaceTexture_finalize },
     {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
     {"nativeUpdateTexImage",       "()V",   (void*)SurfaceTexture_updateTexImage },
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 0862cdd..17795f3 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -126,7 +126,34 @@
      */
     public SurfaceTexture(int texName, boolean singleBufferMode) {
         mCreatorLooper = Looper.myLooper();
-        nativeInit(texName, singleBufferMode, new WeakReference<SurfaceTexture>(this));
+        nativeInit(false, texName, singleBufferMode, new WeakReference<SurfaceTexture>(this));
+    }
+
+    /**
+     * Construct a new SurfaceTexture to stream images to a given OpenGL texture.
+     *
+     * In single buffered mode the application is responsible for serializing access to the image
+     * content buffer. Each time the image content is to be updated, the
+     * {@link #releaseTexImage()} method must be called before the image content producer takes
+     * ownership of the buffer. For example, when producing image content with the NDK
+     * ANativeWindow_lock and ANativeWindow_unlockAndPost functions, {@link #releaseTexImage()}
+     * must be called before each ANativeWindow_lock, or that call will fail. When producing
+     * image content with OpenGL ES, {@link #releaseTexImage()} must be called before the first
+     * OpenGL ES function call each frame.
+     *
+     * Unlike {@link #SurfaceTexture(int, boolean)}, which takes an OpenGL texture object name,
+     * this constructor creates the SurfaceTexture in detached mode. A texture name must be passed
+     * in using {@link #attachToGLContext} before calling {@link #releaseTexImage()} and producing
+     * image content using OpenGL ES.
+     *
+     * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode.
+     *
+     * @throws Surface.OutOfResourcesException If the SurfaceTexture cannot be created.
+     * @hide
+     */
+    public SurfaceTexture(boolean singleBufferMode) {
+        mCreatorLooper = Looper.myLooper();
+        nativeInit(true, 0, singleBufferMode, new WeakReference<SurfaceTexture>(this));
     }
 
     /**
@@ -339,8 +366,8 @@
         }
     }
 
-    private native void nativeInit(int texName, boolean singleBufferMode,
-            WeakReference<SurfaceTexture> weakSelf)
+    private native void nativeInit(boolean isDetached, int texName,
+            boolean singleBufferMode, WeakReference<SurfaceTexture> weakSelf)
             throws Surface.OutOfResourcesException;
     private native void nativeFinalize();
     private native void nativeGetTransformMatrix(float[] mtx);