blob: 0987b8a82b072565f37821142083a6f5f48dc276 [file] [log] [blame]
John Reckcec24ae2013-11-05 13:27:50 -08001/*
2 * Copyright (C) 2013 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
John Reckba6adf62015-02-19 14:36:50 -080019import android.annotation.IntDef;
Chris Craik2507c342015-05-04 14:36:49 -070020import android.annotation.NonNull;
Mathew Inwoode5ad5982018-08-17 15:07:52 +010021import android.annotation.UnsupportedAppUsage;
Sudheer Shankadc589ac2016-11-10 15:30:17 -080022import android.app.ActivityManager;
John Reckb8802b12014-06-16 15:28:50 -070023import android.content.Context;
Alan Viverette58c42c32014-07-12 20:33:45 -070024import android.content.res.TypedArray;
John Reck04fc5832014-02-05 16:38:25 -080025import android.graphics.Bitmap;
Alan Viverette50210d92015-05-14 18:05:36 -070026import android.graphics.Point;
Alan Viveretteccb11e12014-07-08 16:04:02 -070027import android.graphics.Rect;
Doris Liu67ce99b2016-05-17 16:50:31 -070028import android.graphics.drawable.AnimatedVectorDrawable;
John Reck66f0be62014-05-13 13:39:31 -070029import android.os.IBinder;
John Reckedc524c2015-03-18 15:24:33 -070030import android.os.ParcelFileDescriptor;
John Reckdf1742e2017-01-19 15:56:21 -080031import android.os.RemoteException;
John Reck66f0be62014-05-13 13:39:31 -070032import android.os.ServiceManager;
Jaesung Chung9a89d832017-05-16 01:54:17 +090033import android.os.SystemProperties;
John Reckcec24ae2013-11-05 13:27:50 -080034import android.os.Trace;
John Reck66f0be62014-05-13 13:39:31 -070035import android.util.Log;
John Reckcec24ae2013-11-05 13:27:50 -080036import android.view.Surface.OutOfResourcesException;
37import android.view.View.AttachInfo;
Mihai Popa4bcd4d402018-02-07 17:13:51 +000038import android.view.animation.AnimationUtils;
John Reckcec24ae2013-11-05 13:27:50 -080039
John Reckba6adf62015-02-19 14:36:50 -080040import com.android.internal.R;
Andres Morales06f5bc72015-12-15 15:21:31 -080041import com.android.internal.util.VirtualRefBasePtr;
John Reckba6adf62015-02-19 14:36:50 -080042
John Reck51aaf902015-12-02 15:08:07 -080043import java.io.File;
John Reckfe5e7b72014-05-23 17:42:28 -070044import java.io.FileDescriptor;
John Reckcec24ae2013-11-05 13:27:50 -080045import java.io.PrintWriter;
John Reckba6adf62015-02-19 14:36:50 -080046import java.lang.annotation.Retention;
47import java.lang.annotation.RetentionPolicy;
John Reckcec24ae2013-11-05 13:27:50 -080048
49/**
Stan Iliev45faba52016-06-28 13:33:15 -040050 * Threaded renderer that proxies the rendering to a render thread. Most calls
John Reck4f02bf42014-01-03 18:09:17 -080051 * are currently synchronous.
John Reckcec24ae2013-11-05 13:27:50 -080052 *
53 * The UI thread can block on the RenderThread, but RenderThread must never
54 * block on the UI thread.
55 *
John Reck4f02bf42014-01-03 18:09:17 -080056 * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
57 * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
58 * by the lifecycle of the RenderProxy.
59 *
John Reckcec24ae2013-11-05 13:27:50 -080060 * Note that although currently the EGL context & surfaces are created & managed
61 * by the render thread, the goal is to move that into a shared structure that can
62 * be managed by both threads. EGLSurface creation & deletion should ideally be
63 * done on the UI thread and not the RenderThread to avoid stalling the
64 * RenderThread with surface buffer allocation.
65 *
66 * @hide
67 */
John Reck51aaf902015-12-02 15:08:07 -080068public final class ThreadedRenderer {
69 private static final String LOG_TAG = "ThreadedRenderer";
70
71 /**
72 * Name of the file that holds the shaders cache.
73 */
74 private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
Stan Ilievd495f432017-10-09 15:49:32 -040075 private static final String CACHE_PATH_SKIASHADERS = "com.android.skia.shaders_cache";
John Reck51aaf902015-12-02 15:08:07 -080076
77 /**
Stan Iliev45faba52016-06-28 13:33:15 -040078 * System property used to enable or disable threaded rendering profiling.
John Reck51aaf902015-12-02 15:08:07 -080079 * The default value of this property is assumed to be false.
80 *
81 * When profiling is enabled, the adb shell dumpsys gfxinfo command will
82 * output extra information about the time taken to execute by the last
83 * frames.
84 *
85 * Possible values:
86 * "true", to enable profiling
87 * "visual_bars", to enable profiling and visualize the results on screen
88 * "false", to disable profiling
89 *
90 * @see #PROFILE_PROPERTY_VISUALIZE_BARS
91 *
92 * @hide
93 */
94 public static final String PROFILE_PROPERTY = "debug.hwui.profile";
95
96 /**
97 * Value for {@link #PROFILE_PROPERTY}. When the property is set to this
98 * value, profiling data will be visualized on screen as a bar chart.
99 *
100 * @hide
101 */
102 public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars";
103
104 /**
105 * System property used to specify the number of frames to be used
Stan Iliev45faba52016-06-28 13:33:15 -0400106 * when doing threaded rendering profiling.
John Reck51aaf902015-12-02 15:08:07 -0800107 * The default value of this property is #PROFILE_MAX_FRAMES.
108 *
109 * When profiling is enabled, the adb shell dumpsys gfxinfo command will
110 * output extra information about the time taken to execute by the last
111 * frames.
112 *
113 * Possible values:
114 * "60", to set the limit of frames to 60
115 */
116 static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes";
117
118 /**
119 * System property used to debug EGL configuration choice.
120 *
121 * Possible values:
122 * "choice", print the chosen configuration only
123 * "all", print all possible configurations
124 */
125 static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config";
126
127 /**
128 * Turn on to draw dirty regions every other frame.
129 *
130 * Possible values:
131 * "true", to enable dirty regions debugging
132 * "false", to disable dirty regions debugging
133 *
134 * @hide
135 */
136 public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
137
138 /**
139 * Turn on to flash hardware layers when they update.
140 *
141 * Possible values:
142 * "true", to enable hardware layers updates debugging
143 * "false", to disable hardware layers updates debugging
144 *
145 * @hide
146 */
147 public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
148 "debug.hwui.show_layers_updates";
149
150 /**
151 * Controls overdraw debugging.
152 *
153 * Possible values:
154 * "false", to disable overdraw debugging
155 * "show", to show overdraw areas on screen
156 * "count", to display an overdraw counter
157 *
158 * @hide
159 */
160 public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
161
162 /**
163 * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
164 * value, overdraw will be shown on screen by coloring pixels.
165 *
166 * @hide
167 */
168 public static final String OVERDRAW_PROPERTY_SHOW = "show";
169
170 /**
171 * Turn on to debug non-rectangular clip operations.
172 *
173 * Possible values:
174 * "hide", to disable this debug mode
175 * "highlight", highlight drawing commands tested against a non-rectangular clip
176 * "stencil", renders the clip region on screen when set
177 *
178 * @hide
179 */
180 public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
181 "debug.hwui.show_non_rect_clip";
182
John Reck9f516442017-09-25 10:27:21 -0700183 /**
184 * Sets the FPS devisor to lower the FPS.
185 *
186 * Sets a positive integer as a divisor. 1 (the default value) menas the full FPS, and 2
187 * means half the full FPS.
188 *
189 *
190 * @hide
191 */
192 public static final String DEBUG_FPS_DIVISOR = "debug.hwui.fps_divisor";
193
Jorim Jaggi767e25e2018-04-04 23:07:35 +0200194 public static int EGL_CONTEXT_PRIORITY_HIGH_IMG = 0x3101;
195 public static int EGL_CONTEXT_PRIORITY_MEDIUM_IMG = 0x3102;
196 public static int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;
197
Jaesung Chung9a89d832017-05-16 01:54:17 +0900198 static {
199 // Try to check OpenGL support early if possible.
200 isAvailable();
201 }
202
John Reck51aaf902015-12-02 15:08:07 -0800203 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400204 * A process can set this flag to false to prevent the use of threaded
John Reck51aaf902015-12-02 15:08:07 -0800205 * rendering.
206 *
207 * @hide
208 */
209 public static boolean sRendererDisabled = false;
210
211 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400212 * Further threaded renderer disabling for the system process.
John Reck51aaf902015-12-02 15:08:07 -0800213 *
214 * @hide
215 */
216 public static boolean sSystemRendererDisabled = false;
217
218 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400219 * Invoke this method to disable threaded rendering in the current process.
John Reck51aaf902015-12-02 15:08:07 -0800220 *
221 * @hide
222 */
223 public static void disable(boolean system) {
224 sRendererDisabled = true;
225 if (system) {
226 sSystemRendererDisabled = true;
227 }
228 }
229
230 public static boolean sTrimForeground = false;
231
232 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400233 * Controls whether or not the renderer should aggressively trim
234 * memory. Note that this must not be set for any process that uses
235 * WebView! This should be only used by system_process or similar
John Reck51aaf902015-12-02 15:08:07 -0800236 * that do not go into the background.
237 */
238 public static void enableForegroundTrimming() {
239 sTrimForeground = true;
240 }
241
Jaesung Chung9a89d832017-05-16 01:54:17 +0900242 private static Boolean sSupportsOpenGL;
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -0400243
John Reck51aaf902015-12-02 15:08:07 -0800244 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400245 * Indicates whether threaded rendering is available under any form for
John Reck51aaf902015-12-02 15:08:07 -0800246 * the view hierarchy.
247 *
Stan Iliev45faba52016-06-28 13:33:15 -0400248 * @return True if the view hierarchy can potentially be defer rendered,
John Reck51aaf902015-12-02 15:08:07 -0800249 * false otherwise
250 */
251 public static boolean isAvailable() {
Jaesung Chung9a89d832017-05-16 01:54:17 +0900252 if (sSupportsOpenGL != null) {
253 return sSupportsOpenGL.booleanValue();
254 }
255 if (SystemProperties.getInt("ro.kernel.qemu", 0) == 0) {
256 // Device is not an emulator.
257 sSupportsOpenGL = true;
258 return true;
259 }
260 int qemu_gles = SystemProperties.getInt("qemu.gles", -1);
261 if (qemu_gles == -1) {
262 // In this case, the value of the qemu.gles property is not ready
263 // because the SurfaceFlinger service may not start at this point.
264 return false;
265 }
266 // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
267 // enabled, 0 otherwise. On old emulator versions it will be undefined.
268 sSupportsOpenGL = qemu_gles > 0;
269 return sSupportsOpenGL.booleanValue();
John Reck51aaf902015-12-02 15:08:07 -0800270 }
271
272 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400273 * Sets the directory to use as a persistent storage for threaded rendering
John Reck51aaf902015-12-02 15:08:07 -0800274 * resources.
275 *
276 * @param cacheDir A directory the current process can write to
277 *
278 * @hide
279 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100280 @UnsupportedAppUsage
John Reck51aaf902015-12-02 15:08:07 -0800281 public static void setupDiskCache(File cacheDir) {
Stan Ilievd495f432017-10-09 15:49:32 -0400282 ThreadedRenderer.setupShadersDiskCache(
283 new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(),
284 new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath());
John Reck51aaf902015-12-02 15:08:07 -0800285 }
286
287 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400288 * Creates a threaded renderer using OpenGL.
John Reck51aaf902015-12-02 15:08:07 -0800289 *
290 * @param translucent True if the surface is translucent, false otherwise
291 *
Stan Iliev45faba52016-06-28 13:33:15 -0400292 * @return A threaded renderer backed by OpenGL.
John Reck51aaf902015-12-02 15:08:07 -0800293 */
John Reckdf1742e2017-01-19 15:56:21 -0800294 public static ThreadedRenderer create(Context context, boolean translucent, String name) {
John Reck51aaf902015-12-02 15:08:07 -0800295 ThreadedRenderer renderer = null;
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -0400296 if (isAvailable()) {
John Reckdf1742e2017-01-19 15:56:21 -0800297 renderer = new ThreadedRenderer(context, translucent, name);
John Reck51aaf902015-12-02 15:08:07 -0800298 }
299 return renderer;
300 }
301
302 /**
303 * Invoke this method when the system is running out of memory. This
304 * method will attempt to recover as much memory as possible, based on
305 * the specified hint.
306 *
307 * @param level Hint about the amount of memory that should be trimmed,
308 * see {@link android.content.ComponentCallbacks}
309 */
310 public static void trimMemory(int level) {
311 nTrimMemory(level);
312 }
313
314 public static void overrideProperty(@NonNull String name, @NonNull String value) {
315 if (name == null || value == null) {
316 throw new IllegalArgumentException("name and value must be non-null");
317 }
318 nOverrideProperty(name, value);
319 }
320
John Reckf9be7792014-05-02 18:21:16 -0700321 // Keep in sync with DrawFrameTask.h SYNC_* flags
322 // Nothing interesting to report
John Reckcd028f32014-06-24 08:44:29 -0700323 private static final int SYNC_OK = 0;
John Reckf9be7792014-05-02 18:21:16 -0700324 // Needs a ViewRoot invalidate
John Reckcd028f32014-06-24 08:44:29 -0700325 private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
John Reckaa95a882014-11-07 11:02:07 -0800326 // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
327 private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
John Reck9a17da82016-04-18 11:17:52 -0700328 // setStopped is true, drawing is false
329 // TODO: Remove this and SYNC_LOST_SURFACE_REWARD_IF_FOUND?
330 // This flag isn't really used as there's nothing that we care to do
331 // in response, so it really just exists to differentiate from LOST_SURFACE
332 // but possibly both can just be deleted.
333 private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
John Reck5b02c622018-05-17 10:44:00 -0700334 private static final int SYNC_FRAME_DROPPED = 1 << 3;
John Reckf9be7792014-05-02 18:21:16 -0700335
John Reckfe5e7b72014-05-23 17:42:28 -0700336 private static final String[] VISUALIZERS = {
337 PROFILE_PROPERTY_VISUALIZE_BARS,
338 };
339
John Reckba6adf62015-02-19 14:36:50 -0800340 private static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
341 private static final int FLAG_DUMP_RESET = 1 << 1;
John Reck184264d2018-02-12 16:21:21 -0800342 private static final int FLAG_DUMP_ALL = FLAG_DUMP_FRAMESTATS;
John Reckba6adf62015-02-19 14:36:50 -0800343
Jeff Sharkeyce8db992017-12-13 20:05:05 -0700344 @IntDef(flag = true, prefix = { "FLAG_DUMP_" }, value = {
345 FLAG_DUMP_FRAMESTATS,
346 FLAG_DUMP_RESET
347 })
John Reckba6adf62015-02-19 14:36:50 -0800348 @Retention(RetentionPolicy.SOURCE)
349 public @interface DumpFlags {}
350
Alan Viveretteccb11e12014-07-08 16:04:02 -0700351 // Size of the rendered content.
John Reckcec24ae2013-11-05 13:27:50 -0800352 private int mWidth, mHeight;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700353
354 // Actual size of the drawing surface.
355 private int mSurfaceWidth, mSurfaceHeight;
356
357 // Insets between the drawing surface and rendered content. These are
358 // applied as translation when updating the root render node.
359 private int mInsetTop, mInsetLeft;
360
Alan Viverette57774a82014-07-15 15:49:55 -0700361 // Whether the surface has insets. Used to protect opacity.
362 private boolean mHasInsets;
363
Alan Viverette58c42c32014-07-12 20:33:45 -0700364 // Light and shadow properties specified by the theme.
365 private final float mLightY;
366 private final float mLightZ;
367 private final float mLightRadius;
Chris Craik058fc642014-07-23 18:19:28 -0700368 private final int mAmbientShadowAlpha;
369 private final int mSpotShadowAlpha;
Alan Viverette58c42c32014-07-12 20:33:45 -0700370
John Reck4f02bf42014-01-03 18:09:17 -0800371 private long mNativeProxy;
John Reckf7d9c1d2014-04-09 10:01:03 -0700372 private boolean mInitialized = false;
John Reckbc0cc022014-04-11 16:08:14 -0700373 private RenderNode mRootNode;
John Reck0a973302014-07-16 13:29:45 -0700374 private boolean mRootNodeNeedsUpdate;
John Reckcec24ae2013-11-05 13:27:50 -0800375
John Reck51aaf902015-12-02 15:08:07 -0800376 private boolean mEnabled;
377 private boolean mRequested = true;
John Reck3e04f092017-06-02 15:50:09 -0700378 private boolean mIsOpaque = false;
John Reck51aaf902015-12-02 15:08:07 -0800379
John Reckdf1742e2017-01-19 15:56:21 -0800380 ThreadedRenderer(Context context, boolean translucent, String name) {
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700381 final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
Alan Viverette58c42c32014-07-12 20:33:45 -0700382 mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
383 mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
384 mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700385 mAmbientShadowAlpha =
386 (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
387 mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
Alan Viverette58c42c32014-07-12 20:33:45 -0700388 a.recycle();
389
John Recke45b1fd2014-04-15 09:50:16 -0700390 long rootNodePtr = nCreateRootRenderNode();
391 mRootNode = RenderNode.adopt(rootNodePtr);
John Reckbc0cc022014-04-11 16:08:14 -0700392 mRootNode.setClipToBounds(false);
John Reck3e04f092017-06-02 15:50:09 -0700393 mIsOpaque = !translucent;
John Recke45b1fd2014-04-15 09:50:16 -0700394 mNativeProxy = nCreateProxy(translucent, rootNodePtr);
John Reckdf1742e2017-01-19 15:56:21 -0800395 nSetName(mNativeProxy, name);
John Reck18f16e62014-05-02 16:46:41 -0700396
John Reckedc524c2015-03-18 15:24:33 -0700397 ProcessInitializer.sInstance.init(context, mNativeProxy);
John Reck3b202512014-06-23 13:13:08 -0700398
John Reckfe5e7b72014-05-23 17:42:28 -0700399 loadSystemProperties();
John Reckcec24ae2013-11-05 13:27:50 -0800400 }
401
John Reck51aaf902015-12-02 15:08:07 -0800402 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400403 * Destroys the threaded rendering context.
John Reck51aaf902015-12-02 15:08:07 -0800404 */
John Reckf47a5942014-06-30 16:20:04 -0700405 void destroy() {
John Reckf7d9c1d2014-04-09 10:01:03 -0700406 mInitialized = false;
407 updateEnabledState(null);
Doris Liu350e6522016-02-19 14:20:37 -0800408 nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
John Reckcec24ae2013-11-05 13:27:50 -0800409 }
410
John Reck51aaf902015-12-02 15:08:07 -0800411 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400412 * Indicates whether threaded rendering is currently enabled.
John Reck51aaf902015-12-02 15:08:07 -0800413 *
Stan Iliev45faba52016-06-28 13:33:15 -0400414 * @return True if threaded rendering is in use, false otherwise.
John Reck51aaf902015-12-02 15:08:07 -0800415 */
416 boolean isEnabled() {
417 return mEnabled;
418 }
419
420 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400421 * Indicates whether threaded rendering is currently enabled.
John Reck51aaf902015-12-02 15:08:07 -0800422 *
Stan Iliev45faba52016-06-28 13:33:15 -0400423 * @param enabled True if the threaded renderer is in use, false otherwise.
John Reck51aaf902015-12-02 15:08:07 -0800424 */
425 void setEnabled(boolean enabled) {
426 mEnabled = enabled;
427 }
428
429 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400430 * Indicates whether threaded rendering is currently request but not
John Reck51aaf902015-12-02 15:08:07 -0800431 * necessarily enabled yet.
432 *
433 * @return True if requested, false otherwise.
434 */
435 boolean isRequested() {
436 return mRequested;
437 }
438
439 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400440 * Indicates whether threaded rendering is currently requested but not
John Reck51aaf902015-12-02 15:08:07 -0800441 * necessarily enabled yet.
John Reck51aaf902015-12-02 15:08:07 -0800442 */
443 void setRequested(boolean requested) {
444 mRequested = requested;
445 }
446
John Reckf7d9c1d2014-04-09 10:01:03 -0700447 private void updateEnabledState(Surface surface) {
448 if (surface == null || !surface.isValid()) {
449 setEnabled(false);
450 } else {
451 setEnabled(mInitialized);
452 }
453 }
454
John Reck51aaf902015-12-02 15:08:07 -0800455 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400456 * Initializes the threaded renderer for the specified surface.
John Reck51aaf902015-12-02 15:08:07 -0800457 *
Stan Iliev45faba52016-06-28 13:33:15 -0400458 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800459 *
460 * @return True if the initialization was successful, false otherwise.
461 */
John Reckcec24ae2013-11-05 13:27:50 -0800462 boolean initialize(Surface surface) throws OutOfResourcesException {
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100463 boolean status = !mInitialized;
John Reckf7d9c1d2014-04-09 10:01:03 -0700464 mInitialized = true;
465 updateEnabledState(surface);
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100466 nInitialize(mNativeProxy, surface);
Dan Stoza5795d642014-06-20 13:01:36 -0700467 return status;
John Reckcec24ae2013-11-05 13:27:50 -0800468 }
469
John Reck51aaf902015-12-02 15:08:07 -0800470 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400471 * Initializes the threaded renderer for the specified surface and setup the
John Reck51aaf902015-12-02 15:08:07 -0800472 * renderer for drawing, if needed. This is invoked when the ViewAncestor has
Stan Iliev45faba52016-06-28 13:33:15 -0400473 * potentially lost the threaded renderer. The threaded renderer should be
John Reck51aaf902015-12-02 15:08:07 -0800474 * reinitialized and setup when the render {@link #isRequested()} and
475 * {@link #isEnabled()}.
476 *
477 * @param width The width of the drawing surface.
478 * @param height The height of the drawing surface.
479 * @param attachInfo Information about the window.
Stan Iliev45faba52016-06-28 13:33:15 -0400480 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800481 * @param surfaceInsets The drawing surface insets to apply
482 *
483 * @return true if the surface was initialized, false otherwise. Returning
484 * false might mean that the surface was already initialized.
485 */
486 boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
487 Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
488 if (isRequested()) {
489 // We lost the gl context, so recreate it.
490 if (!isEnabled()) {
491 if (initialize(surface)) {
492 setup(width, height, attachInfo, surfaceInsets);
493 return true;
494 }
495 }
496 }
497 return false;
498 }
499
500 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400501 * Updates the threaded renderer for the specified surface.
John Reck51aaf902015-12-02 15:08:07 -0800502 *
Stan Iliev45faba52016-06-28 13:33:15 -0400503 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800504 */
John Reckcec24ae2013-11-05 13:27:50 -0800505 void updateSurface(Surface surface) throws OutOfResourcesException {
John Reckf7d9c1d2014-04-09 10:01:03 -0700506 updateEnabledState(surface);
John Reck4f02bf42014-01-03 18:09:17 -0800507 nUpdateSurface(mNativeProxy, surface);
John Reckcec24ae2013-11-05 13:27:50 -0800508 }
509
John Reck51aaf902015-12-02 15:08:07 -0800510 /**
John Reck8afcc762016-04-13 10:24:06 -0700511 * Halts any current rendering into the surface. Use this if it is unclear whether
Stan Iliev45faba52016-06-28 13:33:15 -0400512 * or not the surface used by the ThreadedRenderer will be changing. It
John Reck8afcc762016-04-13 10:24:06 -0700513 * Suspends any rendering into the surface, but will not do any destruction.
514 *
515 * Any subsequent draws will override the pause, resuming normal operation.
John Reck51aaf902015-12-02 15:08:07 -0800516 */
John Reck01a5ea32014-12-03 13:01:07 -0800517 boolean pauseSurface(Surface surface) {
518 return nPauseSurface(mNativeProxy, surface);
John Reckf7d9c1d2014-04-09 10:01:03 -0700519 }
520
John Reck51aaf902015-12-02 15:08:07 -0800521 /**
John Reck8afcc762016-04-13 10:24:06 -0700522 * Hard stops or resumes rendering into the surface. This flag is used to
523 * determine whether or not it is safe to use the given surface *at all*
524 */
525 void setStopped(boolean stopped) {
526 nSetStopped(mNativeProxy, stopped);
527 }
528
529 /**
John Reck51aaf902015-12-02 15:08:07 -0800530 * Destroys all hardware rendering resources associated with the specified
531 * view hierarchy.
532 *
533 * @param view The root of the view hierarchy
534 */
John Reckcec24ae2013-11-05 13:27:50 -0800535 void destroyHardwareResources(View view) {
John Reck4f02bf42014-01-03 18:09:17 -0800536 destroyResources(view);
John Reckf47a5942014-06-30 16:20:04 -0700537 nDestroyHardwareResources(mNativeProxy);
John Reck4f02bf42014-01-03 18:09:17 -0800538 }
539
540 private static void destroyResources(View view) {
541 view.destroyHardwareResources();
John Reckcec24ae2013-11-05 13:27:50 -0800542 }
543
John Reck51aaf902015-12-02 15:08:07 -0800544 /**
John Reck51aaf902015-12-02 15:08:07 -0800545 * Detaches the layer's surface texture from the GL context and releases
546 * the texture id
547 */
John Reck918ad522014-06-27 14:45:25 -0700548 void detachSurfaceTexture(long hardwareLayer) {
549 nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
John Reckcec24ae2013-11-05 13:27:50 -0800550 }
551
John Reck51aaf902015-12-02 15:08:07 -0800552 /**
553 * Sets up the renderer for drawing.
554 *
555 * @param width The width of the drawing surface.
556 * @param height The height of the drawing surface.
557 * @param attachInfo Information about the window.
558 * @param surfaceInsets The drawing surface insets to apply
559 */
Alan Viverette50210d92015-05-14 18:05:36 -0700560 void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
John Reckcec24ae2013-11-05 13:27:50 -0800561 mWidth = width;
562 mHeight = height;
Alan Viverette50210d92015-05-14 18:05:36 -0700563
Alan Viverette3aa1ffb2014-10-30 12:22:08 -0700564 if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
565 || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
Alan Viverette57774a82014-07-15 15:49:55 -0700566 mHasInsets = true;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700567 mInsetLeft = surfaceInsets.left;
568 mInsetTop = surfaceInsets.top;
569 mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
570 mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
Alan Viverette57774a82014-07-15 15:49:55 -0700571
572 // If the surface has insets, it can't be opaque.
573 setOpaque(false);
Alan Viveretteccb11e12014-07-08 16:04:02 -0700574 } else {
Alan Viverette57774a82014-07-15 15:49:55 -0700575 mHasInsets = false;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700576 mInsetLeft = 0;
577 mInsetTop = 0;
578 mSurfaceWidth = width;
579 mSurfaceHeight = height;
580 }
Alan Viverette50210d92015-05-14 18:05:36 -0700581
Alan Viveretteccb11e12014-07-08 16:04:02 -0700582 mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
John Reckab1080c2016-06-21 16:24:20 -0700583 nSetup(mNativeProxy, mLightRadius,
John Reckb36016c2015-03-11 08:50:53 -0700584 mAmbientShadowAlpha, mSpotShadowAlpha);
Alan Viverette50210d92015-05-14 18:05:36 -0700585
586 setLightCenter(attachInfo);
587 }
588
John Reck51aaf902015-12-02 15:08:07 -0800589 /**
590 * Updates the light position based on the position of the window.
591 *
592 * @param attachInfo Information about the window.
593 */
Alan Viverette50210d92015-05-14 18:05:36 -0700594 void setLightCenter(AttachInfo attachInfo) {
595 // Adjust light position for window offsets.
596 final Point displaySize = attachInfo.mPoint;
597 attachInfo.mDisplay.getRealSize(displaySize);
598 final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
599 final float lightY = mLightY - attachInfo.mWindowTop;
600
601 nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
John Reckcec24ae2013-11-05 13:27:50 -0800602 }
603
John Reck51aaf902015-12-02 15:08:07 -0800604 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400605 * Change the ThreadedRenderer's opacity
John Reck51aaf902015-12-02 15:08:07 -0800606 */
John Reck63a06672014-05-07 13:45:54 -0700607 void setOpaque(boolean opaque) {
John Reck3e04f092017-06-02 15:50:09 -0700608 mIsOpaque = opaque && !mHasInsets;
609 nSetOpaque(mNativeProxy, mIsOpaque);
610 }
611
612 boolean isOpaque() {
613 return mIsOpaque;
John Reck63a06672014-05-07 13:45:54 -0700614 }
615
John Reck51aaf902015-12-02 15:08:07 -0800616 /**
Romain Guy26a2b972017-04-17 09:39:51 -0700617 * Enable/disable wide gamut rendering on this renderer.
618 */
619 void setWideGamut(boolean wideGamut) {
620 nSetWideGamut(mNativeProxy, wideGamut);
621 }
622
623 /**
John Reck51aaf902015-12-02 15:08:07 -0800624 * Gets the current width of the surface. This is the width that the surface
625 * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
626 *
627 * @return the current width of the surface
628 */
John Reckcec24ae2013-11-05 13:27:50 -0800629 int getWidth() {
630 return mWidth;
631 }
632
John Reck51aaf902015-12-02 15:08:07 -0800633 /**
634 * Gets the current height of the surface. This is the height that the surface
635 * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
636 *
637 * @return the current width of the surface
638 */
John Reckcec24ae2013-11-05 13:27:50 -0800639 int getHeight() {
640 return mHeight;
641 }
642
John Reck51aaf902015-12-02 15:08:07 -0800643 /**
644 * Outputs extra debugging information in the specified file descriptor.
645 */
John Reckba6adf62015-02-19 14:36:50 -0800646 void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
John Reckfe5e7b72014-05-23 17:42:28 -0700647 pw.flush();
John Reck184264d2018-02-12 16:21:21 -0800648 // If there's no arguments, eg 'dumpsys gfxinfo', then dump everything.
649 // If there's a targetted package, eg 'dumpsys gfxinfo com.android.systemui', then only
650 // dump the summary information
651 int flags = (args == null || args.length == 0) ? FLAG_DUMP_ALL : 0;
John Reckba6adf62015-02-19 14:36:50 -0800652 for (int i = 0; i < args.length; i++) {
653 switch (args[i]) {
654 case "framestats":
655 flags |= FLAG_DUMP_FRAMESTATS;
656 break;
657 case "reset":
658 flags |= FLAG_DUMP_RESET;
659 break;
John Reck184264d2018-02-12 16:21:21 -0800660 case "-a": // magic option passed when dumping a bugreport.
661 flags = FLAG_DUMP_ALL;
662 break;
John Reckba6adf62015-02-19 14:36:50 -0800663 }
John Reckfe5e7b72014-05-23 17:42:28 -0700664 }
John Reckba6adf62015-02-19 14:36:50 -0800665 nDumpProfileInfo(mNativeProxy, fd, flags);
John Reckcec24ae2013-11-05 13:27:50 -0800666 }
667
John Reck51aaf902015-12-02 15:08:07 -0800668 /**
669 * Loads system properties used by the renderer. This method is invoked
670 * whenever system properties are modified. Implementations can use this
671 * to trigger live updates of the renderer based on properties.
672 *
673 * @return True if a property has changed.
674 */
John Reckcec24ae2013-11-05 13:27:50 -0800675 boolean loadSystemProperties() {
John Reckfe5e7b72014-05-23 17:42:28 -0700676 boolean changed = nLoadSystemProperties(mNativeProxy);
John Reck23d307c2014-10-27 12:38:48 -0700677 if (changed) {
678 invalidateRoot();
679 }
John Reckfe5e7b72014-05-23 17:42:28 -0700680 return changed;
John Reckcec24ae2013-11-05 13:27:50 -0800681 }
682
John Reck0a973302014-07-16 13:29:45 -0700683 private void updateViewTreeDisplayList(View view) {
John Reckcec24ae2013-11-05 13:27:50 -0800684 view.mPrivateFlags |= View.PFLAG_DRAWN;
John Reckcec24ae2013-11-05 13:27:50 -0800685 view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
686 == View.PFLAG_INVALIDATED;
687 view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
Chris Craik31a2d062015-05-01 14:22:47 -0700688 view.updateDisplayListIfDirty();
John Reckcec24ae2013-11-05 13:27:50 -0800689 view.mRecreateDisplayList = false;
John Reckbc0cc022014-04-11 16:08:14 -0700690 }
691
Stan Iliev45faba52016-06-28 13:33:15 -0400692 private void updateRootDisplayList(View view, DrawCallbacks callbacks) {
Chris Craik70850ea2014-11-18 10:49:23 -0800693 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
John Reck0a973302014-07-16 13:29:45 -0700694 updateViewTreeDisplayList(view);
695
696 if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
Chris Craikf6829a02015-03-10 10:28:59 -0700697 DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
John Reck0a973302014-07-16 13:29:45 -0700698 try {
Alan Viverettedbed8932014-08-06 17:54:52 -0700699 final int saveCount = canvas.save();
John Reck0a973302014-07-16 13:29:45 -0700700 canvas.translate(mInsetLeft, mInsetTop);
Stan Iliev45faba52016-06-28 13:33:15 -0400701 callbacks.onPreDraw(canvas);
Chris Craikabedca32014-08-28 15:03:55 -0700702
703 canvas.insertReorderBarrier();
Chris Craik31a2d062015-05-01 14:22:47 -0700704 canvas.drawRenderNode(view.updateDisplayListIfDirty());
Chris Craikabedca32014-08-28 15:03:55 -0700705 canvas.insertInorderBarrier();
706
Stan Iliev45faba52016-06-28 13:33:15 -0400707 callbacks.onPostDraw(canvas);
Alan Viverettedbed8932014-08-06 17:54:52 -0700708 canvas.restoreToCount(saveCount);
John Reck0a973302014-07-16 13:29:45 -0700709 mRootNodeNeedsUpdate = false;
710 } finally {
711 mRootNode.end(canvas);
712 }
713 }
714 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
715 }
716
Skuhneea7a7fb2015-08-28 07:10:31 -0700717 /**
718 * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
719 * rendernode of the UI thread.
720 * @param node The node to add.
721 * @param placeFront If true, the render node will be placed in front of the content node,
722 * otherwise behind the content node.
723 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100724 @UnsupportedAppUsage
Skuhneea7a7fb2015-08-28 07:10:31 -0700725 public void addRenderNode(RenderNode node, boolean placeFront) {
726 nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
727 }
728
729 /**
730 * Only especially added render nodes can be removed.
731 * @param node The node which was added via addRenderNode which should get removed again.
732 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100733 @UnsupportedAppUsage
Skuhneea7a7fb2015-08-28 07:10:31 -0700734 public void removeRenderNode(RenderNode node) {
735 nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
736 }
737
738 /**
739 * Draws a particular render node. If the node is not the content node, only the additional
740 * nodes will get drawn and the content remains untouched.
741 * @param node The node to be drawn.
742 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100743 @UnsupportedAppUsage
Skuhneea7a7fb2015-08-28 07:10:31 -0700744 public void drawRenderNode(RenderNode node) {
745 nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
746 }
747
748 /**
749 * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
750 * will be prevented to overdraw this area. It will be synchronized with the draw call.
751 * This should be updated in the content view's draw call.
752 * @param left The left side of the protected bounds.
753 * @param top The top side of the protected bounds.
754 * @param right The right side of the protected bounds.
755 * @param bottom The bottom side of the protected bounds.
756 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100757 @UnsupportedAppUsage
Skuhneb8160872015-09-22 09:51:39 -0700758 public void setContentDrawBounds(int left, int top, int right, int bottom) {
Jorim Jaggie85ce992016-05-09 19:05:22 -0700759 nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
Skuhneea7a7fb2015-08-28 07:10:31 -0700760 }
761
John Reck51aaf902015-12-02 15:08:07 -0800762 /**
763 * Interface used to receive callbacks whenever a view is drawn by
Stan Iliev45faba52016-06-28 13:33:15 -0400764 * a threaded renderer instance.
John Reck51aaf902015-12-02 15:08:07 -0800765 */
Stan Iliev45faba52016-06-28 13:33:15 -0400766 interface DrawCallbacks {
John Reck51aaf902015-12-02 15:08:07 -0800767 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400768 * Invoked before a view is drawn by a threaded renderer.
John Reck51aaf902015-12-02 15:08:07 -0800769 * This method can be used to apply transformations to the
770 * canvas but no drawing command should be issued.
771 *
772 * @param canvas The Canvas used to render the view.
773 */
Stan Iliev45faba52016-06-28 13:33:15 -0400774 void onPreDraw(DisplayListCanvas canvas);
John Reck51aaf902015-12-02 15:08:07 -0800775
776 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400777 * Invoked after a view is drawn by a threaded renderer.
John Reck51aaf902015-12-02 15:08:07 -0800778 * It is safe to invoke drawing commands from this method.
779 *
780 * @param canvas The Canvas used to render the view.
781 */
Stan Iliev45faba52016-06-28 13:33:15 -0400782 void onPostDraw(DisplayListCanvas canvas);
John Reck51aaf902015-12-02 15:08:07 -0800783 }
784
785 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400786 * Indicates that the content drawn by DrawCallbacks needs to
John Reck51aaf902015-12-02 15:08:07 -0800787 * be updated, which will be done by the next call to draw()
788 */
John Reck0a973302014-07-16 13:29:45 -0700789 void invalidateRoot() {
790 mRootNodeNeedsUpdate = true;
791 }
792
John Reck51aaf902015-12-02 15:08:07 -0800793 /**
794 * Draws the specified view.
795 *
796 * @param view The view to draw.
797 * @param attachInfo AttachInfo tied to the specified view.
798 * @param callbacks Callbacks invoked when drawing happens.
799 */
Jorim Jaggi64be98d2018-04-26 23:23:29 +0200800 void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks,
801 FrameDrawingCallback frameDrawingCallback) {
John Reckbc0cc022014-04-11 16:08:14 -0700802 attachInfo.mIgnoreDirtyState = true;
John Reckbc0cc022014-04-11 16:08:14 -0700803
John Reckba6adf62015-02-19 14:36:50 -0800804 final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
805 choreographer.mFrameInfo.markDrawStart();
John Reckfe5e7b72014-05-23 17:42:28 -0700806
John Reck61375a82014-09-18 19:27:48 +0000807 updateRootDisplayList(view, callbacks);
John Reckcec24ae2013-11-05 13:27:50 -0800808
John Reck6313b922014-04-16 18:59:21 -0700809 attachInfo.mIgnoreDirtyState = false;
810
John Reck119907c2014-08-14 09:02:01 -0700811 // register animating rendernodes which started animating prior to renderer
812 // creation, which is typical for animators started prior to first draw
813 if (attachInfo.mPendingAnimatingRenderNodes != null) {
814 final int count = attachInfo.mPendingAnimatingRenderNodes.size();
815 for (int i = 0; i < count; i++) {
816 registerAnimatingRenderNode(
817 attachInfo.mPendingAnimatingRenderNodes.get(i));
818 }
819 attachInfo.mPendingAnimatingRenderNodes.clear();
820 // We don't need this anymore as subsequent calls to
821 // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
822 attachInfo.mPendingAnimatingRenderNodes = null;
823 }
824
John Reckba6adf62015-02-19 14:36:50 -0800825 final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
Jorim Jaggi64be98d2018-04-26 23:23:29 +0200826 if (frameDrawingCallback != null) {
827 nSetFrameCallback(mNativeProxy, frameDrawingCallback);
828 }
John Reck51f2d602016-04-06 07:50:47 -0700829 int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
John Reckaa95a882014-11-07 11:02:07 -0800830 if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
831 setEnabled(false);
John Reckb13de072014-11-19 16:33:47 -0800832 attachInfo.mViewRootImpl.mSurface.release();
John Reckaa95a882014-11-07 11:02:07 -0800833 // Invalidate since we failed to draw. This should fetch a Surface
834 // if it is still needed or do nothing if we are no longer drawing
835 attachInfo.mViewRootImpl.invalidate();
836 }
John Reckf9be7792014-05-02 18:21:16 -0700837 if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
838 attachInfo.mViewRootImpl.invalidate();
839 }
John Reckcec24ae2013-11-05 13:27:50 -0800840 }
841
John Reck5b02c622018-05-17 10:44:00 -0700842 void setFrameCompleteCallback(FrameCompleteCallback callback) {
843 nSetFrameCompleteCallback(mNativeProxy, callback);
844 }
845
John Reck3b202512014-06-23 13:13:08 -0700846 static void invokeFunctor(long functor, boolean waitForCompletion) {
847 nInvokeFunctor(functor, waitForCompletion);
John Reck0d1f6342014-03-28 20:30:27 -0700848 }
849
John Reck51aaf902015-12-02 15:08:07 -0800850 /**
851 * Creates a new hardware layer. A hardware layer built by calling this
852 * method will be treated as a texture layer, instead of as a render target.
853 *
854 * @return A hardware layer
855 */
John Reck9d8d99d2018-02-21 12:55:41 -0800856 TextureLayer createTextureLayer() {
John Reck19b6bcf2014-02-14 20:03:38 -0800857 long layer = nCreateTextureLayer(mNativeProxy);
John Reck9d8d99d2018-02-21 12:55:41 -0800858 return TextureLayer.adoptTextureLayer(this, layer);
John Reck19b6bcf2014-02-14 20:03:38 -0800859 }
860
John Reck51aaf902015-12-02 15:08:07 -0800861
John Reck3e824952014-08-20 10:08:39 -0700862 void buildLayer(RenderNode node) {
863 nBuildLayer(mNativeProxy, node.getNativeDisplayList());
864 }
865
John Reck51aaf902015-12-02 15:08:07 -0800866
John Reck9d8d99d2018-02-21 12:55:41 -0800867 boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
John Reck19b6bcf2014-02-14 20:03:38 -0800868 return nCopyLayerInto(mNativeProxy,
John Reck3731dc22015-04-13 15:20:29 -0700869 layer.getDeferredLayerUpdater(), bitmap);
John Reck19b6bcf2014-02-14 20:03:38 -0800870 }
871
John Reck51aaf902015-12-02 15:08:07 -0800872 /**
873 * Indicates that the specified hardware layer needs to be updated
874 * as soon as possible.
875 *
876 * @param layer The hardware layer that needs an update
877 */
John Reck9d8d99d2018-02-21 12:55:41 -0800878 void pushLayerUpdate(TextureLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700879 nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800880 }
881
John Reck51aaf902015-12-02 15:08:07 -0800882 /**
883 * Tells the HardwareRenderer that the layer is destroyed. The renderer
884 * should remove the layer from any update queues.
885 */
John Reck9d8d99d2018-02-21 12:55:41 -0800886 void onLayerDestroyed(TextureLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700887 nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800888 }
889
John Reck51aaf902015-12-02 15:08:07 -0800890 /**
John Reck51aaf902015-12-02 15:08:07 -0800891 * Blocks until all previously queued work has completed.
892 */
John Reck28ad7b52014-04-07 16:59:25 -0700893 void fence() {
894 nFence(mNativeProxy);
895 }
896
John Reck51aaf902015-12-02 15:08:07 -0800897 /**
898 * Prevents any further drawing until draw() is called. This is a signal
899 * that the contents of the RenderNode tree are no longer safe to play back.
900 * In practice this usually means that there are Functor pointers in the
901 * display list that are no longer valid.
902 */
John Reckf47a5942014-06-30 16:20:04 -0700903 void stopDrawing() {
904 nStopDrawing(mNativeProxy);
905 }
906
John Reck51aaf902015-12-02 15:08:07 -0800907 /**
908 * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
909 */
John Recka5dda642014-05-22 15:43:54 -0700910 public void notifyFramePending() {
911 nNotifyFramePending(mNativeProxy);
912 }
913
John Reck51aaf902015-12-02 15:08:07 -0800914
John Reck119907c2014-08-14 09:02:01 -0700915 void registerAnimatingRenderNode(RenderNode animator) {
916 nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
917 }
918
Doris Liu67ce99b2016-05-17 16:50:31 -0700919 void registerVectorDrawableAnimator(
920 AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
921 nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
922 animator.getAnimatorNativePtr());
923 }
924
John Recke248bd12015-08-05 13:53:53 -0700925 public void serializeDisplayListTree() {
926 nSerializeDisplayListTree(mNativeProxy);
927 }
928
John Reck95801462016-09-01 09:44:09 -0700929 public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
930 if (srcRect == null) {
931 // Empty rect means entire surface
932 return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap);
933 } else {
934 return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
935 srcRect.right, srcRect.bottom, bitmap);
936 }
John Reck10dd0582016-03-31 16:36:16 -0700937 }
938
John Reck1fedd912017-05-23 14:45:22 -0700939 /**
940 * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given
941 * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and
942 * not the RenderNode from a View.
943 **/
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100944 @UnsupportedAppUsage
John Reck1fedd912017-05-23 14:45:22 -0700945 public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
946 return nCreateHardwareBitmap(node.getNativeDisplayList(), width, height);
947 }
948
John Reck938e8842017-08-24 13:41:59 -0700949 /**
950 * Sets whether or not high contrast text rendering is enabled. The setting is global
951 * but only affects content rendered after the change is made.
952 */
953 public static void setHighContrastText(boolean highContrastText) {
954 nSetHighContrastText(highContrastText);
955 }
956
John Reck56428472018-03-16 17:27:17 -0700957 /**
958 * If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source
959 */
960 public static void setIsolatedProcess(boolean isIsolated) {
961 nSetIsolatedProcess(isIsolated);
962 }
963
964 /**
965 * If set extra graphics debugging abilities will be enabled such as dumping skp
966 */
967 public static void setDebuggingEnabled(boolean enable) {
968 nSetDebuggingEnabled(enable);
969 }
970
Jorim Jaggi7823ee72018-07-17 15:24:16 +0200971 void allocateBuffers(Surface surface) {
972 nAllocateBuffers(mNativeProxy, surface);
973 }
974
John Reck119907c2014-08-14 09:02:01 -0700975 @Override
John Reck4f02bf42014-01-03 18:09:17 -0800976 protected void finalize() throws Throwable {
977 try {
978 nDeleteProxy(mNativeProxy);
John Reck0ed751d2014-04-08 14:10:17 -0700979 mNativeProxy = 0;
John Reck4f02bf42014-01-03 18:09:17 -0800980 } finally {
981 super.finalize();
John Reckcec24ae2013-11-05 13:27:50 -0800982 }
983 }
984
Mihai Popa4bcd4d402018-02-07 17:13:51 +0000985 /**
986 * Basic synchronous renderer. Currently only used to render the Magnifier, so use with care.
987 * TODO: deduplicate against ThreadedRenderer.
988 *
989 * @hide
990 */
991 public static class SimpleRenderer {
992 private final RenderNode mRootNode;
993 private long mNativeProxy;
994 private final float mLightY, mLightZ;
995 private Surface mSurface;
996 private final FrameInfo mFrameInfo = new FrameInfo();
997
998 public SimpleRenderer(final Context context, final String name, final Surface surface) {
999 final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
1000 mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
1001 mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
1002 final float lightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
1003 final int ambientShadowAlpha =
1004 (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
1005 final int spotShadowAlpha =
1006 (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
1007 a.recycle();
1008
1009 final long rootNodePtr = nCreateRootRenderNode();
1010 mRootNode = RenderNode.adopt(rootNodePtr);
1011 mRootNode.setClipToBounds(false);
1012 mNativeProxy = nCreateProxy(true /* translucent */, rootNodePtr);
1013 nSetName(mNativeProxy, name);
1014
1015 ProcessInitializer.sInstance.init(context, mNativeProxy);
1016 nLoadSystemProperties(mNativeProxy);
1017
1018 nSetup(mNativeProxy, lightRadius, ambientShadowAlpha, spotShadowAlpha);
1019
1020 mSurface = surface;
1021 nUpdateSurface(mNativeProxy, surface);
1022 }
1023
1024 /**
1025 * Set the light center.
1026 */
1027 public void setLightCenter(final Display display,
1028 final int windowLeft, final int windowTop) {
1029 // Adjust light position for window offsets.
1030 final Point displaySize = new Point();
1031 display.getRealSize(displaySize);
1032 final float lightX = displaySize.x / 2f - windowLeft;
1033 final float lightY = mLightY - windowTop;
1034
1035 nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
1036 }
1037
1038 public RenderNode getRootNode() {
1039 return mRootNode;
1040 }
1041
1042 /**
1043 * Draw the surface.
1044 */
1045 public void draw(final FrameDrawingCallback callback) {
1046 final long vsync = AnimationUtils.currentAnimationTimeMillis() * 1000000L;
1047 mFrameInfo.setVsync(vsync, vsync);
1048 mFrameInfo.addFlags(1 << 2 /* VSYNC */);
1049 if (callback != null) {
Mihai Popa95688002018-02-23 16:10:11 +00001050 nSetFrameCallback(mNativeProxy, callback);
Mihai Popa4bcd4d402018-02-07 17:13:51 +00001051 }
1052 nSyncAndDrawFrame(mNativeProxy, mFrameInfo.mFrameInfo, mFrameInfo.mFrameInfo.length);
1053 }
1054
1055 /**
1056 * Destroy the renderer.
1057 */
1058 public void destroy() {
1059 mSurface = null;
1060 nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
1061 }
1062
1063 @Override
1064 protected void finalize() throws Throwable {
1065 try {
1066 nDeleteProxy(mNativeProxy);
1067 mNativeProxy = 0;
1068 } finally {
1069 super.finalize();
1070 }
1071 }
1072 }
1073
1074 /**
1075 * Interface used to receive callbacks when a frame is being drawn.
1076 */
1077 public interface FrameDrawingCallback {
1078 /**
1079 * Invoked during a frame drawing.
1080 *
1081 * @param frame The id of the frame being drawn.
1082 */
1083 void onFrameDraw(long frame);
1084 }
1085
John Reck5b02c622018-05-17 10:44:00 -07001086 /**
1087 * Interface used to be notified when a frame has finished rendering
1088 */
1089 public interface FrameCompleteCallback {
1090 /**
1091 * Invoked after a frame draw
1092 *
1093 * @param frameNr The id of the frame that was drawn.
1094 */
1095 void onFrameComplete(long frameNr);
1096 }
1097
John Reckedc524c2015-03-18 15:24:33 -07001098 private static class ProcessInitializer {
1099 static ProcessInitializer sInstance = new ProcessInitializer();
John Reck66f0be62014-05-13 13:39:31 -07001100
1101 private boolean mInitialized = false;
1102
John Reckdf1742e2017-01-19 15:56:21 -08001103 private Context mAppContext;
1104 private IGraphicsStats mGraphicsStatsService;
1105 private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
1106 @Override
1107 public void onRotateGraphicsStatsBuffer() throws RemoteException {
1108 rotateBuffer();
1109 }
1110 };
1111
John Reckedc524c2015-03-18 15:24:33 -07001112 private ProcessInitializer() {}
John Reck66f0be62014-05-13 13:39:31 -07001113
John Reck3b202512014-06-23 13:13:08 -07001114 synchronized void init(Context context, long renderProxy) {
John Reck66f0be62014-05-13 13:39:31 -07001115 if (mInitialized) return;
John Reckedc524c2015-03-18 15:24:33 -07001116 mInitialized = true;
John Reckdf1742e2017-01-19 15:56:21 -08001117 mAppContext = context.getApplicationContext();
John Reck9f516442017-09-25 10:27:21 -07001118
Romain Guy26a2b972017-04-17 09:39:51 -07001119 initSched(renderProxy);
John Reckf1b96102018-03-07 11:06:41 -08001120
1121 if (mAppContext != null) {
John Reckf1b96102018-03-07 11:06:41 -08001122 initGraphicsStats();
1123 }
John Reckedc524c2015-03-18 15:24:33 -07001124 }
1125
Romain Guy26a2b972017-04-17 09:39:51 -07001126 private void initSched(long renderProxy) {
Tim Murray33eb07f2016-06-10 10:03:20 -07001127 try {
1128 int tid = nGetRenderThreadTid(renderProxy);
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001129 ActivityManager.getService().setRenderThread(tid);
Tim Murray33eb07f2016-06-10 10:03:20 -07001130 } catch (Throwable t) {
1131 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
1132 }
1133 }
1134
John Reckdf1742e2017-01-19 15:56:21 -08001135 private void initGraphicsStats() {
John Reckedc524c2015-03-18 15:24:33 -07001136 try {
John Reck828698b2015-06-30 12:56:03 -07001137 IBinder binder = ServiceManager.getService("graphicsstats");
1138 if (binder == null) return;
John Reckdf1742e2017-01-19 15:56:21 -08001139 mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
1140 requestBuffer();
1141 } catch (Throwable t) {
1142 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
1143 }
1144 }
1145
1146 private void rotateBuffer() {
1147 nRotateProcessStatsBuffer();
1148 requestBuffer();
1149 }
1150
1151 private void requestBuffer() {
1152 try {
1153 final String pkg = mAppContext.getApplicationInfo().packageName;
1154 ParcelFileDescriptor pfd = mGraphicsStatsService
1155 .requestBufferForProcess(pkg, mGraphicsStatsCallback);
1156 nSetProcessStatsBuffer(pfd.getFd());
John Reckedc524c2015-03-18 15:24:33 -07001157 pfd.close();
John Reck828698b2015-06-30 12:56:03 -07001158 } catch (Throwable t) {
1159 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
John Reckedc524c2015-03-18 15:24:33 -07001160 }
1161 }
John Reck66f0be62014-05-13 13:39:31 -07001162 }
1163
Andres Morales910beb82016-02-02 16:19:40 -08001164 void addFrameMetricsObserver(FrameMetricsObserver observer) {
1165 long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
1166 observer.mNative = new VirtualRefBasePtr(nativeObserver);
Andres Morales06f5bc72015-12-15 15:21:31 -08001167 }
1168
Andres Morales910beb82016-02-02 16:19:40 -08001169 void removeFrameMetricsObserver(FrameMetricsObserver observer) {
1170 nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
1171 observer.mNative = null;
Andres Morales06f5bc72015-12-15 15:21:31 -08001172 }
1173
John Reck9f516442017-09-25 10:27:21 -07001174 /** b/68769804: For low FPS experiments. */
1175 public static void setFPSDivisor(int divisor) {
Makoto Onukib708cbe2018-01-09 12:35:06 -08001176 nHackySetRTAnimationsEnabled(divisor <= 1);
John Reck9f516442017-09-25 10:27:21 -07001177 }
1178
Jorim Jaggi767e25e2018-04-04 23:07:35 +02001179 /**
1180 * Changes the OpenGL context priority if IMG_context_priority extension is available. Must be
1181 * called before any OpenGL context is created.
1182 *
1183 * @param priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values.
1184 */
1185 public static void setContextPriority(int priority) {
1186 nSetContextPriority(priority);
1187 }
1188
John Recka8963062017-06-14 10:47:50 -07001189 /** Not actually public - internal use only. This doc to make lint happy */
1190 public static native void disableVsync();
1191
Stan Ilievd495f432017-10-09 15:49:32 -04001192 static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
John Reck84a4c882014-05-30 14:34:03 -07001193
John Reckdf1742e2017-01-19 15:56:21 -08001194 private static native void nRotateProcessStatsBuffer();
1195 private static native void nSetProcessStatsBuffer(int fd);
Tim Murray33eb07f2016-06-10 10:03:20 -07001196 private static native int nGetRenderThreadTid(long nativeProxy);
John Reck4f02bf42014-01-03 18:09:17 -08001197
John Recke45b1fd2014-04-15 09:50:16 -07001198 private static native long nCreateRootRenderNode();
1199 private static native long nCreateProxy(boolean translucent, long rootRenderNode);
John Reck4f02bf42014-01-03 18:09:17 -08001200 private static native void nDeleteProxy(long nativeProxy);
1201
John Recke4280ba2014-05-05 16:39:37 -07001202 private static native boolean nLoadSystemProperties(long nativeProxy);
John Reckb36016c2015-03-11 08:50:53 -07001203 private static native void nSetName(long nativeProxy, String name);
John Reck18f16e62014-05-02 16:46:41 -07001204
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +01001205 private static native void nInitialize(long nativeProxy, Surface window);
John Reck4f02bf42014-01-03 18:09:17 -08001206 private static native void nUpdateSurface(long nativeProxy, Surface window);
John Reck01a5ea32014-12-03 13:01:07 -08001207 private static native boolean nPauseSurface(long nativeProxy, Surface window);
John Reck8afcc762016-04-13 10:24:06 -07001208 private static native void nSetStopped(long nativeProxy, boolean stopped);
John Reckab1080c2016-06-21 16:24:20 -07001209 private static native void nSetup(long nativeProxy,
Alan Viverette50210d92015-05-14 18:05:36 -07001210 float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
1211 private static native void nSetLightCenter(long nativeProxy,
1212 float lightX, float lightY, float lightZ);
John Reck63a06672014-05-07 13:45:54 -07001213 private static native void nSetOpaque(long nativeProxy, boolean opaque);
Romain Guy26a2b972017-04-17 09:39:51 -07001214 private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
John Reck51f2d602016-04-06 07:50:47 -07001215 private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
Doris Liu350e6522016-02-19 14:20:37 -08001216 private static native void nDestroy(long nativeProxy, long rootRenderNode);
John Reck119907c2014-08-14 09:02:01 -07001217 private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
Doris Liu67ce99b2016-05-17 16:50:31 -07001218 private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
John Reck4f02bf42014-01-03 18:09:17 -08001219
John Reck3b202512014-06-23 13:13:08 -07001220 private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
John Reck19b6bcf2014-02-14 20:03:38 -08001221
John Reck19b6bcf2014-02-14 20:03:38 -08001222 private static native long nCreateTextureLayer(long nativeProxy);
John Reck3e824952014-08-20 10:08:39 -07001223 private static native void nBuildLayer(long nativeProxy, long node);
John Reck3731dc22015-04-13 15:20:29 -07001224 private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
John Reckd72e0a32014-05-29 18:56:11 -07001225 private static native void nPushLayerUpdate(long nativeProxy, long layer);
1226 private static native void nCancelLayerUpdate(long nativeProxy, long layer);
John Reck918ad522014-06-27 14:45:25 -07001227 private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
John Reck28ad7b52014-04-07 16:59:25 -07001228
John Reckf47a5942014-06-30 16:20:04 -07001229 private static native void nDestroyHardwareResources(long nativeProxy);
1230 private static native void nTrimMemory(int level);
Chris Craik2507c342015-05-04 14:36:49 -07001231 private static native void nOverrideProperty(String name, String value);
John Recke1628b72014-05-23 15:11:19 -07001232
John Reck28ad7b52014-04-07 16:59:25 -07001233 private static native void nFence(long nativeProxy);
John Reckf47a5942014-06-30 16:20:04 -07001234 private static native void nStopDrawing(long nativeProxy);
John Recka5dda642014-05-22 15:43:54 -07001235 private static native void nNotifyFramePending(long nativeProxy);
John Reckfe5e7b72014-05-23 17:42:28 -07001236
John Recke248bd12015-08-05 13:53:53 -07001237 private static native void nSerializeDisplayListTree(long nativeProxy);
1238
John Reckba6adf62015-02-19 14:36:50 -08001239 private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1240 @DumpFlags int dumpFlags);
Skuhneea7a7fb2015-08-28 07:10:31 -07001241
1242 private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1243 boolean placeFront);
1244 private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1245 private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
Skuhneb8160872015-09-22 09:51:39 -07001246 private static native void nSetContentDrawBounds(long nativeProxy, int left,
Skuhneea7a7fb2015-08-28 07:10:31 -07001247 int top, int right, int bottom);
Mihai Popa95688002018-02-23 16:10:11 +00001248 private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
John Reck5b02c622018-05-17 10:44:00 -07001249 private static native void nSetFrameCompleteCallback(long nativeProxy,
1250 FrameCompleteCallback callback);
Andres Morales06f5bc72015-12-15 15:21:31 -08001251
Andres Morales910beb82016-02-02 16:19:40 -08001252 private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
1253 private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
John Reck10dd0582016-03-31 16:36:16 -07001254
John Reck95801462016-09-01 09:44:09 -07001255 private static native int nCopySurfaceInto(Surface surface,
1256 int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
John Reck1fedd912017-05-23 14:45:22 -07001257
1258 private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
John Reck938e8842017-08-24 13:41:59 -07001259 private static native void nSetHighContrastText(boolean enabled);
John Reck9f516442017-09-25 10:27:21 -07001260 // For temporary experimentation b/66945974
1261 private static native void nHackySetRTAnimationsEnabled(boolean enabled);
John Reck6afa0092018-03-01 17:28:35 -08001262 private static native void nSetDebuggingEnabled(boolean enabled);
John Reck56428472018-03-16 17:27:17 -07001263 private static native void nSetIsolatedProcess(boolean enabled);
Jorim Jaggi767e25e2018-04-04 23:07:35 +02001264 private static native void nSetContextPriority(int priority);
Jorim Jaggi7823ee72018-07-17 15:24:16 +02001265 private static native void nAllocateBuffers(long nativeProxy, Surface window);
John Reckcec24ae2013-11-05 13:27:50 -08001266}