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