• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 #include <android/surface_texture.h>
18 #include <android/surface_texture_jni.h>
19 
20 #define LOG_TAG "ASurfaceTexture"
21 
22 #include <utils/Log.h>
23 
24 #include <gui/Surface.h>
25 
26 #include <surfacetexture/surface_texture_platform.h>
27 #include <surfacetexture/SurfaceTexture.h>
28 
29 #include <mutex>
30 
31 #include <jni.h>
32 #include <nativehelper/scoped_local_ref.h>
33 
34 struct ASurfaceTexture {
35     android::sp<android::SurfaceTexture> consumer;
36     android::sp<android::IGraphicBufferProducer> producer;
37 };
38 
39 using namespace android;
40 
41 const char* const kSurfaceTextureClassPathName = "android/graphics/SurfaceTexture";
42 
43 struct fields_t {
44     jfieldID  surfaceTexture;
45     jfieldID  producer;
46 };
47 static fields_t fields;
48 static std::once_flag sInitFieldsOnce;
49 
50 #define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
51 #define ANDROID_GRAPHICS_PRODUCER_JNI_ID "mProducer"
52 
SurfaceTexture_classInit(JNIEnv * env,jclass clazz)53 static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz)
54 {
55     fields.surfaceTexture = env->GetFieldID(clazz,
56             ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "J");
57     if (fields.surfaceTexture == NULL) {
58         ALOGE("can't find android/graphics/SurfaceTexture.%s",
59                 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
60     }
61     fields.producer = env->GetFieldID(clazz,
62             ANDROID_GRAPHICS_PRODUCER_JNI_ID, "J");
63     if (fields.producer == NULL) {
64         ALOGE("can't find android/graphics/SurfaceTexture.%s",
65                 ANDROID_GRAPHICS_PRODUCER_JNI_ID);
66     }
67 }
68 
FindClassOrDie(JNIEnv * env,const char * class_name)69 static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
70     jclass clazz = env->FindClass(class_name);
71     LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
72     return clazz;
73 }
74 
register_android_graphics_SurfaceTexture(JNIEnv * env)75 static void register_android_graphics_SurfaceTexture(JNIEnv* env)
76 {
77     // Cache some fields.
78     ScopedLocalRef<jclass> klass(env, FindClassOrDie(env, kSurfaceTextureClassPathName));
79     SurfaceTexture_classInit(env, klass.get());
80 }
81 
android_SurfaceTexture_isInstanceOf(JNIEnv * env,jobject thiz)82 static bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) {
83     std::call_once(sInitFieldsOnce, [=]() {
84         register_android_graphics_SurfaceTexture(env);
85     });
86 
87     jclass surfaceTextureClass = env->FindClass(kSurfaceTextureClassPathName);
88     return env->IsInstanceOf(thiz, surfaceTextureClass);
89 }
90 
SurfaceTexture_getSurfaceTexture(JNIEnv * env,jobject thiz)91 static sp<SurfaceTexture> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) {
92     std::call_once(sInitFieldsOnce, [=]() {
93         register_android_graphics_SurfaceTexture(env);
94     });
95 
96     return (SurfaceTexture*)env->GetLongField(thiz, fields.surfaceTexture);
97 }
98 
SurfaceTexture_getProducer(JNIEnv * env,jobject thiz)99 static sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz) {
100     std::call_once(sInitFieldsOnce, [=]() {
101         register_android_graphics_SurfaceTexture(env);
102     });
103 
104     return (IGraphicBufferProducer*)env->GetLongField(thiz, fields.producer);
105 }
106 
107 // The following functions implement NDK API.
ASurfaceTexture_fromSurfaceTexture(JNIEnv * env,jobject surfacetexture)108 ASurfaceTexture* ASurfaceTexture_fromSurfaceTexture(JNIEnv* env, jobject surfacetexture) {
109     if (!surfacetexture || !android_SurfaceTexture_isInstanceOf(env, surfacetexture)) {
110         return nullptr;
111     }
112     ASurfaceTexture* ast = new ASurfaceTexture;
113     ast->consumer = SurfaceTexture_getSurfaceTexture(env, surfacetexture);
114     ast->producer = SurfaceTexture_getProducer(env, surfacetexture);
115     return ast;
116 }
117 
ASurfaceTexture_acquireANativeWindow(ASurfaceTexture * st)118 ANativeWindow* ASurfaceTexture_acquireANativeWindow(ASurfaceTexture* st) {
119     sp<Surface> surface = new Surface(st->producer);
120     ANativeWindow* win(surface.get());
121     ANativeWindow_acquire(win);
122     return win;
123 }
124 
ASurfaceTexture_release(ASurfaceTexture * st)125 void ASurfaceTexture_release(ASurfaceTexture* st) {
126     delete st;
127 }
128 
ASurfaceTexture_attachToGLContext(ASurfaceTexture * st,uint32_t tex)129 int ASurfaceTexture_attachToGLContext(ASurfaceTexture* st, uint32_t tex) {
130     return st->consumer->attachToContext(tex);
131 }
132 
ASurfaceTexture_detachFromGLContext(ASurfaceTexture * st)133 int ASurfaceTexture_detachFromGLContext(ASurfaceTexture* st) {
134     return st->consumer->detachFromContext();
135 }
136 
ASurfaceTexture_updateTexImage(ASurfaceTexture * st)137 int ASurfaceTexture_updateTexImage(ASurfaceTexture* st) {
138     return st->consumer->updateTexImage();
139 }
140 
ASurfaceTexture_getTransformMatrix(ASurfaceTexture * st,float mtx[16])141 void ASurfaceTexture_getTransformMatrix(ASurfaceTexture* st, float mtx[16]) {
142     st->consumer->getTransformMatrix(mtx);
143 }
144 
ASurfaceTexture_getTimestamp(ASurfaceTexture * st)145 int64_t ASurfaceTexture_getTimestamp(ASurfaceTexture* st) {
146     return st->consumer->getTimestamp();
147 }
148 
149 // The following functions are private/unstable API.
150 namespace android {
ASurfaceTexture_routeAcquireANativeWindow(ASurfaceTexture * st)151 ANativeWindow* ASurfaceTexture_routeAcquireANativeWindow(ASurfaceTexture* st) {
152     return ASurfaceTexture_acquireANativeWindow(st);
153 }
154 
ASurfaceTexture_routeAttachToGLContext(ASurfaceTexture * st,uint32_t texName)155 int ASurfaceTexture_routeAttachToGLContext(ASurfaceTexture* st, uint32_t texName) {
156     return ASurfaceTexture_attachToGLContext(st, texName);
157 }
158 
ASurfaceTexture_routeRelease(ASurfaceTexture * st)159 void ASurfaceTexture_routeRelease(ASurfaceTexture* st) {
160     return ASurfaceTexture_release(st);
161 }
162 
ASurfaceTexture_routeDetachFromGLContext(ASurfaceTexture * st)163 int ASurfaceTexture_routeDetachFromGLContext(ASurfaceTexture* st) {
164     return ASurfaceTexture_detachFromGLContext(st);
165 }
166 
ASurfaceTexture_routeUpdateTexImage(ASurfaceTexture * st)167 int ASurfaceTexture_routeUpdateTexImage(ASurfaceTexture* st) {
168     return ASurfaceTexture_updateTexImage(st);
169 }
170 
ASurfaceTexture_routeGetTransformMatrix(ASurfaceTexture * st,float mtx[16])171 void ASurfaceTexture_routeGetTransformMatrix(ASurfaceTexture* st, float mtx[16]) {
172     return ASurfaceTexture_getTransformMatrix(st, mtx);
173 }
174 
ASurfaceTexture_routeGetTimestamp(ASurfaceTexture * st)175 int64_t ASurfaceTexture_routeGetTimestamp(ASurfaceTexture* st) {
176     return ASurfaceTexture_getTimestamp(st);
177 }
178 
ASurfaceTexture_routeFromSurfaceTexture(JNIEnv * env,jobject surfacetexture)179 ASurfaceTexture* ASurfaceTexture_routeFromSurfaceTexture(JNIEnv* env, jobject surfacetexture) {
180     return ASurfaceTexture_fromSurfaceTexture(env, surfacetexture);
181 }
182 
ASurfaceTexture_getCurrentTextureTarget(ASurfaceTexture * st)183 unsigned int ASurfaceTexture_getCurrentTextureTarget(ASurfaceTexture* st) {
184     return st->consumer->getCurrentTextureTarget();
185 }
186 
ASurfaceTexture_takeConsumerOwnership(ASurfaceTexture * texture)187 void ASurfaceTexture_takeConsumerOwnership(ASurfaceTexture* texture) {
188     texture->consumer->takeConsumerOwnership();
189 }
190 
ASurfaceTexture_releaseConsumerOwnership(ASurfaceTexture * texture)191 void ASurfaceTexture_releaseConsumerOwnership(ASurfaceTexture* texture) {
192     texture->consumer->releaseConsumerOwnership();
193 }
194 
ASurfaceTexture_dequeueBuffer(ASurfaceTexture * st,int * outSlotid,android_dataspace * outDataspace,AHdrMetadataType * outHdrType,android_cta861_3_metadata * outCta861_3,android_smpte2086_metadata * outSmpte2086,float * outTransformMatrix,uint32_t * outTransform,bool * outNewContent,ASurfaceTexture_createReleaseFence createFence,ASurfaceTexture_fenceWait fenceWait,void * handle,ARect * currentCrop)195 AHardwareBuffer* ASurfaceTexture_dequeueBuffer(
196         ASurfaceTexture* st, int* outSlotid, android_dataspace* outDataspace,
197         AHdrMetadataType* outHdrType, android_cta861_3_metadata* outCta861_3,
198         android_smpte2086_metadata* outSmpte2086, float* outTransformMatrix, uint32_t* outTransform,
199         bool* outNewContent, ASurfaceTexture_createReleaseFence createFence,
200         ASurfaceTexture_fenceWait fenceWait, void* handle, ARect* currentCrop) {
201     sp<GraphicBuffer> buffer;
202     *outNewContent = false;
203     bool queueEmpty;
204     do {
205         HdrMetadata metadata;
206         buffer = st->consumer->dequeueBuffer(outSlotid, outDataspace, &metadata, outTransformMatrix,
207                                              outTransform, &queueEmpty, createFence, fenceWait,
208                                              handle, currentCrop);
209         *outHdrType = static_cast<AHdrMetadataType>(metadata.validTypes);
210         *outCta861_3 = metadata.cta8613;
211         *outSmpte2086 = metadata.smpte2086;
212         if (!queueEmpty) {
213             *outNewContent = true;
214         }
215     } while (buffer.get() && (!queueEmpty));
216     AHardwareBuffer* result = nullptr;
217     if (buffer.get()) {
218       result = buffer->toAHardwareBuffer();
219       // add a reference to keep the hardware buffer alive, even if
220       // BufferQueueProducer is disconnected. This is needed, because
221       // sp reference is destroyed at the end of this function.
222       AHardwareBuffer_acquire(result);
223     }
224     return result;
225 }
226 
227 } // namespace android
228