SurfaceTexture.cpp revision 846db33313aa0899fa7928256c6734964bd92520
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#include <gui/SurfaceTextureClient.h> 23 24#include <android_runtime/AndroidRuntime.h> 25 26#include <utils/Log.h> 27#include <utils/misc.h> 28 29#include "jni.h" 30#include "JNIHelp.h" 31 32// ---------------------------------------------------------------------------- 33 34namespace android { 35 36static const char* const OutOfResourcesException = 37 "android/graphics/SurfaceTexture$OutOfResourcesException"; 38 39struct fields_t { 40 jfieldID surfaceTexture; 41 jmethodID postEvent; 42}; 43static fields_t fields; 44 45// ---------------------------------------------------------------------------- 46 47static void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz, 48 const sp<SurfaceTexture>& surfaceTexture) 49{ 50 SurfaceTexture* const p = 51 (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture); 52 if (surfaceTexture.get()) { 53 surfaceTexture->incStrong(thiz); 54 } 55 if (p) { 56 p->decStrong(thiz); 57 } 58 env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get()); 59} 60 61sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) 62{ 63 sp<SurfaceTexture> surfaceTexture( 64 (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture)); 65 return surfaceTexture; 66} 67 68sp<ANativeWindow> android_SurfaceTexture_getNativeWindow( 69 JNIEnv* env, jobject thiz) 70{ 71 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); 72 sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ? 73 new SurfaceTextureClient(surfaceTexture) : NULL); 74 return surfaceTextureClient; 75} 76 77// ---------------------------------------------------------------------------- 78 79class JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener 80{ 81public: 82 JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz); 83 virtual ~JNISurfaceTextureContext(); 84 virtual void onFrameAvailable(); 85 86private: 87 jobject mWeakThiz; 88 jclass mClazz; 89}; 90 91JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env, 92 jobject weakThiz, jclass clazz) : 93 mWeakThiz(env->NewGlobalRef(weakThiz)), 94 mClazz((jclass)env->NewGlobalRef(clazz)) 95{} 96 97JNISurfaceTextureContext::~JNISurfaceTextureContext() 98{ 99 JNIEnv *env = AndroidRuntime::getJNIEnv(); 100 env->DeleteGlobalRef(mWeakThiz); 101 env->DeleteGlobalRef(mClazz); 102} 103 104void JNISurfaceTextureContext::onFrameAvailable() 105{ 106 JNIEnv *env = AndroidRuntime::getJNIEnv(); 107 env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); 108} 109 110// ---------------------------------------------------------------------------- 111 112static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz) 113{ 114 fields.surfaceTexture = env->GetFieldID(clazz, 115 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I"); 116 if (fields.surfaceTexture == NULL) { 117 LOGE("can't find android/graphics/SurfaceTexture.%s", 118 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID); 119 } 120 121 fields.postEvent = env->GetStaticMethodID(clazz, "postEventFromNative", 122 "(Ljava/lang/Object;)V"); 123 if (fields.postEvent == NULL) { 124 LOGE("can't find android/graphics/SurfaceTexture.postEventFromNative"); 125 } 126 127} 128 129static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jint texName, 130 jobject weakThiz) 131{ 132 sp<SurfaceTexture> surfaceTexture(new SurfaceTexture(texName)); 133 if (surfaceTexture == 0) { 134 jniThrowException(env, OutOfResourcesException, 135 "Unable to create native SurfaceTexture"); 136 return; 137 } 138 SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture); 139 140 jclass clazz = env->GetObjectClass(thiz); 141 if (clazz == NULL) { 142 jniThrowRuntimeException(env, 143 "Can't find android/graphics/SurfaceTexture"); 144 return; 145 } 146 147 sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz, 148 clazz)); 149 surfaceTexture->setFrameAvailableListener(ctx); 150} 151 152static void SurfaceTexture_finalize(JNIEnv* env, jobject thiz) 153{ 154 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); 155 surfaceTexture->setFrameAvailableListener(0); 156 SurfaceTexture_setSurfaceTexture(env, thiz, 0); 157} 158 159static void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz) 160{ 161 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); 162 surfaceTexture->updateTexImage(); 163} 164 165static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz, 166 jfloatArray jmtx) 167{ 168 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); 169 float* mtx = env->GetFloatArrayElements(jmtx, NULL); 170 surfaceTexture->getTransformMatrix(mtx); 171 env->ReleaseFloatArrayElements(jmtx, mtx, 0); 172} 173 174// ---------------------------------------------------------------------------- 175 176const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture"; 177 178static JNINativeMethod gSurfaceTextureMethods[] = { 179 {"nativeClassInit", "()V", (void*)SurfaceTexture_classInit }, 180 {"nativeInit", "(ILjava/lang/Object;)V", (void*)SurfaceTexture_init }, 181 {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize }, 182 {"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage }, 183 {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix }, 184}; 185 186int register_android_graphics_SurfaceTexture(JNIEnv* env) 187{ 188 int err = 0; 189 err = AndroidRuntime::registerNativeMethods(env, kSurfaceTextureClassPathName, 190 gSurfaceTextureMethods, NELEM(gSurfaceTextureMethods)); 191 return err; 192} 193 194} // namespace android 195