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>
22846db33313aa0899fa7928256c6734964bd92520Glenn Kasten#include <gui/SurfaceTextureClient.h>
236714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
246714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <android_runtime/AndroidRuntime.h>
256714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
266714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <utils/Log.h>
276714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include <utils/misc.h>
286714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
296714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis#include "jni.h"
30376590d668e22a918439877b55faf075427b13f3Jamie Gennis#include "JNIHelp.h"
316714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
326714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
336714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
346714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisnamespace android {
356714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
366714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisstatic const char* const OutOfResourcesException =
376714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    "android/graphics/SurfaceTexture$OutOfResourcesException";
382b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennisstatic const char* const IllegalStateException = "java/lang/IllegalStateException";
39050316184b01c0d1a01c46afae7429b89a27c31btedboconst char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
406714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
41376590d668e22a918439877b55faf075427b13f3Jamie Gennisstruct fields_t {
42376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jfieldID  surfaceTexture;
43376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jmethodID postEvent;
446714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis};
45376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic fields_t fields;
466714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
476714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
486714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
49376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz,
506714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis        const sp<SurfaceTexture>& surfaceTexture)
516714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
526714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    SurfaceTexture* const p =
53376590d668e22a918439877b55faf075427b13f3Jamie Gennis        (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture);
546714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (surfaceTexture.get()) {
55376590d668e22a918439877b55faf075427b13f3Jamie Gennis        surfaceTexture->incStrong(thiz);
566714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
576714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (p) {
58376590d668e22a918439877b55faf075427b13f3Jamie Gennis        p->decStrong(thiz);
596714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
60376590d668e22a918439877b55faf075427b13f3Jamie Gennis    env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get());
616714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
626714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
63376590d668e22a918439877b55faf075427b13f3Jamie Gennissp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz)
646714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
656714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    sp<SurfaceTexture> surfaceTexture(
66376590d668e22a918439877b55faf075427b13f3Jamie Gennis        (SurfaceTexture*)env->GetIntField(thiz, fields.surfaceTexture));
676714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    return surfaceTexture;
686714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
696714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
70846db33313aa0899fa7928256c6734964bd92520Glenn Kastensp<ANativeWindow> android_SurfaceTexture_getNativeWindow(
71846db33313aa0899fa7928256c6734964bd92520Glenn Kasten        JNIEnv* env, jobject thiz)
72846db33313aa0899fa7928256c6734964bd92520Glenn Kasten{
73846db33313aa0899fa7928256c6734964bd92520Glenn Kasten    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
74846db33313aa0899fa7928256c6734964bd92520Glenn Kasten    sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ?
75846db33313aa0899fa7928256c6734964bd92520Glenn Kasten            new SurfaceTextureClient(surfaceTexture) : NULL);
76846db33313aa0899fa7928256c6734964bd92520Glenn Kasten    return surfaceTextureClient;
77846db33313aa0899fa7928256c6734964bd92520Glenn Kasten}
78846db33313aa0899fa7928256c6734964bd92520Glenn Kasten
79050316184b01c0d1a01c46afae7429b89a27c31btedbobool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz)
80050316184b01c0d1a01c46afae7429b89a27c31btedbo{
81050316184b01c0d1a01c46afae7429b89a27c31btedbo    jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
82050316184b01c0d1a01c46afae7429b89a27c31btedbo    return env->IsInstanceOf(thiz, surfaceTextureClass);
83050316184b01c0d1a01c46afae7429b89a27c31btedbo}
84050316184b01c0d1a01c46afae7429b89a27c31btedbo
856714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
866714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
87376590d668e22a918439877b55faf075427b13f3Jamie Gennisclass JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener
886714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
89376590d668e22a918439877b55faf075427b13f3Jamie Gennispublic:
90376590d668e22a918439877b55faf075427b13f3Jamie Gennis    JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz);
91376590d668e22a918439877b55faf075427b13f3Jamie Gennis    virtual ~JNISurfaceTextureContext();
92376590d668e22a918439877b55faf075427b13f3Jamie Gennis    virtual void onFrameAvailable();
93376590d668e22a918439877b55faf075427b13f3Jamie Gennis
94376590d668e22a918439877b55faf075427b13f3Jamie Gennisprivate:
950a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    static JNIEnv* getJNIEnv(bool* needsDetach);
960a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    static void detachJNI();
9784293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis
98376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jobject mWeakThiz;
99376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jclass mClazz;
100376590d668e22a918439877b55faf075427b13f3Jamie Gennis};
101376590d668e22a918439877b55faf075427b13f3Jamie Gennis
102376590d668e22a918439877b55faf075427b13f3Jamie GennisJNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env,
103376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jobject weakThiz, jclass clazz) :
104376590d668e22a918439877b55faf075427b13f3Jamie Gennis    mWeakThiz(env->NewGlobalRef(weakThiz)),
105376590d668e22a918439877b55faf075427b13f3Jamie Gennis    mClazz((jclass)env->NewGlobalRef(clazz))
106376590d668e22a918439877b55faf075427b13f3Jamie Gennis{}
107376590d668e22a918439877b55faf075427b13f3Jamie Gennis
1080a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie GennisJNIEnv* JNISurfaceTextureContext::getJNIEnv(bool* needsDetach) {
1090a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    *needsDetach = false;
1100a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    JNIEnv* env = AndroidRuntime::getJNIEnv();
1110a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    if (env == NULL) {
1120a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
1130a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        JavaVM* vm = AndroidRuntime::getJavaVM();
1140a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        int result = vm->AttachCurrentThread(&env, (void*) &args);
1150a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        if (result != JNI_OK) {
1163762c311729fe9f3af085c14c5c1fb471d994c03Steve Block            ALOGE("thread attach failed: %#x", result);
1170a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis            return NULL;
1180a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        }
1190a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        *needsDetach = true;
1200a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    }
1210a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    return env;
1220a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis}
1230a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis
1240a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennisvoid JNISurfaceTextureContext::detachJNI() {
12584293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    JavaVM* vm = AndroidRuntime::getJavaVM();
1260a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    int result = vm->DetachCurrentThread();
12784293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    if (result != JNI_OK) {
1283762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("thread detach failed: %#x", result);
12984293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    }
13084293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis}
13184293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis
132376590d668e22a918439877b55faf075427b13f3Jamie GennisJNISurfaceTextureContext::~JNISurfaceTextureContext()
133376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
1340a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    bool needsDetach = false;
1350a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    JNIEnv* env = getJNIEnv(&needsDetach);
13684293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    if (env != NULL) {
13784293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis        env->DeleteGlobalRef(mWeakThiz);
13884293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis        env->DeleteGlobalRef(mClazz);
13984293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    } else {
1408564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("leaking JNI object references");
14184293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    }
1420a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    if (needsDetach) {
1430a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        detachJNI();
1440a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    }
145376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
146376590d668e22a918439877b55faf075427b13f3Jamie Gennis
147376590d668e22a918439877b55faf075427b13f3Jamie Gennisvoid JNISurfaceTextureContext::onFrameAvailable()
148376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
1490a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    bool needsDetach = false;
1500a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    JNIEnv* env = getJNIEnv(&needsDetach);
15184293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    if (env != NULL) {
15284293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis        env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz);
15384293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    } else {
1548564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("onFrameAvailable event will not posted");
15584293fb9625a3ab7d7d302436bea05441b8d7316Jamie Gennis    }
1560a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    if (needsDetach) {
1570a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis        detachJNI();
1580a8fd9b610b2de92930c92d71ac184dc9e2bcb4dJamie Gennis    }
159376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
160376590d668e22a918439877b55faf075427b13f3Jamie Gennis
161376590d668e22a918439877b55faf075427b13f3Jamie Gennis// ----------------------------------------------------------------------------
162376590d668e22a918439877b55faf075427b13f3Jamie Gennis
163376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
164376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
165376590d668e22a918439877b55faf075427b13f3Jamie Gennis    fields.surfaceTexture = env->GetFieldID(clazz,
166376590d668e22a918439877b55faf075427b13f3Jamie Gennis            ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I");
167376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (fields.surfaceTexture == NULL) {
1683762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("can't find android/graphics/SurfaceTexture.%s",
169376590d668e22a918439877b55faf075427b13f3Jamie Gennis                ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
170376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
171376590d668e22a918439877b55faf075427b13f3Jamie Gennis
172376590d668e22a918439877b55faf075427b13f3Jamie Gennis    fields.postEvent = env->GetStaticMethodID(clazz, "postEventFromNative",
173376590d668e22a918439877b55faf075427b13f3Jamie Gennis            "(Ljava/lang/Object;)V");
174376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (fields.postEvent == NULL) {
1753762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("can't find android/graphics/SurfaceTexture.postEventFromNative");
176376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
177376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
1786714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
179376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_init(JNIEnv* env, jobject thiz, jint texName,
1800904d0af81e8a0a5404d6c03f4dcea02bea8170dGrace Kloba        jobject weakThiz, jboolean allowSynchronous)
181376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
1820904d0af81e8a0a5404d6c03f4dcea02bea8170dGrace Kloba    sp<SurfaceTexture> surfaceTexture(new SurfaceTexture(texName, allowSynchronous));
1836714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    if (surfaceTexture == 0) {
184376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jniThrowException(env, OutOfResourcesException,
185376590d668e22a918439877b55faf075427b13f3Jamie Gennis                "Unable to create native SurfaceTexture");
186376590d668e22a918439877b55faf075427b13f3Jamie Gennis        return;
187376590d668e22a918439877b55faf075427b13f3Jamie Gennis    }
188376590d668e22a918439877b55faf075427b13f3Jamie Gennis    SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
189376590d668e22a918439877b55faf075427b13f3Jamie Gennis
190376590d668e22a918439877b55faf075427b13f3Jamie Gennis    jclass clazz = env->GetObjectClass(thiz);
191376590d668e22a918439877b55faf075427b13f3Jamie Gennis    if (clazz == NULL) {
192376590d668e22a918439877b55faf075427b13f3Jamie Gennis        jniThrowRuntimeException(env,
193376590d668e22a918439877b55faf075427b13f3Jamie Gennis                "Can't find android/graphics/SurfaceTexture");
1946714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis        return;
1956714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    }
196376590d668e22a918439877b55faf075427b13f3Jamie Gennis
197376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz,
198376590d668e22a918439877b55faf075427b13f3Jamie Gennis            clazz));
199376590d668e22a918439877b55faf075427b13f3Jamie Gennis    surfaceTexture->setFrameAvailableListener(ctx);
200376590d668e22a918439877b55faf075427b13f3Jamie Gennis}
201376590d668e22a918439877b55faf075427b13f3Jamie Gennis
202376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_finalize(JNIEnv* env, jobject thiz)
203376590d668e22a918439877b55faf075427b13f3Jamie Gennis{
204376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
205376590d668e22a918439877b55faf075427b13f3Jamie Gennis    surfaceTexture->setFrameAvailableListener(0);
206376590d668e22a918439877b55faf075427b13f3Jamie Gennis    SurfaceTexture_setSurfaceTexture(env, thiz, 0);
2076714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
2086714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
209050316184b01c0d1a01c46afae7429b89a27c31btedbostatic void SurfaceTexture_setDefaultBufferSize(
210050316184b01c0d1a01c46afae7429b89a27c31btedbo        JNIEnv* env, jobject thiz, jint width, jint height)
211050316184b01c0d1a01c46afae7429b89a27c31btedbo{
212050316184b01c0d1a01c46afae7429b89a27c31btedbo    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
213050316184b01c0d1a01c46afae7429b89a27c31btedbo    surfaceTexture->setDefaultBufferSize(width, height);
214050316184b01c0d1a01c46afae7429b89a27c31btedbo}
215050316184b01c0d1a01c46afae7429b89a27c31btedbo
2162b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennisstatic void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz)
2176714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
218376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
2192b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    status_t err = surfaceTexture->updateTexImage();
2202b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    if (err == INVALID_OPERATION) {
2212b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis        jniThrowException(env, IllegalStateException, "Unable to update texture contents (see "
2222b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis                "logcat for details)");
223721bfaa63d14f0ac858d32431ab2eff582143b0fJamie Gennis    } else if (err < 0) {
2242b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis        jniThrowRuntimeException(env, "Error during updateTexImage (see logcat for details)");
2252b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    }
2266714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
2276714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
228c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennisstatic jint SurfaceTexture_detachFromGLContext(JNIEnv* env, jobject thiz)
229c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis{
230c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
231c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    return surfaceTexture->detachFromContext();
232c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis}
233c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis
234c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennisstatic jint SurfaceTexture_attachToGLContext(JNIEnv* env, jobject thiz, jint tex)
235c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis{
236c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
237c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    return surfaceTexture->attachToContext((GLuint)tex);
238c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis}
239c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis
240376590d668e22a918439877b55faf075427b13f3Jamie Gennisstatic void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
241b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis        jfloatArray jmtx)
242b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis{
243376590d668e22a918439877b55faf075427b13f3Jamie Gennis    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
244b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    float* mtx = env->GetFloatArrayElements(jmtx, NULL);
245b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    surfaceTexture->getTransformMatrix(mtx);
246b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis    env->ReleaseFloatArrayElements(jmtx, mtx, 0);
247b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis}
248b0ba48c95ea8768a051100c5adb4c906caa1e080Jamie Gennis
249c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvalastatic jlong SurfaceTexture_getTimestamp(JNIEnv* env, jobject thiz)
250c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala{
251c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
252c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala    return surfaceTexture->getTimestamp();
253c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala}
254c5f94d8a4779050125145396ca83fbc862c7ed6bEino-Ville Talvala
255ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopianstatic void SurfaceTexture_release(JNIEnv* env, jobject thiz)
256ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian{
257ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
258ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian    surfaceTexture->abandon();
259ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian}
260ec46b4e1ca89d7c3a9ad70ded58da08b5e19f08fMathias Agopian
2616714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis// ----------------------------------------------------------------------------
2626714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
2636714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisstatic JNINativeMethod gSurfaceTextureMethods[] = {
264c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeClassInit",            "()V",   (void*)SurfaceTexture_classInit },
265c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeInit",                 "(ILjava/lang/Object;Z)V", (void*)SurfaceTexture_init },
266c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeFinalize",             "()V",   (void*)SurfaceTexture_finalize },
267050316184b01c0d1a01c46afae7429b89a27c31btedbo    {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
2682b4bfa5efec7df408b4db127961cfc9aca9e57cfJamie Gennis    {"nativeUpdateTexImage",       "()V",   (void*)SurfaceTexture_updateTexImage },
269c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeDetachFromGLContext",  "()I",   (void*)SurfaceTexture_detachFromGLContext },
270c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeAttachToGLContext",    "(I)I",   (void*)SurfaceTexture_attachToGLContext },
271c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeGetTransformMatrix",   "([F)V", (void*)SurfaceTexture_getTransformMatrix },
272c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeGetTimestamp",         "()J",   (void*)SurfaceTexture_getTimestamp },
273c6d993077761fc737bbb0f4db44b961a4e7b6bbbJamie Gennis    {"nativeRelease",              "()V",   (void*)SurfaceTexture_release },
2746714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis};
2756714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
2766714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennisint register_android_graphics_SurfaceTexture(JNIEnv* env)
2776714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis{
2786714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    int err = 0;
2796714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    err = AndroidRuntime::registerNativeMethods(env, kSurfaceTextureClassPathName,
2806714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis            gSurfaceTextureMethods, NELEM(gSurfaceTextureMethods));
2816714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis    return err;
2826714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis}
2836714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis
2846714efc5e0c52953b65e774de0003e22377e7d39Jamie Gennis} // namespace android
285