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
214bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner#include <EGL/egl.h>
224bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner#include <EGL/eglext.h>
23e3eae73abb5e429d9747f9c36ab025219e68bb26Mathias Agopian#include <GLES2/gl2.h>
24e3eae73abb5e429d9747f9c36ab025219e68bb26Mathias Agopian#include <GLES2/gl2ext.h>
25e3eae73abb5e429d9747f9c36ab025219e68bb26Mathias Agopian
26d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden#include <gui/GLConsumer.h>
2752800617946c456e78ed010c82d0ec4358368164Mathias Agopian#include <gui/Surface.h>
28f1cb02e7b53e22655f0e14041b0abf73f51a11b0Mathias Agopian#include <gui/BufferQueue.h>
296714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
30ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
316714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
32df7707cb4f34138b423dde493fccfa4e7fb50c20Mathias Agopian#include <cutils/atomic.h>
336714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <utils/Log.h>
346714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <utils/misc.h>
356714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
366714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include "jni.h"
37376590d668e22a918439877b55faf075427b13f3Jamie Gennis#include "JNIHelp.h"
38a7993241a96ff8832bac5fbc052d8a9ac6e72877Andreas Gampe#include "ScopedLocalRef.h"
396714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
406714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
416714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
42afe9a4c67c2e2988c76232796f017a992a6f2a28Craig Donner#define EGL_PROTECTED_CONTENT_EXT 0x32C0
434bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner
446714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisnamespace android {
456714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
466714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisstatic const char* const OutOfResourcesException =
47a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin    "android/view/Surface$OutOfResourcesException";
482b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennisstatic const char* const IllegalStateException = "java/lang/IllegalStateException";
49050316184b01c0d1a01c46afae7429b89a27c31btedboconst char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
506714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
51376590d668e22a918439877b55faf075427b13f3Jamie Gennisstruct fields_t {
52376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jfieldID  surfaceTexture;
530dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    jfieldID  producer;
54c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    jfieldID  frameAvailableListener;
55376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jmethodID postEvent;
566714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis};
57376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic fields_t fields;
586714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
59ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala// Get an ID that's unique within this process.
60ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvalastatic int32_t createProcessUniqueId() {
61ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala    static volatile int32_t globalCounter = 0;
62ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala    return android_atomic_inc(&globalCounter);
63ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala}
64ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala
654bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner// Check whether the current EGL context is protected.
664bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donnerstatic bool isProtectedContext() {
674bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner    EGLDisplay dpy = eglGetCurrentDisplay();
684bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner    EGLContext ctx = eglGetCurrentContext();
694bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner
70afe9a4c67c2e2988c76232796f017a992a6f2a28Craig Donner    if (dpy == EGL_NO_DISPLAY || ctx == EGL_NO_CONTEXT) {
714bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner        return false;
724bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner    }
734bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner
744bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner    EGLint isProtected = EGL_FALSE;
75afe9a4c67c2e2988c76232796f017a992a6f2a28Craig Donner    eglQueryContext(dpy, ctx, EGL_PROTECTED_CONTENT_EXT, &isProtected);
764bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner
774bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner    return isProtected;
784bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner}
794bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner
806714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
816714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
82376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz,
83d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden        const sp<GLConsumer>& surfaceTexture)
846714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
85d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    GLConsumer* const p =
8672aa313ff4c91e7b2aae3d37067f9201b2b0fdbeAshok Bhat        (GLConsumer*)env->GetLongField(thiz, fields.surfaceTexture);
876714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (surfaceTexture.get()) {
88b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian        surfaceTexture->incStrong((void*)SurfaceTexture_setSurfaceTexture);
896714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
906714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (p) {
91b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian        p->decStrong((void*)SurfaceTexture_setSurfaceTexture);
926714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
9372aa313ff4c91e7b2aae3d37067f9201b2b0fdbeAshok Bhat    env->SetLongField(thiz, fields.surfaceTexture, (jlong)surfaceTexture.get());
946714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
956714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
960dc146be5a6cd0c33910d5b18885df46873a93cbDan Stozastatic void SurfaceTexture_setProducer(JNIEnv* env, jobject thiz,
970dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza        const sp<IGraphicBufferProducer>& producer)
9852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian{
990dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    IGraphicBufferProducer* const p =
1000dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza        (IGraphicBufferProducer*)env->GetLongField(thiz, fields.producer);
1010dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    if (producer.get()) {
1020dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza        producer->incStrong((void*)SurfaceTexture_setProducer);
10352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    }
10452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    if (p) {
1050dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza        p->decStrong((void*)SurfaceTexture_setProducer);
10652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    }
1070dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    env->SetLongField(thiz, fields.producer, (jlong)producer.get());
10852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian}
10952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian
110c99db2bc460cc795947d99076da380e22a21e493Igor Murashkinstatic void SurfaceTexture_setFrameAvailableListener(JNIEnv* env,
111d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden        jobject thiz, sp<GLConsumer::FrameAvailableListener> listener)
1126714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
113d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    GLConsumer::FrameAvailableListener* const p =
114d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden        (GLConsumer::FrameAvailableListener*)
11572aa313ff4c91e7b2aae3d37067f9201b2b0fdbeAshok Bhat            env->GetLongField(thiz, fields.frameAvailableListener);
116c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    if (listener.get()) {
117b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian        listener->incStrong((void*)SurfaceTexture_setSurfaceTexture);
118c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    }
119c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    if (p) {
120b1d90c8f60f71422196c337f1d078b68867f5710Mathias Agopian        p->decStrong((void*)SurfaceTexture_setSurfaceTexture);
121c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    }
12272aa313ff4c91e7b2aae3d37067f9201b2b0fdbeAshok Bhat    env->SetLongField(thiz, fields.frameAvailableListener, (jlong)listener.get());
123c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin}
124c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin
12552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopiansp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) {
12672aa313ff4c91e7b2aae3d37067f9201b2b0fdbeAshok Bhat    return (GLConsumer*)env->GetLongField(thiz, fields.surfaceTexture);
1276714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
1286714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
12952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopiansp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz) {
1300dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    return (IGraphicBufferProducer*)env->GetLongField(thiz, fields.producer);
13152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian}
13252a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian
13352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopiansp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz) {
134d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
13552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, thiz));
13652a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    sp<Surface> surfaceTextureClient(surfaceTexture != NULL ? new Surface(producer) : NULL);
137846db33313aa0899fa7928256c6734964bd92520Glenn Kasten    return surfaceTextureClient;
138846db33313aa0899fa7928256c6734964bd92520Glenn Kasten}
139846db33313aa0899fa7928256c6734964bd92520Glenn Kasten
14052a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopianbool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) {
141050316184b01c0d1a01c46afae7429b89a27c31btedbo    jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
142050316184b01c0d1a01c46afae7429b89a27c31btedbo    return env->IsInstanceOf(thiz, surfaceTextureClass);
143050316184b01c0d1a01c46afae7429b89a27c31btedbo}
144050316184b01c0d1a01c46afae7429b89a27c31btedbo
1456714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
1466714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
147d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFaddenclass JNISurfaceTextureContext : public GLConsumer::FrameAvailableListener
1486714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
149376590d668e22a918439877b55faf075427b13f3Jamie Gennispublic:
150376590d668e22a918439877b55faf075427b13f3Jamie Gennis    JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz);
151376590d668e22a918439877b55faf075427b13f3Jamie Gennis    virtual ~JNISurfaceTextureContext();
1522c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stoza    virtual void onFrameAvailable(const BufferItem& item);
153376590d668e22a918439877b55faf075427b13f3Jamie Gennis
154376590d668e22a918439877b55faf075427b13f3Jamie Gennisprivate:
1550a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    static JNIEnv* getJNIEnv(bool* needsDetach);
1560a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    static void detachJNI();
15784293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis
158376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jobject mWeakThiz;
159376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jclass mClazz;
160376590d668e22a918439877b55faf075427b13f3Jamie Gennis};
161376590d668e22a918439877b55faf075427b13f3Jamie Gennis
162376590d668e22a918439877b55faf075427b13f3Jamie GennisJNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env,
163376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jobject weakThiz, jclass clazz) :
164376590d668e22a918439877b55faf075427b13f3Jamie Gennis    mWeakThiz(env->NewGlobalRef(weakThiz)),
165376590d668e22a918439877b55faf075427b13f3Jamie Gennis    mClazz((jclass)env->NewGlobalRef(clazz))
166376590d668e22a918439877b55faf075427b13f3Jamie Gennis{}
167376590d668e22a918439877b55faf075427b13f3Jamie Gennis
1680a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie GennisJNIEnv* JNISurfaceTextureContext::getJNIEnv(bool* needsDetach) {
1690a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    *needsDetach = false;
1700a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    JNIEnv* env = AndroidRuntime::getJNIEnv();
1710a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    if (env == NULL) {
1729b311c900dcc3666febf52c1bed8eae7ce1f2815Andy McFadden        JavaVMAttachArgs args = {
1739b311c900dcc3666febf52c1bed8eae7ce1f2815Andy McFadden            JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL };
1740a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        JavaVM* vm = AndroidRuntime::getJavaVM();
1750a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        int result = vm->AttachCurrentThread(&env, (void*) &args);
1760a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        if (result != JNI_OK) {
1773762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("thread attach failed: %#x", result);
1780a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis            return NULL;
1790a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        }
1800a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        *needsDetach = true;
1810a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    }
1820a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    return env;
1830a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis}
1840a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis
1850a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennisvoid JNISurfaceTextureContext::detachJNI() {
18684293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    JavaVM* vm = AndroidRuntime::getJavaVM();
1870a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    int result = vm->DetachCurrentThread();
18884293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    if (result != JNI_OK) {
1893762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("thread detach failed: %#x", result);
19084293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    }
19184293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis}
19284293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis
193376590d668e22a918439877b55faf075427b13f3Jamie GennisJNISurfaceTextureContext::~JNISurfaceTextureContext()
194376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
1950a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    bool needsDetach = false;
1960a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    JNIEnv* env = getJNIEnv(&needsDetach);
19784293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    if (env != NULL) {
19884293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis        env->DeleteGlobalRef(mWeakThiz);
19984293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis        env->DeleteGlobalRef(mClazz);
20084293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    } else {
2018564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("leaking JNI object references");
20284293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    }
2030a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    if (needsDetach) {
2040a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        detachJNI();
2050a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    }
206376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
207376590d668e22a918439877b55faf075427b13f3Jamie Gennis
2082c34b5e8136eac0332dac294cb06a6a98eac1c14Dan Stozavoid JNISurfaceTextureContext::onFrameAvailable(const BufferItem& /* item */)
209376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
2100a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    bool needsDetach = false;
2110a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    JNIEnv* env = getJNIEnv(&needsDetach);
21284293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    if (env != NULL) {
21384293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis        env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz);
21484293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    } else {
2158564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("onFrameAvailable event will not posted");
21684293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    }
2170a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    if (needsDetach) {
2180a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        detachJNI();
2190a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    }
220376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
221376590d668e22a918439877b55faf075427b13f3Jamie Gennis
222376590d668e22a918439877b55faf075427b13f3Jamie Gennis// ----------------------------------------------------------------------------
223376590d668e22a918439877b55faf075427b13f3Jamie Gennis
22452a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian
22552a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
2260dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza#define ANDROID_GRAPHICS_PRODUCER_JNI_ID "mProducer"
22752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
22852a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian                                         "mFrameAvailableListener"
22952a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian
230376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
231376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
232376590d668e22a918439877b55faf075427b13f3Jamie Gennis    fields.surfaceTexture = env->GetFieldID(clazz,
23372aa313ff4c91e7b2aae3d37067f9201b2b0fdbeAshok Bhat            ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "J");
234376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (fields.surfaceTexture == NULL) {
2353762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("can't find android/graphics/SurfaceTexture.%s",
236376590d668e22a918439877b55faf075427b13f3Jamie Gennis                ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
237376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
2380dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    fields.producer = env->GetFieldID(clazz,
2390dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza            ANDROID_GRAPHICS_PRODUCER_JNI_ID, "J");
2400dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    if (fields.producer == NULL) {
24152a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian        ALOGE("can't find android/graphics/SurfaceTexture.%s",
2420dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza                ANDROID_GRAPHICS_PRODUCER_JNI_ID);
24352a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian    }
244c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    fields.frameAvailableListener = env->GetFieldID(clazz,
24572aa313ff4c91e7b2aae3d37067f9201b2b0fdbeAshok Bhat            ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID, "J");
246c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    if (fields.frameAvailableListener == NULL) {
247c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin        ALOGE("can't find android/graphics/SurfaceTexture.%s",
248c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin                ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID);
249c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    }
250376590d668e22a918439877b55faf075427b13f3Jamie Gennis
251376590d668e22a918439877b55faf075427b13f3Jamie Gennis    fields.postEvent = env->GetStaticMethodID(clazz, "postEventFromNative",
252c7282e57cd01f1576baac04356bf99bee34e4c18Jeff Brown            "(Ljava/lang/ref/WeakReference;)V");
253376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (fields.postEvent == NULL) {
2543762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("can't find android/graphics/SurfaceTexture.postEventFromNative");
255376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
256376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
2576714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
258493f2e11909e2d5839ca81ddc66d48d538192478Dan Stozastatic void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached,
259e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian        jint texName, jboolean singleBufferMode, jobject weakThiz)
260376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
2610dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    sp<IGraphicBufferProducer> producer;
2620dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    sp<IGraphicBufferConsumer> consumer;
2630dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
264e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian
265e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    if (singleBufferMode) {
266e442b63c837c8852546f9fa7ba28985e8eea7290Pablo Ceballos        consumer->setMaxBufferCount(1);
267e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    }
268e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian
269493f2e11909e2d5839ca81ddc66d48d538192478Dan Stoza    sp<GLConsumer> surfaceTexture;
270493f2e11909e2d5839ca81ddc66d48d538192478Dan Stoza    if (isDetached) {
271493f2e11909e2d5839ca81ddc66d48d538192478Dan Stoza        surfaceTexture = new GLConsumer(consumer, GL_TEXTURE_EXTERNAL_OES,
272e442b63c837c8852546f9fa7ba28985e8eea7290Pablo Ceballos                true, !singleBufferMode);
273493f2e11909e2d5839ca81ddc66d48d538192478Dan Stoza    } else {
274493f2e11909e2d5839ca81ddc66d48d538192478Dan Stoza        surfaceTexture = new GLConsumer(consumer, texName,
275e442b63c837c8852546f9fa7ba28985e8eea7290Pablo Ceballos                GL_TEXTURE_EXTERNAL_OES, true, !singleBufferMode);
276493f2e11909e2d5839ca81ddc66d48d538192478Dan Stoza    }
277493f2e11909e2d5839ca81ddc66d48d538192478Dan Stoza
2786714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (surfaceTexture == 0) {
279376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jniThrowException(env, OutOfResourcesException,
280376590d668e22a918439877b55faf075427b13f3Jamie Gennis                "Unable to create native SurfaceTexture");
281376590d668e22a918439877b55faf075427b13f3Jamie Gennis        return;
282376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
283ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala    surfaceTexture->setName(String8::format("SurfaceTexture-%d-%d-%d",
284ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala            (isDetached ? 0 : texName),
285ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala            getpid(),
286ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala            createProcessUniqueId()));
287ef9db7d81b0ce1093944b9e3d5efb6ab756f5cbcEino-Ville Talvala
2884bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner    // If the current context is protected, inform the producer.
289a3e1d7b43eeee44ab80571bd4a0c2425b443d578Jiwen 'Steve' Cai    consumer->setConsumerIsProtected(isProtectedContext());
2904bbb8504a755fd273cd8e6be3d6e2fbc7ccbc2a4Craig Donner
291376590d668e22a918439877b55faf075427b13f3Jamie Gennis    SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
2920dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    SurfaceTexture_setProducer(env, thiz, producer);
293376590d668e22a918439877b55faf075427b13f3Jamie Gennis
294376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jclass clazz = env->GetObjectClass(thiz);
295376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (clazz == NULL) {
296376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jniThrowRuntimeException(env,
297376590d668e22a918439877b55faf075427b13f3Jamie Gennis                "Can't find android/graphics/SurfaceTexture");
2986714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis        return;
2996714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
300376590d668e22a918439877b55faf075427b13f3Jamie Gennis
301376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz,
302376590d668e22a918439877b55faf075427b13f3Jamie Gennis            clazz));
303376590d668e22a918439877b55faf075427b13f3Jamie Gennis    surfaceTexture->setFrameAvailableListener(ctx);
304c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    SurfaceTexture_setFrameAvailableListener(env, thiz, ctx);
305376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
306376590d668e22a918439877b55faf075427b13f3Jamie Gennis
307376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_finalize(JNIEnv* env, jobject thiz)
308376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
309d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
310376590d668e22a918439877b55faf075427b13f3Jamie Gennis    surfaceTexture->setFrameAvailableListener(0);
311c99db2bc460cc795947d99076da380e22a21e493Igor Murashkin    SurfaceTexture_setFrameAvailableListener(env, thiz, 0);
312376590d668e22a918439877b55faf075427b13f3Jamie Gennis    SurfaceTexture_setSurfaceTexture(env, thiz, 0);
3130dc146be5a6cd0c33910d5b18885df46873a93cbDan Stoza    SurfaceTexture_setProducer(env, thiz, 0);
3146714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
3156714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
316050316184b01c0d1a01c46afae7429b89a27c31btedbostatic void SurfaceTexture_setDefaultBufferSize(
31752a9a10b6b8c7b7a9f97777541841b94d4fd9754Mathias Agopian        JNIEnv* env, jobject thiz, jint width, jint height) {
318d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
319050316184b01c0d1a01c46afae7429b89a27c31btedbo    surfaceTexture->setDefaultBufferSize(width, height);
320050316184b01c0d1a01c46afae7429b89a27c31btedbo}
321050316184b01c0d1a01c46afae7429b89a27c31btedbo
3222b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennisstatic void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz)
3236714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
324d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
3252b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    status_t err = surfaceTexture->updateTexImage();
3262b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    if (err == INVALID_OPERATION) {
3272b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis        jniThrowException(env, IllegalStateException, "Unable to update texture contents (see "
3282b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis                "logcat for details)");
329721bfaa63d14f0ac858d32431ab2eff582143b0fJamie Gennis    } else if (err < 0) {
3302b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis        jniThrowRuntimeException(env, "Error during updateTexImage (see logcat for details)");
3312b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    }
3326714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
3336714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
334e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopianstatic void SurfaceTexture_releaseTexImage(JNIEnv* env, jobject thiz)
335e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian{
336e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
337e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    status_t err = surfaceTexture->releaseTexImage();
338e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    if (err == INVALID_OPERATION) {
339e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian        jniThrowException(env, IllegalStateException, "Unable to release texture contents (see "
340e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian                "logcat for details)");
341e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    } else if (err < 0) {
342e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian        jniThrowRuntimeException(env, "Error during updateTexImage (see logcat for details)");
343e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    }
344e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian}
345e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian
346c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennisstatic jint SurfaceTexture_detachFromGLContext(JNIEnv* env, jobject thiz)
347c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis{
348d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
349c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    return surfaceTexture->detachFromContext();
350c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis}
351c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis
352c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennisstatic jint SurfaceTexture_attachToGLContext(JNIEnv* env, jobject thiz, jint tex)
353c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis{
354d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
355c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    return surfaceTexture->attachToContext((GLuint)tex);
356c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis}
357c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis
358376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
359b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis        jfloatArray jmtx)
360b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis{
361d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
362b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    float* mtx = env->GetFloatArrayElements(jmtx, NULL);
363b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    surfaceTexture->getTransformMatrix(mtx);
364b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    env->ReleaseFloatArrayElements(jmtx, mtx, 0);
365b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis}
366b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis
367c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvalastatic jlong SurfaceTexture_getTimestamp(JNIEnv* env, jobject thiz)
368c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala{
369d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
370c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    return surfaceTexture->getTimestamp();
371c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala}
372c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala
373ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopianstatic void SurfaceTexture_release(JNIEnv* env, jobject thiz)
374ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian{
375d47f7d8b5fe3a3861d7cbdc5f912235407823c8eAndy McFadden    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
376ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian    surfaceTexture->abandon();
377ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian}
378ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian
3796d8371e73ff6452be5a23089e7edeb8d6d96f065John Reckstatic jboolean SurfaceTexture_isReleased(JNIEnv* env, jobject thiz)
3806d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck{
3816d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
3826d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck    return surfaceTexture->isAbandoned();
3836d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck}
3846d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck
3856714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
3866714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
38776f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gSurfaceTextureMethods[] = {
388493f2e11909e2d5839ca81ddc66d48d538192478Dan Stoza    {"nativeInit",                 "(ZIZLjava/lang/ref/WeakReference;)V", (void*)SurfaceTexture_init },
389c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeFinalize",             "()V",   (void*)SurfaceTexture_finalize },
390050316184b01c0d1a01c46afae7429b89a27c31btedbo    {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
3912b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    {"nativeUpdateTexImage",       "()V",   (void*)SurfaceTexture_updateTexImage },
392e591b49de038a9942cbcc77540c03e85c96e3dcbMathias Agopian    {"nativeReleaseTexImage",      "()V",   (void*)SurfaceTexture_releaseTexImage },
393c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeDetachFromGLContext",  "()I",   (void*)SurfaceTexture_detachFromGLContext },
394c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeAttachToGLContext",    "(I)I",   (void*)SurfaceTexture_attachToGLContext },
395c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeGetTransformMatrix",   "([F)V", (void*)SurfaceTexture_getTransformMatrix },
396c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeGetTimestamp",         "()J",   (void*)SurfaceTexture_getTimestamp },
397c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeRelease",              "()V",   (void*)SurfaceTexture_release },
3986d8371e73ff6452be5a23089e7edeb8d6d96f065John Reck    {"nativeIsReleased",           "()Z",   (void*)SurfaceTexture_isReleased },
3996714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis};
4006714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
4016714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisint register_android_graphics_SurfaceTexture(JNIEnv* env)
4026714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
403a7993241a96ff8832bac5fbc052d8a9ac6e72877Andreas Gampe    // Cache some fields.
404a7993241a96ff8832bac5fbc052d8a9ac6e72877Andreas Gampe    ScopedLocalRef<jclass> klass(env, FindClassOrDie(env, kSurfaceTextureClassPathName));
405a7993241a96ff8832bac5fbc052d8a9ac6e72877Andreas Gampe    SurfaceTexture_classInit(env, klass.get());
406a7993241a96ff8832bac5fbc052d8a9ac6e72877Andreas Gampe
407ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    return RegisterMethodsOrDie(env, kSurfaceTextureClassPathName, gSurfaceTextureMethods,
408ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe                                NELEM(gSurfaceTextureMethods));
4096714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
4106714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
4116714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis} // namespace android
412