diff options
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | core/jni/android/graphics/SurfaceTexture.cpp | 24 | ||||
-rw-r--r-- | graphics/java/android/graphics/SurfaceTexture.java | 53 |
3 files changed, 67 insertions, 12 deletions
diff --git a/api/current.txt b/api/current.txt index 0b7416e..6bb40e1 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9770,11 +9770,13 @@ package android.graphics { public class SurfaceTexture { ctor public SurfaceTexture(int); + ctor public SurfaceTexture(int, boolean); method public void attachToGLContext(int); method public void detachFromGLContext(); method public long getTimestamp(); method public void getTransformMatrix(float[]); method public void release(); + method public void releaseTexImage(); method public void setDefaultBufferSize(int, int); method public void setOnFrameAvailableListener(android.graphics.SurfaceTexture.OnFrameAvailableListener); method public void updateTexImage(); diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index bf9177b..31b2cad 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -197,9 +197,16 @@ static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz) } } -static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jint texName, jobject weakThiz) +static void SurfaceTexture_init(JNIEnv* env, jobject thiz, + jint texName, jboolean singleBufferMode, jobject weakThiz) { sp<BufferQueue> bq = new BufferQueue(); + + if (singleBufferMode) { + bq->disableAsyncBuffer(); + bq->setDefaultMaxBufferCount(1); + } + sp<GLConsumer> surfaceTexture(new GLConsumer(bq, texName, GL_TEXTURE_EXTERNAL_OES, true, true)); if (surfaceTexture == 0) { jniThrowException(env, OutOfResourcesException, @@ -248,6 +255,18 @@ static void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz) } } +static void SurfaceTexture_releaseTexImage(JNIEnv* env, jobject thiz) +{ + sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); + status_t err = surfaceTexture->releaseTexImage(); + if (err == INVALID_OPERATION) { + jniThrowException(env, IllegalStateException, "Unable to release texture contents (see " + "logcat for details)"); + } else if (err < 0) { + jniThrowRuntimeException(env, "Error during updateTexImage (see logcat for details)"); + } +} + static jint SurfaceTexture_detachFromGLContext(JNIEnv* env, jobject thiz) { sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); @@ -285,10 +304,11 @@ static void SurfaceTexture_release(JNIEnv* env, jobject thiz) static JNINativeMethod gSurfaceTextureMethods[] = { {"nativeClassInit", "()V", (void*)SurfaceTexture_classInit }, - {"nativeInit", "(ILjava/lang/Object;)V", (void*)SurfaceTexture_init }, + {"nativeInit", "(IZLjava/lang/Object;)V", (void*)SurfaceTexture_init }, {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize }, {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize }, {"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage }, + {"nativeReleaseTexImage", "()V", (void*)SurfaceTexture_releaseTexImage }, {"nativeDetachFromGLContext", "()I", (void*)SurfaceTexture_detachFromGLContext }, {"nativeAttachToGLContext", "(I)I", (void*)SurfaceTexture_attachToGLContext }, {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix }, diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index aaed094..06a8d99 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -95,15 +95,26 @@ public class SurfaceTexture { * @param texName the OpenGL texture object name (e.g. generated via glGenTextures) */ public SurfaceTexture(int texName) { - Looper looper; - if ((looper = Looper.myLooper()) != null) { - mEventHandler = new EventHandler(looper); - } else if ((looper = Looper.getMainLooper()) != null) { - mEventHandler = new EventHandler(looper); - } else { - mEventHandler = null; - } - nativeInit(texName, new WeakReference<SurfaceTexture>(this)); + init(texName, false); + } + + /** + * 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. + * + * @param texName the OpenGL texture object name (e.g. generated via glGenTextures) + * @param singleBufferMode whether the SurfaceTexture will be in single buffered mode. + */ + public SurfaceTexture(int texName, boolean singleBufferMode) { + init(texName, singleBufferMode); } /** @@ -149,6 +160,15 @@ public class SurfaceTexture { } /** + * Releases the the texture content. This is needed in single buffered mode to allow the image + * content producer to take ownership of the image buffer. + * For more information see {@link SurfaceTexture(int, boolean)}. + */ + public void releaseTexImage() { + nativeReleaseTexImage(); + } + + /** * Detach the SurfaceTexture from the OpenGL ES context that owns the OpenGL ES texture object. * This call must be made with the OpenGL ES context current on the calling thread. The OpenGL * ES texture object will be deleted as a result of this call. After calling this method all @@ -284,12 +304,25 @@ public class SurfaceTexture { } } - private native void nativeInit(int texName, Object weakSelf); + private void init(int texName, boolean singleBufferMode) { + Looper looper; + if ((looper = Looper.myLooper()) != null) { + mEventHandler = new EventHandler(looper); + } else if ((looper = Looper.getMainLooper()) != null) { + mEventHandler = new EventHandler(looper); + } else { + mEventHandler = null; + } + nativeInit(texName, singleBufferMode, new WeakReference<SurfaceTexture>(this)); + } + + private native void nativeInit(int texName, boolean singleBufferMode, Object weakSelf); private native void nativeFinalize(); private native void nativeGetTransformMatrix(float[] mtx); private native long nativeGetTimestamp(); private native void nativeSetDefaultBufferSize(int width, int height); private native void nativeUpdateTexImage(); + private native void nativeReleaseTexImage(); private native int nativeDetachFromGLContext(); private native int nativeAttachToGLContext(int texName); private native int nativeGetQueuedCount(); |