Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e591b49d authored by Mathias Agopian's avatar Mathias Agopian
Browse files

single buffer mode for SurfaceTexture

Bug: 9891035
Change-Id: Ib9cc2b64f7ff3c084ef1d7db442db8e7a24a923d
parent d06db894
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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();
+22 −2
Original line number Diff line number Diff line
@@ -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 },
+43 −10
Original line number Diff line number Diff line
@@ -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;
        init(texName, false);
    }
        nativeInit(texName, 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.
     *
     * @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);
    }

    /**
@@ -148,6 +159,15 @@ public class SurfaceTexture {
        nativeUpdateTexImage();
    }

    /**
     * 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
@@ -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();