SurfaceTexture.cpp revision 376590d668e22a918439877b55faf075427b13f3
16714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis/*
26714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * Copyright (C) 2010 The Android Open Source Project
36714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis *
46714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * Licensed under the Apache License, Version 2.0 (the "License");
56714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * you may not use this file except in compliance with the License.
66714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * You may obtain a copy of the License at
76714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis *
86714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis *      http://www.apache.org/licenses/LICENSE-2.0
96714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis *
106714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * Unless required by applicable law or agreed to in writing, software
116714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * distributed under the License is distributed on an "AS IS" BASIS,
126714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * See the License for the specific language governing permissions and
146714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis * limitations under the License.
156714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis */
166714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
176714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#define LOG_TAG "SurfaceTexture"
186714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
196714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <stdio.h>
206714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
216714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <gui/SurfaceTexture.h>
226714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
236714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <android_runtime/AndroidRuntime.h>
246714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
256714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <utils/Log.h>
266714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <utils/misc.h>
276714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
286714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include "jni.h"
29376590d668e22a918439877b55faf075427b13f3Jamie Gennis#include "JNIHelp.h"
306714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
316714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
326714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
336714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisnamespace android {
346714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
356714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisstatic const char* const OutOfResourcesException =
366714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    "android/graphics/SurfaceTexture$OutOfResourcesException";
376714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
38376590d668e22a918439877b55faf075427b13f3Jamie Gennisstruct fields_t {
39376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jfieldID  surfaceTexture;
40376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jmethodID postEvent;
416714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis};
42376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic fields_t fields;
436714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
446714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
456714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
46376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz,
476714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis        const sp<SurfaceTexture>& surfaceTexture)
486714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
496714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    SurfaceTexture* const p =
50376590d668e22a918439877b55faf075427b13f3Jamie Gennis        (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture);
516714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (surfaceTexture.get()) {
52376590d668e22a918439877b55faf075427b13f3Jamie Gennis        surfaceTexture->incStrong(thiz);
536714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
546714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (p) {
55376590d668e22a918439877b55faf075427b13f3Jamie Gennis        p->decStrong(thiz);
566714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
57376590d668e22a918439877b55faf075427b13f3Jamie Gennis    env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get());
586714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
596714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
60376590d668e22a918439877b55faf075427b13f3Jamie Gennissp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz)
616714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
626714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    sp<SurfaceTexture> surfaceTexture(
63376590d668e22a918439877b55faf075427b13f3Jamie Gennis        (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture));
646714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    return surfaceTexture;
656714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
666714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
676714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
686714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
69376590d668e22a918439877b55faf075427b13f3Jamie Gennisclass JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener
706714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
71376590d668e22a918439877b55faf075427b13f3Jamie Gennispublic:
72376590d668e22a918439877b55faf075427b13f3Jamie Gennis    JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz);
73376590d668e22a918439877b55faf075427b13f3Jamie Gennis    virtual ~JNISurfaceTextureContext();
74376590d668e22a918439877b55faf075427b13f3Jamie Gennis    virtual void onFrameAvailable();
75376590d668e22a918439877b55faf075427b13f3Jamie Gennis
76376590d668e22a918439877b55faf075427b13f3Jamie Gennisprivate:
77376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jobject mWeakThiz;
78376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jclass mClazz;
79376590d668e22a918439877b55faf075427b13f3Jamie Gennis};
80376590d668e22a918439877b55faf075427b13f3Jamie Gennis
81376590d668e22a918439877b55faf075427b13f3Jamie GennisJNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env,
82376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jobject weakThiz, jclass clazz) :
83376590d668e22a918439877b55faf075427b13f3Jamie Gennis    mWeakThiz(env->NewGlobalRef(weakThiz)),
84376590d668e22a918439877b55faf075427b13f3Jamie Gennis    mClazz((jclass)env->NewGlobalRef(clazz))
85376590d668e22a918439877b55faf075427b13f3Jamie Gennis{}
86376590d668e22a918439877b55faf075427b13f3Jamie Gennis
87376590d668e22a918439877b55faf075427b13f3Jamie GennisJNISurfaceTextureContext::~JNISurfaceTextureContext()
88376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
89376590d668e22a918439877b55faf075427b13f3Jamie Gennis    JNIEnv *env = AndroidRuntime::getJNIEnv();
90376590d668e22a918439877b55faf075427b13f3Jamie Gennis    env->DeleteGlobalRef(mWeakThiz);
91376590d668e22a918439877b55faf075427b13f3Jamie Gennis    env->DeleteGlobalRef(mClazz);
92376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
93376590d668e22a918439877b55faf075427b13f3Jamie Gennis
94376590d668e22a918439877b55faf075427b13f3Jamie Gennisvoid JNISurfaceTextureContext::onFrameAvailable()
95376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
96376590d668e22a918439877b55faf075427b13f3Jamie Gennis    JNIEnv *env = AndroidRuntime::getJNIEnv();
97376590d668e22a918439877b55faf075427b13f3Jamie Gennis    env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz);
98376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
99376590d668e22a918439877b55faf075427b13f3Jamie Gennis
100376590d668e22a918439877b55faf075427b13f3Jamie Gennis// ----------------------------------------------------------------------------
101376590d668e22a918439877b55faf075427b13f3Jamie Gennis
102376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
103376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
104376590d668e22a918439877b55faf075427b13f3Jamie Gennis    fields.surfaceTexture = env->GetFieldID(clazz,
105376590d668e22a918439877b55faf075427b13f3Jamie Gennis            ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I");
106376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (fields.surfaceTexture == NULL) {
107376590d668e22a918439877b55faf075427b13f3Jamie Gennis        LOGE("can't find android/graphics/SurfaceTexture.%s",
108376590d668e22a918439877b55faf075427b13f3Jamie Gennis                ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
109376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
110376590d668e22a918439877b55faf075427b13f3Jamie Gennis
111376590d668e22a918439877b55faf075427b13f3Jamie Gennis    fields.postEvent = env->GetStaticMethodID(clazz, "postEventFromNative",
112376590d668e22a918439877b55faf075427b13f3Jamie Gennis            "(Ljava/lang/Object;)V");
113376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (fields.postEvent == NULL) {
114376590d668e22a918439877b55faf075427b13f3Jamie Gennis        LOGE("can't find android/graphics/SurfaceTexture.postEventFromNative");
115376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
116376590d668e22a918439877b55faf075427b13f3Jamie Gennis
117376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
1186714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
119376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_init(JNIEnv* env, jobject thiz, jint texName,
120376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jobject weakThiz)
121376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
122376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<SurfaceTexture> surfaceTexture(new SurfaceTexture(texName));
1236714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (surfaceTexture == 0) {
124376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jniThrowException(env, OutOfResourcesException,
125376590d668e22a918439877b55faf075427b13f3Jamie Gennis                "Unable to create native SurfaceTexture");
126376590d668e22a918439877b55faf075427b13f3Jamie Gennis        return;
127376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
128376590d668e22a918439877b55faf075427b13f3Jamie Gennis    SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
129376590d668e22a918439877b55faf075427b13f3Jamie Gennis
130376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jclass clazz = env->GetObjectClass(thiz);
131376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (clazz == NULL) {
132376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jniThrowRuntimeException(env,
133376590d668e22a918439877b55faf075427b13f3Jamie Gennis                "Can't find android/graphics/SurfaceTexture");
1346714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis        return;
1356714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
136376590d668e22a918439877b55faf075427b13f3Jamie Gennis
137376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz,
138376590d668e22a918439877b55faf075427b13f3Jamie Gennis            clazz));
139376590d668e22a918439877b55faf075427b13f3Jamie Gennis    surfaceTexture->setFrameAvailableListener(ctx);
140376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
141376590d668e22a918439877b55faf075427b13f3Jamie Gennis
142376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_finalize(JNIEnv* env, jobject thiz)
143376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
144376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
145376590d668e22a918439877b55faf075427b13f3Jamie Gennis    surfaceTexture->setFrameAvailableListener(0);
146376590d668e22a918439877b55faf075427b13f3Jamie Gennis    SurfaceTexture_setSurfaceTexture(env, thiz, 0);
1476714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
1486714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
149376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz)
1506714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
151376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
1526714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    surfaceTexture->updateTexImage();
1536714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
1546714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
155376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
156b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis        jfloatArray jmtx)
157b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis{
158376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
159b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    float* mtx = env->GetFloatArrayElements(jmtx, NULL);
160b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    surfaceTexture->getTransformMatrix(mtx);
161b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    env->ReleaseFloatArrayElements(jmtx, mtx, 0);
162b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis}
163b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis
1646714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
1656714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
1666714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisconst char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
1676714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
1686714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisstatic JNINativeMethod gSurfaceTextureMethods[] = {
169376590d668e22a918439877b55faf075427b13f3Jamie Gennis    {"nativeClassInit",          "()V",   (void*)SurfaceTexture_classInit },
170376590d668e22a918439877b55faf075427b13f3Jamie Gennis    {"nativeInit",               "(ILjava/lang/Object;)V", (void*)SurfaceTexture_init },
171376590d668e22a918439877b55faf075427b13f3Jamie Gennis    {"nativeFinalize",            "()V",  (void*)SurfaceTexture_finalize },
172376590d668e22a918439877b55faf075427b13f3Jamie Gennis    {"nativeUpdateTexImage",     "()V",   (void*)SurfaceTexture_updateTexImage },
173376590d668e22a918439877b55faf075427b13f3Jamie Gennis    {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
1746714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis};
1756714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
1766714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisint register_android_graphics_SurfaceTexture(JNIEnv* env)
1776714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
1786714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    int err = 0;
1796714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    err = AndroidRuntime::registerNativeMethods(env, kSurfaceTextureClassPathName,
1806714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis            gSurfaceTextureMethods, NELEM(gSurfaceTextureMethods));
1816714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    return err;
1826714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
1836714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
1846714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis} // namespace android
185