blob: df81a311bb89f560fe8c354a0fbdbd0f04d97658 [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
17package android.view;
18
Tor Norbyed9273d62013-05-30 15:59:53 -070019import android.annotation.IntDef;
Mitsuru Oshima240f8a72009-07-22 20:39:14 -070020import android.content.res.CompatibilityInfo.Translator;
Jeff Brown0b722fe2012-08-24 22:40:14 -070021import android.graphics.Canvas;
Robert Carra35e5de2017-03-03 17:04:54 -080022import android.graphics.GraphicBuffer;
Jeff Brown0b722fe2012-08-24 22:40:14 -070023import android.graphics.Matrix;
24import android.graphics.Rect;
Jeff Brown0b722fe2012-08-24 22:40:14 -070025import android.graphics.SurfaceTexture;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.os.Parcel;
Mathias Agopian3866f0d2013-02-11 22:08:48 -080027import android.os.Parcelable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.util.Log;
Tor Norbyed9273d62013-05-30 15:59:53 -070029
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070030import dalvik.system.CloseGuard;
31
Tor Norbyed9273d62013-05-30 15:59:53 -070032import java.lang.annotation.Retention;
33import java.lang.annotation.RetentionPolicy;
34
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035/**
Glenn Kasten334031c2010-11-09 21:54:38 -080036 * Handle onto a raw buffer that is being managed by the screen compositor.
Eino-Ville Talvalac4faf0c2016-09-16 13:34:52 -070037 *
38 * <p>A Surface is generally created by or from a consumer of image buffers (such as a
39 * {@link android.graphics.SurfaceTexture}, {@link android.media.MediaRecorder}, or
40 * {@link android.renderscript.Allocation}), and is handed to some kind of producer (such as
41 * {@link android.opengl.EGL14#eglCreateWindowSurface(android.opengl.EGLDisplay,android.opengl.EGLConfig,java.lang.Object,int[],int) OpenGL},
42 * {@link android.media.MediaPlayer#setSurface MediaPlayer}, or
43 * {@link android.hardware.camera2.CameraDevice#createCaptureSession CameraDevice}) to draw
44 * into.</p>
45 *
46 * <p><strong>Note:</strong> A Surface acts like a
47 * {@link java.lang.ref.WeakReference weak reference} to the consumer it is associated with. By
48 * itself it will not keep its parent consumer from being reclaimed.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049 */
50public class Surface implements Parcelable {
Jeff Brown64a55af2012-08-26 02:47:39 -070051 private static final String TAG = "Surface";
Mathias Agopianb9230662011-08-03 14:44:48 -070052
Ashok Bhat36bef0b2014-01-20 20:08:01 +000053 private static native long nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
Mathias Agopian29479eb2013-02-14 14:36:04 -080054 throws OutOfResourcesException;
Bryce Lee02949f12017-06-16 07:20:34 -070055
Ashok Bhat36bef0b2014-01-20 20:08:01 +000056 private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject);
Bryce Lee02949f12017-06-16 07:20:34 -070057 private static native long nativeGetFromSurfaceControl(long surfaceControlNativeObject);
Mathias Agopian52800612013-02-14 17:11:20 -080058
Ashok Bhat36bef0b2014-01-20 20:08:01 +000059 private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
Jeff Brownfc0ebd72013-04-30 16:33:00 -070060 throws OutOfResourcesException;
Ashok Bhat36bef0b2014-01-20 20:08:01 +000061 private static native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas);
Mathias Agopian29479eb2013-02-14 14:36:04 -080062
Ashok Bhat36bef0b2014-01-20 20:08:01 +000063 private static native void nativeRelease(long nativeObject);
64 private static native boolean nativeIsValid(long nativeObject);
65 private static native boolean nativeIsConsumerRunningBehind(long nativeObject);
66 private static native long nativeReadFromParcel(long nativeObject, Parcel source);
67 private static native void nativeWriteToParcel(long nativeObject, Parcel dest);
Mathias Agopian29479eb2013-02-14 14:36:04 -080068
Dan Stoza5795d642014-06-20 13:01:36 -070069 private static native void nativeAllocateBuffers(long nativeObject);
70
John Reckb35c9602014-11-13 16:15:08 -080071 private static native int nativeGetWidth(long nativeObject);
72 private static native int nativeGetHeight(long nativeObject);
73
Rob Carr64e516f2015-10-29 00:20:45 +000074 private static native long nativeGetNextFrameNumber(long nativeObject);
Robert Carrcd9a18c2015-12-16 18:16:21 -080075 private static native int nativeSetScalingMode(long nativeObject, int scalingMode);
Robert Carr387838b2016-09-07 14:12:44 -070076 private static native int nativeForceScopedDisconnect(long nativeObject);
Robert Carra35e5de2017-03-03 17:04:54 -080077 private static native int nativeAttachAndQueueBuffer(long nativeObject, GraphicBuffer buffer);
Rob Carr64e516f2015-10-29 00:20:45 +000078
Romain Guy0bbf0b42017-07-20 08:57:07 -070079 private static native int nativeSetSharedBufferModeEnabled(long nativeObject, boolean enabled);
80 private static native int nativeSetAutoRefreshEnabled(long nativeObject, boolean enabled);
81
Jeff Brown64a55af2012-08-26 02:47:39 -070082 public static final Parcelable.Creator<Surface> CREATOR =
83 new Parcelable.Creator<Surface>() {
Jeff Brownfc0ebd72013-04-30 16:33:00 -070084 @Override
Jeff Brown64a55af2012-08-26 02:47:39 -070085 public Surface createFromParcel(Parcel source) {
86 try {
87 Surface s = new Surface();
88 s.readFromParcel(source);
89 return s;
90 } catch (Exception e) {
91 Log.e(TAG, "Exception creating surface from parcel", e);
92 return null;
93 }
Kevin Hesterb85c9332012-03-08 17:06:56 -080094 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -070095
96 @Override
Jeff Brown64a55af2012-08-26 02:47:39 -070097 public Surface[] newArray(int size) {
98 return new Surface[size];
99 }
100 };
Kevin Hesterb85c9332012-03-08 17:06:56 -0800101
Jeff Brown64a55af2012-08-26 02:47:39 -0700102 private final CloseGuard mCloseGuard = CloseGuard.get();
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700103
104 // Guarded state.
105 final Object mLock = new Object(); // protects the native state
Jeff Brown64a55af2012-08-26 02:47:39 -0700106 private String mName;
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000107 long mNativeObject; // package scope only for SurfaceControl access
108 private long mLockedObject;
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700109 private int mGenerationId; // incremented each time mNativeObject changes
Jeff Brown64a55af2012-08-26 02:47:39 -0700110 private final Canvas mCanvas = new CompatibleCanvas();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111
Mitsuru Oshima240f8a72009-07-22 20:39:14 -0700112 // A matrix to scale the matrix set by application. This is set to null for
113 // non compatibility mode.
114 private Matrix mCompatibleMatrix;
Mitsuru Oshima38ed7d772009-07-21 14:39:34 -0700115
John Reckbb2d0cc2014-10-21 10:09:36 -0700116 private HwuiContext mHwuiContext;
117
Pablo Ceballosaff2f942016-07-29 14:49:55 -0700118 private boolean mIsSingleBuffered;
Romain Guy0bbf0b42017-07-20 08:57:07 -0700119 private boolean mIsSharedBufferModeEnabled;
120 private boolean mIsAutoRefreshEnabled;
Pablo Ceballosaff2f942016-07-29 14:49:55 -0700121
Tor Norbyed9273d62013-05-30 15:59:53 -0700122 /** @hide */
Robert Carrcd9a18c2015-12-16 18:16:21 -0800123 @Retention(RetentionPolicy.SOURCE)
Jeff Sharkeyce8db992017-12-13 20:05:05 -0700124 @IntDef(prefix = { "SCALING_MODE_" }, value = {
125 SCALING_MODE_FREEZE,
126 SCALING_MODE_SCALE_TO_WINDOW,
127 SCALING_MODE_SCALE_CROP,
128 SCALING_MODE_NO_SCALE_CROP
129 })
Robert Carrcd9a18c2015-12-16 18:16:21 -0800130 public @interface ScalingMode {}
131 // From system/window.h
132 /** @hide */
Robert Carr1ca6a332016-04-11 18:00:43 -0700133 public static final int SCALING_MODE_FREEZE = 0;
Robert Carrcd9a18c2015-12-16 18:16:21 -0800134 /** @hide */
Robert Carr1ca6a332016-04-11 18:00:43 -0700135 public static final int SCALING_MODE_SCALE_TO_WINDOW = 1;
Robert Carrcd9a18c2015-12-16 18:16:21 -0800136 /** @hide */
Robert Carr1ca6a332016-04-11 18:00:43 -0700137 public static final int SCALING_MODE_SCALE_CROP = 2;
Robert Carrcd9a18c2015-12-16 18:16:21 -0800138 /** @hide */
Robert Carr1ca6a332016-04-11 18:00:43 -0700139 public static final int SCALING_MODE_NO_SCALE_CROP = 3;
Robert Carrcd9a18c2015-12-16 18:16:21 -0800140
141 /** @hide */
Jeff Sharkeyce8db992017-12-13 20:05:05 -0700142 @IntDef(prefix = { "ROTATION_" }, value = {
143 ROTATION_0,
144 ROTATION_90,
145 ROTATION_180,
146 ROTATION_270
147 })
Tor Norbyed9273d62013-05-30 15:59:53 -0700148 @Retention(RetentionPolicy.SOURCE)
149 public @interface Rotation {}
150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 /**
Mathias Agopian29479eb2013-02-14 14:36:04 -0800152 * Rotation constant: 0 degree rotation (natural orientation)
153 */
154 public static final int ROTATION_0 = 0;
155
156 /**
157 * Rotation constant: 90 degree rotation.
158 */
159 public static final int ROTATION_90 = 1;
160
161 /**
162 * Rotation constant: 180 degree rotation.
163 */
164 public static final int ROTATION_180 = 2;
165
166 /**
167 * Rotation constant: 270 degree rotation.
168 */
169 public static final int ROTATION_270 = 3;
170
Mathias Agopian29479eb2013-02-14 14:36:04 -0800171 /**
Jeff Brown64a55af2012-08-26 02:47:39 -0700172 * Create an empty surface, which will later be filled in by readFromParcel().
Mathias Agopianb9230662011-08-03 14:44:48 -0700173 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 */
175 public Surface() {
Jeff Brown64a55af2012-08-26 02:47:39 -0700176 }
177
178 /**
179 * Create Surface from a {@link SurfaceTexture}.
180 *
181 * Images drawn to the Surface will be made available to the {@link
182 * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link
183 * SurfaceTexture#updateTexImage}.
184 *
Eino-Ville Talvalaec99efa2017-11-29 15:35:42 -0800185 * Please note that holding onto the Surface created here is not enough to
186 * keep the provided SurfaceTexture from being reclaimed. In that sense,
187 * the Surface will act like a
188 * {@link java.lang.ref.WeakReference weak reference} to the SurfaceTexture.
189 *
Jeff Brown64a55af2012-08-26 02:47:39 -0700190 * @param surfaceTexture The {@link SurfaceTexture} that is updated by this
191 * Surface.
Igor Murashkina86ab6402013-08-30 12:58:36 -0700192 * @throws OutOfResourcesException if the surface could not be created.
Jeff Brown64a55af2012-08-26 02:47:39 -0700193 */
194 public Surface(SurfaceTexture surfaceTexture) {
195 if (surfaceTexture == null) {
196 throw new IllegalArgumentException("surfaceTexture must not be null");
197 }
Pablo Ceballosaff2f942016-07-29 14:49:55 -0700198 mIsSingleBuffered = surfaceTexture.isSingleBuffered();
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700199 synchronized (mLock) {
200 mName = surfaceTexture.toString();
Igor Murashkina86ab6402013-08-30 12:58:36 -0700201 setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
Jeff Brown64a55af2012-08-26 02:47:39 -0700202 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700203 }
204
Mathias Agopian86e1bc72013-03-13 17:48:22 -0700205 /* called from android_view_Surface_createFromIGraphicBufferProducer() */
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000206 private Surface(long nativeObject) {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700207 synchronized (mLock) {
208 setNativeObjectLocked(nativeObject);
209 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800210 }
211
Jeff Brown64a55af2012-08-26 02:47:39 -0700212 @Override
213 protected void finalize() throws Throwable {
214 try {
215 if (mCloseGuard != null) {
216 mCloseGuard.warnIfOpen();
217 }
Mathias Agopian86e1bc72013-03-13 17:48:22 -0700218 release();
Jeff Brown64a55af2012-08-26 02:47:39 -0700219 } finally {
220 super.finalize();
221 }
222 }
223
224 /**
225 * Release the local reference to the server-side surface.
226 * Always call release() when you're done with a Surface.
227 * This will make the surface invalid.
228 */
229 public void release() {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700230 synchronized (mLock) {
Mathias Agopian7c116b52013-03-18 20:27:02 -0700231 if (mNativeObject != 0) {
232 nativeRelease(mNativeObject);
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700233 setNativeObjectLocked(0);
Mathias Agopian7c116b52013-03-18 20:27:02 -0700234 }
John Reckbb2d0cc2014-10-21 10:09:36 -0700235 if (mHwuiContext != null) {
236 mHwuiContext.destroy();
237 mHwuiContext = null;
238 }
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800239 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700240 }
241
242 /**
243 * Free all server-side state associated with this surface and
244 * release this object's reference. This method can only be
245 * called from the process that created the service.
246 * @hide
247 */
248 public void destroy() {
Mathias Agopian86e1bc72013-03-13 17:48:22 -0700249 release();
Jeff Brown64a55af2012-08-26 02:47:39 -0700250 }
251
252 /**
Lucas Dupin41c25ce2018-03-27 09:50:19 -0700253 * Destroys the HwuiContext without completely
254 * releasing the Surface.
255 * @hide
256 */
257 public void hwuiDestroy() {
258 if (mHwuiContext != null) {
259 mHwuiContext.destroy();
260 mHwuiContext = null;
261 }
262 }
263
264 /**
Jeff Brown64a55af2012-08-26 02:47:39 -0700265 * Returns true if this object holds a valid surface.
266 *
267 * @return True if it holds a physical surface, so lockCanvas() will succeed.
268 * Otherwise returns false.
269 */
270 public boolean isValid() {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700271 synchronized (mLock) {
Mathias Agopian7c116b52013-03-18 20:27:02 -0700272 if (mNativeObject == 0) return false;
273 return nativeIsValid(mNativeObject);
274 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700275 }
276
277 /**
278 * Gets the generation number of this surface, incremented each time
279 * the native surface contained within this object changes.
280 *
281 * @return The current generation number.
282 * @hide
283 */
284 public int getGenerationId() {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700285 synchronized (mLock) {
286 return mGenerationId;
287 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700288 }
289
290 /**
Rob Carr64e516f2015-10-29 00:20:45 +0000291 * Returns the next frame number which will be dequeued for rendering.
292 * Intended for use with SurfaceFlinger's deferred transactions API.
293 *
294 * @hide
295 */
296 public long getNextFrameNumber() {
297 synchronized (mLock) {
Jorim Jaggi388090f2018-01-22 17:03:59 +0100298 checkNotReleasedLocked();
Rob Carr64e516f2015-10-29 00:20:45 +0000299 return nativeGetNextFrameNumber(mNativeObject);
300 }
301 }
302
303 /**
Jeff Brown64a55af2012-08-26 02:47:39 -0700304 * Returns true if the consumer of this Surface is running behind the producer.
305 *
306 * @return True if the consumer is more than one buffer ahead of the producer.
307 * @hide
308 */
309 public boolean isConsumerRunningBehind() {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700310 synchronized (mLock) {
Mathias Agopian7c116b52013-03-18 20:27:02 -0700311 checkNotReleasedLocked();
312 return nativeIsConsumerRunningBehind(mNativeObject);
313 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700314 }
315
316 /**
317 * Gets a {@link Canvas} for drawing into this surface.
318 *
Mathias Agopian9ddf32a2013-04-17 15:04:47 -0700319 * After drawing into the provided {@link Canvas}, the caller must
Jeff Brown64a55af2012-08-26 02:47:39 -0700320 * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
321 *
Mathias Agopian30d7ab92013-02-14 15:38:40 -0800322 * @param inOutDirty A rectangle that represents the dirty region that the caller wants
Jeff Brown64a55af2012-08-26 02:47:39 -0700323 * to redraw. This function may choose to expand the dirty rectangle if for example
324 * the surface has been resized or if the previous contents of the surface were
Mathias Agopian9ddf32a2013-04-17 15:04:47 -0700325 * not available. The caller must redraw the entire dirty region as represented
326 * by the contents of the inOutDirty rectangle upon return from this function.
Jeff Brown64a55af2012-08-26 02:47:39 -0700327 * The caller may also pass <code>null</code> instead, in the case where the
328 * entire surface should be redrawn.
329 * @return A canvas for drawing into the surface.
Igor Murashkina86ab6402013-08-30 12:58:36 -0700330 *
331 * @throws IllegalArgumentException If the inOutDirty rectangle is not valid.
332 * @throws OutOfResourcesException If the canvas cannot be locked.
Jeff Brown64a55af2012-08-26 02:47:39 -0700333 */
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800334 public Canvas lockCanvas(Rect inOutDirty)
Igor Murashkina86ab6402013-08-30 12:58:36 -0700335 throws Surface.OutOfResourcesException, IllegalArgumentException {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700336 synchronized (mLock) {
Mathias Agopian7c116b52013-03-18 20:27:02 -0700337 checkNotReleasedLocked();
Andy McFaddened55c8d2013-08-20 10:05:51 -0700338 if (mLockedObject != 0) {
339 // Ideally, nativeLockCanvas() would throw in this situation and prevent the
340 // double-lock, but that won't happen if mNativeObject was updated. We can't
341 // abandon the old mLockedObject because it might still be in use, so instead
342 // we just refuse to re-lock the Surface.
Jesse Halld7e55962014-10-13 11:01:15 -0700343 throw new IllegalArgumentException("Surface was already locked");
Andy McFaddened55c8d2013-08-20 10:05:51 -0700344 }
345 mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700346 return mCanvas;
Mathias Agopian7c116b52013-03-18 20:27:02 -0700347 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700348 }
349
350 /**
351 * Posts the new contents of the {@link Canvas} to the surface and
352 * releases the {@link Canvas}.
353 *
354 * @param canvas The canvas previously obtained from {@link #lockCanvas}.
355 */
356 public void unlockCanvasAndPost(Canvas canvas) {
John Reckbb2d0cc2014-10-21 10:09:36 -0700357 synchronized (mLock) {
358 checkNotReleasedLocked();
359
360 if (mHwuiContext != null) {
361 mHwuiContext.unlockAndPost(canvas);
362 } else {
363 unlockSwCanvasAndPost(canvas);
364 }
365 }
366 }
367
368 private void unlockSwCanvasAndPost(Canvas canvas) {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700369 if (canvas != mCanvas) {
370 throw new IllegalArgumentException("canvas object must be the same instance that "
371 + "was previously returned by lockCanvas");
372 }
John Reckbb2d0cc2014-10-21 10:09:36 -0700373 if (mNativeObject != mLockedObject) {
374 Log.w(TAG, "WARNING: Surface's mNativeObject (0x" +
375 Long.toHexString(mNativeObject) + ") != mLockedObject (0x" +
376 Long.toHexString(mLockedObject) +")");
377 }
378 if (mLockedObject == 0) {
379 throw new IllegalStateException("Surface was not locked");
380 }
381 try {
382 nativeUnlockCanvasAndPost(mLockedObject, canvas);
383 } finally {
384 nativeRelease(mLockedObject);
385 mLockedObject = 0;
386 }
387 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700388
John Reckbb2d0cc2014-10-21 10:09:36 -0700389 /**
390 * Gets a {@link Canvas} for drawing into this surface.
391 *
392 * After drawing into the provided {@link Canvas}, the caller must
393 * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
394 *
395 * Unlike {@link #lockCanvas(Rect)} this will return a hardware-accelerated
396 * canvas. See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported">
397 * unsupported drawing operations</a> for a list of what is and isn't
John Reck43a53282014-10-23 13:56:03 -0700398 * supported in a hardware-accelerated canvas. It is also required to
399 * fully cover the surface every time {@link #lockHardwareCanvas()} is
400 * called as the buffer is not preserved between frames. Partial updates
401 * are not supported.
John Reckbb2d0cc2014-10-21 10:09:36 -0700402 *
403 * @return A canvas for drawing into the surface.
404 *
405 * @throws IllegalStateException If the canvas cannot be locked.
406 */
407 public Canvas lockHardwareCanvas() {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700408 synchronized (mLock) {
Mathias Agopian7c116b52013-03-18 20:27:02 -0700409 checkNotReleasedLocked();
John Reckbb2d0cc2014-10-21 10:09:36 -0700410 if (mHwuiContext == null) {
Peiyong Lind8b68712018-03-06 18:34:21 -0800411 mHwuiContext = new HwuiContext(false);
412 }
413 return mHwuiContext.lockCanvas(
414 nativeGetWidth(mNativeObject),
415 nativeGetHeight(mNativeObject));
416 }
417 }
418
419 /**
420 * Gets a {@link Canvas} for drawing into this surface that supports wide color gamut.
421 *
422 * After drawing into the provided {@link Canvas}, the caller must
423 * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface.
424 *
425 * Unlike {@link #lockCanvas(Rect)} and {@link #lockHardwareCanvas()},
426 * this will return a hardware-accelerated canvas that supports wide color gamut.
427 * See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported">
428 * unsupported drawing operations</a> for a list of what is and isn't
429 * supported in a hardware-accelerated canvas. It is also required to
430 * fully cover the surface every time {@link #lockHardwareCanvas()} is
431 * called as the buffer is not preserved between frames. Partial updates
432 * are not supported.
433 *
434 * @return A canvas for drawing into the surface.
435 *
436 * @throws IllegalStateException If the canvas cannot be locked.
437 *
438 * @hide
439 */
440 public Canvas lockHardwareWideColorGamutCanvas() {
441 synchronized (mLock) {
442 checkNotReleasedLocked();
443 if (mHwuiContext != null && !mHwuiContext.isWideColorGamut()) {
444 mHwuiContext.destroy();
445 mHwuiContext = null;
446 }
447 if (mHwuiContext == null) {
448 mHwuiContext = new HwuiContext(true);
Andy McFaddened55c8d2013-08-20 10:05:51 -0700449 }
John Reckb35c9602014-11-13 16:15:08 -0800450 return mHwuiContext.lockCanvas(
451 nativeGetWidth(mNativeObject),
452 nativeGetHeight(mNativeObject));
Mathias Agopian7c116b52013-03-18 20:27:02 -0700453 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700454 }
455
Andy McFaddened55c8d2013-08-20 10:05:51 -0700456 /**
Jeff Brown64a55af2012-08-26 02:47:39 -0700457 * @deprecated This API has been removed and is not supported. Do not use.
458 */
459 @Deprecated
460 public void unlockCanvas(Canvas canvas) {
461 throw new UnsupportedOperationException();
462 }
463
464 /**
465 * Sets the translator used to scale canvas's width/height in compatibility
466 * mode.
467 */
468 void setCompatibilityTranslator(Translator translator) {
469 if (translator != null) {
470 float appScale = translator.applicationScale;
471 mCompatibleMatrix = new Matrix();
472 mCompatibleMatrix.setScale(appScale, appScale);
473 }
474 }
475
Mitsuru Oshima38ed7d772009-07-21 14:39:34 -0700476 /**
Mathias Agopianb9230662011-08-03 14:44:48 -0700477 * Copy another surface to this one. This surface now holds a reference
478 * to the same data as the original surface, and is -not- the owner.
Dianne Hackborn61566cc2011-12-02 23:31:52 -0800479 * This is for use by the window manager when returning a window surface
480 * back from a client, converting it from the representation being managed
481 * by the window manager to the representation the client uses to draw
482 * in to it.
Bryce Lee02949f12017-06-16 07:20:34 -0700483 *
484 * @param other {@link SurfaceControl} to copy from.
485 *
Mathias Agopianb9230662011-08-03 14:44:48 -0700486 * @hide
487 */
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800488 public void copyFrom(SurfaceControl other) {
Jeff Brown64a55af2012-08-26 02:47:39 -0700489 if (other == null) {
490 throw new IllegalArgumentException("other must not be null");
491 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700492
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000493 long surfaceControlPtr = other.mNativeObject;
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700494 if (surfaceControlPtr == 0) {
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800495 throw new NullPointerException(
Bryce Lee02949f12017-06-16 07:20:34 -0700496 "null SurfaceControl native object. Are you using a released SurfaceControl?");
497 }
498 long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);
499
500 synchronized (mLock) {
501 if (mNativeObject != 0) {
502 nativeRelease(mNativeObject);
503 }
504 setNativeObjectLocked(newNativeObject);
505 }
506 }
507
508 /**
509 * Gets a reference a surface created from this one. This surface now holds a reference
510 * to the same data as the original surface, and is -not- the owner.
511 * This is for use by the window manager when returning a window surface
512 * back from a client, converting it from the representation being managed
513 * by the window manager to the representation the client uses to draw
514 * in to it.
515 *
516 * @param other {@link SurfaceControl} to create surface from.
517 *
518 * @hide
519 */
520 public void createFrom(SurfaceControl other) {
521 if (other == null) {
522 throw new IllegalArgumentException("other must not be null");
523 }
524
525 long surfaceControlPtr = other.mNativeObject;
526 if (surfaceControlPtr == 0) {
527 throw new NullPointerException(
528 "null SurfaceControl native object. Are you using a released SurfaceControl?");
Jeff Brown64a55af2012-08-26 02:47:39 -0700529 }
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000530 long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700531
532 synchronized (mLock) {
533 if (mNativeObject != 0) {
534 nativeRelease(mNativeObject);
Mathias Agopian7c116b52013-03-18 20:27:02 -0700535 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700536 setNativeObjectLocked(newNativeObject);
Mathias Agopian86e1bc72013-03-13 17:48:22 -0700537 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700538 }
Dianne Hackborn61566cc2011-12-02 23:31:52 -0800539
540 /**
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700541 * This is intended to be used by {@link SurfaceView#updateWindow} only.
Mathias Agopian7c116b52013-03-18 20:27:02 -0700542 * @param other access is not thread safe
543 * @hide
544 * @deprecated
Dianne Hackborn61566cc2011-12-02 23:31:52 -0800545 */
Mathias Agopian7c116b52013-03-18 20:27:02 -0700546 @Deprecated
Jeff Brown64a55af2012-08-26 02:47:39 -0700547 public void transferFrom(Surface other) {
548 if (other == null) {
549 throw new IllegalArgumentException("other must not be null");
550 }
551 if (other != this) {
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000552 final long newPtr;
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700553 synchronized (other.mLock) {
554 newPtr = other.mNativeObject;
555 other.setNativeObjectLocked(0);
556 }
557
558 synchronized (mLock) {
Mathias Agopian7c116b52013-03-18 20:27:02 -0700559 if (mNativeObject != 0) {
Mathias Agopian7c116b52013-03-18 20:27:02 -0700560 nativeRelease(mNativeObject);
561 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700562 setNativeObjectLocked(newPtr);
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800563 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700564 }
Mathias Agopianb9230662011-08-03 14:44:48 -0700565 }
566
Jeff Brown64a55af2012-08-26 02:47:39 -0700567 @Override
568 public int describeContents() {
569 return 0;
570 }
571
572 public void readFromParcel(Parcel source) {
573 if (source == null) {
574 throw new IllegalArgumentException("source must not be null");
575 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700576
577 synchronized (mLock) {
Andy McFaddened55c8d2013-08-20 10:05:51 -0700578 // nativeReadFromParcel() will either return mNativeObject, or
579 // create a new native Surface and return it after reducing
580 // the reference count on mNativeObject. Either way, it is
581 // not necessary to call nativeRelease() here.
Eino-Ville Talvalaf005f5e2016-08-29 17:51:23 -0700582 // NOTE: This must be kept synchronized with the native parceling code
583 // in frameworks/native/libs/Surface.cpp
Mathias Agopian7c116b52013-03-18 20:27:02 -0700584 mName = source.readString();
Pablo Ceballosaff2f942016-07-29 14:49:55 -0700585 mIsSingleBuffered = source.readInt() != 0;
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700586 setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
Mathias Agopian86e1bc72013-03-13 17:48:22 -0700587 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700588 }
589
590 @Override
591 public void writeToParcel(Parcel dest, int flags) {
592 if (dest == null) {
593 throw new IllegalArgumentException("dest must not be null");
594 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700595 synchronized (mLock) {
Eino-Ville Talvalaf005f5e2016-08-29 17:51:23 -0700596 // NOTE: This must be kept synchronized with the native parceling code
597 // in frameworks/native/libs/Surface.cpp
Mathias Agopian7c116b52013-03-18 20:27:02 -0700598 dest.writeString(mName);
Pablo Ceballosaff2f942016-07-29 14:49:55 -0700599 dest.writeInt(mIsSingleBuffered ? 1 : 0);
Mathias Agopian7c116b52013-03-18 20:27:02 -0700600 nativeWriteToParcel(mNativeObject, dest);
601 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700602 if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
603 release();
604 }
605 }
606
607 @Override
608 public String toString() {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700609 synchronized (mLock) {
Andy McFaddened55c8d2013-08-20 10:05:51 -0700610 return "Surface(name=" + mName + ")/@0x" +
611 Integer.toHexString(System.identityHashCode(this));
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700612 }
613 }
614
Ashok Bhat36bef0b2014-01-20 20:08:01 +0000615 private void setNativeObjectLocked(long ptr) {
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700616 if (mNativeObject != ptr) {
617 if (mNativeObject == 0 && ptr != 0) {
618 mCloseGuard.open("release");
619 } else if (mNativeObject != 0 && ptr == 0) {
620 mCloseGuard.close();
621 }
622 mNativeObject = ptr;
623 mGenerationId += 1;
John Reckbb2d0cc2014-10-21 10:09:36 -0700624 if (mHwuiContext != null) {
625 mHwuiContext.updateSurface();
626 }
Jeff Brownfc0ebd72013-04-30 16:33:00 -0700627 }
628 }
629
630 private void checkNotReleasedLocked() {
631 if (mNativeObject == 0) {
632 throw new IllegalStateException("Surface has already been released.");
633 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700634 }
635
Mathias Agopianc14bacf2012-04-23 18:23:08 -0700636 /**
Dan Stoza5795d642014-06-20 13:01:36 -0700637 * Allocate buffers ahead of time to avoid allocation delays during rendering
638 * @hide
639 */
640 public void allocateBuffers() {
641 synchronized (mLock) {
642 checkNotReleasedLocked();
643 nativeAllocateBuffers(mNativeObject);
644 }
645 }
646
647 /**
Robert Carrcd9a18c2015-12-16 18:16:21 -0800648 * Set the scaling mode to be used for this surfaces buffers
649 * @hide
650 */
651 void setScalingMode(@ScalingMode int scalingMode) {
652 synchronized (mLock) {
653 checkNotReleasedLocked();
654 int err = nativeSetScalingMode(mNativeObject, scalingMode);
655 if (err != 0) {
656 throw new IllegalArgumentException("Invalid scaling mode: " + scalingMode);
657 }
658 }
659 }
660
Robert Carr387838b2016-09-07 14:12:44 -0700661 void forceScopedDisconnect() {
662 synchronized (mLock) {
663 checkNotReleasedLocked();
664 int err = nativeForceScopedDisconnect(mNativeObject);
665 if (err != 0) {
666 throw new RuntimeException("Failed to disconnect Surface instance (bad object?)");
667 }
668 }
669 }
670
Robert Carrcd9a18c2015-12-16 18:16:21 -0800671 /**
Robert Carra35e5de2017-03-03 17:04:54 -0800672 * Transfer ownership of buffer and present it on the Surface.
673 * @hide
674 */
675 public void attachAndQueueBuffer(GraphicBuffer buffer) {
676 synchronized (mLock) {
677 checkNotReleasedLocked();
678 int err = nativeAttachAndQueueBuffer(mNativeObject, buffer);
679 if (err != 0) {
680 throw new RuntimeException(
681 "Failed to attach and queue buffer to Surface (bad object?)");
682 }
683 }
684 }
685
686 /**
Pablo Ceballosaff2f942016-07-29 14:49:55 -0700687 * Returns whether or not this Surface is backed by a single-buffered SurfaceTexture
688 * @hide
689 */
690 public boolean isSingleBuffered() {
691 return mIsSingleBuffered;
692 }
693
694 /**
Romain Guy0bbf0b42017-07-20 08:57:07 -0700695 * <p>The shared buffer mode allows both the application and the surface compositor
696 * (SurfaceFlinger) to concurrently access this surface's buffer. While the
697 * application is still required to issue a present request
698 * (see {@link #unlockCanvasAndPost(Canvas)}) to the compositor when an update is required,
699 * the compositor may trigger an update at any time. Since the surface's buffer is shared
700 * between the application and the compositor, updates triggered by the compositor may
701 * cause visible tearing.</p>
702 *
703 * <p>The shared buffer mode can be used with
704 * {@link #setAutoRefreshEnabled(boolean) auto-refresh} to avoid the overhead of
705 * issuing present requests.</p>
706 *
707 * <p>If the application uses the shared buffer mode to reduce latency, it is
708 * recommended to use software rendering (see {@link #lockCanvas(Rect)} to ensure
709 * the graphics workloads are not affected by other applications and/or the system
710 * using the GPU. When using software rendering, the application should update the
711 * smallest possible region of the surface required.</p>
712 *
713 * <p class="note">The shared buffer mode might not be supported by the underlying
714 * hardware. Enabling shared buffer mode on hardware that does not support it will
715 * not yield an error but the application will not benefit from lower latency (and
716 * tearing will not be visible).</p>
717 *
718 * <p class="note">Depending on how many and what kind of surfaces are visible, the
719 * surface compositor may need to copy the shared buffer before it is displayed. When
720 * this happens, the latency benefits of shared buffer mode will be reduced.</p>
721 *
722 * @param enabled True to enable the shared buffer mode on this surface, false otherwise
723 *
724 * @see #isSharedBufferModeEnabled()
725 * @see #setAutoRefreshEnabled(boolean)
Romain Guy010f0822017-08-16 09:43:07 -0700726 *
727 * @hide
Romain Guy0bbf0b42017-07-20 08:57:07 -0700728 */
729 public void setSharedBufferModeEnabled(boolean enabled) {
730 if (mIsSharedBufferModeEnabled != enabled) {
731 int error = nativeSetSharedBufferModeEnabled(mNativeObject, enabled);
732 if (error != 0) {
733 throw new RuntimeException(
734 "Failed to set shared buffer mode on Surface (bad object?)");
735 } else {
736 mIsSharedBufferModeEnabled = enabled;
737 }
738 }
739 }
740
741 /**
742 * @return True if shared buffer mode is enabled on this surface, false otherwise
743 *
744 * @see #setSharedBufferModeEnabled(boolean)
Romain Guy010f0822017-08-16 09:43:07 -0700745 *
746 * @hide
Romain Guy0bbf0b42017-07-20 08:57:07 -0700747 */
748 public boolean isSharedBufferModeEnabled() {
749 return mIsSharedBufferModeEnabled;
750 }
751
752 /**
753 * <p>When auto-refresh is enabled, the surface compositor (SurfaceFlinger)
754 * automatically updates the display on a regular refresh cycle. The application
755 * can continue to issue present requests but it is not required. Enabling
756 * auto-refresh may result in visible tearing.</p>
757 *
758 * <p>Auto-refresh has no effect if the {@link #setSharedBufferModeEnabled(boolean)
759 * shared buffer mode} is not enabled.</p>
760 *
761 * <p>Because auto-refresh will trigger continuous updates of the display, it is
762 * recommended to turn it on only when necessary. For example, in a drawing/painting
763 * application auto-refresh should be enabled on finger/pen down and disabled on
764 * finger/pen up.</p>
765 *
766 * @param enabled True to enable auto-refresh on this surface, false otherwise
767 *
768 * @see #isAutoRefreshEnabled()
769 * @see #setSharedBufferModeEnabled(boolean)
Romain Guy010f0822017-08-16 09:43:07 -0700770 *
771 * @hide
Romain Guy0bbf0b42017-07-20 08:57:07 -0700772 */
773 public void setAutoRefreshEnabled(boolean enabled) {
774 if (mIsAutoRefreshEnabled != enabled) {
775 int error = nativeSetAutoRefreshEnabled(mNativeObject, enabled);
776 if (error != 0) {
777 throw new RuntimeException("Failed to set auto refresh on Surface (bad object?)");
778 } else {
779 mIsAutoRefreshEnabled = enabled;
780 }
781 }
782 }
783
784 /**
785 * @return True if auto-refresh is enabled on this surface, false otherwise
Romain Guy010f0822017-08-16 09:43:07 -0700786 *
787 * @hide
Romain Guy0bbf0b42017-07-20 08:57:07 -0700788 */
789 public boolean isAutoRefreshEnabled() {
790 return mIsAutoRefreshEnabled;
791 }
792
793 /**
Igor Murashkina86ab6402013-08-30 12:58:36 -0700794 * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or
795 * when a SurfaceTexture could not successfully be allocated.
Jeff Brown64a55af2012-08-26 02:47:39 -0700796 */
Igor Murashkina86ab6402013-08-30 12:58:36 -0700797 @SuppressWarnings("serial")
798 public static class OutOfResourcesException extends RuntimeException {
Jeff Brown64a55af2012-08-26 02:47:39 -0700799 public OutOfResourcesException() {
800 }
Jeff Brown64a55af2012-08-26 02:47:39 -0700801 public OutOfResourcesException(String name) {
802 super(name);
803 }
804 }
805
806 /**
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700807 * Returns a human readable representation of a rotation.
808 *
809 * @param rotation The rotation.
810 * @return The rotation symbolic name.
Svetoslav Ganov545252f2012-12-10 18:29:24 -0800811 *
812 * @hide
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700813 */
814 public static String rotationToString(int rotation) {
815 switch (rotation) {
816 case Surface.ROTATION_0: {
817 return "ROTATION_0";
818 }
819 case Surface.ROTATION_90: {
Romain Guy0bbf0b42017-07-20 08:57:07 -0700820 return "ROTATION_90";
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700821 }
822 case Surface.ROTATION_180: {
Romain Guy0bbf0b42017-07-20 08:57:07 -0700823 return "ROTATION_180";
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700824 }
825 case Surface.ROTATION_270: {
Romain Guy0bbf0b42017-07-20 08:57:07 -0700826 return "ROTATION_270";
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700827 }
828 default: {
Michael Wright19859762017-09-18 20:57:58 +0100829 return Integer.toString(rotation);
Svetoslav Ganov152e9bb2012-10-12 20:15:29 -0700830 }
831 }
832 }
833
834 /**
Jeff Brown64a55af2012-08-26 02:47:39 -0700835 * A Canvas class that can handle the compatibility mode.
836 * This does two things differently.
Mitsuru Oshima240f8a72009-07-22 20:39:14 -0700837 * <ul>
Mathias Agopianb9230662011-08-03 14:44:48 -0700838 * <li>Returns the width and height of the target metrics, rather than
839 * native. For example, the canvas returns 320x480 even if an app is running
840 * in WVGA high density.
841 * <li>Scales the matrix in setMatrix by the application scale, except if
842 * the matrix looks like obtained from getMatrix. This is a hack to handle
843 * the case that an application uses getMatrix to keep the original matrix,
844 * set matrix of its own, then set the original matrix back. There is no
845 * perfect solution that works for all cases, and there are a lot of cases
846 * that this model does not work, but we hope this works for many apps.
Mitsuru Oshima240f8a72009-07-22 20:39:14 -0700847 * </ul>
848 */
Jeff Brown64a55af2012-08-26 02:47:39 -0700849 private final class CompatibleCanvas extends Canvas {
Mitsuru Oshima240f8a72009-07-22 20:39:14 -0700850 // A temp matrix to remember what an application obtained via {@link getMatrix}
851 private Matrix mOrigMatrix = null;
852
853 @Override
Mitsuru Oshima240f8a72009-07-22 20:39:14 -0700854 public void setMatrix(Matrix matrix) {
855 if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
856 // don't scale the matrix if it's not compatibility mode, or
857 // the matrix was obtained from getMatrix.
858 super.setMatrix(matrix);
859 } else {
860 Matrix m = new Matrix(mCompatibleMatrix);
861 m.preConcat(matrix);
862 super.setMatrix(m);
863 }
864 }
865
Romain Guy8b5aa482013-02-28 18:13:54 -0800866 @SuppressWarnings("deprecation")
Mitsuru Oshima240f8a72009-07-22 20:39:14 -0700867 @Override
868 public void getMatrix(Matrix m) {
869 super.getMatrix(m);
870 if (mOrigMatrix == null) {
Andy McFaddened55c8d2013-08-20 10:05:51 -0700871 mOrigMatrix = new Matrix();
Mitsuru Oshima240f8a72009-07-22 20:39:14 -0700872 }
873 mOrigMatrix.set(m);
874 }
Romain Guyd10cd572010-10-10 13:33:22 -0700875 }
John Reckbb2d0cc2014-10-21 10:09:36 -0700876
877 private final class HwuiContext {
878 private final RenderNode mRenderNode;
879 private long mHwuiRenderer;
Chris Craikf6829a02015-03-10 10:28:59 -0700880 private DisplayListCanvas mCanvas;
Peiyong Lind8b68712018-03-06 18:34:21 -0800881 private final boolean mIsWideColorGamut;
John Reckbb2d0cc2014-10-21 10:09:36 -0700882
Peiyong Lind8b68712018-03-06 18:34:21 -0800883 HwuiContext(boolean isWideColorGamut) {
John Reckbb2d0cc2014-10-21 10:09:36 -0700884 mRenderNode = RenderNode.create("HwuiCanvas", null);
885 mRenderNode.setClipToBounds(false);
Peiyong Lind8b68712018-03-06 18:34:21 -0800886 mIsWideColorGamut = isWideColorGamut;
887 mHwuiRenderer = nHwuiCreate(mRenderNode.mNativeRenderNode, mNativeObject,
888 isWideColorGamut);
John Reckbb2d0cc2014-10-21 10:09:36 -0700889 }
890
John Reckb35c9602014-11-13 16:15:08 -0800891 Canvas lockCanvas(int width, int height) {
John Reckbb2d0cc2014-10-21 10:09:36 -0700892 if (mCanvas != null) {
893 throw new IllegalStateException("Surface was already locked!");
894 }
John Reckb35c9602014-11-13 16:15:08 -0800895 mCanvas = mRenderNode.start(width, height);
John Reckbb2d0cc2014-10-21 10:09:36 -0700896 return mCanvas;
897 }
898
899 void unlockAndPost(Canvas canvas) {
900 if (canvas != mCanvas) {
901 throw new IllegalArgumentException("canvas object must be the same instance that "
902 + "was previously returned by lockCanvas");
903 }
904 mRenderNode.end(mCanvas);
905 mCanvas = null;
906 nHwuiDraw(mHwuiRenderer);
907 }
908
909 void updateSurface() {
910 nHwuiSetSurface(mHwuiRenderer, mNativeObject);
911 }
912
913 void destroy() {
914 if (mHwuiRenderer != 0) {
915 nHwuiDestroy(mHwuiRenderer);
916 mHwuiRenderer = 0;
917 }
918 }
Peiyong Lind8b68712018-03-06 18:34:21 -0800919
920 boolean isWideColorGamut() {
921 return mIsWideColorGamut;
922 }
John Reckbb2d0cc2014-10-21 10:09:36 -0700923 }
924
Peiyong Lind8b68712018-03-06 18:34:21 -0800925 private static native long nHwuiCreate(long rootNode, long surface, boolean isWideColorGamut);
John Reckbb2d0cc2014-10-21 10:09:36 -0700926 private static native void nHwuiSetSurface(long renderer, long surface);
927 private static native void nHwuiDraw(long renderer);
928 private static native void nHwuiDestroy(long renderer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929}