SurfaceTexture.cpp revision a86ab640f7bb0bf3cb4eaed80473ca8c5d131903
16714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis/*
26714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * Copyright (C) 2010 The Android Open Source Project
36714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis *
46714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
56714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * you may not use this file except in compliance with the License.
66714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * You may obtain a copy of the License at
76714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis *
86714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
96714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis *
106714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * Unless required by applicable law or agreed to in writing, software
116714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
126714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * See the License for the specific language governing permissions and
146714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * limitations under the License.
156714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis */
166714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
176714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#define LOG_TAG "SurfaceTexture"
186714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
196714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <stdio.h>
206714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
21e3eae73abb5e429d9747f9c36ab025219e68bb26Mathias Agopian#include <GLES2/gl2.h>
22e3eae73abb5e429d9747f9c36ab025219e68bb26Mathias Agopian#include <GLES2/gl2ext.h>
23e3eae73abb5e429d9747f9c36ab025219e68bb26Mathias Agopian
24d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden#include <gui/GLConsumer.h>
2552800617946c456e78ed010c82d0ec4358368164Mathias Agopian#include <gui/Surface.h>
266714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
276714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <android_runtime/AndroidRuntime.h>
286714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
296714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <utils/Log.h>
306714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <utils/misc.h>
316714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
326714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include "jni.h"
33376590d668e22a918439877b55faf075427b13f3Jamie Gennis#include "JNIHelp.h"
346714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
356714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
366714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
376714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisnamespace android {
386714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
396714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisstatic const char* const OutOfResourcesException =
40a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin    "android/view/Surface$OutOfResourcesException";
412b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennisstatic const char* const IllegalStateException = "java/lang/IllegalStateException";
42050316184b01c0d1a01c46afae7429b89a27c31btedboconst char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
436714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
44376590d668e22a918439877b55faf075427b13f3Jamie Gennisstruct fields_t {
45376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jfieldID  surfaceTexture;
4652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    jfieldID  bufferQueue;
47c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    jfieldID  frameAvailableListener;
48376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jmethodID postEvent;
496714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis};
50376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic fields_t fields;
516714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
526714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
536714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
54376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz,
55d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden        const sp<GLConsumer>& surfaceTexture)
566714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
57d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    GLConsumer* const p =
58d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden        (GLConsumer*)env->GetIntField(thiz, fields.surfaceTexture);
596714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (surfaceTexture.get()) {
60b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian        surfaceTexture->incStrong((void*)SurfaceTexture_setSurfaceTexture);
616714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
626714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (p) {
63b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian        p->decStrong((void*)SurfaceTexture_setSurfaceTexture);
646714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
65376590d668e22a918439877b55faf075427b13f3Jamie Gennis    env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get());
666714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
676714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
6852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopianstatic void SurfaceTexture_setBufferQueue(JNIEnv* env, jobject thiz,
6952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian        const sp<BufferQueue>& bq)
7052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian{
7152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    BufferQueue* const p =
7252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian        (BufferQueue*)env->GetIntField(thiz, fields.bufferQueue);
7352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    if (bq.get()) {
7452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian        bq->incStrong((void*)SurfaceTexture_setBufferQueue);
7552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    }
7652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    if (p) {
7752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian        p->decStrong((void*)SurfaceTexture_setBufferQueue);
7852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    }
7952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    env->SetIntField(thiz, fields.bufferQueue, (int)bq.get());
8052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian}
8152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian
82c99db2bc460cc795947d99076da380e22a21e493Igor Murashkinstatic void SurfaceTexture_setFrameAvailableListener(JNIEnv* env,
83d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden        jobject thiz, sp<GLConsumer::FrameAvailableListener> listener)
846714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
85d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    GLConsumer::FrameAvailableListener* const p =
86d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden        (GLConsumer::FrameAvailableListener*)
87c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin            env->GetIntField(thiz, fields.frameAvailableListener);
88c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    if (listener.get()) {
89b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian        listener->incStrong((void*)SurfaceTexture_setSurfaceTexture);
90c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    }
91c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    if (p) {
92b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian        p->decStrong((void*)SurfaceTexture_setSurfaceTexture);
93c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    }
94c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    env->SetIntField(thiz, fields.frameAvailableListener, (int)listener.get());
95c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin}
96c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin
9752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopiansp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) {
98d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    return (GLConsumer*)env->GetIntField(thiz, fields.surfaceTexture);
996714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
1006714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
10152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopiansp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz) {
10252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    return (BufferQueue*)env->GetIntField(thiz, fields.bufferQueue);
10352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian}
10452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian
10552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopiansp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz) {
106d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
10752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, thiz));
10852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    sp<Surface> surfaceTextureClient(surfaceTexture != NULL ? new Surface(producer) : NULL);
109846db33313aa0899fa7928256c6734964bd92520Glenn Kasten    return surfaceTextureClient;
110846db33313aa0899fa7928256c6734964bd92520Glenn Kasten}
111846db33313aa0899fa7928256c6734964bd92520Glenn Kasten
11252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopianbool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) {
113050316184b01c0d1a01c46afae7429b89a27c31btedbo    jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
114050316184b01c0d1a01c46afae7429b89a27c31btedbo    return env->IsInstanceOf(thiz, surfaceTextureClass);
115050316184b01c0d1a01c46afae7429b89a27c31btedbo}
116050316184b01c0d1a01c46afae7429b89a27c31btedbo
1176714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
1186714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
119d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFaddenclass JNISurfaceTextureContext : public GLConsumer::FrameAvailableListener
1206714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
121376590d668e22a918439877b55faf075427b13f3Jamie Gennispublic:
122376590d668e22a918439877b55faf075427b13f3Jamie Gennis    JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz);
123376590d668e22a918439877b55faf075427b13f3Jamie Gennis    virtual ~JNISurfaceTextureContext();
124376590d668e22a918439877b55faf075427b13f3Jamie Gennis    virtual void onFrameAvailable();
125376590d668e22a918439877b55faf075427b13f3Jamie Gennis
126376590d668e22a918439877b55faf075427b13f3Jamie Gennisprivate:
1270a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    static JNIEnv* getJNIEnv(bool* needsDetach);
1280a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    static void detachJNI();
12984293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis
130376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jobject mWeakThiz;
131376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jclass mClazz;
132376590d668e22a918439877b55faf075427b13f3Jamie Gennis};
133376590d668e22a918439877b55faf075427b13f3Jamie Gennis
134376590d668e22a918439877b55faf075427b13f3Jamie GennisJNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env,
135376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jobject weakThiz, jclass clazz) :
136376590d668e22a918439877b55faf075427b13f3Jamie Gennis    mWeakThiz(env->NewGlobalRef(weakThiz)),
137376590d668e22a918439877b55faf075427b13f3Jamie Gennis    mClazz((jclass)env->NewGlobalRef(clazz))
138376590d668e22a918439877b55faf075427b13f3Jamie Gennis{}
139376590d668e22a918439877b55faf075427b13f3Jamie Gennis
1400a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie GennisJNIEnv* JNISurfaceTextureContext::getJNIEnv(bool* needsDetach) {
1410a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    *needsDetach = false;
1420a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    JNIEnv* env = AndroidRuntime::getJNIEnv();
1430a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    if (env == NULL) {
1440a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
1450a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        JavaVM* vm = AndroidRuntime::getJavaVM();
1460a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        int result = vm->AttachCurrentThread(&env, (void*) &args);
1470a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        if (result != JNI_OK) {
1483762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("thread attach failed: %#x", result);
1490a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis            return NULL;
1500a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        }
1510a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        *needsDetach = true;
1520a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    }
1530a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    return env;
1540a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis}
1550a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis
1560a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennisvoid JNISurfaceTextureContext::detachJNI() {
15784293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    JavaVM* vm = AndroidRuntime::getJavaVM();
1580a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    int result = vm->DetachCurrentThread();
15984293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    if (result != JNI_OK) {
1603762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("thread detach failed: %#x", result);
16184293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    }
16284293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis}
16384293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis
164376590d668e22a918439877b55faf075427b13f3Jamie GennisJNISurfaceTextureContext::~JNISurfaceTextureContext()
165376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
1660a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    bool needsDetach = false;
1670a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    JNIEnv* env = getJNIEnv(&needsDetach);
16884293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    if (env != NULL) {
16984293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis        env->DeleteGlobalRef(mWeakThiz);
17084293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis        env->DeleteGlobalRef(mClazz);
17184293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    } else {
1728564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("leaking JNI object references");
17384293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    }
1740a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    if (needsDetach) {
1750a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        detachJNI();
1760a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    }
177376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
178376590d668e22a918439877b55faf075427b13f3Jamie Gennis
179376590d668e22a918439877b55faf075427b13f3Jamie Gennisvoid JNISurfaceTextureContext::onFrameAvailable()
180376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
1810a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    bool needsDetach = false;
1820a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    JNIEnv* env = getJNIEnv(&needsDetach);
18384293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    if (env != NULL) {
18484293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis        env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz);
18584293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    } else {
1868564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("onFrameAvailable event will not posted");
18784293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    }
1880a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    if (needsDetach) {
1890a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        detachJNI();
1900a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    }
191376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
192376590d668e22a918439877b55faf075427b13f3Jamie Gennis
193376590d668e22a918439877b55faf075427b13f3Jamie Gennis// ----------------------------------------------------------------------------
194376590d668e22a918439877b55faf075427b13f3Jamie Gennis
19552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian
19652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
19752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian#define ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID "mBufferQueue"
19852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
19952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian                                         "mFrameAvailableListener"
20052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian
201376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
202376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
203376590d668e22a918439877b55faf075427b13f3Jamie Gennis    fields.surfaceTexture = env->GetFieldID(clazz,
204376590d668e22a918439877b55faf075427b13f3Jamie Gennis            ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I");
205376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (fields.surfaceTexture == NULL) {
2063762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("can't find android/graphics/SurfaceTexture.%s",
207376590d668e22a918439877b55faf075427b13f3Jamie Gennis                ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
208376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
20952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    fields.bufferQueue = env->GetFieldID(clazz,
21052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian            ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID, "I");
21152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    if (fields.bufferQueue == NULL) {
21252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian        ALOGE("can't find android/graphics/SurfaceTexture.%s",
21352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian                ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID);
21452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    }
215c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    fields.frameAvailableListener = env->GetFieldID(clazz,
216c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin            ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID, "I");
217c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    if (fields.frameAvailableListener == NULL) {
218c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin        ALOGE("can't find android/graphics/SurfaceTexture.%s",
219c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin                ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID);
220c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    }
221376590d668e22a918439877b55faf075427b13f3Jamie Gennis
222376590d668e22a918439877b55faf075427b13f3Jamie Gennis    fields.postEvent = env->GetStaticMethodID(clazz, "postEventFromNative",
223376590d668e22a918439877b55faf075427b13f3Jamie Gennis            "(Ljava/lang/Object;)V");
224376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (fields.postEvent == NULL) {
2253762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("can't find android/graphics/SurfaceTexture.postEventFromNative");
226376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
227376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
2286714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
229e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopianstatic void SurfaceTexture_init(JNIEnv* env, jobject thiz,
230e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian        jint texName, jboolean singleBufferMode, jobject weakThiz)
231376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
232e32632682ca9207bd247ca27012cf670b5c23f54Mathias Agopian    sp<BufferQueue> bq = new BufferQueue();
233e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian
234e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    if (singleBufferMode) {
235e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian        bq->disableAsyncBuffer();
236e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian        bq->setDefaultMaxBufferCount(1);
237e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    }
238e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian
239e32632682ca9207bd247ca27012cf670b5c23f54Mathias Agopian    sp<GLConsumer> surfaceTexture(new GLConsumer(bq, texName, GL_TEXTURE_EXTERNAL_OES, true, true));
2406714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (surfaceTexture == 0) {
241376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jniThrowException(env, OutOfResourcesException,
242376590d668e22a918439877b55faf075427b13f3Jamie Gennis                "Unable to create native SurfaceTexture");
243376590d668e22a918439877b55faf075427b13f3Jamie Gennis        return;
244376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
245376590d668e22a918439877b55faf075427b13f3Jamie Gennis    SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
24652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    SurfaceTexture_setBufferQueue(env, thiz, bq);
247376590d668e22a918439877b55faf075427b13f3Jamie Gennis
248376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jclass clazz = env->GetObjectClass(thiz);
249376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (clazz == NULL) {
250376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jniThrowRuntimeException(env,
251376590d668e22a918439877b55faf075427b13f3Jamie Gennis                "Can't find android/graphics/SurfaceTexture");
2526714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis        return;
2536714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
254376590d668e22a918439877b55faf075427b13f3Jamie Gennis
255376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz,
256376590d668e22a918439877b55faf075427b13f3Jamie Gennis            clazz));
257376590d668e22a918439877b55faf075427b13f3Jamie Gennis    surfaceTexture->setFrameAvailableListener(ctx);
258c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    SurfaceTexture_setFrameAvailableListener(env, thiz, ctx);
259376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
260376590d668e22a918439877b55faf075427b13f3Jamie Gennis
261376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_finalize(JNIEnv* env, jobject thiz)
262376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
263d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
264376590d668e22a918439877b55faf075427b13f3Jamie Gennis    surfaceTexture->setFrameAvailableListener(0);
265c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    SurfaceTexture_setFrameAvailableListener(env, thiz, 0);
266376590d668e22a918439877b55faf075427b13f3Jamie Gennis    SurfaceTexture_setSurfaceTexture(env, thiz, 0);
26752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    SurfaceTexture_setBufferQueue(env, thiz, 0);
2686714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
2696714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
270050316184b01c0d1a01c46afae7429b89a27c31btedbostatic void SurfaceTexture_setDefaultBufferSize(
27152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian        JNIEnv* env, jobject thiz, jint width, jint height) {
272d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
273050316184b01c0d1a01c46afae7429b89a27c31btedbo    surfaceTexture->setDefaultBufferSize(width, height);
274050316184b01c0d1a01c46afae7429b89a27c31btedbo}
275050316184b01c0d1a01c46afae7429b89a27c31btedbo
2762b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennisstatic void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz)
2776714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
278d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
2792b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    status_t err = surfaceTexture->updateTexImage();
2802b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    if (err == INVALID_OPERATION) {
2812b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis        jniThrowException(env, IllegalStateException, "Unable to update texture contents (see "
2822b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis                "logcat for details)");
283721bfaa63d14f0ac858d32431ab2eff582143b0fJamie Gennis    } else if (err < 0) {
2842b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis        jniThrowRuntimeException(env, "Error during updateTexImage (see logcat for details)");
2852b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    }
2866714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
2876714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
288e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopianstatic void SurfaceTexture_releaseTexImage(JNIEnv* env, jobject thiz)
289e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian{
290e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
291e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    status_t err = surfaceTexture->releaseTexImage();
292e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    if (err == INVALID_OPERATION) {
293e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian        jniThrowException(env, IllegalStateException, "Unable to release texture contents (see "
294e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian                "logcat for details)");
295e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    } else if (err < 0) {
296e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian        jniThrowRuntimeException(env, "Error during updateTexImage (see logcat for details)");
297e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    }
298e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian}
299e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian
300c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennisstatic jint SurfaceTexture_detachFromGLContext(JNIEnv* env, jobject thiz)
301c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis{
302d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
303c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    return surfaceTexture->detachFromContext();
304c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis}
305c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis
306c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennisstatic jint SurfaceTexture_attachToGLContext(JNIEnv* env, jobject thiz, jint tex)
307c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis{
308d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
309c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    return surfaceTexture->attachToContext((GLuint)tex);
310c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis}
311c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis
312376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
313b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis        jfloatArray jmtx)
314b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis{
315d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
316b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    float* mtx = env->GetFloatArrayElements(jmtx, NULL);
317b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    surfaceTexture->getTransformMatrix(mtx);
318b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    env->ReleaseFloatArrayElements(jmtx, mtx, 0);
319b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis}
320b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis
321c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvalastatic jlong SurfaceTexture_getTimestamp(JNIEnv* env, jobject thiz)
322c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala{
323d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
324c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    return surfaceTexture->getTimestamp();
325c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala}
326c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala
327ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopianstatic void SurfaceTexture_release(JNIEnv* env, jobject thiz)
328ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian{
329d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
330ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian    surfaceTexture->abandon();
331ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian}
332ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian
3336714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
3346714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
3356714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisstatic JNINativeMethod gSurfaceTextureMethods[] = {
336c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeClassInit",            "()V",   (void*)SurfaceTexture_classInit },
337e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    {"nativeInit",                 "(IZLjava/lang/Object;)V", (void*)SurfaceTexture_init },
338c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeFinalize",             "()V",   (void*)SurfaceTexture_finalize },
339050316184b01c0d1a01c46afae7429b89a27c31btedbo    {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
3402b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    {"nativeUpdateTexImage",       "()V",   (void*)SurfaceTexture_updateTexImage },
341e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    {"nativeReleaseTexImage",      "()V",   (void*)SurfaceTexture_releaseTexImage },
342c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeDetachFromGLContext",  "()I",   (void*)SurfaceTexture_detachFromGLContext },
343c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeAttachToGLContext",    "(I)I",   (void*)SurfaceTexture_attachToGLContext },
344c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeGetTransformMatrix",   "([F)V", (void*)SurfaceTexture_getTransformMatrix },
345c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeGetTimestamp",         "()J",   (void*)SurfaceTexture_getTimestamp },
346c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeRelease",              "()V",   (void*)SurfaceTexture_release },
3476714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis};
3486714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
3496714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisint register_android_graphics_SurfaceTexture(JNIEnv* env)
3506714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
3516714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    int err = 0;
3526714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    err = AndroidRuntime::registerNativeMethods(env, kSurfaceTextureClassPathName,
3536714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis            gSurfaceTextureMethods, NELEM(gSurfaceTextureMethods));
3546714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    return err;
3556714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
3566714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
3576714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis} // namespace android
358