blob: 7c76bab2343d5ad0f635d21b3fb9f2f4182ab6ec [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 /**
Derek Sollenberger4badfe62017-02-14 11:38:06 -0500169 * Defines the rendering pipeline to be used by the ThreadedRenderer.
170 *
171 * Possible values:
172 * "opengl", will use the existing OpenGL renderer
173 * "skiagl", will use Skia's OpenGL renderer
174 * "skiavk", will use Skia's Vulkan renderer
175 *
176 * @hide
177 */
178 public static final String DEBUG_RENDERER_PROPERTY = "debug.hwui.renderer";
179
180 /**
John Reck51aaf902015-12-02 15:08:07 -0800181 * Turn on to debug non-rectangular clip operations.
182 *
183 * Possible values:
184 * "hide", to disable this debug mode
185 * "highlight", highlight drawing commands tested against a non-rectangular clip
186 * "stencil", renders the clip region on screen when set
187 *
188 * @hide
189 */
190 public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
191 "debug.hwui.show_non_rect_clip";
192
Jaesung Chung9a89d832017-05-16 01:54:17 +0900193 static {
194 // Try to check OpenGL support early if possible.
195 isAvailable();
196 }
197
John Reck51aaf902015-12-02 15:08:07 -0800198 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400199 * A process can set this flag to false to prevent the use of threaded
John Reck51aaf902015-12-02 15:08:07 -0800200 * rendering.
201 *
202 * @hide
203 */
204 public static boolean sRendererDisabled = false;
205
206 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400207 * Further threaded renderer disabling for the system process.
John Reck51aaf902015-12-02 15:08:07 -0800208 *
209 * @hide
210 */
211 public static boolean sSystemRendererDisabled = false;
212
213 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400214 * Invoke this method to disable threaded rendering in the current process.
John Reck51aaf902015-12-02 15:08:07 -0800215 *
216 * @hide
217 */
218 public static void disable(boolean system) {
219 sRendererDisabled = true;
220 if (system) {
221 sSystemRendererDisabled = true;
222 }
223 }
224
225 public static boolean sTrimForeground = false;
226
227 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400228 * Controls whether or not the renderer should aggressively trim
229 * memory. Note that this must not be set for any process that uses
230 * WebView! This should be only used by system_process or similar
John Reck51aaf902015-12-02 15:08:07 -0800231 * that do not go into the background.
232 */
233 public static void enableForegroundTrimming() {
234 sTrimForeground = true;
235 }
236
Jaesung Chung9a89d832017-05-16 01:54:17 +0900237 private static Boolean sSupportsOpenGL;
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -0400238
John Reck51aaf902015-12-02 15:08:07 -0800239 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400240 * Indicates whether threaded rendering is available under any form for
John Reck51aaf902015-12-02 15:08:07 -0800241 * the view hierarchy.
242 *
Stan Iliev45faba52016-06-28 13:33:15 -0400243 * @return True if the view hierarchy can potentially be defer rendered,
John Reck51aaf902015-12-02 15:08:07 -0800244 * false otherwise
245 */
246 public static boolean isAvailable() {
Jaesung Chung9a89d832017-05-16 01:54:17 +0900247 if (sSupportsOpenGL != null) {
248 return sSupportsOpenGL.booleanValue();
249 }
250 if (SystemProperties.getInt("ro.kernel.qemu", 0) == 0) {
251 // Device is not an emulator.
252 sSupportsOpenGL = true;
253 return true;
254 }
255 int qemu_gles = SystemProperties.getInt("qemu.gles", -1);
256 if (qemu_gles == -1) {
257 // In this case, the value of the qemu.gles property is not ready
258 // because the SurfaceFlinger service may not start at this point.
259 return false;
260 }
261 // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
262 // enabled, 0 otherwise. On old emulator versions it will be undefined.
263 sSupportsOpenGL = qemu_gles > 0;
264 return sSupportsOpenGL.booleanValue();
John Reck51aaf902015-12-02 15:08:07 -0800265 }
266
267 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400268 * Sets the directory to use as a persistent storage for threaded rendering
John Reck51aaf902015-12-02 15:08:07 -0800269 * resources.
270 *
271 * @param cacheDir A directory the current process can write to
272 *
273 * @hide
274 */
275 public static void setupDiskCache(File cacheDir) {
Stan Ilievd495f432017-10-09 15:49:32 -0400276 ThreadedRenderer.setupShadersDiskCache(
277 new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(),
278 new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath());
John Reck51aaf902015-12-02 15:08:07 -0800279 }
280
281 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400282 * Creates a threaded renderer using OpenGL.
John Reck51aaf902015-12-02 15:08:07 -0800283 *
284 * @param translucent True if the surface is translucent, false otherwise
285 *
Stan Iliev45faba52016-06-28 13:33:15 -0400286 * @return A threaded renderer backed by OpenGL.
John Reck51aaf902015-12-02 15:08:07 -0800287 */
John Reckdf1742e2017-01-19 15:56:21 -0800288 public static ThreadedRenderer create(Context context, boolean translucent, String name) {
John Reck51aaf902015-12-02 15:08:07 -0800289 ThreadedRenderer renderer = null;
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -0400290 if (isAvailable()) {
John Reckdf1742e2017-01-19 15:56:21 -0800291 renderer = new ThreadedRenderer(context, translucent, name);
John Reck51aaf902015-12-02 15:08:07 -0800292 }
293 return renderer;
294 }
295
296 /**
297 * Invoke this method when the system is running out of memory. This
298 * method will attempt to recover as much memory as possible, based on
299 * the specified hint.
300 *
301 * @param level Hint about the amount of memory that should be trimmed,
302 * see {@link android.content.ComponentCallbacks}
303 */
304 public static void trimMemory(int level) {
305 nTrimMemory(level);
306 }
307
308 public static void overrideProperty(@NonNull String name, @NonNull String value) {
309 if (name == null || value == null) {
310 throw new IllegalArgumentException("name and value must be non-null");
311 }
312 nOverrideProperty(name, value);
313 }
314
John Reckf9be7792014-05-02 18:21:16 -0700315 // Keep in sync with DrawFrameTask.h SYNC_* flags
316 // Nothing interesting to report
John Reckcd028f32014-06-24 08:44:29 -0700317 private static final int SYNC_OK = 0;
John Reckf9be7792014-05-02 18:21:16 -0700318 // Needs a ViewRoot invalidate
John Reckcd028f32014-06-24 08:44:29 -0700319 private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
John Reckaa95a882014-11-07 11:02:07 -0800320 // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
321 private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
John Reck9a17da82016-04-18 11:17:52 -0700322 // setStopped is true, drawing is false
323 // TODO: Remove this and SYNC_LOST_SURFACE_REWARD_IF_FOUND?
324 // This flag isn't really used as there's nothing that we care to do
325 // in response, so it really just exists to differentiate from LOST_SURFACE
326 // but possibly both can just be deleted.
327 private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
John Reckf9be7792014-05-02 18:21:16 -0700328
John Reckfe5e7b72014-05-23 17:42:28 -0700329 private static final String[] VISUALIZERS = {
330 PROFILE_PROPERTY_VISUALIZE_BARS,
331 };
332
John Reckba6adf62015-02-19 14:36:50 -0800333 private static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
334 private static final int FLAG_DUMP_RESET = 1 << 1;
335
336 @IntDef(flag = true, value = {
337 FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET })
338 @Retention(RetentionPolicy.SOURCE)
339 public @interface DumpFlags {}
340
Alan Viveretteccb11e12014-07-08 16:04:02 -0700341 // Size of the rendered content.
John Reckcec24ae2013-11-05 13:27:50 -0800342 private int mWidth, mHeight;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700343
344 // Actual size of the drawing surface.
345 private int mSurfaceWidth, mSurfaceHeight;
346
347 // Insets between the drawing surface and rendered content. These are
348 // applied as translation when updating the root render node.
349 private int mInsetTop, mInsetLeft;
350
Alan Viverette57774a82014-07-15 15:49:55 -0700351 // Whether the surface has insets. Used to protect opacity.
352 private boolean mHasInsets;
353
Alan Viverette58c42c32014-07-12 20:33:45 -0700354 // Light and shadow properties specified by the theme.
355 private final float mLightY;
356 private final float mLightZ;
357 private final float mLightRadius;
Chris Craik058fc642014-07-23 18:19:28 -0700358 private final int mAmbientShadowAlpha;
359 private final int mSpotShadowAlpha;
Alan Viverette58c42c32014-07-12 20:33:45 -0700360
John Reck4f02bf42014-01-03 18:09:17 -0800361 private long mNativeProxy;
John Reckf7d9c1d2014-04-09 10:01:03 -0700362 private boolean mInitialized = false;
John Reckbc0cc022014-04-11 16:08:14 -0700363 private RenderNode mRootNode;
John Reck0a973302014-07-16 13:29:45 -0700364 private boolean mRootNodeNeedsUpdate;
John Reckcec24ae2013-11-05 13:27:50 -0800365
John Reck51aaf902015-12-02 15:08:07 -0800366 private boolean mEnabled;
367 private boolean mRequested = true;
John Reck3e04f092017-06-02 15:50:09 -0700368 private boolean mIsOpaque = false;
John Reck51aaf902015-12-02 15:08:07 -0800369
John Reckdf1742e2017-01-19 15:56:21 -0800370 ThreadedRenderer(Context context, boolean translucent, String name) {
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700371 final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
Alan Viverette58c42c32014-07-12 20:33:45 -0700372 mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
373 mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
374 mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700375 mAmbientShadowAlpha =
376 (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
377 mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
Alan Viverette58c42c32014-07-12 20:33:45 -0700378 a.recycle();
379
John Recke45b1fd2014-04-15 09:50:16 -0700380 long rootNodePtr = nCreateRootRenderNode();
381 mRootNode = RenderNode.adopt(rootNodePtr);
John Reckbc0cc022014-04-11 16:08:14 -0700382 mRootNode.setClipToBounds(false);
John Reck3e04f092017-06-02 15:50:09 -0700383 mIsOpaque = !translucent;
John Recke45b1fd2014-04-15 09:50:16 -0700384 mNativeProxy = nCreateProxy(translucent, rootNodePtr);
John Reckdf1742e2017-01-19 15:56:21 -0800385 nSetName(mNativeProxy, name);
John Reck18f16e62014-05-02 16:46:41 -0700386
John Reckedc524c2015-03-18 15:24:33 -0700387 ProcessInitializer.sInstance.init(context, mNativeProxy);
John Reck3b202512014-06-23 13:13:08 -0700388
John Reckfe5e7b72014-05-23 17:42:28 -0700389 loadSystemProperties();
John Reckcec24ae2013-11-05 13:27:50 -0800390 }
391
John Reck51aaf902015-12-02 15:08:07 -0800392 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400393 * Destroys the threaded rendering context.
John Reck51aaf902015-12-02 15:08:07 -0800394 */
John Reckf47a5942014-06-30 16:20:04 -0700395 void destroy() {
John Reckf7d9c1d2014-04-09 10:01:03 -0700396 mInitialized = false;
397 updateEnabledState(null);
Doris Liu350e6522016-02-19 14:20:37 -0800398 nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
John Reckcec24ae2013-11-05 13:27:50 -0800399 }
400
John Reck51aaf902015-12-02 15:08:07 -0800401 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400402 * Indicates whether threaded rendering is currently enabled.
John Reck51aaf902015-12-02 15:08:07 -0800403 *
Stan Iliev45faba52016-06-28 13:33:15 -0400404 * @return True if threaded rendering is in use, false otherwise.
John Reck51aaf902015-12-02 15:08:07 -0800405 */
406 boolean isEnabled() {
407 return mEnabled;
408 }
409
410 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400411 * Indicates whether threaded rendering is currently enabled.
John Reck51aaf902015-12-02 15:08:07 -0800412 *
Stan Iliev45faba52016-06-28 13:33:15 -0400413 * @param enabled True if the threaded renderer is in use, false otherwise.
John Reck51aaf902015-12-02 15:08:07 -0800414 */
415 void setEnabled(boolean enabled) {
416 mEnabled = enabled;
417 }
418
419 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400420 * Indicates whether threaded rendering is currently request but not
John Reck51aaf902015-12-02 15:08:07 -0800421 * necessarily enabled yet.
422 *
423 * @return True if requested, false otherwise.
424 */
425 boolean isRequested() {
426 return mRequested;
427 }
428
429 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400430 * Indicates whether threaded rendering is currently requested but not
John Reck51aaf902015-12-02 15:08:07 -0800431 * necessarily enabled yet.
John Reck51aaf902015-12-02 15:08:07 -0800432 */
433 void setRequested(boolean requested) {
434 mRequested = requested;
435 }
436
John Reckf7d9c1d2014-04-09 10:01:03 -0700437 private void updateEnabledState(Surface surface) {
438 if (surface == null || !surface.isValid()) {
439 setEnabled(false);
440 } else {
441 setEnabled(mInitialized);
442 }
443 }
444
John Reck51aaf902015-12-02 15:08:07 -0800445 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400446 * Initializes the threaded renderer for the specified surface.
John Reck51aaf902015-12-02 15:08:07 -0800447 *
Stan Iliev45faba52016-06-28 13:33:15 -0400448 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800449 *
450 * @return True if the initialization was successful, false otherwise.
451 */
John Reckcec24ae2013-11-05 13:27:50 -0800452 boolean initialize(Surface surface) throws OutOfResourcesException {
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100453 boolean status = !mInitialized;
John Reckf7d9c1d2014-04-09 10:01:03 -0700454 mInitialized = true;
455 updateEnabledState(surface);
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100456 nInitialize(mNativeProxy, surface);
Dan Stoza5795d642014-06-20 13:01:36 -0700457 return status;
John Reckcec24ae2013-11-05 13:27:50 -0800458 }
459
John Reck51aaf902015-12-02 15:08:07 -0800460 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400461 * Initializes the threaded renderer for the specified surface and setup the
John Reck51aaf902015-12-02 15:08:07 -0800462 * renderer for drawing, if needed. This is invoked when the ViewAncestor has
Stan Iliev45faba52016-06-28 13:33:15 -0400463 * potentially lost the threaded renderer. The threaded renderer should be
John Reck51aaf902015-12-02 15:08:07 -0800464 * reinitialized and setup when the render {@link #isRequested()} and
465 * {@link #isEnabled()}.
466 *
467 * @param width The width of the drawing surface.
468 * @param height The height of the drawing surface.
469 * @param attachInfo Information about the window.
Stan Iliev45faba52016-06-28 13:33:15 -0400470 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800471 * @param surfaceInsets The drawing surface insets to apply
472 *
473 * @return true if the surface was initialized, false otherwise. Returning
474 * false might mean that the surface was already initialized.
475 */
476 boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
477 Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
478 if (isRequested()) {
479 // We lost the gl context, so recreate it.
480 if (!isEnabled()) {
481 if (initialize(surface)) {
482 setup(width, height, attachInfo, surfaceInsets);
483 return true;
484 }
485 }
486 }
487 return false;
488 }
489
490 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400491 * Updates the threaded renderer for the specified surface.
John Reck51aaf902015-12-02 15:08:07 -0800492 *
Stan Iliev45faba52016-06-28 13:33:15 -0400493 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800494 */
John Reckcec24ae2013-11-05 13:27:50 -0800495 void updateSurface(Surface surface) throws OutOfResourcesException {
John Reckf7d9c1d2014-04-09 10:01:03 -0700496 updateEnabledState(surface);
John Reck4f02bf42014-01-03 18:09:17 -0800497 nUpdateSurface(mNativeProxy, surface);
John Reckcec24ae2013-11-05 13:27:50 -0800498 }
499
John Reck51aaf902015-12-02 15:08:07 -0800500 /**
John Reck8afcc762016-04-13 10:24:06 -0700501 * Halts any current rendering into the surface. Use this if it is unclear whether
Stan Iliev45faba52016-06-28 13:33:15 -0400502 * or not the surface used by the ThreadedRenderer will be changing. It
John Reck8afcc762016-04-13 10:24:06 -0700503 * Suspends any rendering into the surface, but will not do any destruction.
504 *
505 * Any subsequent draws will override the pause, resuming normal operation.
John Reck51aaf902015-12-02 15:08:07 -0800506 */
John Reck01a5ea32014-12-03 13:01:07 -0800507 boolean pauseSurface(Surface surface) {
508 return nPauseSurface(mNativeProxy, surface);
John Reckf7d9c1d2014-04-09 10:01:03 -0700509 }
510
John Reck51aaf902015-12-02 15:08:07 -0800511 /**
John Reck8afcc762016-04-13 10:24:06 -0700512 * Hard stops or resumes rendering into the surface. This flag is used to
513 * determine whether or not it is safe to use the given surface *at all*
514 */
515 void setStopped(boolean stopped) {
516 nSetStopped(mNativeProxy, stopped);
517 }
518
519 /**
John Reck51aaf902015-12-02 15:08:07 -0800520 * Destroys all hardware rendering resources associated with the specified
521 * view hierarchy.
522 *
523 * @param view The root of the view hierarchy
524 */
John Reckcec24ae2013-11-05 13:27:50 -0800525 void destroyHardwareResources(View view) {
John Reck4f02bf42014-01-03 18:09:17 -0800526 destroyResources(view);
John Reckf47a5942014-06-30 16:20:04 -0700527 nDestroyHardwareResources(mNativeProxy);
John Reck4f02bf42014-01-03 18:09:17 -0800528 }
529
530 private static void destroyResources(View view) {
531 view.destroyHardwareResources();
John Reckcec24ae2013-11-05 13:27:50 -0800532 }
533
John Reck51aaf902015-12-02 15:08:07 -0800534 /**
John Reck51aaf902015-12-02 15:08:07 -0800535 * Detaches the layer's surface texture from the GL context and releases
536 * the texture id
537 */
John Reck918ad522014-06-27 14:45:25 -0700538 void detachSurfaceTexture(long hardwareLayer) {
539 nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
John Reckcec24ae2013-11-05 13:27:50 -0800540 }
541
John Reck51aaf902015-12-02 15:08:07 -0800542 /**
543 * Sets up the renderer for drawing.
544 *
545 * @param width The width of the drawing surface.
546 * @param height The height of the drawing surface.
547 * @param attachInfo Information about the window.
548 * @param surfaceInsets The drawing surface insets to apply
549 */
Alan Viverette50210d92015-05-14 18:05:36 -0700550 void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
John Reckcec24ae2013-11-05 13:27:50 -0800551 mWidth = width;
552 mHeight = height;
Alan Viverette50210d92015-05-14 18:05:36 -0700553
Alan Viverette3aa1ffb2014-10-30 12:22:08 -0700554 if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
555 || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
Alan Viverette57774a82014-07-15 15:49:55 -0700556 mHasInsets = true;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700557 mInsetLeft = surfaceInsets.left;
558 mInsetTop = surfaceInsets.top;
559 mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
560 mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
Alan Viverette57774a82014-07-15 15:49:55 -0700561
562 // If the surface has insets, it can't be opaque.
563 setOpaque(false);
Alan Viveretteccb11e12014-07-08 16:04:02 -0700564 } else {
Alan Viverette57774a82014-07-15 15:49:55 -0700565 mHasInsets = false;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700566 mInsetLeft = 0;
567 mInsetTop = 0;
568 mSurfaceWidth = width;
569 mSurfaceHeight = height;
570 }
Alan Viverette50210d92015-05-14 18:05:36 -0700571
Alan Viveretteccb11e12014-07-08 16:04:02 -0700572 mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
John Reckab1080c2016-06-21 16:24:20 -0700573 nSetup(mNativeProxy, mLightRadius,
John Reckb36016c2015-03-11 08:50:53 -0700574 mAmbientShadowAlpha, mSpotShadowAlpha);
Alan Viverette50210d92015-05-14 18:05:36 -0700575
576 setLightCenter(attachInfo);
577 }
578
John Reck51aaf902015-12-02 15:08:07 -0800579 /**
580 * Updates the light position based on the position of the window.
581 *
582 * @param attachInfo Information about the window.
583 */
Alan Viverette50210d92015-05-14 18:05:36 -0700584 void setLightCenter(AttachInfo attachInfo) {
585 // Adjust light position for window offsets.
586 final Point displaySize = attachInfo.mPoint;
587 attachInfo.mDisplay.getRealSize(displaySize);
588 final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
589 final float lightY = mLightY - attachInfo.mWindowTop;
590
591 nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
John Reckcec24ae2013-11-05 13:27:50 -0800592 }
593
John Reck51aaf902015-12-02 15:08:07 -0800594 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400595 * Change the ThreadedRenderer's opacity
John Reck51aaf902015-12-02 15:08:07 -0800596 */
John Reck63a06672014-05-07 13:45:54 -0700597 void setOpaque(boolean opaque) {
John Reck3e04f092017-06-02 15:50:09 -0700598 mIsOpaque = opaque && !mHasInsets;
599 nSetOpaque(mNativeProxy, mIsOpaque);
600 }
601
602 boolean isOpaque() {
603 return mIsOpaque;
John Reck63a06672014-05-07 13:45:54 -0700604 }
605
John Reck51aaf902015-12-02 15:08:07 -0800606 /**
Romain Guy26a2b972017-04-17 09:39:51 -0700607 * Enable/disable wide gamut rendering on this renderer.
608 */
609 void setWideGamut(boolean wideGamut) {
610 nSetWideGamut(mNativeProxy, wideGamut);
611 }
612
613 /**
John Reck51aaf902015-12-02 15:08:07 -0800614 * Gets the current width of the surface. This is the width that the surface
615 * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
616 *
617 * @return the current width of the surface
618 */
John Reckcec24ae2013-11-05 13:27:50 -0800619 int getWidth() {
620 return mWidth;
621 }
622
John Reck51aaf902015-12-02 15:08:07 -0800623 /**
624 * Gets the current height of the surface. This is the height 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 getHeight() {
630 return mHeight;
631 }
632
John Reck51aaf902015-12-02 15:08:07 -0800633 /**
634 * Outputs extra debugging information in the specified file descriptor.
635 */
John Reckba6adf62015-02-19 14:36:50 -0800636 void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
John Reckfe5e7b72014-05-23 17:42:28 -0700637 pw.flush();
John Reckba6adf62015-02-19 14:36:50 -0800638 int flags = 0;
639 for (int i = 0; i < args.length; i++) {
640 switch (args[i]) {
641 case "framestats":
642 flags |= FLAG_DUMP_FRAMESTATS;
643 break;
644 case "reset":
645 flags |= FLAG_DUMP_RESET;
646 break;
647 }
John Reckfe5e7b72014-05-23 17:42:28 -0700648 }
John Reckba6adf62015-02-19 14:36:50 -0800649 nDumpProfileInfo(mNativeProxy, fd, flags);
John Reckcec24ae2013-11-05 13:27:50 -0800650 }
651
John Reck51aaf902015-12-02 15:08:07 -0800652 /**
653 * Loads system properties used by the renderer. This method is invoked
654 * whenever system properties are modified. Implementations can use this
655 * to trigger live updates of the renderer based on properties.
656 *
657 * @return True if a property has changed.
658 */
John Reckcec24ae2013-11-05 13:27:50 -0800659 boolean loadSystemProperties() {
John Reckfe5e7b72014-05-23 17:42:28 -0700660 boolean changed = nLoadSystemProperties(mNativeProxy);
John Reck23d307c2014-10-27 12:38:48 -0700661 if (changed) {
662 invalidateRoot();
663 }
John Reckfe5e7b72014-05-23 17:42:28 -0700664 return changed;
John Reckcec24ae2013-11-05 13:27:50 -0800665 }
666
John Reck0a973302014-07-16 13:29:45 -0700667 private void updateViewTreeDisplayList(View view) {
John Reckcec24ae2013-11-05 13:27:50 -0800668 view.mPrivateFlags |= View.PFLAG_DRAWN;
John Reckcec24ae2013-11-05 13:27:50 -0800669 view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
670 == View.PFLAG_INVALIDATED;
671 view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
Chris Craik31a2d062015-05-01 14:22:47 -0700672 view.updateDisplayListIfDirty();
John Reckcec24ae2013-11-05 13:27:50 -0800673 view.mRecreateDisplayList = false;
John Reckbc0cc022014-04-11 16:08:14 -0700674 }
675
Stan Iliev45faba52016-06-28 13:33:15 -0400676 private void updateRootDisplayList(View view, DrawCallbacks callbacks) {
Chris Craik70850ea2014-11-18 10:49:23 -0800677 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
John Reck0a973302014-07-16 13:29:45 -0700678 updateViewTreeDisplayList(view);
679
680 if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
Chris Craikf6829a02015-03-10 10:28:59 -0700681 DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
John Reck0a973302014-07-16 13:29:45 -0700682 try {
Alan Viverettedbed8932014-08-06 17:54:52 -0700683 final int saveCount = canvas.save();
John Reck0a973302014-07-16 13:29:45 -0700684 canvas.translate(mInsetLeft, mInsetTop);
Stan Iliev45faba52016-06-28 13:33:15 -0400685 callbacks.onPreDraw(canvas);
Chris Craikabedca32014-08-28 15:03:55 -0700686
687 canvas.insertReorderBarrier();
Chris Craik31a2d062015-05-01 14:22:47 -0700688 canvas.drawRenderNode(view.updateDisplayListIfDirty());
Chris Craikabedca32014-08-28 15:03:55 -0700689 canvas.insertInorderBarrier();
690
Stan Iliev45faba52016-06-28 13:33:15 -0400691 callbacks.onPostDraw(canvas);
Alan Viverettedbed8932014-08-06 17:54:52 -0700692 canvas.restoreToCount(saveCount);
John Reck0a973302014-07-16 13:29:45 -0700693 mRootNodeNeedsUpdate = false;
694 } finally {
695 mRootNode.end(canvas);
696 }
697 }
698 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
699 }
700
Skuhneea7a7fb2015-08-28 07:10:31 -0700701 /**
702 * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
703 * rendernode of the UI thread.
704 * @param node The node to add.
705 * @param placeFront If true, the render node will be placed in front of the content node,
706 * otherwise behind the content node.
707 */
708 public void addRenderNode(RenderNode node, boolean placeFront) {
709 nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
710 }
711
712 /**
713 * Only especially added render nodes can be removed.
714 * @param node The node which was added via addRenderNode which should get removed again.
715 */
716 public void removeRenderNode(RenderNode node) {
717 nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
718 }
719
720 /**
721 * Draws a particular render node. If the node is not the content node, only the additional
722 * nodes will get drawn and the content remains untouched.
723 * @param node The node to be drawn.
724 */
725 public void drawRenderNode(RenderNode node) {
726 nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
727 }
728
729 /**
730 * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
731 * will be prevented to overdraw this area. It will be synchronized with the draw call.
732 * This should be updated in the content view's draw call.
733 * @param left The left side of the protected bounds.
734 * @param top The top side of the protected bounds.
735 * @param right The right side of the protected bounds.
736 * @param bottom The bottom side of the protected bounds.
737 */
Skuhneb8160872015-09-22 09:51:39 -0700738 public void setContentDrawBounds(int left, int top, int right, int bottom) {
Jorim Jaggie85ce992016-05-09 19:05:22 -0700739 nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
Skuhneea7a7fb2015-08-28 07:10:31 -0700740 }
741
John Reck51aaf902015-12-02 15:08:07 -0800742 /**
743 * Interface used to receive callbacks whenever a view is drawn by
Stan Iliev45faba52016-06-28 13:33:15 -0400744 * a threaded renderer instance.
John Reck51aaf902015-12-02 15:08:07 -0800745 */
Stan Iliev45faba52016-06-28 13:33:15 -0400746 interface DrawCallbacks {
John Reck51aaf902015-12-02 15:08:07 -0800747 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400748 * Invoked before a view is drawn by a threaded renderer.
John Reck51aaf902015-12-02 15:08:07 -0800749 * This method can be used to apply transformations to the
750 * canvas but no drawing command should be issued.
751 *
752 * @param canvas The Canvas used to render the view.
753 */
Stan Iliev45faba52016-06-28 13:33:15 -0400754 void onPreDraw(DisplayListCanvas canvas);
John Reck51aaf902015-12-02 15:08:07 -0800755
756 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400757 * Invoked after a view is drawn by a threaded renderer.
John Reck51aaf902015-12-02 15:08:07 -0800758 * It is safe to invoke drawing commands from this method.
759 *
760 * @param canvas The Canvas used to render the view.
761 */
Stan Iliev45faba52016-06-28 13:33:15 -0400762 void onPostDraw(DisplayListCanvas canvas);
John Reck51aaf902015-12-02 15:08:07 -0800763 }
764
765 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400766 * Indicates that the content drawn by DrawCallbacks needs to
John Reck51aaf902015-12-02 15:08:07 -0800767 * be updated, which will be done by the next call to draw()
768 */
John Reck0a973302014-07-16 13:29:45 -0700769 void invalidateRoot() {
770 mRootNodeNeedsUpdate = true;
771 }
772
John Reck51aaf902015-12-02 15:08:07 -0800773 /**
774 * Draws the specified view.
775 *
776 * @param view The view to draw.
777 * @param attachInfo AttachInfo tied to the specified view.
778 * @param callbacks Callbacks invoked when drawing happens.
779 */
Stan Iliev45faba52016-06-28 13:33:15 -0400780 void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {
John Reckbc0cc022014-04-11 16:08:14 -0700781 attachInfo.mIgnoreDirtyState = true;
John Reckbc0cc022014-04-11 16:08:14 -0700782
John Reckba6adf62015-02-19 14:36:50 -0800783 final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
784 choreographer.mFrameInfo.markDrawStart();
John Reckfe5e7b72014-05-23 17:42:28 -0700785
John Reck61375a82014-09-18 19:27:48 +0000786 updateRootDisplayList(view, callbacks);
John Reckcec24ae2013-11-05 13:27:50 -0800787
John Reck6313b922014-04-16 18:59:21 -0700788 attachInfo.mIgnoreDirtyState = false;
789
John Reck119907c2014-08-14 09:02:01 -0700790 // register animating rendernodes which started animating prior to renderer
791 // creation, which is typical for animators started prior to first draw
792 if (attachInfo.mPendingAnimatingRenderNodes != null) {
793 final int count = attachInfo.mPendingAnimatingRenderNodes.size();
794 for (int i = 0; i < count; i++) {
795 registerAnimatingRenderNode(
796 attachInfo.mPendingAnimatingRenderNodes.get(i));
797 }
798 attachInfo.mPendingAnimatingRenderNodes.clear();
799 // We don't need this anymore as subsequent calls to
800 // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
801 attachInfo.mPendingAnimatingRenderNodes = null;
802 }
803
John Reckba6adf62015-02-19 14:36:50 -0800804 final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
John Reck51f2d602016-04-06 07:50:47 -0700805 int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
John Reckaa95a882014-11-07 11:02:07 -0800806 if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
807 setEnabled(false);
John Reckb13de072014-11-19 16:33:47 -0800808 attachInfo.mViewRootImpl.mSurface.release();
John Reckaa95a882014-11-07 11:02:07 -0800809 // Invalidate since we failed to draw. This should fetch a Surface
810 // if it is still needed or do nothing if we are no longer drawing
811 attachInfo.mViewRootImpl.invalidate();
812 }
John Reckf9be7792014-05-02 18:21:16 -0700813 if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
814 attachInfo.mViewRootImpl.invalidate();
815 }
John Reckcec24ae2013-11-05 13:27:50 -0800816 }
817
John Reck3b202512014-06-23 13:13:08 -0700818 static void invokeFunctor(long functor, boolean waitForCompletion) {
819 nInvokeFunctor(functor, waitForCompletion);
John Reck0d1f6342014-03-28 20:30:27 -0700820 }
821
John Reck51aaf902015-12-02 15:08:07 -0800822 /**
823 * Creates a new hardware layer. A hardware layer built by calling this
824 * method will be treated as a texture layer, instead of as a render target.
825 *
826 * @return A hardware layer
827 */
John Reck19b6bcf2014-02-14 20:03:38 -0800828 HardwareLayer createTextureLayer() {
829 long layer = nCreateTextureLayer(mNativeProxy);
830 return HardwareLayer.adoptTextureLayer(this, layer);
831 }
832
John Reck51aaf902015-12-02 15:08:07 -0800833
John Reck3e824952014-08-20 10:08:39 -0700834 void buildLayer(RenderNode node) {
835 nBuildLayer(mNativeProxy, node.getNativeDisplayList());
836 }
837
John Reck51aaf902015-12-02 15:08:07 -0800838
John Reck19b6bcf2014-02-14 20:03:38 -0800839 boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
840 return nCopyLayerInto(mNativeProxy,
John Reck3731dc22015-04-13 15:20:29 -0700841 layer.getDeferredLayerUpdater(), bitmap);
John Reck19b6bcf2014-02-14 20:03:38 -0800842 }
843
John Reck51aaf902015-12-02 15:08:07 -0800844 /**
845 * Indicates that the specified hardware layer needs to be updated
846 * as soon as possible.
847 *
848 * @param layer The hardware layer that needs an update
849 */
John Reck19b6bcf2014-02-14 20:03:38 -0800850 void pushLayerUpdate(HardwareLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700851 nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800852 }
853
John Reck51aaf902015-12-02 15:08:07 -0800854 /**
855 * Tells the HardwareRenderer that the layer is destroyed. The renderer
856 * should remove the layer from any update queues.
857 */
John Reck19b6bcf2014-02-14 20:03:38 -0800858 void onLayerDestroyed(HardwareLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700859 nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800860 }
861
John Reck51aaf902015-12-02 15:08:07 -0800862 /**
John Reck51aaf902015-12-02 15:08:07 -0800863 * Blocks until all previously queued work has completed.
864 */
John Reck28ad7b52014-04-07 16:59:25 -0700865 void fence() {
866 nFence(mNativeProxy);
867 }
868
John Reck51aaf902015-12-02 15:08:07 -0800869 /**
870 * Prevents any further drawing until draw() is called. This is a signal
871 * that the contents of the RenderNode tree are no longer safe to play back.
872 * In practice this usually means that there are Functor pointers in the
873 * display list that are no longer valid.
874 */
John Reckf47a5942014-06-30 16:20:04 -0700875 void stopDrawing() {
876 nStopDrawing(mNativeProxy);
877 }
878
John Reck51aaf902015-12-02 15:08:07 -0800879 /**
880 * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
881 */
John Recka5dda642014-05-22 15:43:54 -0700882 public void notifyFramePending() {
883 nNotifyFramePending(mNativeProxy);
884 }
885
John Reck51aaf902015-12-02 15:08:07 -0800886
John Reck119907c2014-08-14 09:02:01 -0700887 void registerAnimatingRenderNode(RenderNode animator) {
888 nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
889 }
890
Doris Liu67ce99b2016-05-17 16:50:31 -0700891 void registerVectorDrawableAnimator(
892 AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
893 nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
894 animator.getAnimatorNativePtr());
895 }
896
John Recke248bd12015-08-05 13:53:53 -0700897 public void serializeDisplayListTree() {
898 nSerializeDisplayListTree(mNativeProxy);
899 }
900
John Reck95801462016-09-01 09:44:09 -0700901 public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
902 if (srcRect == null) {
903 // Empty rect means entire surface
904 return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap);
905 } else {
906 return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
907 srcRect.right, srcRect.bottom, bitmap);
908 }
John Reck10dd0582016-03-31 16:36:16 -0700909 }
910
John Reck1fedd912017-05-23 14:45:22 -0700911 /**
912 * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given
913 * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and
914 * not the RenderNode from a View.
915 **/
916 public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
917 return nCreateHardwareBitmap(node.getNativeDisplayList(), width, height);
918 }
919
John Reck938e8842017-08-24 13:41:59 -0700920 /**
921 * Sets whether or not high contrast text rendering is enabled. The setting is global
922 * but only affects content rendered after the change is made.
923 */
924 public static void setHighContrastText(boolean highContrastText) {
925 nSetHighContrastText(highContrastText);
926 }
927
John Reck119907c2014-08-14 09:02:01 -0700928 @Override
John Reck4f02bf42014-01-03 18:09:17 -0800929 protected void finalize() throws Throwable {
930 try {
931 nDeleteProxy(mNativeProxy);
John Reck0ed751d2014-04-08 14:10:17 -0700932 mNativeProxy = 0;
John Reck4f02bf42014-01-03 18:09:17 -0800933 } finally {
934 super.finalize();
John Reckcec24ae2013-11-05 13:27:50 -0800935 }
936 }
937
John Reckedc524c2015-03-18 15:24:33 -0700938 private static class ProcessInitializer {
939 static ProcessInitializer sInstance = new ProcessInitializer();
John Reck66f0be62014-05-13 13:39:31 -0700940
941 private boolean mInitialized = false;
942
John Reckdf1742e2017-01-19 15:56:21 -0800943 private Context mAppContext;
944 private IGraphicsStats mGraphicsStatsService;
945 private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
946 @Override
947 public void onRotateGraphicsStatsBuffer() throws RemoteException {
948 rotateBuffer();
949 }
950 };
951
John Reckedc524c2015-03-18 15:24:33 -0700952 private ProcessInitializer() {}
John Reck66f0be62014-05-13 13:39:31 -0700953
John Reck3b202512014-06-23 13:13:08 -0700954 synchronized void init(Context context, long renderProxy) {
John Reck66f0be62014-05-13 13:39:31 -0700955 if (mInitialized) return;
John Reckedc524c2015-03-18 15:24:33 -0700956 mInitialized = true;
John Reckdf1742e2017-01-19 15:56:21 -0800957 mAppContext = context.getApplicationContext();
Romain Guy26a2b972017-04-17 09:39:51 -0700958 initSched(renderProxy);
John Reckdf1742e2017-01-19 15:56:21 -0800959 initGraphicsStats();
John Reckedc524c2015-03-18 15:24:33 -0700960 }
961
Romain Guy26a2b972017-04-17 09:39:51 -0700962 private void initSched(long renderProxy) {
Tim Murray33eb07f2016-06-10 10:03:20 -0700963 try {
964 int tid = nGetRenderThreadTid(renderProxy);
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800965 ActivityManager.getService().setRenderThread(tid);
Tim Murray33eb07f2016-06-10 10:03:20 -0700966 } catch (Throwable t) {
967 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
968 }
969 }
970
John Reckdf1742e2017-01-19 15:56:21 -0800971 private void initGraphicsStats() {
John Reckedc524c2015-03-18 15:24:33 -0700972 try {
John Reck828698b2015-06-30 12:56:03 -0700973 IBinder binder = ServiceManager.getService("graphicsstats");
974 if (binder == null) return;
John Reckdf1742e2017-01-19 15:56:21 -0800975 mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
976 requestBuffer();
977 } catch (Throwable t) {
978 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
979 }
980 }
981
982 private void rotateBuffer() {
983 nRotateProcessStatsBuffer();
984 requestBuffer();
985 }
986
987 private void requestBuffer() {
988 try {
989 final String pkg = mAppContext.getApplicationInfo().packageName;
990 ParcelFileDescriptor pfd = mGraphicsStatsService
991 .requestBufferForProcess(pkg, mGraphicsStatsCallback);
992 nSetProcessStatsBuffer(pfd.getFd());
John Reckedc524c2015-03-18 15:24:33 -0700993 pfd.close();
John Reck828698b2015-06-30 12:56:03 -0700994 } catch (Throwable t) {
995 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
John Reckedc524c2015-03-18 15:24:33 -0700996 }
997 }
John Reck66f0be62014-05-13 13:39:31 -0700998 }
999
Andres Morales910beb82016-02-02 16:19:40 -08001000 void addFrameMetricsObserver(FrameMetricsObserver observer) {
1001 long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
1002 observer.mNative = new VirtualRefBasePtr(nativeObserver);
Andres Morales06f5bc72015-12-15 15:21:31 -08001003 }
1004
Andres Morales910beb82016-02-02 16:19:40 -08001005 void removeFrameMetricsObserver(FrameMetricsObserver observer) {
1006 nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
1007 observer.mNative = null;
Andres Morales06f5bc72015-12-15 15:21:31 -08001008 }
1009
John Recka8963062017-06-14 10:47:50 -07001010 /** Not actually public - internal use only. This doc to make lint happy */
1011 public static native void disableVsync();
1012
Stan Ilievd495f432017-10-09 15:49:32 -04001013 static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
John Reck84a4c882014-05-30 14:34:03 -07001014
John Reckdf1742e2017-01-19 15:56:21 -08001015 private static native void nRotateProcessStatsBuffer();
1016 private static native void nSetProcessStatsBuffer(int fd);
Tim Murray33eb07f2016-06-10 10:03:20 -07001017 private static native int nGetRenderThreadTid(long nativeProxy);
John Reck4f02bf42014-01-03 18:09:17 -08001018
John Recke45b1fd2014-04-15 09:50:16 -07001019 private static native long nCreateRootRenderNode();
1020 private static native long nCreateProxy(boolean translucent, long rootRenderNode);
John Reck4f02bf42014-01-03 18:09:17 -08001021 private static native void nDeleteProxy(long nativeProxy);
1022
John Recke4280ba2014-05-05 16:39:37 -07001023 private static native boolean nLoadSystemProperties(long nativeProxy);
John Reckb36016c2015-03-11 08:50:53 -07001024 private static native void nSetName(long nativeProxy, String name);
John Reck18f16e62014-05-02 16:46:41 -07001025
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +01001026 private static native void nInitialize(long nativeProxy, Surface window);
John Reck4f02bf42014-01-03 18:09:17 -08001027 private static native void nUpdateSurface(long nativeProxy, Surface window);
John Reck01a5ea32014-12-03 13:01:07 -08001028 private static native boolean nPauseSurface(long nativeProxy, Surface window);
John Reck8afcc762016-04-13 10:24:06 -07001029 private static native void nSetStopped(long nativeProxy, boolean stopped);
John Reckab1080c2016-06-21 16:24:20 -07001030 private static native void nSetup(long nativeProxy,
Alan Viverette50210d92015-05-14 18:05:36 -07001031 float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
1032 private static native void nSetLightCenter(long nativeProxy,
1033 float lightX, float lightY, float lightZ);
John Reck63a06672014-05-07 13:45:54 -07001034 private static native void nSetOpaque(long nativeProxy, boolean opaque);
Romain Guy26a2b972017-04-17 09:39:51 -07001035 private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
John Reck51f2d602016-04-06 07:50:47 -07001036 private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
Doris Liu350e6522016-02-19 14:20:37 -08001037 private static native void nDestroy(long nativeProxy, long rootRenderNode);
John Reck119907c2014-08-14 09:02:01 -07001038 private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
Doris Liu67ce99b2016-05-17 16:50:31 -07001039 private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
John Reck4f02bf42014-01-03 18:09:17 -08001040
John Reck3b202512014-06-23 13:13:08 -07001041 private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
John Reck19b6bcf2014-02-14 20:03:38 -08001042
John Reck19b6bcf2014-02-14 20:03:38 -08001043 private static native long nCreateTextureLayer(long nativeProxy);
John Reck3e824952014-08-20 10:08:39 -07001044 private static native void nBuildLayer(long nativeProxy, long node);
John Reck3731dc22015-04-13 15:20:29 -07001045 private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
John Reckd72e0a32014-05-29 18:56:11 -07001046 private static native void nPushLayerUpdate(long nativeProxy, long layer);
1047 private static native void nCancelLayerUpdate(long nativeProxy, long layer);
John Reck918ad522014-06-27 14:45:25 -07001048 private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
John Reck28ad7b52014-04-07 16:59:25 -07001049
John Reckf47a5942014-06-30 16:20:04 -07001050 private static native void nDestroyHardwareResources(long nativeProxy);
1051 private static native void nTrimMemory(int level);
Chris Craik2507c342015-05-04 14:36:49 -07001052 private static native void nOverrideProperty(String name, String value);
John Recke1628b72014-05-23 15:11:19 -07001053
John Reck28ad7b52014-04-07 16:59:25 -07001054 private static native void nFence(long nativeProxy);
John Reckf47a5942014-06-30 16:20:04 -07001055 private static native void nStopDrawing(long nativeProxy);
John Recka5dda642014-05-22 15:43:54 -07001056 private static native void nNotifyFramePending(long nativeProxy);
John Reckfe5e7b72014-05-23 17:42:28 -07001057
John Recke248bd12015-08-05 13:53:53 -07001058 private static native void nSerializeDisplayListTree(long nativeProxy);
1059
John Reckba6adf62015-02-19 14:36:50 -08001060 private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1061 @DumpFlags int dumpFlags);
Skuhneea7a7fb2015-08-28 07:10:31 -07001062
1063 private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1064 boolean placeFront);
1065 private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1066 private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
Skuhneb8160872015-09-22 09:51:39 -07001067 private static native void nSetContentDrawBounds(long nativeProxy, int left,
Skuhneea7a7fb2015-08-28 07:10:31 -07001068 int top, int right, int bottom);
Andres Morales06f5bc72015-12-15 15:21:31 -08001069
Andres Morales910beb82016-02-02 16:19:40 -08001070 private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
1071 private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
John Reck10dd0582016-03-31 16:36:16 -07001072
John Reck95801462016-09-01 09:44:09 -07001073 private static native int nCopySurfaceInto(Surface surface,
1074 int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
John Reck1fedd912017-05-23 14:45:22 -07001075
1076 private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
John Reck938e8842017-08-24 13:41:59 -07001077 private static native void nSetHighContrastText(boolean enabled);
John Reckcec24ae2013-11-05 13:27:50 -08001078}