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