blob: e50d40ef098fbbbb84031f8daaa7ee99f0b75b24 [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;
Sudheer Shankadc589ac2016-11-10 15:30:17 -080021import android.app.ActivityManager;
John Reckb8802b12014-06-16 15:28:50 -070022import android.content.Context;
Alan Viverette58c42c32014-07-12 20:33:45 -070023import android.content.res.TypedArray;
John Reck04fc5832014-02-05 16:38:25 -080024import android.graphics.Bitmap;
Alan Viverette50210d92015-05-14 18:05:36 -070025import android.graphics.Point;
Alan Viveretteccb11e12014-07-08 16:04:02 -070026import android.graphics.Rect;
Doris Liu67ce99b2016-05-17 16:50:31 -070027import android.graphics.drawable.AnimatedVectorDrawable;
John Reck66f0be62014-05-13 13:39:31 -070028import android.os.IBinder;
John Reckedc524c2015-03-18 15:24:33 -070029import android.os.ParcelFileDescriptor;
John Reckdf1742e2017-01-19 15:56:21 -080030import android.os.RemoteException;
John Reck66f0be62014-05-13 13:39:31 -070031import android.os.ServiceManager;
Jaesung Chung9a89d832017-05-16 01:54:17 +090032import android.os.SystemProperties;
John Reckcec24ae2013-11-05 13:27:50 -080033import android.os.Trace;
John Reck66f0be62014-05-13 13:39:31 -070034import android.util.Log;
John Reckcec24ae2013-11-05 13:27:50 -080035import android.view.Surface.OutOfResourcesException;
36import android.view.View.AttachInfo;
37
John Reckba6adf62015-02-19 14:36:50 -080038import com.android.internal.R;
Andres Morales06f5bc72015-12-15 15:21:31 -080039import com.android.internal.util.VirtualRefBasePtr;
John Reckba6adf62015-02-19 14:36:50 -080040
John Reck51aaf902015-12-02 15:08:07 -080041import java.io.File;
John Reckfe5e7b72014-05-23 17:42:28 -070042import java.io.FileDescriptor;
John Reckcec24ae2013-11-05 13:27:50 -080043import java.io.PrintWriter;
John Reckba6adf62015-02-19 14:36:50 -080044import java.lang.annotation.Retention;
45import java.lang.annotation.RetentionPolicy;
John Reckcec24ae2013-11-05 13:27:50 -080046
47/**
Stan Iliev45faba52016-06-28 13:33:15 -040048 * Threaded renderer that proxies the rendering to a render thread. Most calls
John Reck4f02bf42014-01-03 18:09:17 -080049 * are currently synchronous.
John Reckcec24ae2013-11-05 13:27:50 -080050 *
51 * The UI thread can block on the RenderThread, but RenderThread must never
52 * block on the UI thread.
53 *
John Reck4f02bf42014-01-03 18:09:17 -080054 * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
55 * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
56 * by the lifecycle of the RenderProxy.
57 *
John Reckcec24ae2013-11-05 13:27:50 -080058 * Note that although currently the EGL context & surfaces are created & managed
59 * by the render thread, the goal is to move that into a shared structure that can
60 * be managed by both threads. EGLSurface creation & deletion should ideally be
61 * done on the UI thread and not the RenderThread to avoid stalling the
62 * RenderThread with surface buffer allocation.
63 *
64 * @hide
65 */
John Reck51aaf902015-12-02 15:08:07 -080066public final class ThreadedRenderer {
67 private static final String LOG_TAG = "ThreadedRenderer";
68
69 /**
70 * Name of the file that holds the shaders cache.
71 */
72 private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
Stan Ilievd495f432017-10-09 15:49:32 -040073 private static final String CACHE_PATH_SKIASHADERS = "com.android.skia.shaders_cache";
John Reck51aaf902015-12-02 15:08:07 -080074
75 /**
Stan Iliev45faba52016-06-28 13:33:15 -040076 * System property used to enable or disable threaded rendering profiling.
John Reck51aaf902015-12-02 15:08:07 -080077 * The default value of this property is assumed to be false.
78 *
79 * When profiling is enabled, the adb shell dumpsys gfxinfo command will
80 * output extra information about the time taken to execute by the last
81 * frames.
82 *
83 * Possible values:
84 * "true", to enable profiling
85 * "visual_bars", to enable profiling and visualize the results on screen
86 * "false", to disable profiling
87 *
88 * @see #PROFILE_PROPERTY_VISUALIZE_BARS
89 *
90 * @hide
91 */
92 public static final String PROFILE_PROPERTY = "debug.hwui.profile";
93
94 /**
95 * Value for {@link #PROFILE_PROPERTY}. When the property is set to this
96 * value, profiling data will be visualized on screen as a bar chart.
97 *
98 * @hide
99 */
100 public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars";
101
102 /**
103 * System property used to specify the number of frames to be used
Stan Iliev45faba52016-06-28 13:33:15 -0400104 * when doing threaded rendering profiling.
John Reck51aaf902015-12-02 15:08:07 -0800105 * The default value of this property is #PROFILE_MAX_FRAMES.
106 *
107 * When profiling is enabled, the adb shell dumpsys gfxinfo command will
108 * output extra information about the time taken to execute by the last
109 * frames.
110 *
111 * Possible values:
112 * "60", to set the limit of frames to 60
113 */
114 static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes";
115
116 /**
117 * System property used to debug EGL configuration choice.
118 *
119 * Possible values:
120 * "choice", print the chosen configuration only
121 * "all", print all possible configurations
122 */
123 static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config";
124
125 /**
126 * Turn on to draw dirty regions every other frame.
127 *
128 * Possible values:
129 * "true", to enable dirty regions debugging
130 * "false", to disable dirty regions debugging
131 *
132 * @hide
133 */
134 public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
135
136 /**
137 * Turn on to flash hardware layers when they update.
138 *
139 * Possible values:
140 * "true", to enable hardware layers updates debugging
141 * "false", to disable hardware layers updates debugging
142 *
143 * @hide
144 */
145 public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
146 "debug.hwui.show_layers_updates";
147
148 /**
149 * Controls overdraw debugging.
150 *
151 * Possible values:
152 * "false", to disable overdraw debugging
153 * "show", to show overdraw areas on screen
154 * "count", to display an overdraw counter
155 *
156 * @hide
157 */
158 public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
159
160 /**
161 * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
162 * value, overdraw will be shown on screen by coloring pixels.
163 *
164 * @hide
165 */
166 public static final String OVERDRAW_PROPERTY_SHOW = "show";
167
168 /**
169 * Turn on to debug non-rectangular clip operations.
170 *
171 * Possible values:
172 * "hide", to disable this debug mode
173 * "highlight", highlight drawing commands tested against a non-rectangular clip
174 * "stencil", renders the clip region on screen when set
175 *
176 * @hide
177 */
178 public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
179 "debug.hwui.show_non_rect_clip";
180
John Reck9f516442017-09-25 10:27:21 -0700181 /**
182 * Sets the FPS devisor to lower the FPS.
183 *
184 * Sets a positive integer as a divisor. 1 (the default value) menas the full FPS, and 2
185 * means half the full FPS.
186 *
187 *
188 * @hide
189 */
190 public static final String DEBUG_FPS_DIVISOR = "debug.hwui.fps_divisor";
191
Jaesung Chung9a89d832017-05-16 01:54:17 +0900192 static {
193 // Try to check OpenGL support early if possible.
194 isAvailable();
195 }
196
John Reck51aaf902015-12-02 15:08:07 -0800197 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400198 * A process can set this flag to false to prevent the use of threaded
John Reck51aaf902015-12-02 15:08:07 -0800199 * rendering.
200 *
201 * @hide
202 */
203 public static boolean sRendererDisabled = false;
204
205 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400206 * Further threaded renderer disabling for the system process.
John Reck51aaf902015-12-02 15:08:07 -0800207 *
208 * @hide
209 */
210 public static boolean sSystemRendererDisabled = false;
211
212 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400213 * Invoke this method to disable threaded rendering in the current process.
John Reck51aaf902015-12-02 15:08:07 -0800214 *
215 * @hide
216 */
217 public static void disable(boolean system) {
218 sRendererDisabled = true;
219 if (system) {
220 sSystemRendererDisabled = true;
221 }
222 }
223
224 public static boolean sTrimForeground = false;
225
226 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400227 * Controls whether or not the renderer should aggressively trim
228 * memory. Note that this must not be set for any process that uses
229 * WebView! This should be only used by system_process or similar
John Reck51aaf902015-12-02 15:08:07 -0800230 * that do not go into the background.
231 */
232 public static void enableForegroundTrimming() {
233 sTrimForeground = true;
234 }
235
Jaesung Chung9a89d832017-05-16 01:54:17 +0900236 private static Boolean sSupportsOpenGL;
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -0400237
John Reck51aaf902015-12-02 15:08:07 -0800238 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400239 * Indicates whether threaded rendering is available under any form for
John Reck51aaf902015-12-02 15:08:07 -0800240 * the view hierarchy.
241 *
Stan Iliev45faba52016-06-28 13:33:15 -0400242 * @return True if the view hierarchy can potentially be defer rendered,
John Reck51aaf902015-12-02 15:08:07 -0800243 * false otherwise
244 */
245 public static boolean isAvailable() {
Jaesung Chung9a89d832017-05-16 01:54:17 +0900246 if (sSupportsOpenGL != null) {
247 return sSupportsOpenGL.booleanValue();
248 }
249 if (SystemProperties.getInt("ro.kernel.qemu", 0) == 0) {
250 // Device is not an emulator.
251 sSupportsOpenGL = true;
252 return true;
253 }
254 int qemu_gles = SystemProperties.getInt("qemu.gles", -1);
255 if (qemu_gles == -1) {
256 // In this case, the value of the qemu.gles property is not ready
257 // because the SurfaceFlinger service may not start at this point.
258 return false;
259 }
260 // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
261 // enabled, 0 otherwise. On old emulator versions it will be undefined.
262 sSupportsOpenGL = qemu_gles > 0;
263 return sSupportsOpenGL.booleanValue();
John Reck51aaf902015-12-02 15:08:07 -0800264 }
265
266 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400267 * Sets the directory to use as a persistent storage for threaded rendering
John Reck51aaf902015-12-02 15:08:07 -0800268 * resources.
269 *
270 * @param cacheDir A directory the current process can write to
271 *
272 * @hide
273 */
274 public static void setupDiskCache(File cacheDir) {
Stan Ilievd495f432017-10-09 15:49:32 -0400275 ThreadedRenderer.setupShadersDiskCache(
276 new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(),
277 new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath());
John Reck51aaf902015-12-02 15:08:07 -0800278 }
279
280 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400281 * Creates a threaded renderer using OpenGL.
John Reck51aaf902015-12-02 15:08:07 -0800282 *
283 * @param translucent True if the surface is translucent, false otherwise
284 *
Stan Iliev45faba52016-06-28 13:33:15 -0400285 * @return A threaded renderer backed by OpenGL.
John Reck51aaf902015-12-02 15:08:07 -0800286 */
John Reckdf1742e2017-01-19 15:56:21 -0800287 public static ThreadedRenderer create(Context context, boolean translucent, String name) {
John Reck51aaf902015-12-02 15:08:07 -0800288 ThreadedRenderer renderer = null;
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -0400289 if (isAvailable()) {
John Reckdf1742e2017-01-19 15:56:21 -0800290 renderer = new ThreadedRenderer(context, translucent, name);
John Reck51aaf902015-12-02 15:08:07 -0800291 }
292 return renderer;
293 }
294
295 /**
296 * Invoke this method when the system is running out of memory. This
297 * method will attempt to recover as much memory as possible, based on
298 * the specified hint.
299 *
300 * @param level Hint about the amount of memory that should be trimmed,
301 * see {@link android.content.ComponentCallbacks}
302 */
303 public static void trimMemory(int level) {
304 nTrimMemory(level);
305 }
306
307 public static void overrideProperty(@NonNull String name, @NonNull String value) {
308 if (name == null || value == null) {
309 throw new IllegalArgumentException("name and value must be non-null");
310 }
311 nOverrideProperty(name, value);
312 }
313
John Reckf9be7792014-05-02 18:21:16 -0700314 // Keep in sync with DrawFrameTask.h SYNC_* flags
315 // Nothing interesting to report
John Reckcd028f32014-06-24 08:44:29 -0700316 private static final int SYNC_OK = 0;
John Reckf9be7792014-05-02 18:21:16 -0700317 // Needs a ViewRoot invalidate
John Reckcd028f32014-06-24 08:44:29 -0700318 private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
John Reckaa95a882014-11-07 11:02:07 -0800319 // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
320 private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
John Reck9a17da82016-04-18 11:17:52 -0700321 // setStopped is true, drawing is false
322 // TODO: Remove this and SYNC_LOST_SURFACE_REWARD_IF_FOUND?
323 // This flag isn't really used as there's nothing that we care to do
324 // in response, so it really just exists to differentiate from LOST_SURFACE
325 // but possibly both can just be deleted.
326 private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
John Reckf9be7792014-05-02 18:21:16 -0700327
John Reckfe5e7b72014-05-23 17:42:28 -0700328 private static final String[] VISUALIZERS = {
329 PROFILE_PROPERTY_VISUALIZE_BARS,
330 };
331
John Reckba6adf62015-02-19 14:36:50 -0800332 private static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
333 private static final int FLAG_DUMP_RESET = 1 << 1;
John Reck184264d2018-02-12 16:21:21 -0800334 private static final int FLAG_DUMP_ALL = FLAG_DUMP_FRAMESTATS;
John Reckba6adf62015-02-19 14:36:50 -0800335
Jeff Sharkeyce8db992017-12-13 20:05:05 -0700336 @IntDef(flag = true, prefix = { "FLAG_DUMP_" }, value = {
337 FLAG_DUMP_FRAMESTATS,
338 FLAG_DUMP_RESET
339 })
John Reckba6adf62015-02-19 14:36:50 -0800340 @Retention(RetentionPolicy.SOURCE)
341 public @interface DumpFlags {}
342
Alan Viveretteccb11e12014-07-08 16:04:02 -0700343 // Size of the rendered content.
John Reckcec24ae2013-11-05 13:27:50 -0800344 private int mWidth, mHeight;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700345
346 // Actual size of the drawing surface.
347 private int mSurfaceWidth, mSurfaceHeight;
348
349 // Insets between the drawing surface and rendered content. These are
350 // applied as translation when updating the root render node.
351 private int mInsetTop, mInsetLeft;
352
Alan Viverette57774a82014-07-15 15:49:55 -0700353 // Whether the surface has insets. Used to protect opacity.
354 private boolean mHasInsets;
355
Alan Viverette58c42c32014-07-12 20:33:45 -0700356 // Light and shadow properties specified by the theme.
357 private final float mLightY;
358 private final float mLightZ;
359 private final float mLightRadius;
Chris Craik058fc642014-07-23 18:19:28 -0700360 private final int mAmbientShadowAlpha;
361 private final int mSpotShadowAlpha;
Alan Viverette58c42c32014-07-12 20:33:45 -0700362
John Reck4f02bf42014-01-03 18:09:17 -0800363 private long mNativeProxy;
John Reckf7d9c1d2014-04-09 10:01:03 -0700364 private boolean mInitialized = false;
John Reckbc0cc022014-04-11 16:08:14 -0700365 private RenderNode mRootNode;
John Reck0a973302014-07-16 13:29:45 -0700366 private boolean mRootNodeNeedsUpdate;
John Reckcec24ae2013-11-05 13:27:50 -0800367
John Reck51aaf902015-12-02 15:08:07 -0800368 private boolean mEnabled;
369 private boolean mRequested = true;
John Reck3e04f092017-06-02 15:50:09 -0700370 private boolean mIsOpaque = false;
John Reck51aaf902015-12-02 15:08:07 -0800371
John Reckdf1742e2017-01-19 15:56:21 -0800372 ThreadedRenderer(Context context, boolean translucent, String name) {
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700373 final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
Alan Viverette58c42c32014-07-12 20:33:45 -0700374 mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
375 mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
376 mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700377 mAmbientShadowAlpha =
378 (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
379 mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
Alan Viverette58c42c32014-07-12 20:33:45 -0700380 a.recycle();
381
John Recke45b1fd2014-04-15 09:50:16 -0700382 long rootNodePtr = nCreateRootRenderNode();
383 mRootNode = RenderNode.adopt(rootNodePtr);
John Reckbc0cc022014-04-11 16:08:14 -0700384 mRootNode.setClipToBounds(false);
John Reck3e04f092017-06-02 15:50:09 -0700385 mIsOpaque = !translucent;
John Recke45b1fd2014-04-15 09:50:16 -0700386 mNativeProxy = nCreateProxy(translucent, rootNodePtr);
John Reckdf1742e2017-01-19 15:56:21 -0800387 nSetName(mNativeProxy, name);
John Reck18f16e62014-05-02 16:46:41 -0700388
John Reckedc524c2015-03-18 15:24:33 -0700389 ProcessInitializer.sInstance.init(context, mNativeProxy);
John Reck3b202512014-06-23 13:13:08 -0700390
John Reckfe5e7b72014-05-23 17:42:28 -0700391 loadSystemProperties();
John Reckcec24ae2013-11-05 13:27:50 -0800392 }
393
John Reck51aaf902015-12-02 15:08:07 -0800394 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400395 * Destroys the threaded rendering context.
John Reck51aaf902015-12-02 15:08:07 -0800396 */
John Reckf47a5942014-06-30 16:20:04 -0700397 void destroy() {
John Reckf7d9c1d2014-04-09 10:01:03 -0700398 mInitialized = false;
399 updateEnabledState(null);
Doris Liu350e6522016-02-19 14:20:37 -0800400 nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
John Reckcec24ae2013-11-05 13:27:50 -0800401 }
402
John Reck51aaf902015-12-02 15:08:07 -0800403 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400404 * Indicates whether threaded rendering is currently enabled.
John Reck51aaf902015-12-02 15:08:07 -0800405 *
Stan Iliev45faba52016-06-28 13:33:15 -0400406 * @return True if threaded rendering is in use, false otherwise.
John Reck51aaf902015-12-02 15:08:07 -0800407 */
408 boolean isEnabled() {
409 return mEnabled;
410 }
411
412 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400413 * Indicates whether threaded rendering is currently enabled.
John Reck51aaf902015-12-02 15:08:07 -0800414 *
Stan Iliev45faba52016-06-28 13:33:15 -0400415 * @param enabled True if the threaded renderer is in use, false otherwise.
John Reck51aaf902015-12-02 15:08:07 -0800416 */
417 void setEnabled(boolean enabled) {
418 mEnabled = enabled;
419 }
420
421 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400422 * Indicates whether threaded rendering is currently request but not
John Reck51aaf902015-12-02 15:08:07 -0800423 * necessarily enabled yet.
424 *
425 * @return True if requested, false otherwise.
426 */
427 boolean isRequested() {
428 return mRequested;
429 }
430
431 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400432 * Indicates whether threaded rendering is currently requested but not
John Reck51aaf902015-12-02 15:08:07 -0800433 * necessarily enabled yet.
John Reck51aaf902015-12-02 15:08:07 -0800434 */
435 void setRequested(boolean requested) {
436 mRequested = requested;
437 }
438
John Reckf7d9c1d2014-04-09 10:01:03 -0700439 private void updateEnabledState(Surface surface) {
440 if (surface == null || !surface.isValid()) {
441 setEnabled(false);
442 } else {
443 setEnabled(mInitialized);
444 }
445 }
446
John Reck51aaf902015-12-02 15:08:07 -0800447 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400448 * Initializes the threaded renderer for the specified surface.
John Reck51aaf902015-12-02 15:08:07 -0800449 *
Stan Iliev45faba52016-06-28 13:33:15 -0400450 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800451 *
452 * @return True if the initialization was successful, false otherwise.
453 */
John Reckcec24ae2013-11-05 13:27:50 -0800454 boolean initialize(Surface surface) throws OutOfResourcesException {
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100455 boolean status = !mInitialized;
John Reckf7d9c1d2014-04-09 10:01:03 -0700456 mInitialized = true;
457 updateEnabledState(surface);
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100458 nInitialize(mNativeProxy, surface);
Dan Stoza5795d642014-06-20 13:01:36 -0700459 return status;
John Reckcec24ae2013-11-05 13:27:50 -0800460 }
461
John Reck51aaf902015-12-02 15:08:07 -0800462 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400463 * Initializes the threaded renderer for the specified surface and setup the
John Reck51aaf902015-12-02 15:08:07 -0800464 * renderer for drawing, if needed. This is invoked when the ViewAncestor has
Stan Iliev45faba52016-06-28 13:33:15 -0400465 * potentially lost the threaded renderer. The threaded renderer should be
John Reck51aaf902015-12-02 15:08:07 -0800466 * reinitialized and setup when the render {@link #isRequested()} and
467 * {@link #isEnabled()}.
468 *
469 * @param width The width of the drawing surface.
470 * @param height The height of the drawing surface.
471 * @param attachInfo Information about the window.
Stan Iliev45faba52016-06-28 13:33:15 -0400472 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800473 * @param surfaceInsets The drawing surface insets to apply
474 *
475 * @return true if the surface was initialized, false otherwise. Returning
476 * false might mean that the surface was already initialized.
477 */
478 boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
479 Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
480 if (isRequested()) {
481 // We lost the gl context, so recreate it.
482 if (!isEnabled()) {
483 if (initialize(surface)) {
484 setup(width, height, attachInfo, surfaceInsets);
485 return true;
486 }
487 }
488 }
489 return false;
490 }
491
492 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400493 * Updates the threaded renderer for the specified surface.
John Reck51aaf902015-12-02 15:08:07 -0800494 *
Stan Iliev45faba52016-06-28 13:33:15 -0400495 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800496 */
John Reckcec24ae2013-11-05 13:27:50 -0800497 void updateSurface(Surface surface) throws OutOfResourcesException {
John Reckf7d9c1d2014-04-09 10:01:03 -0700498 updateEnabledState(surface);
John Reck4f02bf42014-01-03 18:09:17 -0800499 nUpdateSurface(mNativeProxy, surface);
John Reckcec24ae2013-11-05 13:27:50 -0800500 }
501
John Reck51aaf902015-12-02 15:08:07 -0800502 /**
John Reck8afcc762016-04-13 10:24:06 -0700503 * Halts any current rendering into the surface. Use this if it is unclear whether
Stan Iliev45faba52016-06-28 13:33:15 -0400504 * or not the surface used by the ThreadedRenderer will be changing. It
John Reck8afcc762016-04-13 10:24:06 -0700505 * Suspends any rendering into the surface, but will not do any destruction.
506 *
507 * Any subsequent draws will override the pause, resuming normal operation.
John Reck51aaf902015-12-02 15:08:07 -0800508 */
John Reck01a5ea32014-12-03 13:01:07 -0800509 boolean pauseSurface(Surface surface) {
510 return nPauseSurface(mNativeProxy, surface);
John Reckf7d9c1d2014-04-09 10:01:03 -0700511 }
512
John Reck51aaf902015-12-02 15:08:07 -0800513 /**
John Reck8afcc762016-04-13 10:24:06 -0700514 * Hard stops or resumes rendering into the surface. This flag is used to
515 * determine whether or not it is safe to use the given surface *at all*
516 */
517 void setStopped(boolean stopped) {
518 nSetStopped(mNativeProxy, stopped);
519 }
520
521 /**
John Reck51aaf902015-12-02 15:08:07 -0800522 * Destroys all hardware rendering resources associated with the specified
523 * view hierarchy.
524 *
525 * @param view The root of the view hierarchy
526 */
John Reckcec24ae2013-11-05 13:27:50 -0800527 void destroyHardwareResources(View view) {
John Reck4f02bf42014-01-03 18:09:17 -0800528 destroyResources(view);
John Reckf47a5942014-06-30 16:20:04 -0700529 nDestroyHardwareResources(mNativeProxy);
John Reck4f02bf42014-01-03 18:09:17 -0800530 }
531
532 private static void destroyResources(View view) {
533 view.destroyHardwareResources();
John Reckcec24ae2013-11-05 13:27:50 -0800534 }
535
John Reck51aaf902015-12-02 15:08:07 -0800536 /**
John Reck51aaf902015-12-02 15:08:07 -0800537 * Detaches the layer's surface texture from the GL context and releases
538 * the texture id
539 */
John Reck918ad522014-06-27 14:45:25 -0700540 void detachSurfaceTexture(long hardwareLayer) {
541 nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
John Reckcec24ae2013-11-05 13:27:50 -0800542 }
543
John Reck51aaf902015-12-02 15:08:07 -0800544 /**
545 * Sets up the renderer for drawing.
546 *
547 * @param width The width of the drawing surface.
548 * @param height The height of the drawing surface.
549 * @param attachInfo Information about the window.
550 * @param surfaceInsets The drawing surface insets to apply
551 */
Alan Viverette50210d92015-05-14 18:05:36 -0700552 void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
John Reckcec24ae2013-11-05 13:27:50 -0800553 mWidth = width;
554 mHeight = height;
Alan Viverette50210d92015-05-14 18:05:36 -0700555
Alan Viverette3aa1ffb2014-10-30 12:22:08 -0700556 if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
557 || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
Alan Viverette57774a82014-07-15 15:49:55 -0700558 mHasInsets = true;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700559 mInsetLeft = surfaceInsets.left;
560 mInsetTop = surfaceInsets.top;
561 mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
562 mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
Alan Viverette57774a82014-07-15 15:49:55 -0700563
564 // If the surface has insets, it can't be opaque.
565 setOpaque(false);
Alan Viveretteccb11e12014-07-08 16:04:02 -0700566 } else {
Alan Viverette57774a82014-07-15 15:49:55 -0700567 mHasInsets = false;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700568 mInsetLeft = 0;
569 mInsetTop = 0;
570 mSurfaceWidth = width;
571 mSurfaceHeight = height;
572 }
Alan Viverette50210d92015-05-14 18:05:36 -0700573
Alan Viveretteccb11e12014-07-08 16:04:02 -0700574 mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
John Reckab1080c2016-06-21 16:24:20 -0700575 nSetup(mNativeProxy, mLightRadius,
John Reckb36016c2015-03-11 08:50:53 -0700576 mAmbientShadowAlpha, mSpotShadowAlpha);
Alan Viverette50210d92015-05-14 18:05:36 -0700577
578 setLightCenter(attachInfo);
579 }
580
John Reck51aaf902015-12-02 15:08:07 -0800581 /**
582 * Updates the light position based on the position of the window.
583 *
584 * @param attachInfo Information about the window.
585 */
Alan Viverette50210d92015-05-14 18:05:36 -0700586 void setLightCenter(AttachInfo attachInfo) {
587 // Adjust light position for window offsets.
588 final Point displaySize = attachInfo.mPoint;
589 attachInfo.mDisplay.getRealSize(displaySize);
590 final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
591 final float lightY = mLightY - attachInfo.mWindowTop;
592
593 nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
John Reckcec24ae2013-11-05 13:27:50 -0800594 }
595
John Reck51aaf902015-12-02 15:08:07 -0800596 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400597 * Change the ThreadedRenderer's opacity
John Reck51aaf902015-12-02 15:08:07 -0800598 */
John Reck63a06672014-05-07 13:45:54 -0700599 void setOpaque(boolean opaque) {
John Reck3e04f092017-06-02 15:50:09 -0700600 mIsOpaque = opaque && !mHasInsets;
601 nSetOpaque(mNativeProxy, mIsOpaque);
602 }
603
604 boolean isOpaque() {
605 return mIsOpaque;
John Reck63a06672014-05-07 13:45:54 -0700606 }
607
John Reck51aaf902015-12-02 15:08:07 -0800608 /**
Romain Guy26a2b972017-04-17 09:39:51 -0700609 * Enable/disable wide gamut rendering on this renderer.
610 */
611 void setWideGamut(boolean wideGamut) {
612 nSetWideGamut(mNativeProxy, wideGamut);
613 }
614
615 /**
John Reck51aaf902015-12-02 15:08:07 -0800616 * Gets the current width of the surface. This is the width that the surface
617 * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
618 *
619 * @return the current width of the surface
620 */
John Reckcec24ae2013-11-05 13:27:50 -0800621 int getWidth() {
622 return mWidth;
623 }
624
John Reck51aaf902015-12-02 15:08:07 -0800625 /**
626 * Gets the current height of the surface. This is the height that the surface
627 * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
628 *
629 * @return the current width of the surface
630 */
John Reckcec24ae2013-11-05 13:27:50 -0800631 int getHeight() {
632 return mHeight;
633 }
634
John Reck51aaf902015-12-02 15:08:07 -0800635 /**
636 * Outputs extra debugging information in the specified file descriptor.
637 */
John Reckba6adf62015-02-19 14:36:50 -0800638 void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
John Reckfe5e7b72014-05-23 17:42:28 -0700639 pw.flush();
John Reck184264d2018-02-12 16:21:21 -0800640 // If there's no arguments, eg 'dumpsys gfxinfo', then dump everything.
641 // If there's a targetted package, eg 'dumpsys gfxinfo com.android.systemui', then only
642 // dump the summary information
643 int flags = (args == null || args.length == 0) ? FLAG_DUMP_ALL : 0;
John Reckba6adf62015-02-19 14:36:50 -0800644 for (int i = 0; i < args.length; i++) {
645 switch (args[i]) {
646 case "framestats":
647 flags |= FLAG_DUMP_FRAMESTATS;
648 break;
649 case "reset":
650 flags |= FLAG_DUMP_RESET;
651 break;
John Reck184264d2018-02-12 16:21:21 -0800652 case "-a": // magic option passed when dumping a bugreport.
653 flags = FLAG_DUMP_ALL;
654 break;
John Reckba6adf62015-02-19 14:36:50 -0800655 }
John Reckfe5e7b72014-05-23 17:42:28 -0700656 }
John Reckba6adf62015-02-19 14:36:50 -0800657 nDumpProfileInfo(mNativeProxy, fd, flags);
John Reckcec24ae2013-11-05 13:27:50 -0800658 }
659
John Reck51aaf902015-12-02 15:08:07 -0800660 /**
661 * Loads system properties used by the renderer. This method is invoked
662 * whenever system properties are modified. Implementations can use this
663 * to trigger live updates of the renderer based on properties.
664 *
665 * @return True if a property has changed.
666 */
John Reckcec24ae2013-11-05 13:27:50 -0800667 boolean loadSystemProperties() {
John Reckfe5e7b72014-05-23 17:42:28 -0700668 boolean changed = nLoadSystemProperties(mNativeProxy);
John Reck23d307c2014-10-27 12:38:48 -0700669 if (changed) {
670 invalidateRoot();
671 }
John Reckfe5e7b72014-05-23 17:42:28 -0700672 return changed;
John Reckcec24ae2013-11-05 13:27:50 -0800673 }
674
John Reck0a973302014-07-16 13:29:45 -0700675 private void updateViewTreeDisplayList(View view) {
John Reckcec24ae2013-11-05 13:27:50 -0800676 view.mPrivateFlags |= View.PFLAG_DRAWN;
John Reckcec24ae2013-11-05 13:27:50 -0800677 view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
678 == View.PFLAG_INVALIDATED;
679 view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
Chris Craik31a2d062015-05-01 14:22:47 -0700680 view.updateDisplayListIfDirty();
John Reckcec24ae2013-11-05 13:27:50 -0800681 view.mRecreateDisplayList = false;
John Reckbc0cc022014-04-11 16:08:14 -0700682 }
683
Stan Iliev45faba52016-06-28 13:33:15 -0400684 private void updateRootDisplayList(View view, DrawCallbacks callbacks) {
Chris Craik70850ea2014-11-18 10:49:23 -0800685 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
John Reck0a973302014-07-16 13:29:45 -0700686 updateViewTreeDisplayList(view);
687
688 if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
Chris Craikf6829a02015-03-10 10:28:59 -0700689 DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
John Reck0a973302014-07-16 13:29:45 -0700690 try {
Alan Viverettedbed8932014-08-06 17:54:52 -0700691 final int saveCount = canvas.save();
John Reck0a973302014-07-16 13:29:45 -0700692 canvas.translate(mInsetLeft, mInsetTop);
Stan Iliev45faba52016-06-28 13:33:15 -0400693 callbacks.onPreDraw(canvas);
Chris Craikabedca32014-08-28 15:03:55 -0700694
695 canvas.insertReorderBarrier();
Chris Craik31a2d062015-05-01 14:22:47 -0700696 canvas.drawRenderNode(view.updateDisplayListIfDirty());
Chris Craikabedca32014-08-28 15:03:55 -0700697 canvas.insertInorderBarrier();
698
Stan Iliev45faba52016-06-28 13:33:15 -0400699 callbacks.onPostDraw(canvas);
Alan Viverettedbed8932014-08-06 17:54:52 -0700700 canvas.restoreToCount(saveCount);
John Reck0a973302014-07-16 13:29:45 -0700701 mRootNodeNeedsUpdate = false;
702 } finally {
703 mRootNode.end(canvas);
704 }
705 }
706 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
707 }
708
Skuhneea7a7fb2015-08-28 07:10:31 -0700709 /**
710 * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
711 * rendernode of the UI thread.
712 * @param node The node to add.
713 * @param placeFront If true, the render node will be placed in front of the content node,
714 * otherwise behind the content node.
715 */
716 public void addRenderNode(RenderNode node, boolean placeFront) {
717 nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
718 }
719
720 /**
721 * Only especially added render nodes can be removed.
722 * @param node The node which was added via addRenderNode which should get removed again.
723 */
724 public void removeRenderNode(RenderNode node) {
725 nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
726 }
727
728 /**
729 * Draws a particular render node. If the node is not the content node, only the additional
730 * nodes will get drawn and the content remains untouched.
731 * @param node The node to be drawn.
732 */
733 public void drawRenderNode(RenderNode node) {
734 nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
735 }
736
737 /**
738 * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
739 * will be prevented to overdraw this area. It will be synchronized with the draw call.
740 * This should be updated in the content view's draw call.
741 * @param left The left side of the protected bounds.
742 * @param top The top side of the protected bounds.
743 * @param right The right side of the protected bounds.
744 * @param bottom The bottom side of the protected bounds.
745 */
Skuhneb8160872015-09-22 09:51:39 -0700746 public void setContentDrawBounds(int left, int top, int right, int bottom) {
Jorim Jaggie85ce992016-05-09 19:05:22 -0700747 nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
Skuhneea7a7fb2015-08-28 07:10:31 -0700748 }
749
John Reck51aaf902015-12-02 15:08:07 -0800750 /**
751 * Interface used to receive callbacks whenever a view is drawn by
Stan Iliev45faba52016-06-28 13:33:15 -0400752 * a threaded renderer instance.
John Reck51aaf902015-12-02 15:08:07 -0800753 */
Stan Iliev45faba52016-06-28 13:33:15 -0400754 interface DrawCallbacks {
John Reck51aaf902015-12-02 15:08:07 -0800755 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400756 * Invoked before a view is drawn by a threaded renderer.
John Reck51aaf902015-12-02 15:08:07 -0800757 * This method can be used to apply transformations to the
758 * canvas but no drawing command should be issued.
759 *
760 * @param canvas The Canvas used to render the view.
761 */
Stan Iliev45faba52016-06-28 13:33:15 -0400762 void onPreDraw(DisplayListCanvas canvas);
John Reck51aaf902015-12-02 15:08:07 -0800763
764 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400765 * Invoked after a view is drawn by a threaded renderer.
John Reck51aaf902015-12-02 15:08:07 -0800766 * It is safe to invoke drawing commands from this method.
767 *
768 * @param canvas The Canvas used to render the view.
769 */
Stan Iliev45faba52016-06-28 13:33:15 -0400770 void onPostDraw(DisplayListCanvas canvas);
John Reck51aaf902015-12-02 15:08:07 -0800771 }
772
773 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400774 * Indicates that the content drawn by DrawCallbacks needs to
John Reck51aaf902015-12-02 15:08:07 -0800775 * be updated, which will be done by the next call to draw()
776 */
John Reck0a973302014-07-16 13:29:45 -0700777 void invalidateRoot() {
778 mRootNodeNeedsUpdate = true;
779 }
780
John Reck51aaf902015-12-02 15:08:07 -0800781 /**
782 * Draws the specified view.
783 *
784 * @param view The view to draw.
785 * @param attachInfo AttachInfo tied to the specified view.
786 * @param callbacks Callbacks invoked when drawing happens.
787 */
Stan Iliev45faba52016-06-28 13:33:15 -0400788 void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {
John Reckbc0cc022014-04-11 16:08:14 -0700789 attachInfo.mIgnoreDirtyState = true;
John Reckbc0cc022014-04-11 16:08:14 -0700790
John Reckba6adf62015-02-19 14:36:50 -0800791 final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
792 choreographer.mFrameInfo.markDrawStart();
John Reckfe5e7b72014-05-23 17:42:28 -0700793
John Reck61375a82014-09-18 19:27:48 +0000794 updateRootDisplayList(view, callbacks);
John Reckcec24ae2013-11-05 13:27:50 -0800795
John Reck6313b922014-04-16 18:59:21 -0700796 attachInfo.mIgnoreDirtyState = false;
797
John Reck119907c2014-08-14 09:02:01 -0700798 // register animating rendernodes which started animating prior to renderer
799 // creation, which is typical for animators started prior to first draw
800 if (attachInfo.mPendingAnimatingRenderNodes != null) {
801 final int count = attachInfo.mPendingAnimatingRenderNodes.size();
802 for (int i = 0; i < count; i++) {
803 registerAnimatingRenderNode(
804 attachInfo.mPendingAnimatingRenderNodes.get(i));
805 }
806 attachInfo.mPendingAnimatingRenderNodes.clear();
807 // We don't need this anymore as subsequent calls to
808 // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
809 attachInfo.mPendingAnimatingRenderNodes = null;
810 }
811
John Reckba6adf62015-02-19 14:36:50 -0800812 final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
John Reck51f2d602016-04-06 07:50:47 -0700813 int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
John Reckaa95a882014-11-07 11:02:07 -0800814 if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
815 setEnabled(false);
John Reckb13de072014-11-19 16:33:47 -0800816 attachInfo.mViewRootImpl.mSurface.release();
John Reckaa95a882014-11-07 11:02:07 -0800817 // Invalidate since we failed to draw. This should fetch a Surface
818 // if it is still needed or do nothing if we are no longer drawing
819 attachInfo.mViewRootImpl.invalidate();
820 }
John Reckf9be7792014-05-02 18:21:16 -0700821 if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
822 attachInfo.mViewRootImpl.invalidate();
823 }
John Reckcec24ae2013-11-05 13:27:50 -0800824 }
825
John Reck3b202512014-06-23 13:13:08 -0700826 static void invokeFunctor(long functor, boolean waitForCompletion) {
827 nInvokeFunctor(functor, waitForCompletion);
John Reck0d1f6342014-03-28 20:30:27 -0700828 }
829
John Reck51aaf902015-12-02 15:08:07 -0800830 /**
831 * Creates a new hardware layer. A hardware layer built by calling this
832 * method will be treated as a texture layer, instead of as a render target.
833 *
834 * @return A hardware layer
835 */
John Reck19b6bcf2014-02-14 20:03:38 -0800836 HardwareLayer createTextureLayer() {
837 long layer = nCreateTextureLayer(mNativeProxy);
838 return HardwareLayer.adoptTextureLayer(this, layer);
839 }
840
John Reck51aaf902015-12-02 15:08:07 -0800841
John Reck3e824952014-08-20 10:08:39 -0700842 void buildLayer(RenderNode node) {
843 nBuildLayer(mNativeProxy, node.getNativeDisplayList());
844 }
845
John Reck51aaf902015-12-02 15:08:07 -0800846
John Reck19b6bcf2014-02-14 20:03:38 -0800847 boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
848 return nCopyLayerInto(mNativeProxy,
John Reck3731dc22015-04-13 15:20:29 -0700849 layer.getDeferredLayerUpdater(), bitmap);
John Reck19b6bcf2014-02-14 20:03:38 -0800850 }
851
John Reck51aaf902015-12-02 15:08:07 -0800852 /**
853 * Indicates that the specified hardware layer needs to be updated
854 * as soon as possible.
855 *
856 * @param layer The hardware layer that needs an update
857 */
John Reck19b6bcf2014-02-14 20:03:38 -0800858 void pushLayerUpdate(HardwareLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700859 nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800860 }
861
John Reck51aaf902015-12-02 15:08:07 -0800862 /**
863 * Tells the HardwareRenderer that the layer is destroyed. The renderer
864 * should remove the layer from any update queues.
865 */
John Reck19b6bcf2014-02-14 20:03:38 -0800866 void onLayerDestroyed(HardwareLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700867 nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800868 }
869
John Reck51aaf902015-12-02 15:08:07 -0800870 /**
John Reck51aaf902015-12-02 15:08:07 -0800871 * Blocks until all previously queued work has completed.
872 */
John Reck28ad7b52014-04-07 16:59:25 -0700873 void fence() {
874 nFence(mNativeProxy);
875 }
876
John Reck51aaf902015-12-02 15:08:07 -0800877 /**
878 * Prevents any further drawing until draw() is called. This is a signal
879 * that the contents of the RenderNode tree are no longer safe to play back.
880 * In practice this usually means that there are Functor pointers in the
881 * display list that are no longer valid.
882 */
John Reckf47a5942014-06-30 16:20:04 -0700883 void stopDrawing() {
884 nStopDrawing(mNativeProxy);
885 }
886
John Reck51aaf902015-12-02 15:08:07 -0800887 /**
888 * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
889 */
John Recka5dda642014-05-22 15:43:54 -0700890 public void notifyFramePending() {
891 nNotifyFramePending(mNativeProxy);
892 }
893
John Reck51aaf902015-12-02 15:08:07 -0800894
John Reck119907c2014-08-14 09:02:01 -0700895 void registerAnimatingRenderNode(RenderNode animator) {
896 nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
897 }
898
Doris Liu67ce99b2016-05-17 16:50:31 -0700899 void registerVectorDrawableAnimator(
900 AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
901 nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
902 animator.getAnimatorNativePtr());
903 }
904
John Recke248bd12015-08-05 13:53:53 -0700905 public void serializeDisplayListTree() {
906 nSerializeDisplayListTree(mNativeProxy);
907 }
908
John Reck95801462016-09-01 09:44:09 -0700909 public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
910 if (srcRect == null) {
911 // Empty rect means entire surface
912 return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap);
913 } else {
914 return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
915 srcRect.right, srcRect.bottom, bitmap);
916 }
John Reck10dd0582016-03-31 16:36:16 -0700917 }
918
John Reck1fedd912017-05-23 14:45:22 -0700919 /**
920 * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given
921 * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and
922 * not the RenderNode from a View.
923 **/
924 public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
925 return nCreateHardwareBitmap(node.getNativeDisplayList(), width, height);
926 }
927
John Reck938e8842017-08-24 13:41:59 -0700928 /**
929 * Sets whether or not high contrast text rendering is enabled. The setting is global
930 * but only affects content rendered after the change is made.
931 */
932 public static void setHighContrastText(boolean highContrastText) {
933 nSetHighContrastText(highContrastText);
934 }
935
John Reck119907c2014-08-14 09:02:01 -0700936 @Override
John Reck4f02bf42014-01-03 18:09:17 -0800937 protected void finalize() throws Throwable {
938 try {
939 nDeleteProxy(mNativeProxy);
John Reck0ed751d2014-04-08 14:10:17 -0700940 mNativeProxy = 0;
John Reck4f02bf42014-01-03 18:09:17 -0800941 } finally {
942 super.finalize();
John Reckcec24ae2013-11-05 13:27:50 -0800943 }
944 }
945
John Reckedc524c2015-03-18 15:24:33 -0700946 private static class ProcessInitializer {
947 static ProcessInitializer sInstance = new ProcessInitializer();
John Reck66f0be62014-05-13 13:39:31 -0700948
949 private boolean mInitialized = false;
950
John Reckdf1742e2017-01-19 15:56:21 -0800951 private Context mAppContext;
952 private IGraphicsStats mGraphicsStatsService;
953 private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
954 @Override
955 public void onRotateGraphicsStatsBuffer() throws RemoteException {
956 rotateBuffer();
957 }
958 };
959
John Reckedc524c2015-03-18 15:24:33 -0700960 private ProcessInitializer() {}
John Reck66f0be62014-05-13 13:39:31 -0700961
John Reck3b202512014-06-23 13:13:08 -0700962 synchronized void init(Context context, long renderProxy) {
John Reck66f0be62014-05-13 13:39:31 -0700963 if (mInitialized) return;
John Reckedc524c2015-03-18 15:24:33 -0700964 mInitialized = true;
John Reckdf1742e2017-01-19 15:56:21 -0800965 mAppContext = context.getApplicationContext();
John Reck9f516442017-09-25 10:27:21 -0700966
Romain Guy26a2b972017-04-17 09:39:51 -0700967 initSched(renderProxy);
John Reckdf1742e2017-01-19 15:56:21 -0800968 initGraphicsStats();
John Reckedc524c2015-03-18 15:24:33 -0700969 }
970
Romain Guy26a2b972017-04-17 09:39:51 -0700971 private void initSched(long renderProxy) {
Tim Murray33eb07f2016-06-10 10:03:20 -0700972 try {
973 int tid = nGetRenderThreadTid(renderProxy);
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800974 ActivityManager.getService().setRenderThread(tid);
Tim Murray33eb07f2016-06-10 10:03:20 -0700975 } catch (Throwable t) {
976 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
977 }
978 }
979
John Reckdf1742e2017-01-19 15:56:21 -0800980 private void initGraphicsStats() {
John Reckedc524c2015-03-18 15:24:33 -0700981 try {
John Reck828698b2015-06-30 12:56:03 -0700982 IBinder binder = ServiceManager.getService("graphicsstats");
983 if (binder == null) return;
John Reckdf1742e2017-01-19 15:56:21 -0800984 mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
985 requestBuffer();
986 } catch (Throwable t) {
987 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
988 }
989 }
990
991 private void rotateBuffer() {
992 nRotateProcessStatsBuffer();
993 requestBuffer();
994 }
995
996 private void requestBuffer() {
997 try {
998 final String pkg = mAppContext.getApplicationInfo().packageName;
999 ParcelFileDescriptor pfd = mGraphicsStatsService
1000 .requestBufferForProcess(pkg, mGraphicsStatsCallback);
1001 nSetProcessStatsBuffer(pfd.getFd());
John Reckedc524c2015-03-18 15:24:33 -07001002 pfd.close();
John Reck828698b2015-06-30 12:56:03 -07001003 } catch (Throwable t) {
1004 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
John Reckedc524c2015-03-18 15:24:33 -07001005 }
1006 }
John Reck66f0be62014-05-13 13:39:31 -07001007 }
1008
Andres Morales910beb82016-02-02 16:19:40 -08001009 void addFrameMetricsObserver(FrameMetricsObserver observer) {
1010 long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
1011 observer.mNative = new VirtualRefBasePtr(nativeObserver);
Andres Morales06f5bc72015-12-15 15:21:31 -08001012 }
1013
Andres Morales910beb82016-02-02 16:19:40 -08001014 void removeFrameMetricsObserver(FrameMetricsObserver observer) {
1015 nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
1016 observer.mNative = null;
Andres Morales06f5bc72015-12-15 15:21:31 -08001017 }
1018
John Reck9f516442017-09-25 10:27:21 -07001019 /** b/68769804: For low FPS experiments. */
1020 public static void setFPSDivisor(int divisor) {
Makoto Onukib708cbe2018-01-09 12:35:06 -08001021 nHackySetRTAnimationsEnabled(divisor <= 1);
John Reck9f516442017-09-25 10:27:21 -07001022 }
1023
John Recka8963062017-06-14 10:47:50 -07001024 /** Not actually public - internal use only. This doc to make lint happy */
1025 public static native void disableVsync();
1026
Stan Ilievd495f432017-10-09 15:49:32 -04001027 static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
John Reck84a4c882014-05-30 14:34:03 -07001028
John Reckdf1742e2017-01-19 15:56:21 -08001029 private static native void nRotateProcessStatsBuffer();
1030 private static native void nSetProcessStatsBuffer(int fd);
Tim Murray33eb07f2016-06-10 10:03:20 -07001031 private static native int nGetRenderThreadTid(long nativeProxy);
John Reck4f02bf42014-01-03 18:09:17 -08001032
John Recke45b1fd2014-04-15 09:50:16 -07001033 private static native long nCreateRootRenderNode();
1034 private static native long nCreateProxy(boolean translucent, long rootRenderNode);
John Reck4f02bf42014-01-03 18:09:17 -08001035 private static native void nDeleteProxy(long nativeProxy);
1036
John Recke4280ba2014-05-05 16:39:37 -07001037 private static native boolean nLoadSystemProperties(long nativeProxy);
John Reckb36016c2015-03-11 08:50:53 -07001038 private static native void nSetName(long nativeProxy, String name);
John Reck18f16e62014-05-02 16:46:41 -07001039
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +01001040 private static native void nInitialize(long nativeProxy, Surface window);
John Reck4f02bf42014-01-03 18:09:17 -08001041 private static native void nUpdateSurface(long nativeProxy, Surface window);
John Reck01a5ea32014-12-03 13:01:07 -08001042 private static native boolean nPauseSurface(long nativeProxy, Surface window);
John Reck8afcc762016-04-13 10:24:06 -07001043 private static native void nSetStopped(long nativeProxy, boolean stopped);
John Reckab1080c2016-06-21 16:24:20 -07001044 private static native void nSetup(long nativeProxy,
Alan Viverette50210d92015-05-14 18:05:36 -07001045 float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
1046 private static native void nSetLightCenter(long nativeProxy,
1047 float lightX, float lightY, float lightZ);
John Reck63a06672014-05-07 13:45:54 -07001048 private static native void nSetOpaque(long nativeProxy, boolean opaque);
Romain Guy26a2b972017-04-17 09:39:51 -07001049 private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
John Reck51f2d602016-04-06 07:50:47 -07001050 private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
Doris Liu350e6522016-02-19 14:20:37 -08001051 private static native void nDestroy(long nativeProxy, long rootRenderNode);
John Reck119907c2014-08-14 09:02:01 -07001052 private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
Doris Liu67ce99b2016-05-17 16:50:31 -07001053 private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
John Reck4f02bf42014-01-03 18:09:17 -08001054
John Reck3b202512014-06-23 13:13:08 -07001055 private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
John Reck19b6bcf2014-02-14 20:03:38 -08001056
John Reck19b6bcf2014-02-14 20:03:38 -08001057 private static native long nCreateTextureLayer(long nativeProxy);
John Reck3e824952014-08-20 10:08:39 -07001058 private static native void nBuildLayer(long nativeProxy, long node);
John Reck3731dc22015-04-13 15:20:29 -07001059 private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
John Reckd72e0a32014-05-29 18:56:11 -07001060 private static native void nPushLayerUpdate(long nativeProxy, long layer);
1061 private static native void nCancelLayerUpdate(long nativeProxy, long layer);
John Reck918ad522014-06-27 14:45:25 -07001062 private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
John Reck28ad7b52014-04-07 16:59:25 -07001063
John Reckf47a5942014-06-30 16:20:04 -07001064 private static native void nDestroyHardwareResources(long nativeProxy);
1065 private static native void nTrimMemory(int level);
Chris Craik2507c342015-05-04 14:36:49 -07001066 private static native void nOverrideProperty(String name, String value);
John Recke1628b72014-05-23 15:11:19 -07001067
John Reck28ad7b52014-04-07 16:59:25 -07001068 private static native void nFence(long nativeProxy);
John Reckf47a5942014-06-30 16:20:04 -07001069 private static native void nStopDrawing(long nativeProxy);
John Recka5dda642014-05-22 15:43:54 -07001070 private static native void nNotifyFramePending(long nativeProxy);
John Reckfe5e7b72014-05-23 17:42:28 -07001071
John Recke248bd12015-08-05 13:53:53 -07001072 private static native void nSerializeDisplayListTree(long nativeProxy);
1073
John Reckba6adf62015-02-19 14:36:50 -08001074 private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1075 @DumpFlags int dumpFlags);
Skuhneea7a7fb2015-08-28 07:10:31 -07001076
1077 private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1078 boolean placeFront);
1079 private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1080 private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
Skuhneb8160872015-09-22 09:51:39 -07001081 private static native void nSetContentDrawBounds(long nativeProxy, int left,
Skuhneea7a7fb2015-08-28 07:10:31 -07001082 int top, int right, int bottom);
Andres Morales06f5bc72015-12-15 15:21:31 -08001083
Andres Morales910beb82016-02-02 16:19:40 -08001084 private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
1085 private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
John Reck10dd0582016-03-31 16:36:16 -07001086
John Reck95801462016-09-01 09:44:09 -07001087 private static native int nCopySurfaceInto(Surface surface,
1088 int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
John Reck1fedd912017-05-23 14:45:22 -07001089
1090 private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
John Reck938e8842017-08-24 13:41:59 -07001091 private static native void nSetHighContrastText(boolean enabled);
John Reck9f516442017-09-25 10:27:21 -07001092 // For temporary experimentation b/66945974
1093 private static native void nHackySetRTAnimationsEnabled(boolean enabled);
John Reckcec24ae2013-11-05 13:27:50 -08001094}