blob: c4e5878c269411318459f1a9e00c5aa7d719635c [file] [log] [blame]
Jamie Gennis6714efc2010-12-20 12:09:37 -08001/*
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>
Glenn Kasten846db332011-03-04 11:44:32 -080022#include <gui/SurfaceTextureClient.h>
Jamie Gennis6714efc2010-12-20 12:09:37 -080023
24#include <android_runtime/AndroidRuntime.h>
25
26#include <utils/Log.h>
27#include <utils/misc.h>
28
Jamie Gennis6714efc2010-12-20 12:09:37 -080029#include "jni.h"
Jamie Gennis376590d2011-01-13 14:43:36 -080030#include "JNIHelp.h"
Jamie Gennis6714efc2010-12-20 12:09:37 -080031
32// ----------------------------------------------------------------------------
33
34namespace android {
35
36static const char* const OutOfResourcesException =
37 "android/graphics/SurfaceTexture$OutOfResourcesException";
38
Jamie Gennis376590d2011-01-13 14:43:36 -080039struct fields_t {
40 jfieldID surfaceTexture;
41 jmethodID postEvent;
Jamie Gennis6714efc2010-12-20 12:09:37 -080042};
Jamie Gennis376590d2011-01-13 14:43:36 -080043static fields_t fields;
Jamie Gennis6714efc2010-12-20 12:09:37 -080044
45// ----------------------------------------------------------------------------
46
Jamie Gennis376590d2011-01-13 14:43:36 -080047static void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz,
Jamie Gennis6714efc2010-12-20 12:09:37 -080048 const sp<SurfaceTexture>& surfaceTexture)
49{
50 SurfaceTexture* const p =
Jamie Gennis376590d2011-01-13 14:43:36 -080051 (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture);
Jamie Gennis6714efc2010-12-20 12:09:37 -080052 if (surfaceTexture.get()) {
Jamie Gennis376590d2011-01-13 14:43:36 -080053 surfaceTexture->incStrong(thiz);
Jamie Gennis6714efc2010-12-20 12:09:37 -080054 }
55 if (p) {
Jamie Gennis376590d2011-01-13 14:43:36 -080056 p->decStrong(thiz);
Jamie Gennis6714efc2010-12-20 12:09:37 -080057 }
Jamie Gennis376590d2011-01-13 14:43:36 -080058 env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get());
Jamie Gennis6714efc2010-12-20 12:09:37 -080059}
60
Jamie Gennis376590d2011-01-13 14:43:36 -080061sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz)
Jamie Gennis6714efc2010-12-20 12:09:37 -080062{
63 sp<SurfaceTexture> surfaceTexture(
Jamie Gennis376590d2011-01-13 14:43:36 -080064 (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture));
Jamie Gennis6714efc2010-12-20 12:09:37 -080065 return surfaceTexture;
66}
67
Glenn Kasten846db332011-03-04 11:44:32 -080068sp<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
Jamie Gennis6714efc2010-12-20 12:09:37 -080077// ----------------------------------------------------------------------------
78
Jamie Gennis376590d2011-01-13 14:43:36 -080079class JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener
Jamie Gennis6714efc2010-12-20 12:09:37 -080080{
Jamie Gennis376590d2011-01-13 14:43:36 -080081public:
82 JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz);
83 virtual ~JNISurfaceTextureContext();
84 virtual void onFrameAvailable();
Jamie Gennis6714efc2010-12-20 12:09:37 -080085
Jamie Gennis376590d2011-01-13 14:43:36 -080086private:
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);
Jamie Gennis6714efc2010-12-20 12:09:37 -0800102}
103
Jamie Gennis376590d2011-01-13 14:43:36 -0800104void JNISurfaceTextureContext::onFrameAvailable()
Jamie Gennis6714efc2010-12-20 12:09:37 -0800105{
Jamie Gennis376590d2011-01-13 14:43:36 -0800106 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));
Jamie Gennis6714efc2010-12-20 12:09:37 -0800162 surfaceTexture->updateTexImage();
163}
164
Jamie Gennis376590d2011-01-13 14:43:36 -0800165static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
Jamie Gennisb0ba48c2011-01-09 18:22:05 -0800166 jfloatArray jmtx)
167{
Jamie Gennis376590d2011-01-13 14:43:36 -0800168 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Jamie Gennisb0ba48c2011-01-09 18:22:05 -0800169 float* mtx = env->GetFloatArrayElements(jmtx, NULL);
170 surfaceTexture->getTransformMatrix(mtx);
171 env->ReleaseFloatArrayElements(jmtx, mtx, 0);
172}
173
Jamie Gennis6714efc2010-12-20 12:09:37 -0800174// ----------------------------------------------------------------------------
175
176const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
Jamie Gennis6714efc2010-12-20 12:09:37 -0800177
178static JNINativeMethod gSurfaceTextureMethods[] = {
Jamie Gennis376590d2011-01-13 14:43:36 -0800179 {"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 },
Jamie Gennis6714efc2010-12-20 12:09:37 -0800184};
185
Jamie Gennis6714efc2010-12-20 12:09:37 -0800186int 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