blob: a8cb6f753565e8286d3115fcb327df2230bad382 [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";
tedbo05031612011-06-06 16:02:47 -070038const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
Jamie Gennis6714efc2010-12-20 12:09:37 -080039
Jamie Gennis376590d2011-01-13 14:43:36 -080040struct fields_t {
41 jfieldID surfaceTexture;
42 jmethodID postEvent;
Jamie Gennis6714efc2010-12-20 12:09:37 -080043};
Jamie Gennis376590d2011-01-13 14:43:36 -080044static fields_t fields;
Jamie Gennis6714efc2010-12-20 12:09:37 -080045
46// ----------------------------------------------------------------------------
47
Jamie Gennis376590d2011-01-13 14:43:36 -080048static void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz,
Jamie Gennis6714efc2010-12-20 12:09:37 -080049 const sp<SurfaceTexture>& surfaceTexture)
50{
51 SurfaceTexture* const p =
Jamie Gennis376590d2011-01-13 14:43:36 -080052 (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture);
Jamie Gennis6714efc2010-12-20 12:09:37 -080053 if (surfaceTexture.get()) {
Jamie Gennis376590d2011-01-13 14:43:36 -080054 surfaceTexture->incStrong(thiz);
Jamie Gennis6714efc2010-12-20 12:09:37 -080055 }
56 if (p) {
Jamie Gennis376590d2011-01-13 14:43:36 -080057 p->decStrong(thiz);
Jamie Gennis6714efc2010-12-20 12:09:37 -080058 }
Jamie Gennis376590d2011-01-13 14:43:36 -080059 env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get());
Jamie Gennis6714efc2010-12-20 12:09:37 -080060}
61
Jamie Gennis376590d2011-01-13 14:43:36 -080062sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz)
Jamie Gennis6714efc2010-12-20 12:09:37 -080063{
64 sp<SurfaceTexture> surfaceTexture(
Jamie Gennis376590d2011-01-13 14:43:36 -080065 (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture));
Jamie Gennis6714efc2010-12-20 12:09:37 -080066 return surfaceTexture;
67}
68
Glenn Kasten846db332011-03-04 11:44:32 -080069sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(
70 JNIEnv* env, jobject thiz)
71{
72 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
73 sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
74 new SurfaceTextureClient(surfaceTexture) : NULL);
75 return surfaceTextureClient;
76}
77
tedbo05031612011-06-06 16:02:47 -070078bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz)
79{
80 jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
81 return env->IsInstanceOf(thiz, surfaceTextureClass);
82}
83
Jamie Gennis6714efc2010-12-20 12:09:37 -080084// ----------------------------------------------------------------------------
85
Jamie Gennis376590d2011-01-13 14:43:36 -080086class JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener
Jamie Gennis6714efc2010-12-20 12:09:37 -080087{
Jamie Gennis376590d2011-01-13 14:43:36 -080088public:
89 JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz);
90 virtual ~JNISurfaceTextureContext();
91 virtual void onFrameAvailable();
Jamie Gennis6714efc2010-12-20 12:09:37 -080092
Jamie Gennis376590d2011-01-13 14:43:36 -080093private:
Jamie Gennis84293fb2011-06-17 16:35:35 -070094 static JNIEnv* getJNIEnv();
95
Jamie Gennis376590d2011-01-13 14:43:36 -080096 jobject mWeakThiz;
97 jclass mClazz;
98};
99
100JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env,
101 jobject weakThiz, jclass clazz) :
102 mWeakThiz(env->NewGlobalRef(weakThiz)),
103 mClazz((jclass)env->NewGlobalRef(clazz))
104{}
105
Jamie Gennis84293fb2011-06-17 16:35:35 -0700106JNIEnv* JNISurfaceTextureContext::getJNIEnv() {
107 JNIEnv* env;
108 JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
109 JavaVM* vm = AndroidRuntime::getJavaVM();
110 int result = vm->AttachCurrentThread(&env, (void*) &args);
111 if (result != JNI_OK) {
112 LOGE("thread attach failed: %#x", result);
113 return NULL;
114 }
115 return env;
116}
117
Jamie Gennis376590d2011-01-13 14:43:36 -0800118JNISurfaceTextureContext::~JNISurfaceTextureContext()
119{
Jamie Gennis84293fb2011-06-17 16:35:35 -0700120 JNIEnv* env = getJNIEnv();
121 if (env != NULL) {
122 env->DeleteGlobalRef(mWeakThiz);
123 env->DeleteGlobalRef(mClazz);
124 } else {
125 LOGW("leaking JNI object references");
126 }
Jamie Gennis6714efc2010-12-20 12:09:37 -0800127}
128
Jamie Gennis376590d2011-01-13 14:43:36 -0800129void JNISurfaceTextureContext::onFrameAvailable()
Jamie Gennis6714efc2010-12-20 12:09:37 -0800130{
Jamie Gennis84293fb2011-06-17 16:35:35 -0700131 JNIEnv *env = getJNIEnv();
132 if (env != NULL) {
133 env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz);
134 } else {
135 LOGW("onFrameAvailable event will not posted");
136 }
Jamie Gennis376590d2011-01-13 14:43:36 -0800137}
138
139// ----------------------------------------------------------------------------
140
141static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
142{
143 fields.surfaceTexture = env->GetFieldID(clazz,
144 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I");
145 if (fields.surfaceTexture == NULL) {
146 LOGE("can't find android/graphics/SurfaceTexture.%s",
147 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
148 }
149
150 fields.postEvent = env->GetStaticMethodID(clazz, "postEventFromNative",
151 "(Ljava/lang/Object;)V");
152 if (fields.postEvent == NULL) {
153 LOGE("can't find android/graphics/SurfaceTexture.postEventFromNative");
154 }
Jamie Gennis376590d2011-01-13 14:43:36 -0800155}
156
157static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jint texName,
158 jobject weakThiz)
159{
160 sp<SurfaceTexture> surfaceTexture(new SurfaceTexture(texName));
161 if (surfaceTexture == 0) {
162 jniThrowException(env, OutOfResourcesException,
163 "Unable to create native SurfaceTexture");
164 return;
165 }
166 SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
167
168 jclass clazz = env->GetObjectClass(thiz);
169 if (clazz == NULL) {
170 jniThrowRuntimeException(env,
171 "Can't find android/graphics/SurfaceTexture");
172 return;
173 }
174
175 sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz,
176 clazz));
177 surfaceTexture->setFrameAvailableListener(ctx);
178}
179
180static void SurfaceTexture_finalize(JNIEnv* env, jobject thiz)
181{
182 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
183 surfaceTexture->setFrameAvailableListener(0);
184 SurfaceTexture_setSurfaceTexture(env, thiz, 0);
185}
186
tedbo05031612011-06-06 16:02:47 -0700187static void SurfaceTexture_setDefaultBufferSize(
188 JNIEnv* env, jobject thiz, jint width, jint height)
189{
190 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
191 surfaceTexture->setDefaultBufferSize(width, height);
192}
193
Jamie Gennis376590d2011-01-13 14:43:36 -0800194static void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz)
195{
196 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Jamie Gennis6714efc2010-12-20 12:09:37 -0800197 surfaceTexture->updateTexImage();
198}
199
Jamie Gennis376590d2011-01-13 14:43:36 -0800200static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
Jamie Gennisb0ba48c2011-01-09 18:22:05 -0800201 jfloatArray jmtx)
202{
Jamie Gennis376590d2011-01-13 14:43:36 -0800203 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Jamie Gennisb0ba48c2011-01-09 18:22:05 -0800204 float* mtx = env->GetFloatArrayElements(jmtx, NULL);
205 surfaceTexture->getTransformMatrix(mtx);
206 env->ReleaseFloatArrayElements(jmtx, mtx, 0);
207}
208
Eino-Ville Talvalac5f94d82011-02-18 11:02:42 -0800209static jlong SurfaceTexture_getTimestamp(JNIEnv* env, jobject thiz)
210{
211 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
212 return surfaceTexture->getTimestamp();
213}
214
Grace Kloba925bcaa2011-06-22 00:56:54 -0700215static jint SurfaceTexture_getQueuedCount(JNIEnv* env, jobject thiz)
216{
217 sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
218 return surfaceTexture->getQueuedCount();
219}
220
Jamie Gennis6714efc2010-12-20 12:09:37 -0800221// ----------------------------------------------------------------------------
222
Jamie Gennis6714efc2010-12-20 12:09:37 -0800223static JNINativeMethod gSurfaceTextureMethods[] = {
Jamie Gennis376590d2011-01-13 14:43:36 -0800224 {"nativeClassInit", "()V", (void*)SurfaceTexture_classInit },
225 {"nativeInit", "(ILjava/lang/Object;)V", (void*)SurfaceTexture_init },
Eino-Ville Talvalac5f94d82011-02-18 11:02:42 -0800226 {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize },
tedbo05031612011-06-06 16:02:47 -0700227 {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
Jamie Gennis376590d2011-01-13 14:43:36 -0800228 {"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage },
229 {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
Grace Kloba925bcaa2011-06-22 00:56:54 -0700230 {"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
231 {"nativeGetQueuedCount", "()I", (void*)SurfaceTexture_getQueuedCount }
Jamie Gennis6714efc2010-12-20 12:09:37 -0800232};
233
Jamie Gennis6714efc2010-12-20 12:09:37 -0800234int register_android_graphics_SurfaceTexture(JNIEnv* env)
235{
236 int err = 0;
237 err = AndroidRuntime::registerNativeMethods(env, kSurfaceTextureClassPathName,
238 gSurfaceTextureMethods, NELEM(gSurfaceTextureMethods));
239 return err;
240}
241
242} // namespace android