SurfaceTexture.cpp revision 376590d668e22a918439877b55faf075427b13f3
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "SurfaceTexture" 18 19#include <stdio.h> 20 21#include <gui/SurfaceTexture.h> 22 23#include <android_runtime/AndroidRuntime.h> 24 25#include <utils/Log.h> 26#include <utils/misc.h> 27 28#include "jni.h" 29#include "JNIHelp.h" 30 31// ---------------------------------------------------------------------------- 32 33namespace android { 34 35static const char* const OutOfResourcesException = 36 "android/graphics/SurfaceTexture$OutOfResourcesException"; 37 38struct fields_t { 39 jfieldID surfaceTexture; 40 jmethodID postEvent; 41}; 42static fields_t fields; 43 44// ---------------------------------------------------------------------------- 45 46static void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz, 47 const sp<SurfaceTexture>& surfaceTexture) 48{ 49 SurfaceTexture* const p = 50 (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture); 51 if (surfaceTexture.get()) { 52 surfaceTexture->incStrong(thiz); 53 } 54 if (p) { 55 p->decStrong(thiz); 56 } 57 env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get()); 58} 59 60sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) 61{ 62 sp<SurfaceTexture> surfaceTexture( 63 (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture)); 64 return surfaceTexture; 65} 66 67// ---------------------------------------------------------------------------- 68 69class JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener 70{ 71public: 72 JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz); 73 virtual ~JNISurfaceTextureContext(); 74 virtual void onFrameAvailable(); 75 76private: 77 jobject mWeakThiz; 78 jclass mClazz; 79}; 80 81JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env, 82 jobject weakThiz, jclass clazz) : 83 mWeakThiz(env->NewGlobalRef(weakThiz)), 84 mClazz((jclass)env->NewGlobalRef(clazz)) 85{} 86 87JNISurfaceTextureContext::~JNISurfaceTextureContext() 88{ 89 JNIEnv *env = AndroidRuntime::getJNIEnv(); 90 env->DeleteGlobalRef(mWeakThiz); 91 env->DeleteGlobalRef(mClazz); 92} 93 94void JNISurfaceTextureContext::onFrameAvailable() 95{ 96 JNIEnv *env = AndroidRuntime::getJNIEnv(); 97 env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); 98} 99 100// ---------------------------------------------------------------------------- 101 102static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz) 103{ 104 fields.surfaceTexture = env->GetFieldID(clazz, 105 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I"); 106 if (fields.surfaceTexture == NULL) { 107 LOGE("can't find android/graphics/SurfaceTexture.%s", 108 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID); 109 } 110 111 fields.postEvent = env->GetStaticMethodID(clazz, "postEventFromNative", 112 "(Ljava/lang/Object;)V"); 113 if (fields.postEvent == NULL) { 114 LOGE("can't find android/graphics/SurfaceTexture.postEventFromNative"); 115 } 116 117} 118 119static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jint texName, 120 jobject weakThiz) 121{ 122 sp<SurfaceTexture> surfaceTexture(new SurfaceTexture(texName)); 123 if (surfaceTexture == 0) { 124 jniThrowException(env, OutOfResourcesException, 125 "Unable to create native SurfaceTexture"); 126 return; 127 } 128 SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture); 129 130 jclass clazz = env->GetObjectClass(thiz); 131 if (clazz == NULL) { 132 jniThrowRuntimeException(env, 133 "Can't find android/graphics/SurfaceTexture"); 134 return; 135 } 136 137 sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz, 138 clazz)); 139 surfaceTexture->setFrameAvailableListener(ctx); 140} 141 142static void SurfaceTexture_finalize(JNIEnv* env, jobject thiz) 143{ 144 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); 145 surfaceTexture->setFrameAvailableListener(0); 146 SurfaceTexture_setSurfaceTexture(env, thiz, 0); 147} 148 149static void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz) 150{ 151 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); 152 surfaceTexture->updateTexImage(); 153} 154 155static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz, 156 jfloatArray jmtx) 157{ 158 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); 159 float* mtx = env->GetFloatArrayElements(jmtx, NULL); 160 surfaceTexture->getTransformMatrix(mtx); 161 env->ReleaseFloatArrayElements(jmtx, mtx, 0); 162} 163 164// ---------------------------------------------------------------------------- 165 166const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture"; 167 168static JNINativeMethod gSurfaceTextureMethods[] = { 169 {"nativeClassInit", "()V", (void*)SurfaceTexture_classInit }, 170 {"nativeInit", "(ILjava/lang/Object;)V", (void*)SurfaceTexture_init }, 171 {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize }, 172 {"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage }, 173 {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix }, 174}; 175 176int register_android_graphics_SurfaceTexture(JNIEnv* env) 177{ 178 int err = 0; 179 err = AndroidRuntime::registerNativeMethods(env, kSurfaceTextureClassPathName, 180 gSurfaceTextureMethods, NELEM(gSurfaceTextureMethods)); 181 return err; 182} 183 184} // namespace android 185