summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--core/jni/android/graphics/SurfaceTexture.cpp24
-rw-r--r--graphics/java/android/graphics/SurfaceTexture.java53
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();