blob: 9bb8195b8901501d736d88df0d2dca76a038d2bd [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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
Mathias Agopianfae5cb22010-06-04 18:26:32 -070017#define LOG_TAG "Surface"
18
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019#include <stdio.h>
20
Mathias Agopian3866f0d2013-02-11 22:08:48 -080021#include "jni.h"
22#include "JNIHelp.h"
Jeff Brown64a55af2012-08-26 02:47:39 -070023#include "android_os_Parcel.h"
Dianne Hackborna1111872010-11-23 20:55:11 -080024#include "android/graphics/GraphicsJNI.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025
Mathias Agopian3866f0d2013-02-11 22:08:48 -080026#include <android_runtime/AndroidRuntime.h>
27#include <android_runtime/android_view_Surface.h>
28#include <android_runtime/android_graphics_SurfaceTexture.h>
Ruben Brunk87eac992013-09-09 17:44:59 -070029#include <android_runtime/Log.h>
Mathias Agopian8335f1c2012-02-25 18:48:35 -080030
Mathias Agopian4a05f432013-03-12 18:43:34 -070031#include <binder/Parcel.h>
32
Mathias Agopian8335f1c2012-02-25 18:48:35 -080033#include <gui/Surface.h>
Mathias Agopian52800612013-02-14 17:11:20 -080034#include <gui/SurfaceControl.h>
Andy McFaddend47f7d82012-12-18 09:48:38 -080035#include <gui/GLConsumer.h>
Mathias Agopian8335f1c2012-02-25 18:48:35 -080036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037#include <ui/Rect.h>
Mathias Agopian8335f1c2012-02-25 18:48:35 -080038#include <ui/Region.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039
40#include <SkCanvas.h>
41#include <SkBitmap.h>
Leon Scroggins III8790be62013-12-03 16:26:51 -050042#include <SkImage.h>
Mathias Agopian6158b1b2009-05-11 00:03:41 -070043#include <SkRegion.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045#include <utils/misc.h>
Jeff Brown9e316a12012-10-08 19:17:06 -070046#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047
Jeff Brown64a55af2012-08-26 02:47:39 -070048#include <ScopedUtfChars.h>
49
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050// ----------------------------------------------------------------------------
51
52namespace android {
53
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054static const char* const OutOfResourcesException =
55 "android/view/Surface$OutOfResourcesException";
56
Jeff Brown64a55af2012-08-26 02:47:39 -070057static struct {
58 jclass clazz;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080059 jfieldID mNativeObject;
Jeff Brownfc0ebd72013-04-30 16:33:00 -070060 jfieldID mLock;
Jeff Browncbad9762012-09-04 21:57:59 -070061 jmethodID ctor;
Jeff Brown64a55af2012-08-26 02:47:39 -070062} gSurfaceClassInfo;
tedbo05031612011-06-06 16:02:47 -070063
Jeff Brown64a55af2012-08-26 02:47:39 -070064static struct {
65 jfieldID left;
66 jfieldID top;
67 jfieldID right;
68 jfieldID bottom;
69} gRectClassInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
Jeff Brown64a55af2012-08-26 02:47:39 -070071static struct {
Jeff Brown64a55af2012-08-26 02:47:39 -070072 jfieldID mSurfaceFormat;
Florin Malita5c3d9272014-05-08 10:35:36 -040073 jmethodID setNativeBitmap;
Jeff Brown64a55af2012-08-26 02:47:39 -070074} gCanvasClassInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075
Jeff Brown64a55af2012-08-26 02:47:39 -070076// ----------------------------------------------------------------------------
77
Mathias Agopianb1d90c82013-03-06 17:45:42 -080078// this is just a pointer we use to pass to inc/decStrong
79static const void *sRefBaseOwner;
80
Jeff Brown64a55af2012-08-26 02:47:39 -070081bool android_view_Surface_isInstanceOf(JNIEnv* env, jobject obj) {
82 return env->IsInstanceOf(obj, gSurfaceClassInfo.clazz);
83}
84
Mathias Agopian3866f0d2013-02-11 22:08:48 -080085sp<ANativeWindow> android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) {
86 return android_view_Surface_getSurface(env, surfaceObj);
87}
88
Jeff Brown64a55af2012-08-26 02:47:39 -070089sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) {
Mathias Agopian7c116b52013-03-18 20:27:02 -070090 sp<Surface> sur;
91 jobject lock = env->GetObjectField(surfaceObj,
Jeff Brownfc0ebd72013-04-30 16:33:00 -070092 gSurfaceClassInfo.mLock);
Mathias Agopian7c116b52013-03-18 20:27:02 -070093 if (env->MonitorEnter(lock) == JNI_OK) {
94 sur = reinterpret_cast<Surface *>(
Ashok Bhat36bef0b2014-01-20 20:08:01 +000095 env->GetLongField(surfaceObj, gSurfaceClassInfo.mNativeObject));
Mathias Agopian7c116b52013-03-18 20:27:02 -070096 env->MonitorExit(lock);
97 }
Andy McFadden5ad3ab82014-06-11 15:22:32 -070098 env->DeleteLocalRef(lock);
Mathias Agopian7c116b52013-03-18 20:27:02 -070099 return sur;
Jeff Browncbad9762012-09-04 21:57:59 -0700100}
101
Mathias Agopian29479eb2013-02-14 14:36:04 -0800102jobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env,
Andy McFaddend47f7d82012-12-18 09:48:38 -0800103 const sp<IGraphicBufferProducer>& bufferProducer) {
104 if (bufferProducer == NULL) {
Jeff Browncbad9762012-09-04 21:57:59 -0700105 return NULL;
106 }
107
Mathias Agopiane3263262013-07-16 22:54:56 -0700108 sp<Surface> surface(new Surface(bufferProducer, true));
Jeff Browncbad9762012-09-04 21:57:59 -0700109 if (surface == NULL) {
110 return NULL;
111 }
112
Chong Zhangaf608e82014-01-29 12:52:15 -0800113 jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz,
114 gSurfaceClassInfo.ctor, (jlong)surface.get());
Jeff Browncbad9762012-09-04 21:57:59 -0700115 if (surfaceObj == NULL) {
116 if (env->ExceptionCheck()) {
Andy McFaddend47f7d82012-12-18 09:48:38 -0800117 ALOGE("Could not create instance of Surface from IGraphicBufferProducer.");
Jeff Browncbad9762012-09-04 21:57:59 -0700118 LOGE_EX(env);
119 env->ExceptionClear();
120 }
121 return NULL;
122 }
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800123 surface->incStrong(&sRefBaseOwner);
Jeff Browncbad9762012-09-04 21:57:59 -0700124 return surfaceObj;
125}
126
Jeff Brown64a55af2012-08-26 02:47:39 -0700127// ----------------------------------------------------------------------------
128
Mathias Agopianf3d3b4d2013-02-19 18:26:15 -0800129static inline bool isSurfaceValid(const sp<Surface>& sur) {
130 return Surface::isValid(sur);
Mathias Agopian52800612013-02-14 17:11:20 -0800131}
132
133// ----------------------------------------------------------------------------
134
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000135static jlong nativeCreateFromSurfaceTexture(JNIEnv* env, jclass clazz,
Jeff Brown64a55af2012-08-26 02:47:39 -0700136 jobject surfaceTextureObj) {
Mathias Agopian52a9a102013-08-02 01:38:38 -0700137 sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, surfaceTextureObj));
138 if (producer == NULL) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700139 jniThrowException(env, "java/lang/IllegalArgumentException",
140 "SurfaceTexture has already been released");
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800141 return 0;
Jeff Brown64a55af2012-08-26 02:47:39 -0700142 }
143
Mathias Agopian52a9a102013-08-02 01:38:38 -0700144 sp<Surface> surface(new Surface(producer, true));
Jeff Brown64a55af2012-08-26 02:47:39 -0700145 if (surface == NULL) {
146 jniThrowException(env, OutOfResourcesException, NULL);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800147 return 0;
Jeff Brown64a55af2012-08-26 02:47:39 -0700148 }
149
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800150 surface->incStrong(&sRefBaseOwner);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000151 return jlong(surface.get());
Jeff Brown64a55af2012-08-26 02:47:39 -0700152}
153
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000154static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800155 sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800156 sur->decStrong(&sRefBaseOwner);
Jeff Brown64a55af2012-08-26 02:47:39 -0700157}
158
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000159static jboolean nativeIsValid(JNIEnv* env, jclass clazz, jlong nativeObject) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800160 sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
Mathias Agopian52800612013-02-14 17:11:20 -0800161 return isSurfaceValid(sur) ? JNI_TRUE : JNI_FALSE;
Jeff Brown64a55af2012-08-26 02:47:39 -0700162}
163
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000164static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jclass clazz, jlong nativeObject) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800165 sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
Mathias Agopian52800612013-02-14 17:11:20 -0800166 if (!isSurfaceValid(sur)) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700167 doThrowIAE(env);
168 return JNI_FALSE;
169 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700170 int value = 0;
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800171 ANativeWindow* anw = static_cast<ANativeWindow*>(sur.get());
Jeff Brown64a55af2012-08-26 02:47:39 -0700172 anw->query(anw, NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value);
173 return value;
174}
175
Mike Reedb9330552014-06-16 17:31:48 -0400176static inline SkColorType convertPixelFormat(PixelFormat format) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700177 /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
Mike Reedb9330552014-06-16 17:31:48 -0400178 we can map to kN32_SkColorType, and optionally call
Leon Scroggins III8790be62013-12-03 16:26:51 -0500179 bitmap.setAlphaType(kOpaque_SkAlphaType) on the resulting SkBitmap
180 (as an accelerator)
Jeff Brown64a55af2012-08-26 02:47:39 -0700181 */
182 switch (format) {
Mike Reedb9330552014-06-16 17:31:48 -0400183 case PIXEL_FORMAT_RGBX_8888: return kN32_SkColorType;
184 case PIXEL_FORMAT_RGBA_8888: return kN32_SkColorType;
185 case PIXEL_FORMAT_RGB_565: return kRGB_565_SkColorType;
186 default: return kUnknown_SkColorType;
Jeff Brown64a55af2012-08-26 02:47:39 -0700187 }
188}
189
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000190static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
191 jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800192 sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
193
Mathias Agopian52800612013-02-14 17:11:20 -0800194 if (!isSurfaceValid(surface)) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700195 doThrowIAE(env);
Andy McFaddened55c8d2013-08-20 10:05:51 -0700196 return 0;
Jeff Brown64a55af2012-08-26 02:47:39 -0700197 }
198
Mathias Agopian667809e2013-04-17 14:57:41 -0700199 Rect dirtyRect;
200 Rect* dirtyRectPtr = NULL;
201
Jeff Brown64a55af2012-08-26 02:47:39 -0700202 if (dirtyRectObj) {
Mathias Agopian667809e2013-04-17 14:57:41 -0700203 dirtyRect.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
204 dirtyRect.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
205 dirtyRect.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
206 dirtyRect.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
207 dirtyRectPtr = &dirtyRect;
Jeff Brown64a55af2012-08-26 02:47:39 -0700208 }
209
Mathias Agopian52800612013-02-14 17:11:20 -0800210 ANativeWindow_Buffer outBuffer;
Mathias Agopian667809e2013-04-17 14:57:41 -0700211 status_t err = surface->lock(&outBuffer, dirtyRectPtr);
Jeff Brown64a55af2012-08-26 02:47:39 -0700212 if (err < 0) {
213 const char* const exception = (err == NO_MEMORY) ?
214 OutOfResourcesException :
215 "java/lang/IllegalArgumentException";
216 jniThrowException(env, exception, NULL);
Andy McFaddened55c8d2013-08-20 10:05:51 -0700217 return 0;
Jeff Brown64a55af2012-08-26 02:47:39 -0700218 }
219
220 // Associate a SkCanvas object to this surface
Mathias Agopian52800612013-02-14 17:11:20 -0800221 env->SetIntField(canvasObj, gCanvasClassInfo.mSurfaceFormat, outBuffer.format);
Jeff Brown64a55af2012-08-26 02:47:39 -0700222
Mike Reedb9330552014-06-16 17:31:48 -0400223 SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
224 convertPixelFormat(outBuffer.format),
225 kPremul_SkAlphaType);
226 if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) {
227 info.fAlphaType = kOpaque_SkAlphaType;
228 }
229
Jeff Brown64a55af2012-08-26 02:47:39 -0700230 SkBitmap bitmap;
Mathias Agopian52800612013-02-14 17:11:20 -0800231 ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
Mike Reedb9330552014-06-16 17:31:48 -0400232 bitmap.setInfo(info, bpr);
Mathias Agopian52800612013-02-14 17:11:20 -0800233 if (outBuffer.width > 0 && outBuffer.height > 0) {
234 bitmap.setPixels(outBuffer.bits);
Jeff Brown64a55af2012-08-26 02:47:39 -0700235 } else {
236 // be safe with an empty bitmap.
237 bitmap.setPixels(NULL);
238 }
Derek Sollenbergerfc615a02012-12-20 14:39:57 -0500239
Florin Malita5c3d9272014-05-08 10:35:36 -0400240 env->CallVoidMethod(canvasObj, gCanvasClassInfo.setNativeBitmap,
241 reinterpret_cast<jlong>(&bitmap));
Jeff Brown64a55af2012-08-26 02:47:39 -0700242
Mathias Agopian667809e2013-04-17 14:57:41 -0700243 if (dirtyRectPtr) {
Florin Malita5c3d9272014-05-08 10:35:36 -0400244 SkCanvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
Mathias Agopian667809e2013-04-17 14:57:41 -0700245 nativeCanvas->clipRect( SkRect::Make(reinterpret_cast<const SkIRect&>(dirtyRect)) );
Jeff Brown64a55af2012-08-26 02:47:39 -0700246 }
247
Jeff Brown64a55af2012-08-26 02:47:39 -0700248 if (dirtyRectObj) {
Mathias Agopian667809e2013-04-17 14:57:41 -0700249 env->SetIntField(dirtyRectObj, gRectClassInfo.left, dirtyRect.left);
250 env->SetIntField(dirtyRectObj, gRectClassInfo.top, dirtyRect.top);
251 env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right);
252 env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom);
Jeff Brown64a55af2012-08-26 02:47:39 -0700253 }
Andy McFaddened55c8d2013-08-20 10:05:51 -0700254
255 // Create another reference to the surface and return it. This reference
256 // should be passed to nativeUnlockCanvasAndPost in place of mNativeObject,
257 // because the latter could be replaced while the surface is locked.
258 sp<Surface> lockedSurface(surface);
259 lockedSurface->incStrong(&sRefBaseOwner);
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000260 return (jlong) lockedSurface.get();
Jeff Brown64a55af2012-08-26 02:47:39 -0700261}
262
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700263static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000264 jlong nativeObject, jobject canvasObj) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800265 sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
Mathias Agopian52800612013-02-14 17:11:20 -0800266 if (!isSurfaceValid(surface)) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700267 return;
268 }
269
270 // detach the canvas from the surface
Florin Malita5c3d9272014-05-08 10:35:36 -0400271 env->CallVoidMethod(canvasObj, gCanvasClassInfo.setNativeBitmap, (jlong)0);
Jeff Brown64a55af2012-08-26 02:47:39 -0700272
273 // unlock surface
274 status_t err = surface->unlockAndPost();
275 if (err < 0) {
276 doThrowIAE(env);
277 }
278}
279
Dan Stoza5795d642014-06-20 13:01:36 -0700280static void nativeAllocateBuffers(JNIEnv* /* env */ , jclass /* clazz */,
281 jlong nativeObject) {
282 sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
283 if (!isSurfaceValid(surface)) {
284 return;
285 }
286
287 surface->allocateBuffers();
288}
289
Mathias Agopian17f638b2009-04-16 20:04:08 -0700290// ----------------------------------------------------------------------------
291
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000292static jlong nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz,
293 jlong surfaceControlNativeObj) {
Mathias Agopian17f638b2009-04-16 20:04:08 -0700294 /*
295 * This is used by the WindowManagerService just after constructing
296 * a Surface and is necessary for returning the Surface reference to
297 * the caller. At this point, we should only have a SurfaceControl.
Mathias Agopian17f638b2009-04-16 20:04:08 -0700298 */
Mathias Agopianfae5cb22010-06-04 18:26:32 -0700299
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800300 sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700301 sp<Surface> surface(ctrl->getSurface());
302 if (surface != NULL) {
303 surface->incStrong(&sRefBaseOwner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 }
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000305 return reinterpret_cast<jlong>(surface.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306}
307
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000308static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz,
309 jlong nativeObject, jobject parcelObj) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800310 Parcel* parcel = parcelForJavaObject(env, parcelObj);
311 if (parcel == NULL) {
312 doThrowNPE(env);
313 return 0;
314 }
Mathias Agopianc3b9cd62013-03-13 16:07:57 -0700315
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800316 sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
Mathias Agopianc3b9cd62013-03-13 16:07:57 -0700317 sp<IBinder> binder(parcel->readStrongBinder());
318
319 // update the Surface only if the underlying IGraphicBufferProducer
320 // has changed.
321 if (self != NULL
322 && (self->getIGraphicBufferProducer()->asBinder() == binder)) {
323 // same IGraphicBufferProducer, return ourselves
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000324 return jlong(self.get());
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800325 }
Mathias Agopian4a05f432013-03-12 18:43:34 -0700326
327 sp<Surface> sur;
Mathias Agopianc3b9cd62013-03-13 16:07:57 -0700328 sp<IGraphicBufferProducer> gbp(interface_cast<IGraphicBufferProducer>(binder));
Mathias Agopian4a05f432013-03-12 18:43:34 -0700329 if (gbp != NULL) {
Mathias Agopianc3b9cd62013-03-13 16:07:57 -0700330 // we have a new IGraphicBufferProducer, create a new Surface for it
Mathias Agopiane3263262013-07-16 22:54:56 -0700331 sur = new Surface(gbp, true);
Mathias Agopianc3b9cd62013-03-13 16:07:57 -0700332 // and keep a reference before passing to java
Mathias Agopianb1d90c82013-03-06 17:45:42 -0800333 sur->incStrong(&sRefBaseOwner);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800334 }
Mathias Agopian4a05f432013-03-12 18:43:34 -0700335
Mathias Agopianc3b9cd62013-03-13 16:07:57 -0700336 if (self != NULL) {
337 // and loose the java reference to ourselves
338 self->decStrong(&sRefBaseOwner);
339 }
340
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000341 return jlong(sur.get());
Dianne Hackborn61566cc2011-12-02 23:31:52 -0800342}
343
Mathias Agopian29479eb2013-02-14 14:36:04 -0800344static void nativeWriteToParcel(JNIEnv* env, jclass clazz,
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000345 jlong nativeObject, jobject parcelObj) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700346 Parcel* parcel = parcelForJavaObject(env, parcelObj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 if (parcel == NULL) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700348 doThrowNPE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 return;
350 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800351 sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
Mathias Agopian4a05f432013-03-12 18:43:34 -0700352 parcel->writeStrongBinder( self != 0 ? self->getIGraphicBufferProducer()->asBinder() : NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353}
354
355// ----------------------------------------------------------------------------
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356
357static JNINativeMethod gSurfaceMethods[] = {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000358 {"nativeCreateFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)J",
Jeff Brown64a55af2012-08-26 02:47:39 -0700359 (void*)nativeCreateFromSurfaceTexture },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000360 {"nativeRelease", "(J)V",
Jeff Brown64a55af2012-08-26 02:47:39 -0700361 (void*)nativeRelease },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000362 {"nativeIsValid", "(J)Z",
Jeff Brown64a55af2012-08-26 02:47:39 -0700363 (void*)nativeIsValid },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000364 {"nativeIsConsumerRunningBehind", "(J)Z",
Jeff Brown64a55af2012-08-26 02:47:39 -0700365 (void*)nativeIsConsumerRunningBehind },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000366 {"nativeLockCanvas", "(JLandroid/graphics/Canvas;Landroid/graphics/Rect;)J",
Jeff Brown64a55af2012-08-26 02:47:39 -0700367 (void*)nativeLockCanvas },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000368 {"nativeUnlockCanvasAndPost", "(JLandroid/graphics/Canvas;)V",
Jeff Brown64a55af2012-08-26 02:47:39 -0700369 (void*)nativeUnlockCanvasAndPost },
Dan Stoza5795d642014-06-20 13:01:36 -0700370 {"nativeAllocateBuffers", "(J)V",
371 (void*)nativeAllocateBuffers },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000372 {"nativeCreateFromSurfaceControl", "(J)J",
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700373 (void*)nativeCreateFromSurfaceControl },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000374 {"nativeReadFromParcel", "(JLandroid/os/Parcel;)J",
Jeff Brown64a55af2012-08-26 02:47:39 -0700375 (void*)nativeReadFromParcel },
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000376 {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
Jeff Brown64a55af2012-08-26 02:47:39 -0700377 (void*)nativeWriteToParcel },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378};
379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380int register_android_view_Surface(JNIEnv* env)
381{
Jeff Brown64a55af2012-08-26 02:47:39 -0700382 int err = AndroidRuntime::registerNativeMethods(env, "android/view/Surface",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 gSurfaceMethods, NELEM(gSurfaceMethods));
Jeff Brown64a55af2012-08-26 02:47:39 -0700384
385 jclass clazz = env->FindClass("android/view/Surface");
386 gSurfaceClassInfo.clazz = jclass(env->NewGlobalRef(clazz));
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800387 gSurfaceClassInfo.mNativeObject =
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000388 env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeObject", "J");
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700389 gSurfaceClassInfo.mLock =
390 env->GetFieldID(gSurfaceClassInfo.clazz, "mLock", "Ljava/lang/Object;");
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000391 gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "(J)V");
Jeff Brown64a55af2012-08-26 02:47:39 -0700392
393 clazz = env->FindClass("android/graphics/Canvas");
Jeff Brown64a55af2012-08-26 02:47:39 -0700394 gCanvasClassInfo.mSurfaceFormat = env->GetFieldID(clazz, "mSurfaceFormat", "I");
Florin Malita5c3d9272014-05-08 10:35:36 -0400395 gCanvasClassInfo.setNativeBitmap = env->GetMethodID(clazz, "setNativeBitmap", "(J)V");
Derek Sollenbergerfc615a02012-12-20 14:39:57 -0500396
Jeff Brown64a55af2012-08-26 02:47:39 -0700397 clazz = env->FindClass("android/graphics/Rect");
398 gRectClassInfo.left = env->GetFieldID(clazz, "left", "I");
399 gRectClassInfo.top = env->GetFieldID(clazz, "top", "I");
400 gRectClassInfo.right = env->GetFieldID(clazz, "right", "I");
401 gRectClassInfo.bottom = env->GetFieldID(clazz, "bottom", "I");
402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 return err;
404}
405
406};