SurfaceTexture.cpp revision c5f94d8a4779050125145396ca83fbc862c7ed6b
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
174static jlong SurfaceTexture_getTimestamp(JNIEnv* env, jobject thiz)
175{
176    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
177    return surfaceTexture->getTimestamp();
178}
179
180// ----------------------------------------------------------------------------
181
182const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
183
184static JNINativeMethod gSurfaceTextureMethods[] = {
185    {"nativeClassInit",          "()V",   (void*)SurfaceTexture_classInit },
186    {"nativeInit",               "(ILjava/lang/Object;)V", (void*)SurfaceTexture_init },
187    {"nativeFinalize",           "()V",   (void*)SurfaceTexture_finalize },
188    {"nativeUpdateTexImage",     "()V",   (void*)SurfaceTexture_updateTexImage },
189    {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
190    {"nativeGetTimestamp",       "()J",   (void*)SurfaceTexture_getTimestamp }
191};
192
193int register_android_graphics_SurfaceTexture(JNIEnv* env)
194{
195    int err = 0;
196    err = AndroidRuntime::registerNativeMethods(env, kSurfaceTextureClassPathName,
197            gSurfaceTextureMethods, NELEM(gSurfaceTextureMethods));
198    return err;
199}
200
201} // namespace android
202