blob: d098a355085e27027130a51ff7336857eb5a00f1 [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
Craig Donner4bbb8502016-01-12 10:22:39 -080021#include <EGL/egl.h>
22#include <EGL/eglext.h>
Mathias Agopiane3eae732013-08-08 19:24:14 -070023#include <GLES2/gl2.h>
24#include <GLES2/gl2ext.h>
25
Andy McFaddend47f7d82012-12-18 09:48:38 -080026#include <gui/GLConsumer.h>
Mathias Agopian52800612013-02-14 17:11:20 -080027#include <gui/Surface.h>
Mathias Agopianf1cb02e2017-02-13 18:46:36 -080028#include <gui/BufferQueue.h>
Jamie Gennis6714efc2010-12-20 12:09:37 -080029
Andreas Gampeed6b9df2014-11-20 22:02:20 -080030#include "core_jni_helpers.h"
Jamie Gennis6714efc2010-12-20 12:09:37 -080031
Mathias Agopiandf7707c2017-02-28 17:43:39 -080032#include <cutils/atomic.h>
Jamie Gennis6714efc2010-12-20 12:09:37 -080033#include <utils/Log.h>
34#include <utils/misc.h>
35
Jamie Gennis6714efc2010-12-20 12:09:37 -080036#include "jni.h"
Steven Moreland849252c2017-07-28 10:21:47 -070037#include <nativehelper/JNIHelp.h>
38#include <nativehelper/ScopedLocalRef.h>
Jamie Gennis6714efc2010-12-20 12:09:37 -080039
40// ----------------------------------------------------------------------------
41
Craig Donnerafe9a4c2016-04-12 17:25:46 -070042#define EGL_PROTECTED_CONTENT_EXT 0x32C0
Craig Donner4bbb8502016-01-12 10:22:39 -080043
Jamie Gennis6714efc2010-12-20 12:09:37 -080044namespace android {
45
46static const char* const OutOfResourcesException =
Igor Murashkina86ab6402013-08-30 12:58:36 -070047 "android/view/Surface$OutOfResourcesException";
Jamie Gennis2b4bfa52012-04-13 14:48:22 -070048static const char* const IllegalStateException = "java/lang/IllegalStateException";
tedbo05031612011-06-06 16:02:47 -070049const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
Jamie Gennis6714efc2010-12-20 12:09:37 -080050
Jamie Gennis376590d2011-01-13 14:43:36 -080051struct fields_t {
52 jfieldID surfaceTexture;
Dan Stoza0dc146b2014-03-12 15:39:33 -070053 jfieldID producer;
Igor Murashkinc99db2b2012-10-29 13:38:10 -070054 jfieldID frameAvailableListener;
Jamie Gennis376590d2011-01-13 14:43:36 -080055 jmethodID postEvent;
Jamie Gennis6714efc2010-12-20 12:09:37 -080056};
Jamie Gennis376590d2011-01-13 14:43:36 -080057static fields_t fields;
Jamie Gennis6714efc2010-12-20 12:09:37 -080058
Eino-Ville Talvalaef9db7d2015-06-09 14:15:15 -070059// Get an ID that's unique within this process.
60static int32_t createProcessUniqueId() {
61 static volatile int32_t globalCounter = 0;
62 return android_atomic_inc(&globalCounter);
63}
64
Craig Donner4bbb8502016-01-12 10:22:39 -080065// Check whether the current EGL context is protected.
66static bool isProtectedContext() {
67 EGLDisplay dpy = eglGetCurrentDisplay();
68 EGLContext ctx = eglGetCurrentContext();
69
Craig Donnerafe9a4c2016-04-12 17:25:46 -070070 if (dpy == EGL_NO_DISPLAY || ctx == EGL_NO_CONTEXT) {
Craig Donner4bbb8502016-01-12 10:22:39 -080071 return false;
72 }
73
74 EGLint isProtected = EGL_FALSE;
Craig Donnerafe9a4c2016-04-12 17:25:46 -070075 eglQueryContext(dpy, ctx, EGL_PROTECTED_CONTENT_EXT, &isProtected);
Craig Donner4bbb8502016-01-12 10:22:39 -080076
77 return isProtected;
78}
79
Jamie Gennis6714efc2010-12-20 12:09:37 -080080// ----------------------------------------------------------------------------
81
Jamie Gennis376590d2011-01-13 14:43:36 -080082static void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz,
Andy McFaddend47f7d82012-12-18 09:48:38 -080083 const sp<GLConsumer>& surfaceTexture)
Jamie Gennis6714efc2010-12-20 12:09:37 -080084{
Andy McFaddend47f7d82012-12-18 09:48:38 -080085 GLConsumer* const p =
Ashok Bhat72aa3132014-01-13 20:41:06 +000086 (GLConsumer*)env->GetLongField(thiz, fields.surfaceTexture);
Jamie Gennis6714efc2010-12-20 12:09:37 -080087 if (surfaceTexture.get()) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -080088 surfaceTexture->incStrong((void*)SurfaceTexture_setSurfaceTexture);
Jamie Gennis6714efc2010-12-20 12:09:37 -080089 }
90 if (p) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -080091 p->decStrong((void*)SurfaceTexture_setSurfaceTexture);
Jamie Gennis6714efc2010-12-20 12:09:37 -080092 }
Ashok Bhat72aa3132014-01-13 20:41:06 +000093 env->SetLongField(thiz, fields.surfaceTexture, (jlong)surfaceTexture.get());
Jamie Gennis6714efc2010-12-20 12:09:37 -080094}
95
Dan Stoza0dc146b2014-03-12 15:39:33 -070096static void SurfaceTexture_setProducer(JNIEnv* env, jobject thiz,
97 const sp<IGraphicBufferProducer>& producer)
Mathias Agopian52a9a102013-08-02 01:38:38 -070098{
Dan Stoza0dc146b2014-03-12 15:39:33 -070099 IGraphicBufferProducer* const p =
100 (IGraphicBufferProducer*)env->GetLongField(thiz, fields.producer);
101 if (producer.get()) {
102 producer->incStrong((void*)SurfaceTexture_setProducer);
Mathias Agopian52a9a102013-08-02 01:38:38 -0700103 }
104 if (p) {
Dan Stoza0dc146b2014-03-12 15:39:33 -0700105 p->decStrong((void*)SurfaceTexture_setProducer);
Mathias Agopian52a9a102013-08-02 01:38:38 -0700106 }
Dan Stoza0dc146b2014-03-12 15:39:33 -0700107 env->SetLongField(thiz, fields.producer, (jlong)producer.get());
Mathias Agopian52a9a102013-08-02 01:38:38 -0700108}
109
Igor Murashkinc99db2b2012-10-29 13:38:10 -0700110static void SurfaceTexture_setFrameAvailableListener(JNIEnv* env,
Andy McFaddend47f7d82012-12-18 09:48:38 -0800111 jobject thiz, sp<GLConsumer::FrameAvailableListener> listener)
Jamie Gennis6714efc2010-12-20 12:09:37 -0800112{
Andy McFaddend47f7d82012-12-18 09:48:38 -0800113 GLConsumer::FrameAvailableListener* const p =
114 (GLConsumer::FrameAvailableListener*)
Ashok Bhat72aa3132014-01-13 20:41:06 +0000115 env->GetLongField(thiz, fields.frameAvailableListener);
Igor Murashkinc99db2b2012-10-29 13:38:10 -0700116 if (listener.get()) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800117 listener->incStrong((void*)SurfaceTexture_setSurfaceTexture);
Igor Murashkinc99db2b2012-10-29 13:38:10 -0700118 }
119 if (p) {
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800120 p->decStrong((void*)SurfaceTexture_setSurfaceTexture);
Igor Murashkinc99db2b2012-10-29 13:38:10 -0700121 }
Ashok Bhat72aa3132014-01-13 20:41:06 +0000122 env->SetLongField(thiz, fields.frameAvailableListener, (jlong)listener.get());
Igor Murashkinc99db2b2012-10-29 13:38:10 -0700123}
124
Mathias Agopian52a9a102013-08-02 01:38:38 -0700125sp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) {
Ashok Bhat72aa3132014-01-13 20:41:06 +0000126 return (GLConsumer*)env->GetLongField(thiz, fields.surfaceTexture);
Jamie Gennis6714efc2010-12-20 12:09:37 -0800127}
128
Mathias Agopian52a9a102013-08-02 01:38:38 -0700129sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz) {
Dan Stoza0dc146b2014-03-12 15:39:33 -0700130 return (IGraphicBufferProducer*)env->GetLongField(thiz, fields.producer);
Mathias Agopian52a9a102013-08-02 01:38:38 -0700131}
132
133sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz) {
Andy McFaddend47f7d82012-12-18 09:48:38 -0800134 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Mathias Agopian52a9a102013-08-02 01:38:38 -0700135 sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, thiz));
136 sp<Surface> surfaceTextureClient(surfaceTexture != NULL ? new Surface(producer) : NULL);
Glenn Kasten846db332011-03-04 11:44:32 -0800137 return surfaceTextureClient;
138}
139
Mathias Agopian52a9a102013-08-02 01:38:38 -0700140bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) {
tedbo05031612011-06-06 16:02:47 -0700141 jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
142 return env->IsInstanceOf(thiz, surfaceTextureClass);
143}
144
Jamie Gennis6714efc2010-12-20 12:09:37 -0800145// ----------------------------------------------------------------------------
146
Andy McFaddend47f7d82012-12-18 09:48:38 -0800147class JNISurfaceTextureContext : public GLConsumer::FrameAvailableListener
Jamie Gennis6714efc2010-12-20 12:09:37 -0800148{
Jamie Gennis376590d2011-01-13 14:43:36 -0800149public:
150 JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz);
151 virtual ~JNISurfaceTextureContext();
Dan Stoza2c34b5e2014-11-04 11:36:33 -0800152 virtual void onFrameAvailable(const BufferItem& item);
Jamie Gennis6714efc2010-12-20 12:09:37 -0800153
Jamie Gennis376590d2011-01-13 14:43:36 -0800154private:
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700155 static JNIEnv* getJNIEnv(bool* needsDetach);
156 static void detachJNI();
Jamie Gennis84293fb2011-06-17 16:35:35 -0700157
Jamie Gennis376590d2011-01-13 14:43:36 -0800158 jobject mWeakThiz;
159 jclass mClazz;
160};
161
162JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env,
163 jobject weakThiz, jclass clazz) :
164 mWeakThiz(env->NewGlobalRef(weakThiz)),
165 mClazz((jclass)env->NewGlobalRef(clazz))
166{}
167
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700168JNIEnv* JNISurfaceTextureContext::getJNIEnv(bool* needsDetach) {
169 *needsDetach = false;
170 JNIEnv* env = AndroidRuntime::getJNIEnv();
171 if (env == NULL) {
Andy McFadden9b311c92014-02-04 15:59:39 -0800172 JavaVMAttachArgs args = {
173 JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL };
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700174 JavaVM* vm = AndroidRuntime::getJavaVM();
175 int result = vm->AttachCurrentThread(&env, (void*) &args);
176 if (result != JNI_OK) {
Steve Block3762c312012-01-06 19:20:56 +0000177 ALOGE("thread attach failed: %#x", result);
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700178 return NULL;
179 }
180 *needsDetach = true;
Jamie Gennis84293fb2011-06-17 16:35:35 -0700181 }
182 return env;
183}
184
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700185void JNISurfaceTextureContext::detachJNI() {
186 JavaVM* vm = AndroidRuntime::getJavaVM();
187 int result = vm->DetachCurrentThread();
188 if (result != JNI_OK) {
Steve Block3762c312012-01-06 19:20:56 +0000189 ALOGE("thread detach failed: %#x", result);
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700190 }
191}
192
Jamie Gennis376590d2011-01-13 14:43:36 -0800193JNISurfaceTextureContext::~JNISurfaceTextureContext()
194{
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700195 bool needsDetach = false;
196 JNIEnv* env = getJNIEnv(&needsDetach);
Jamie Gennis84293fb2011-06-17 16:35:35 -0700197 if (env != NULL) {
198 env->DeleteGlobalRef(mWeakThiz);
199 env->DeleteGlobalRef(mClazz);
200 } else {
Steve Block8564c8d2012-01-05 23:22:43 +0000201 ALOGW("leaking JNI object references");
Jamie Gennis84293fb2011-06-17 16:35:35 -0700202 }
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700203 if (needsDetach) {
204 detachJNI();
205 }
Jamie Gennis6714efc2010-12-20 12:09:37 -0800206}
207
Dan Stoza2c34b5e2014-11-04 11:36:33 -0800208void JNISurfaceTextureContext::onFrameAvailable(const BufferItem& /* item */)
Jamie Gennis6714efc2010-12-20 12:09:37 -0800209{
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700210 bool needsDetach = false;
211 JNIEnv* env = getJNIEnv(&needsDetach);
Jamie Gennis84293fb2011-06-17 16:35:35 -0700212 if (env != NULL) {
213 env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz);
214 } else {
Steve Block8564c8d2012-01-05 23:22:43 +0000215 ALOGW("onFrameAvailable event will not posted");
Jamie Gennis84293fb2011-06-17 16:35:35 -0700216 }
Jamie Gennis0a8fd9b2011-06-20 18:39:35 -0700217 if (needsDetach) {
218 detachJNI();
219 }
Jamie Gennis376590d2011-01-13 14:43:36 -0800220}
221
222// ----------------------------------------------------------------------------
223
Mathias Agopian52a9a102013-08-02 01:38:38 -0700224
225#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
Dan Stoza0dc146b2014-03-12 15:39:33 -0700226#define ANDROID_GRAPHICS_PRODUCER_JNI_ID "mProducer"
Mathias Agopian52a9a102013-08-02 01:38:38 -0700227#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
228 "mFrameAvailableListener"
229
Jamie Gennis376590d2011-01-13 14:43:36 -0800230static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
231{
232 fields.surfaceTexture = env->GetFieldID(clazz,
Ashok Bhat72aa3132014-01-13 20:41:06 +0000233 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "J");
Jamie Gennis376590d2011-01-13 14:43:36 -0800234 if (fields.surfaceTexture == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000235 ALOGE("can't find android/graphics/SurfaceTexture.%s",
Jamie Gennis376590d2011-01-13 14:43:36 -0800236 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
237 }
Dan Stoza0dc146b2014-03-12 15:39:33 -0700238 fields.producer = env->GetFieldID(clazz,
239 ANDROID_GRAPHICS_PRODUCER_JNI_ID, "J");
240 if (fields.producer == NULL) {
Mathias Agopian52a9a102013-08-02 01:38:38 -0700241 ALOGE("can't find android/graphics/SurfaceTexture.%s",
Dan Stoza0dc146b2014-03-12 15:39:33 -0700242 ANDROID_GRAPHICS_PRODUCER_JNI_ID);
Mathias Agopian52a9a102013-08-02 01:38:38 -0700243 }
Igor Murashkinc99db2b2012-10-29 13:38:10 -0700244 fields.frameAvailableListener = env->GetFieldID(clazz,
Ashok Bhat72aa3132014-01-13 20:41:06 +0000245 ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID, "J");
Igor Murashkinc99db2b2012-10-29 13:38:10 -0700246 if (fields.frameAvailableListener == NULL) {
247 ALOGE("can't find android/graphics/SurfaceTexture.%s",
248 ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID);
249 }
Jamie Gennis376590d2011-01-13 14:43:36 -0800250
251 fields.postEvent = env->GetStaticMethodID(clazz, "postEventFromNative",
Jeff Brownc7282e52014-05-06 16:00:38 -0700252 "(Ljava/lang/ref/WeakReference;)V");
Jamie Gennis376590d2011-01-13 14:43:36 -0800253 if (fields.postEvent == NULL) {
Steve Block3762c312012-01-06 19:20:56 +0000254 ALOGE("can't find android/graphics/SurfaceTexture.postEventFromNative");
Jamie Gennis376590d2011-01-13 14:43:36 -0800255 }
Jamie Gennis376590d2011-01-13 14:43:36 -0800256}
257
Dan Stoza493f2e12014-06-26 13:36:19 -0700258static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached,
Mathias Agopiane591b492013-07-24 19:15:00 -0700259 jint texName, jboolean singleBufferMode, jobject weakThiz)
Jamie Gennis376590d2011-01-13 14:43:36 -0800260{
Dan Stoza0dc146b2014-03-12 15:39:33 -0700261 sp<IGraphicBufferProducer> producer;
262 sp<IGraphicBufferConsumer> consumer;
263 BufferQueue::createBufferQueue(&producer, &consumer);
Mathias Agopiane591b492013-07-24 19:15:00 -0700264
265 if (singleBufferMode) {
Pablo Ceballose442b632015-08-19 16:27:45 -0700266 consumer->setMaxBufferCount(1);
Mathias Agopiane591b492013-07-24 19:15:00 -0700267 }
268
Dan Stoza493f2e12014-06-26 13:36:19 -0700269 sp<GLConsumer> surfaceTexture;
270 if (isDetached) {
271 surfaceTexture = new GLConsumer(consumer, GL_TEXTURE_EXTERNAL_OES,
Pablo Ceballose442b632015-08-19 16:27:45 -0700272 true, !singleBufferMode);
Dan Stoza493f2e12014-06-26 13:36:19 -0700273 } else {
274 surfaceTexture = new GLConsumer(consumer, texName,
Pablo Ceballose442b632015-08-19 16:27:45 -0700275 GL_TEXTURE_EXTERNAL_OES, true, !singleBufferMode);
Dan Stoza493f2e12014-06-26 13:36:19 -0700276 }
277
Jamie Gennis376590d2011-01-13 14:43:36 -0800278 if (surfaceTexture == 0) {
279 jniThrowException(env, OutOfResourcesException,
280 "Unable to create native SurfaceTexture");
281 return;
282 }
Eino-Ville Talvalaef9db7d2015-06-09 14:15:15 -0700283 surfaceTexture->setName(String8::format("SurfaceTexture-%d-%d-%d",
284 (isDetached ? 0 : texName),
285 getpid(),
286 createProcessUniqueId()));
287
Craig Donner4bbb8502016-01-12 10:22:39 -0800288 // If the current context is protected, inform the producer.
Jiwen 'Steve' Caia3e1d7b2017-04-21 19:05:01 -0700289 consumer->setConsumerIsProtected(isProtectedContext());
Craig Donner4bbb8502016-01-12 10:22:39 -0800290
Jamie Gennis376590d2011-01-13 14:43:36 -0800291 SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);
Dan Stoza0dc146b2014-03-12 15:39:33 -0700292 SurfaceTexture_setProducer(env, thiz, producer);
Jamie Gennis376590d2011-01-13 14:43:36 -0800293
294 jclass clazz = env->GetObjectClass(thiz);
295 if (clazz == NULL) {
296 jniThrowRuntimeException(env,
297 "Can't find android/graphics/SurfaceTexture");
298 return;
299 }
300
301 sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz,
302 clazz));
303 surfaceTexture->setFrameAvailableListener(ctx);
Igor Murashkinc99db2b2012-10-29 13:38:10 -0700304 SurfaceTexture_setFrameAvailableListener(env, thiz, ctx);
Jamie Gennis376590d2011-01-13 14:43:36 -0800305}
306
307static void SurfaceTexture_finalize(JNIEnv* env, jobject thiz)
308{
Andy McFaddend47f7d82012-12-18 09:48:38 -0800309 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Jamie Gennis376590d2011-01-13 14:43:36 -0800310 surfaceTexture->setFrameAvailableListener(0);
Igor Murashkinc99db2b2012-10-29 13:38:10 -0700311 SurfaceTexture_setFrameAvailableListener(env, thiz, 0);
Jamie Gennis376590d2011-01-13 14:43:36 -0800312 SurfaceTexture_setSurfaceTexture(env, thiz, 0);
Dan Stoza0dc146b2014-03-12 15:39:33 -0700313 SurfaceTexture_setProducer(env, thiz, 0);
Jamie Gennis376590d2011-01-13 14:43:36 -0800314}
315
tedbo05031612011-06-06 16:02:47 -0700316static void SurfaceTexture_setDefaultBufferSize(
Mathias Agopian52a9a102013-08-02 01:38:38 -0700317 JNIEnv* env, jobject thiz, jint width, jint height) {
Andy McFaddend47f7d82012-12-18 09:48:38 -0800318 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
tedbo05031612011-06-06 16:02:47 -0700319 surfaceTexture->setDefaultBufferSize(width, height);
320}
321
Jamie Gennis2b4bfa52012-04-13 14:48:22 -0700322static void SurfaceTexture_updateTexImage(JNIEnv* env, jobject thiz)
Jamie Gennis376590d2011-01-13 14:43:36 -0800323{
Andy McFaddend47f7d82012-12-18 09:48:38 -0800324 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Jamie Gennis2b4bfa52012-04-13 14:48:22 -0700325 status_t err = surfaceTexture->updateTexImage();
326 if (err == INVALID_OPERATION) {
327 jniThrowException(env, IllegalStateException, "Unable to update texture contents (see "
328 "logcat for details)");
Jamie Gennis721bfaa62012-04-13 19:14:37 -0700329 } else if (err < 0) {
Jamie Gennis2b4bfa52012-04-13 14:48:22 -0700330 jniThrowRuntimeException(env, "Error during updateTexImage (see logcat for details)");
331 }
Jamie Gennis6714efc2010-12-20 12:09:37 -0800332}
333
Mathias Agopiane591b492013-07-24 19:15:00 -0700334static void SurfaceTexture_releaseTexImage(JNIEnv* env, jobject thiz)
335{
336 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
337 status_t err = surfaceTexture->releaseTexImage();
338 if (err == INVALID_OPERATION) {
339 jniThrowException(env, IllegalStateException, "Unable to release texture contents (see "
340 "logcat for details)");
341 } else if (err < 0) {
342 jniThrowRuntimeException(env, "Error during updateTexImage (see logcat for details)");
343 }
344}
345
Jamie Gennisc6d99302012-04-05 11:34:02 -0700346static jint SurfaceTexture_detachFromGLContext(JNIEnv* env, jobject thiz)
347{
Andy McFaddend47f7d82012-12-18 09:48:38 -0800348 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Jamie Gennisc6d99302012-04-05 11:34:02 -0700349 return surfaceTexture->detachFromContext();
350}
351
352static jint SurfaceTexture_attachToGLContext(JNIEnv* env, jobject thiz, jint tex)
353{
Andy McFaddend47f7d82012-12-18 09:48:38 -0800354 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Jamie Gennisc6d99302012-04-05 11:34:02 -0700355 return surfaceTexture->attachToContext((GLuint)tex);
356}
357
Jamie Gennis376590d2011-01-13 14:43:36 -0800358static void SurfaceTexture_getTransformMatrix(JNIEnv* env, jobject thiz,
Jamie Gennisb0ba48c2011-01-09 18:22:05 -0800359 jfloatArray jmtx)
360{
Andy McFaddend47f7d82012-12-18 09:48:38 -0800361 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Jamie Gennisb0ba48c2011-01-09 18:22:05 -0800362 float* mtx = env->GetFloatArrayElements(jmtx, NULL);
363 surfaceTexture->getTransformMatrix(mtx);
364 env->ReleaseFloatArrayElements(jmtx, mtx, 0);
365}
366
Eino-Ville Talvalac5f94d82011-02-18 11:02:42 -0800367static jlong SurfaceTexture_getTimestamp(JNIEnv* env, jobject thiz)
368{
Andy McFaddend47f7d82012-12-18 09:48:38 -0800369 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Eino-Ville Talvalac5f94d82011-02-18 11:02:42 -0800370 return surfaceTexture->getTimestamp();
371}
372
Mathias Agopianec46b4e2011-08-03 15:18:36 -0700373static void SurfaceTexture_release(JNIEnv* env, jobject thiz)
374{
Andy McFaddend47f7d82012-12-18 09:48:38 -0800375 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
Mathias Agopianec46b4e2011-08-03 15:18:36 -0700376 surfaceTexture->abandon();
377}
378
John Reck6d8371e2015-05-14 15:47:03 -0700379static jboolean SurfaceTexture_isReleased(JNIEnv* env, jobject thiz)
380{
381 sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
382 return surfaceTexture->isAbandoned();
383}
384
Jamie Gennis6714efc2010-12-20 12:09:37 -0800385// ----------------------------------------------------------------------------
386
Daniel Micay76f6a862015-09-19 17:31:01 -0400387static const JNINativeMethod gSurfaceTextureMethods[] = {
Dan Stoza493f2e12014-06-26 13:36:19 -0700388 {"nativeInit", "(ZIZLjava/lang/ref/WeakReference;)V", (void*)SurfaceTexture_init },
Jamie Gennisc6d99302012-04-05 11:34:02 -0700389 {"nativeFinalize", "()V", (void*)SurfaceTexture_finalize },
tedbo05031612011-06-06 16:02:47 -0700390 {"nativeSetDefaultBufferSize", "(II)V", (void*)SurfaceTexture_setDefaultBufferSize },
Jamie Gennis2b4bfa52012-04-13 14:48:22 -0700391 {"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage },
Mathias Agopiane591b492013-07-24 19:15:00 -0700392 {"nativeReleaseTexImage", "()V", (void*)SurfaceTexture_releaseTexImage },
Jamie Gennisc6d99302012-04-05 11:34:02 -0700393 {"nativeDetachFromGLContext", "()I", (void*)SurfaceTexture_detachFromGLContext },
394 {"nativeAttachToGLContext", "(I)I", (void*)SurfaceTexture_attachToGLContext },
395 {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
396 {"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
397 {"nativeRelease", "()V", (void*)SurfaceTexture_release },
John Reck6d8371e2015-05-14 15:47:03 -0700398 {"nativeIsReleased", "()Z", (void*)SurfaceTexture_isReleased },
Jamie Gennis6714efc2010-12-20 12:09:37 -0800399};
400
Jamie Gennis6714efc2010-12-20 12:09:37 -0800401int register_android_graphics_SurfaceTexture(JNIEnv* env)
402{
Andreas Gampea7993242017-02-20 16:18:24 -0800403 // Cache some fields.
404 ScopedLocalRef<jclass> klass(env, FindClassOrDie(env, kSurfaceTextureClassPathName));
405 SurfaceTexture_classInit(env, klass.get());
406
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800407 return RegisterMethodsOrDie(env, kSurfaceTextureClassPathName, gSurfaceTextureMethods,
408 NELEM(gSurfaceTextureMethods));
Jamie Gennis6714efc2010-12-20 12:09:37 -0800409}
410
411} // namespace android