blob: c66bf87476a7087234dda5e77b559df51423d92a [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;
John Reckcec24ae2013-11-05 13:27:50 -080032import android.os.Trace;
John Reck66f0be62014-05-13 13:39:31 -070033import android.util.Log;
John Reckcec24ae2013-11-05 13:27:50 -080034import android.view.Surface.OutOfResourcesException;
35import android.view.View.AttachInfo;
36
John Reckba6adf62015-02-19 14:36:50 -080037import com.android.internal.R;
Andres Morales06f5bc72015-12-15 15:21:31 -080038import com.android.internal.util.VirtualRefBasePtr;
John Reckba6adf62015-02-19 14:36:50 -080039
John Reck51aaf902015-12-02 15:08:07 -080040import java.io.File;
John Reckfe5e7b72014-05-23 17:42:28 -070041import java.io.FileDescriptor;
John Reckcec24ae2013-11-05 13:27:50 -080042import java.io.PrintWriter;
John Reckba6adf62015-02-19 14:36:50 -080043import java.lang.annotation.Retention;
44import java.lang.annotation.RetentionPolicy;
John Reckcec24ae2013-11-05 13:27:50 -080045
46/**
Stan Iliev45faba52016-06-28 13:33:15 -040047 * Threaded renderer that proxies the rendering to a render thread. Most calls
John Reck4f02bf42014-01-03 18:09:17 -080048 * are currently synchronous.
John Reckcec24ae2013-11-05 13:27:50 -080049 *
50 * The UI thread can block on the RenderThread, but RenderThread must never
51 * block on the UI thread.
52 *
John Reck4f02bf42014-01-03 18:09:17 -080053 * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
54 * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
55 * by the lifecycle of the RenderProxy.
56 *
John Reckcec24ae2013-11-05 13:27:50 -080057 * Note that although currently the EGL context & surfaces are created & managed
58 * by the render thread, the goal is to move that into a shared structure that can
59 * be managed by both threads. EGLSurface creation & deletion should ideally be
60 * done on the UI thread and not the RenderThread to avoid stalling the
61 * RenderThread with surface buffer allocation.
62 *
63 * @hide
64 */
John Reck51aaf902015-12-02 15:08:07 -080065public final class ThreadedRenderer {
66 private static final String LOG_TAG = "ThreadedRenderer";
67
68 /**
69 * Name of the file that holds the shaders cache.
70 */
71 private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
72
73 /**
Stan Iliev45faba52016-06-28 13:33:15 -040074 * System property used to enable or disable threaded rendering profiling.
John Reck51aaf902015-12-02 15:08:07 -080075 * The default value of this property is assumed to be false.
76 *
77 * When profiling is enabled, the adb shell dumpsys gfxinfo command will
78 * output extra information about the time taken to execute by the last
79 * frames.
80 *
81 * Possible values:
82 * "true", to enable profiling
83 * "visual_bars", to enable profiling and visualize the results on screen
84 * "false", to disable profiling
85 *
86 * @see #PROFILE_PROPERTY_VISUALIZE_BARS
87 *
88 * @hide
89 */
90 public static final String PROFILE_PROPERTY = "debug.hwui.profile";
91
92 /**
93 * Value for {@link #PROFILE_PROPERTY}. When the property is set to this
94 * value, profiling data will be visualized on screen as a bar chart.
95 *
96 * @hide
97 */
98 public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars";
99
100 /**
101 * System property used to specify the number of frames to be used
Stan Iliev45faba52016-06-28 13:33:15 -0400102 * when doing threaded rendering profiling.
John Reck51aaf902015-12-02 15:08:07 -0800103 * The default value of this property is #PROFILE_MAX_FRAMES.
104 *
105 * When profiling is enabled, the adb shell dumpsys gfxinfo command will
106 * output extra information about the time taken to execute by the last
107 * frames.
108 *
109 * Possible values:
110 * "60", to set the limit of frames to 60
111 */
112 static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes";
113
114 /**
115 * System property used to debug EGL configuration choice.
116 *
117 * Possible values:
118 * "choice", print the chosen configuration only
119 * "all", print all possible configurations
120 */
121 static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config";
122
123 /**
124 * Turn on to draw dirty regions every other frame.
125 *
126 * Possible values:
127 * "true", to enable dirty regions debugging
128 * "false", to disable dirty regions debugging
129 *
130 * @hide
131 */
132 public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
133
134 /**
135 * Turn on to flash hardware layers when they update.
136 *
137 * Possible values:
138 * "true", to enable hardware layers updates debugging
139 * "false", to disable hardware layers updates debugging
140 *
141 * @hide
142 */
143 public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
144 "debug.hwui.show_layers_updates";
145
146 /**
147 * Controls overdraw debugging.
148 *
149 * Possible values:
150 * "false", to disable overdraw debugging
151 * "show", to show overdraw areas on screen
152 * "count", to display an overdraw counter
153 *
154 * @hide
155 */
156 public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
157
158 /**
159 * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
160 * value, overdraw will be shown on screen by coloring pixels.
161 *
162 * @hide
163 */
164 public static final String OVERDRAW_PROPERTY_SHOW = "show";
165
166 /**
Derek Sollenberger4badfe62017-02-14 11:38:06 -0500167 * Defines the rendering pipeline to be used by the ThreadedRenderer.
168 *
169 * Possible values:
170 * "opengl", will use the existing OpenGL renderer
171 * "skiagl", will use Skia's OpenGL renderer
172 * "skiavk", will use Skia's Vulkan renderer
173 *
174 * @hide
175 */
176 public static final String DEBUG_RENDERER_PROPERTY = "debug.hwui.renderer";
177
178 /**
John Reck51aaf902015-12-02 15:08:07 -0800179 * Turn on to debug non-rectangular clip operations.
180 *
181 * Possible values:
182 * "hide", to disable this debug mode
183 * "highlight", highlight drawing commands tested against a non-rectangular clip
184 * "stencil", renders the clip region on screen when set
185 *
186 * @hide
187 */
188 public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
189 "debug.hwui.show_non_rect_clip";
190
191 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400192 * A process can set this flag to false to prevent the use of threaded
John Reck51aaf902015-12-02 15:08:07 -0800193 * rendering.
194 *
195 * @hide
196 */
197 public static boolean sRendererDisabled = false;
198
199 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400200 * Further threaded renderer disabling for the system process.
John Reck51aaf902015-12-02 15:08:07 -0800201 *
202 * @hide
203 */
204 public static boolean sSystemRendererDisabled = false;
205
206 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400207 * Invoke this method to disable threaded rendering in the current process.
John Reck51aaf902015-12-02 15:08:07 -0800208 *
209 * @hide
210 */
211 public static void disable(boolean system) {
212 sRendererDisabled = true;
213 if (system) {
214 sSystemRendererDisabled = true;
215 }
216 }
217
218 public static boolean sTrimForeground = false;
219
220 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400221 * Controls whether or not the renderer should aggressively trim
222 * memory. Note that this must not be set for any process that uses
223 * WebView! This should be only used by system_process or similar
John Reck51aaf902015-12-02 15:08:07 -0800224 * that do not go into the background.
225 */
226 public static void enableForegroundTrimming() {
227 sTrimForeground = true;
228 }
229
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -0400230 private static native boolean nSupportsOpenGL();
231 private static boolean sSupportsOpenGL = nSupportsOpenGL();
232
John Reck51aaf902015-12-02 15:08:07 -0800233 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400234 * Indicates whether threaded rendering is available under any form for
John Reck51aaf902015-12-02 15:08:07 -0800235 * the view hierarchy.
236 *
Stan Iliev45faba52016-06-28 13:33:15 -0400237 * @return True if the view hierarchy can potentially be defer rendered,
John Reck51aaf902015-12-02 15:08:07 -0800238 * false otherwise
239 */
240 public static boolean isAvailable() {
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -0400241 return sSupportsOpenGL;
John Reck51aaf902015-12-02 15:08:07 -0800242 }
243
244 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400245 * Sets the directory to use as a persistent storage for threaded rendering
John Reck51aaf902015-12-02 15:08:07 -0800246 * resources.
247 *
248 * @param cacheDir A directory the current process can write to
249 *
250 * @hide
251 */
252 public static void setupDiskCache(File cacheDir) {
253 ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
254 }
255
256 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400257 * Creates a threaded renderer using OpenGL.
John Reck51aaf902015-12-02 15:08:07 -0800258 *
259 * @param translucent True if the surface is translucent, false otherwise
260 *
Stan Iliev45faba52016-06-28 13:33:15 -0400261 * @return A threaded renderer backed by OpenGL.
John Reck51aaf902015-12-02 15:08:07 -0800262 */
John Reckdf1742e2017-01-19 15:56:21 -0800263 public static ThreadedRenderer create(Context context, boolean translucent, String name) {
John Reck51aaf902015-12-02 15:08:07 -0800264 ThreadedRenderer renderer = null;
Derek Sollenbergerf64c34e2016-06-28 16:39:13 -0400265 if (isAvailable()) {
John Reckdf1742e2017-01-19 15:56:21 -0800266 renderer = new ThreadedRenderer(context, translucent, name);
John Reck51aaf902015-12-02 15:08:07 -0800267 }
268 return renderer;
269 }
270
271 /**
272 * Invoke this method when the system is running out of memory. This
273 * method will attempt to recover as much memory as possible, based on
274 * the specified hint.
275 *
276 * @param level Hint about the amount of memory that should be trimmed,
277 * see {@link android.content.ComponentCallbacks}
278 */
279 public static void trimMemory(int level) {
280 nTrimMemory(level);
281 }
282
283 public static void overrideProperty(@NonNull String name, @NonNull String value) {
284 if (name == null || value == null) {
285 throw new IllegalArgumentException("name and value must be non-null");
286 }
287 nOverrideProperty(name, value);
288 }
289
John Reckf9be7792014-05-02 18:21:16 -0700290 // Keep in sync with DrawFrameTask.h SYNC_* flags
291 // Nothing interesting to report
John Reckcd028f32014-06-24 08:44:29 -0700292 private static final int SYNC_OK = 0;
John Reckf9be7792014-05-02 18:21:16 -0700293 // Needs a ViewRoot invalidate
John Reckcd028f32014-06-24 08:44:29 -0700294 private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
John Reckaa95a882014-11-07 11:02:07 -0800295 // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
296 private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
John Reck9a17da82016-04-18 11:17:52 -0700297 // setStopped is true, drawing is false
298 // TODO: Remove this and SYNC_LOST_SURFACE_REWARD_IF_FOUND?
299 // This flag isn't really used as there's nothing that we care to do
300 // in response, so it really just exists to differentiate from LOST_SURFACE
301 // but possibly both can just be deleted.
302 private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
John Reckf9be7792014-05-02 18:21:16 -0700303
John Reckfe5e7b72014-05-23 17:42:28 -0700304 private static final String[] VISUALIZERS = {
305 PROFILE_PROPERTY_VISUALIZE_BARS,
306 };
307
John Reckba6adf62015-02-19 14:36:50 -0800308 private static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
309 private static final int FLAG_DUMP_RESET = 1 << 1;
310
311 @IntDef(flag = true, value = {
312 FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET })
313 @Retention(RetentionPolicy.SOURCE)
314 public @interface DumpFlags {}
315
Alan Viveretteccb11e12014-07-08 16:04:02 -0700316 // Size of the rendered content.
John Reckcec24ae2013-11-05 13:27:50 -0800317 private int mWidth, mHeight;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700318
319 // Actual size of the drawing surface.
320 private int mSurfaceWidth, mSurfaceHeight;
321
322 // Insets between the drawing surface and rendered content. These are
323 // applied as translation when updating the root render node.
324 private int mInsetTop, mInsetLeft;
325
Alan Viverette57774a82014-07-15 15:49:55 -0700326 // Whether the surface has insets. Used to protect opacity.
327 private boolean mHasInsets;
328
Alan Viverette58c42c32014-07-12 20:33:45 -0700329 // Light and shadow properties specified by the theme.
330 private final float mLightY;
331 private final float mLightZ;
332 private final float mLightRadius;
Chris Craik058fc642014-07-23 18:19:28 -0700333 private final int mAmbientShadowAlpha;
334 private final int mSpotShadowAlpha;
Alan Viverette58c42c32014-07-12 20:33:45 -0700335
John Reck4f02bf42014-01-03 18:09:17 -0800336 private long mNativeProxy;
John Reckf7d9c1d2014-04-09 10:01:03 -0700337 private boolean mInitialized = false;
John Reckbc0cc022014-04-11 16:08:14 -0700338 private RenderNode mRootNode;
John Reck18f16e62014-05-02 16:46:41 -0700339 private Choreographer mChoreographer;
John Reck0a973302014-07-16 13:29:45 -0700340 private boolean mRootNodeNeedsUpdate;
John Reckcec24ae2013-11-05 13:27:50 -0800341
John Reck51aaf902015-12-02 15:08:07 -0800342 private boolean mEnabled;
343 private boolean mRequested = true;
344
John Reckdf1742e2017-01-19 15:56:21 -0800345 ThreadedRenderer(Context context, boolean translucent, String name) {
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700346 final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
Alan Viverette58c42c32014-07-12 20:33:45 -0700347 mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
348 mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
349 mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
Alan Viveretteed6f14a2014-08-26 14:53:28 -0700350 mAmbientShadowAlpha =
351 (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
352 mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
Alan Viverette58c42c32014-07-12 20:33:45 -0700353 a.recycle();
354
John Recke45b1fd2014-04-15 09:50:16 -0700355 long rootNodePtr = nCreateRootRenderNode();
356 mRootNode = RenderNode.adopt(rootNodePtr);
John Reckbc0cc022014-04-11 16:08:14 -0700357 mRootNode.setClipToBounds(false);
John Recke45b1fd2014-04-15 09:50:16 -0700358 mNativeProxy = nCreateProxy(translucent, rootNodePtr);
John Reckdf1742e2017-01-19 15:56:21 -0800359 nSetName(mNativeProxy, name);
John Reck18f16e62014-05-02 16:46:41 -0700360
John Reckedc524c2015-03-18 15:24:33 -0700361 ProcessInitializer.sInstance.init(context, mNativeProxy);
John Reck3b202512014-06-23 13:13:08 -0700362
John Reckfe5e7b72014-05-23 17:42:28 -0700363 loadSystemProperties();
John Reckcec24ae2013-11-05 13:27:50 -0800364 }
365
John Reck51aaf902015-12-02 15:08:07 -0800366 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400367 * Destroys the threaded rendering context.
John Reck51aaf902015-12-02 15:08:07 -0800368 */
John Reckf47a5942014-06-30 16:20:04 -0700369 void destroy() {
John Reckf7d9c1d2014-04-09 10:01:03 -0700370 mInitialized = false;
371 updateEnabledState(null);
Doris Liu350e6522016-02-19 14:20:37 -0800372 nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
John Reckcec24ae2013-11-05 13:27:50 -0800373 }
374
John Reck51aaf902015-12-02 15:08:07 -0800375 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400376 * Indicates whether threaded rendering is currently enabled.
John Reck51aaf902015-12-02 15:08:07 -0800377 *
Stan Iliev45faba52016-06-28 13:33:15 -0400378 * @return True if threaded rendering is in use, false otherwise.
John Reck51aaf902015-12-02 15:08:07 -0800379 */
380 boolean isEnabled() {
381 return mEnabled;
382 }
383
384 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400385 * Indicates whether threaded rendering is currently enabled.
John Reck51aaf902015-12-02 15:08:07 -0800386 *
Stan Iliev45faba52016-06-28 13:33:15 -0400387 * @param enabled True if the threaded renderer is in use, false otherwise.
John Reck51aaf902015-12-02 15:08:07 -0800388 */
389 void setEnabled(boolean enabled) {
390 mEnabled = enabled;
391 }
392
393 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400394 * Indicates whether threaded rendering is currently request but not
John Reck51aaf902015-12-02 15:08:07 -0800395 * necessarily enabled yet.
396 *
397 * @return True if requested, false otherwise.
398 */
399 boolean isRequested() {
400 return mRequested;
401 }
402
403 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400404 * Indicates whether threaded rendering is currently requested but not
John Reck51aaf902015-12-02 15:08:07 -0800405 * necessarily enabled yet.
406 *
Stan Iliev45faba52016-06-28 13:33:15 -0400407 * @return True to request threaded rendering, false otherwise.
John Reck51aaf902015-12-02 15:08:07 -0800408 */
409 void setRequested(boolean requested) {
410 mRequested = requested;
411 }
412
John Reckf7d9c1d2014-04-09 10:01:03 -0700413 private void updateEnabledState(Surface surface) {
414 if (surface == null || !surface.isValid()) {
415 setEnabled(false);
416 } else {
417 setEnabled(mInitialized);
418 }
419 }
420
John Reck51aaf902015-12-02 15:08:07 -0800421 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400422 * Initializes the threaded renderer for the specified surface.
John Reck51aaf902015-12-02 15:08:07 -0800423 *
Stan Iliev45faba52016-06-28 13:33:15 -0400424 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800425 *
426 * @return True if the initialization was successful, false otherwise.
427 */
John Reckcec24ae2013-11-05 13:27:50 -0800428 boolean initialize(Surface surface) throws OutOfResourcesException {
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100429 boolean status = !mInitialized;
John Reckf7d9c1d2014-04-09 10:01:03 -0700430 mInitialized = true;
431 updateEnabledState(surface);
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100432 nInitialize(mNativeProxy, surface);
Dan Stoza5795d642014-06-20 13:01:36 -0700433 return status;
John Reckcec24ae2013-11-05 13:27:50 -0800434 }
435
John Reck51aaf902015-12-02 15:08:07 -0800436 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400437 * Initializes the threaded renderer for the specified surface and setup the
John Reck51aaf902015-12-02 15:08:07 -0800438 * renderer for drawing, if needed. This is invoked when the ViewAncestor has
Stan Iliev45faba52016-06-28 13:33:15 -0400439 * potentially lost the threaded renderer. The threaded renderer should be
John Reck51aaf902015-12-02 15:08:07 -0800440 * reinitialized and setup when the render {@link #isRequested()} and
441 * {@link #isEnabled()}.
442 *
443 * @param width The width of the drawing surface.
444 * @param height The height of the drawing surface.
445 * @param attachInfo Information about the window.
Stan Iliev45faba52016-06-28 13:33:15 -0400446 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800447 * @param surfaceInsets The drawing surface insets to apply
448 *
449 * @return true if the surface was initialized, false otherwise. Returning
450 * false might mean that the surface was already initialized.
451 */
452 boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
453 Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
454 if (isRequested()) {
455 // We lost the gl context, so recreate it.
456 if (!isEnabled()) {
457 if (initialize(surface)) {
458 setup(width, height, attachInfo, surfaceInsets);
459 return true;
460 }
461 }
462 }
463 return false;
464 }
465
466 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400467 * Updates the threaded renderer for the specified surface.
John Reck51aaf902015-12-02 15:08:07 -0800468 *
Stan Iliev45faba52016-06-28 13:33:15 -0400469 * @param surface The surface to render
John Reck51aaf902015-12-02 15:08:07 -0800470 */
John Reckcec24ae2013-11-05 13:27:50 -0800471 void updateSurface(Surface surface) throws OutOfResourcesException {
John Reckf7d9c1d2014-04-09 10:01:03 -0700472 updateEnabledState(surface);
John Reck4f02bf42014-01-03 18:09:17 -0800473 nUpdateSurface(mNativeProxy, surface);
John Reckcec24ae2013-11-05 13:27:50 -0800474 }
475
John Reck51aaf902015-12-02 15:08:07 -0800476 /**
John Reck8afcc762016-04-13 10:24:06 -0700477 * Halts any current rendering into the surface. Use this if it is unclear whether
Stan Iliev45faba52016-06-28 13:33:15 -0400478 * or not the surface used by the ThreadedRenderer will be changing. It
John Reck8afcc762016-04-13 10:24:06 -0700479 * Suspends any rendering into the surface, but will not do any destruction.
480 *
481 * Any subsequent draws will override the pause, resuming normal operation.
John Reck51aaf902015-12-02 15:08:07 -0800482 */
John Reck01a5ea32014-12-03 13:01:07 -0800483 boolean pauseSurface(Surface surface) {
484 return nPauseSurface(mNativeProxy, surface);
John Reckf7d9c1d2014-04-09 10:01:03 -0700485 }
486
John Reck51aaf902015-12-02 15:08:07 -0800487 /**
John Reck8afcc762016-04-13 10:24:06 -0700488 * Hard stops or resumes rendering into the surface. This flag is used to
489 * determine whether or not it is safe to use the given surface *at all*
490 */
491 void setStopped(boolean stopped) {
492 nSetStopped(mNativeProxy, stopped);
493 }
494
495 /**
John Reck51aaf902015-12-02 15:08:07 -0800496 * Destroys all hardware rendering resources associated with the specified
497 * view hierarchy.
498 *
499 * @param view The root of the view hierarchy
500 */
John Reckcec24ae2013-11-05 13:27:50 -0800501 void destroyHardwareResources(View view) {
John Reck4f02bf42014-01-03 18:09:17 -0800502 destroyResources(view);
John Reckf47a5942014-06-30 16:20:04 -0700503 nDestroyHardwareResources(mNativeProxy);
John Reck4f02bf42014-01-03 18:09:17 -0800504 }
505
506 private static void destroyResources(View view) {
507 view.destroyHardwareResources();
John Reckcec24ae2013-11-05 13:27:50 -0800508 }
509
John Reck51aaf902015-12-02 15:08:07 -0800510 /**
John Reck51aaf902015-12-02 15:08:07 -0800511 * Detaches the layer's surface texture from the GL context and releases
512 * the texture id
513 */
John Reck918ad522014-06-27 14:45:25 -0700514 void detachSurfaceTexture(long hardwareLayer) {
515 nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
John Reckcec24ae2013-11-05 13:27:50 -0800516 }
517
John Reck51aaf902015-12-02 15:08:07 -0800518 /**
519 * Sets up the renderer for drawing.
520 *
521 * @param width The width of the drawing surface.
522 * @param height The height of the drawing surface.
523 * @param attachInfo Information about the window.
524 * @param surfaceInsets The drawing surface insets to apply
525 */
Alan Viverette50210d92015-05-14 18:05:36 -0700526 void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
John Reckcec24ae2013-11-05 13:27:50 -0800527 mWidth = width;
528 mHeight = height;
Alan Viverette50210d92015-05-14 18:05:36 -0700529
Alan Viverette3aa1ffb2014-10-30 12:22:08 -0700530 if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
531 || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
Alan Viverette57774a82014-07-15 15:49:55 -0700532 mHasInsets = true;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700533 mInsetLeft = surfaceInsets.left;
534 mInsetTop = surfaceInsets.top;
535 mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
536 mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
Alan Viverette57774a82014-07-15 15:49:55 -0700537
538 // If the surface has insets, it can't be opaque.
539 setOpaque(false);
Alan Viveretteccb11e12014-07-08 16:04:02 -0700540 } else {
Alan Viverette57774a82014-07-15 15:49:55 -0700541 mHasInsets = false;
Alan Viveretteccb11e12014-07-08 16:04:02 -0700542 mInsetLeft = 0;
543 mInsetTop = 0;
544 mSurfaceWidth = width;
545 mSurfaceHeight = height;
546 }
Alan Viverette50210d92015-05-14 18:05:36 -0700547
Alan Viveretteccb11e12014-07-08 16:04:02 -0700548 mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
John Reckab1080c2016-06-21 16:24:20 -0700549 nSetup(mNativeProxy, mLightRadius,
John Reckb36016c2015-03-11 08:50:53 -0700550 mAmbientShadowAlpha, mSpotShadowAlpha);
Alan Viverette50210d92015-05-14 18:05:36 -0700551
552 setLightCenter(attachInfo);
553 }
554
John Reck51aaf902015-12-02 15:08:07 -0800555 /**
556 * Updates the light position based on the position of the window.
557 *
558 * @param attachInfo Information about the window.
559 */
Alan Viverette50210d92015-05-14 18:05:36 -0700560 void setLightCenter(AttachInfo attachInfo) {
561 // Adjust light position for window offsets.
562 final Point displaySize = attachInfo.mPoint;
563 attachInfo.mDisplay.getRealSize(displaySize);
564 final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
565 final float lightY = mLightY - attachInfo.mWindowTop;
566
567 nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
John Reckcec24ae2013-11-05 13:27:50 -0800568 }
569
John Reck51aaf902015-12-02 15:08:07 -0800570 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400571 * Change the ThreadedRenderer's opacity
John Reck51aaf902015-12-02 15:08:07 -0800572 */
John Reck63a06672014-05-07 13:45:54 -0700573 void setOpaque(boolean opaque) {
Alan Viverette57774a82014-07-15 15:49:55 -0700574 nSetOpaque(mNativeProxy, opaque && !mHasInsets);
John Reck63a06672014-05-07 13:45:54 -0700575 }
576
John Reck51aaf902015-12-02 15:08:07 -0800577 /**
578 * Gets the current width of the surface. This is the width that the surface
579 * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
580 *
581 * @return the current width of the surface
582 */
John Reckcec24ae2013-11-05 13:27:50 -0800583 int getWidth() {
584 return mWidth;
585 }
586
John Reck51aaf902015-12-02 15:08:07 -0800587 /**
588 * Gets the current height of the surface. This is the height that the surface
589 * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
590 *
591 * @return the current width of the surface
592 */
John Reckcec24ae2013-11-05 13:27:50 -0800593 int getHeight() {
594 return mHeight;
595 }
596
John Reck51aaf902015-12-02 15:08:07 -0800597 /**
598 * Outputs extra debugging information in the specified file descriptor.
599 */
John Reckba6adf62015-02-19 14:36:50 -0800600 void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
John Reckfe5e7b72014-05-23 17:42:28 -0700601 pw.flush();
John Reckba6adf62015-02-19 14:36:50 -0800602 int flags = 0;
603 for (int i = 0; i < args.length; i++) {
604 switch (args[i]) {
605 case "framestats":
606 flags |= FLAG_DUMP_FRAMESTATS;
607 break;
608 case "reset":
609 flags |= FLAG_DUMP_RESET;
610 break;
611 }
John Reckfe5e7b72014-05-23 17:42:28 -0700612 }
John Reckba6adf62015-02-19 14:36:50 -0800613 nDumpProfileInfo(mNativeProxy, fd, flags);
John Reckcec24ae2013-11-05 13:27:50 -0800614 }
615
John Reck51aaf902015-12-02 15:08:07 -0800616 /**
617 * Loads system properties used by the renderer. This method is invoked
618 * whenever system properties are modified. Implementations can use this
619 * to trigger live updates of the renderer based on properties.
620 *
621 * @return True if a property has changed.
622 */
John Reckcec24ae2013-11-05 13:27:50 -0800623 boolean loadSystemProperties() {
John Reckfe5e7b72014-05-23 17:42:28 -0700624 boolean changed = nLoadSystemProperties(mNativeProxy);
John Reck23d307c2014-10-27 12:38:48 -0700625 if (changed) {
626 invalidateRoot();
627 }
John Reckfe5e7b72014-05-23 17:42:28 -0700628 return changed;
John Reckcec24ae2013-11-05 13:27:50 -0800629 }
630
John Reck0a973302014-07-16 13:29:45 -0700631 private void updateViewTreeDisplayList(View view) {
John Reckcec24ae2013-11-05 13:27:50 -0800632 view.mPrivateFlags |= View.PFLAG_DRAWN;
John Reckcec24ae2013-11-05 13:27:50 -0800633 view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
634 == View.PFLAG_INVALIDATED;
635 view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
Chris Craik31a2d062015-05-01 14:22:47 -0700636 view.updateDisplayListIfDirty();
John Reckcec24ae2013-11-05 13:27:50 -0800637 view.mRecreateDisplayList = false;
John Reckbc0cc022014-04-11 16:08:14 -0700638 }
639
Stan Iliev45faba52016-06-28 13:33:15 -0400640 private void updateRootDisplayList(View view, DrawCallbacks callbacks) {
Chris Craik70850ea2014-11-18 10:49:23 -0800641 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
John Reck0a973302014-07-16 13:29:45 -0700642 updateViewTreeDisplayList(view);
643
644 if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
Chris Craikf6829a02015-03-10 10:28:59 -0700645 DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
John Reck0a973302014-07-16 13:29:45 -0700646 try {
Alan Viverettedbed8932014-08-06 17:54:52 -0700647 final int saveCount = canvas.save();
John Reck0a973302014-07-16 13:29:45 -0700648 canvas.translate(mInsetLeft, mInsetTop);
Stan Iliev45faba52016-06-28 13:33:15 -0400649 callbacks.onPreDraw(canvas);
Chris Craikabedca32014-08-28 15:03:55 -0700650
651 canvas.insertReorderBarrier();
Chris Craik31a2d062015-05-01 14:22:47 -0700652 canvas.drawRenderNode(view.updateDisplayListIfDirty());
Chris Craikabedca32014-08-28 15:03:55 -0700653 canvas.insertInorderBarrier();
654
Stan Iliev45faba52016-06-28 13:33:15 -0400655 callbacks.onPostDraw(canvas);
Alan Viverettedbed8932014-08-06 17:54:52 -0700656 canvas.restoreToCount(saveCount);
John Reck0a973302014-07-16 13:29:45 -0700657 mRootNodeNeedsUpdate = false;
658 } finally {
659 mRootNode.end(canvas);
660 }
661 }
662 Trace.traceEnd(Trace.TRACE_TAG_VIEW);
663 }
664
Skuhneea7a7fb2015-08-28 07:10:31 -0700665 /**
666 * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
667 * rendernode of the UI thread.
668 * @param node The node to add.
669 * @param placeFront If true, the render node will be placed in front of the content node,
670 * otherwise behind the content node.
671 */
672 public void addRenderNode(RenderNode node, boolean placeFront) {
673 nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
674 }
675
676 /**
677 * Only especially added render nodes can be removed.
678 * @param node The node which was added via addRenderNode which should get removed again.
679 */
680 public void removeRenderNode(RenderNode node) {
681 nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
682 }
683
684 /**
685 * Draws a particular render node. If the node is not the content node, only the additional
686 * nodes will get drawn and the content remains untouched.
687 * @param node The node to be drawn.
688 */
689 public void drawRenderNode(RenderNode node) {
690 nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
691 }
692
693 /**
694 * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
695 * will be prevented to overdraw this area. It will be synchronized with the draw call.
696 * This should be updated in the content view's draw call.
697 * @param left The left side of the protected bounds.
698 * @param top The top side of the protected bounds.
699 * @param right The right side of the protected bounds.
700 * @param bottom The bottom side of the protected bounds.
701 */
Skuhneb8160872015-09-22 09:51:39 -0700702 public void setContentDrawBounds(int left, int top, int right, int bottom) {
Jorim Jaggie85ce992016-05-09 19:05:22 -0700703 nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
Skuhneea7a7fb2015-08-28 07:10:31 -0700704 }
705
John Reck51aaf902015-12-02 15:08:07 -0800706 /**
707 * Interface used to receive callbacks whenever a view is drawn by
Stan Iliev45faba52016-06-28 13:33:15 -0400708 * a threaded renderer instance.
John Reck51aaf902015-12-02 15:08:07 -0800709 */
Stan Iliev45faba52016-06-28 13:33:15 -0400710 interface DrawCallbacks {
John Reck51aaf902015-12-02 15:08:07 -0800711 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400712 * Invoked before a view is drawn by a threaded renderer.
John Reck51aaf902015-12-02 15:08:07 -0800713 * This method can be used to apply transformations to the
714 * canvas but no drawing command should be issued.
715 *
716 * @param canvas The Canvas used to render the view.
717 */
Stan Iliev45faba52016-06-28 13:33:15 -0400718 void onPreDraw(DisplayListCanvas canvas);
John Reck51aaf902015-12-02 15:08:07 -0800719
720 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400721 * Invoked after a view is drawn by a threaded renderer.
John Reck51aaf902015-12-02 15:08:07 -0800722 * It is safe to invoke drawing commands from this method.
723 *
724 * @param canvas The Canvas used to render the view.
725 */
Stan Iliev45faba52016-06-28 13:33:15 -0400726 void onPostDraw(DisplayListCanvas canvas);
John Reck51aaf902015-12-02 15:08:07 -0800727 }
728
729 /**
Stan Iliev45faba52016-06-28 13:33:15 -0400730 * Indicates that the content drawn by DrawCallbacks needs to
John Reck51aaf902015-12-02 15:08:07 -0800731 * be updated, which will be done by the next call to draw()
732 */
John Reck0a973302014-07-16 13:29:45 -0700733 void invalidateRoot() {
734 mRootNodeNeedsUpdate = true;
735 }
736
John Reck51aaf902015-12-02 15:08:07 -0800737 /**
738 * Draws the specified view.
739 *
740 * @param view The view to draw.
741 * @param attachInfo AttachInfo tied to the specified view.
742 * @param callbacks Callbacks invoked when drawing happens.
743 */
Stan Iliev45faba52016-06-28 13:33:15 -0400744 void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {
John Reckbc0cc022014-04-11 16:08:14 -0700745 attachInfo.mIgnoreDirtyState = true;
John Reckbc0cc022014-04-11 16:08:14 -0700746
John Reckba6adf62015-02-19 14:36:50 -0800747 final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
748 choreographer.mFrameInfo.markDrawStart();
John Reckfe5e7b72014-05-23 17:42:28 -0700749
John Reck61375a82014-09-18 19:27:48 +0000750 updateRootDisplayList(view, callbacks);
John Reckcec24ae2013-11-05 13:27:50 -0800751
John Reck6313b922014-04-16 18:59:21 -0700752 attachInfo.mIgnoreDirtyState = false;
753
John Reck119907c2014-08-14 09:02:01 -0700754 // register animating rendernodes which started animating prior to renderer
755 // creation, which is typical for animators started prior to first draw
756 if (attachInfo.mPendingAnimatingRenderNodes != null) {
757 final int count = attachInfo.mPendingAnimatingRenderNodes.size();
758 for (int i = 0; i < count; i++) {
759 registerAnimatingRenderNode(
760 attachInfo.mPendingAnimatingRenderNodes.get(i));
761 }
762 attachInfo.mPendingAnimatingRenderNodes.clear();
763 // We don't need this anymore as subsequent calls to
764 // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
765 attachInfo.mPendingAnimatingRenderNodes = null;
766 }
767
John Reckba6adf62015-02-19 14:36:50 -0800768 final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
John Reck51f2d602016-04-06 07:50:47 -0700769 int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
John Reckaa95a882014-11-07 11:02:07 -0800770 if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
771 setEnabled(false);
John Reckb13de072014-11-19 16:33:47 -0800772 attachInfo.mViewRootImpl.mSurface.release();
John Reckaa95a882014-11-07 11:02:07 -0800773 // Invalidate since we failed to draw. This should fetch a Surface
774 // if it is still needed or do nothing if we are no longer drawing
775 attachInfo.mViewRootImpl.invalidate();
776 }
John Reckf9be7792014-05-02 18:21:16 -0700777 if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
778 attachInfo.mViewRootImpl.invalidate();
779 }
John Reckcec24ae2013-11-05 13:27:50 -0800780 }
781
John Reck3b202512014-06-23 13:13:08 -0700782 static void invokeFunctor(long functor, boolean waitForCompletion) {
783 nInvokeFunctor(functor, waitForCompletion);
John Reck0d1f6342014-03-28 20:30:27 -0700784 }
785
John Reck51aaf902015-12-02 15:08:07 -0800786 /**
787 * Creates a new hardware layer. A hardware layer built by calling this
788 * method will be treated as a texture layer, instead of as a render target.
789 *
790 * @return A hardware layer
791 */
John Reck19b6bcf2014-02-14 20:03:38 -0800792 HardwareLayer createTextureLayer() {
793 long layer = nCreateTextureLayer(mNativeProxy);
794 return HardwareLayer.adoptTextureLayer(this, layer);
795 }
796
John Reck51aaf902015-12-02 15:08:07 -0800797
John Reck3e824952014-08-20 10:08:39 -0700798 void buildLayer(RenderNode node) {
799 nBuildLayer(mNativeProxy, node.getNativeDisplayList());
800 }
801
John Reck51aaf902015-12-02 15:08:07 -0800802
John Reck19b6bcf2014-02-14 20:03:38 -0800803 boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
804 return nCopyLayerInto(mNativeProxy,
John Reck3731dc22015-04-13 15:20:29 -0700805 layer.getDeferredLayerUpdater(), bitmap);
John Reck19b6bcf2014-02-14 20:03:38 -0800806 }
807
John Reck51aaf902015-12-02 15:08:07 -0800808 /**
809 * Indicates that the specified hardware layer needs to be updated
810 * as soon as possible.
811 *
812 * @param layer The hardware layer that needs an update
813 */
John Reck19b6bcf2014-02-14 20:03:38 -0800814 void pushLayerUpdate(HardwareLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700815 nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800816 }
817
John Reck51aaf902015-12-02 15:08:07 -0800818 /**
819 * Tells the HardwareRenderer that the layer is destroyed. The renderer
820 * should remove the layer from any update queues.
821 */
John Reck19b6bcf2014-02-14 20:03:38 -0800822 void onLayerDestroyed(HardwareLayer layer) {
John Reckd72e0a32014-05-29 18:56:11 -0700823 nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
John Reck19b6bcf2014-02-14 20:03:38 -0800824 }
825
John Reck51aaf902015-12-02 15:08:07 -0800826 /**
John Reck51aaf902015-12-02 15:08:07 -0800827 * Blocks until all previously queued work has completed.
828 */
John Reck28ad7b52014-04-07 16:59:25 -0700829 void fence() {
830 nFence(mNativeProxy);
831 }
832
John Reck51aaf902015-12-02 15:08:07 -0800833 /**
834 * Prevents any further drawing until draw() is called. This is a signal
835 * that the contents of the RenderNode tree are no longer safe to play back.
836 * In practice this usually means that there are Functor pointers in the
837 * display list that are no longer valid.
838 */
John Reckf47a5942014-06-30 16:20:04 -0700839 void stopDrawing() {
840 nStopDrawing(mNativeProxy);
841 }
842
John Reck51aaf902015-12-02 15:08:07 -0800843 /**
844 * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
845 */
John Recka5dda642014-05-22 15:43:54 -0700846 public void notifyFramePending() {
847 nNotifyFramePending(mNativeProxy);
848 }
849
John Reck51aaf902015-12-02 15:08:07 -0800850
John Reck119907c2014-08-14 09:02:01 -0700851 void registerAnimatingRenderNode(RenderNode animator) {
852 nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
853 }
854
Doris Liu67ce99b2016-05-17 16:50:31 -0700855 void registerVectorDrawableAnimator(
856 AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
857 nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
858 animator.getAnimatorNativePtr());
859 }
860
John Recke248bd12015-08-05 13:53:53 -0700861 public void serializeDisplayListTree() {
862 nSerializeDisplayListTree(mNativeProxy);
863 }
864
John Reck95801462016-09-01 09:44:09 -0700865 public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
866 if (srcRect == null) {
867 // Empty rect means entire surface
868 return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap);
869 } else {
870 return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
871 srcRect.right, srcRect.bottom, bitmap);
872 }
John Reck10dd0582016-03-31 16:36:16 -0700873 }
874
John Reck119907c2014-08-14 09:02:01 -0700875 @Override
John Reck4f02bf42014-01-03 18:09:17 -0800876 protected void finalize() throws Throwable {
877 try {
878 nDeleteProxy(mNativeProxy);
John Reck0ed751d2014-04-08 14:10:17 -0700879 mNativeProxy = 0;
John Reck4f02bf42014-01-03 18:09:17 -0800880 } finally {
881 super.finalize();
John Reckcec24ae2013-11-05 13:27:50 -0800882 }
883 }
884
John Reckedc524c2015-03-18 15:24:33 -0700885 private static class ProcessInitializer {
886 static ProcessInitializer sInstance = new ProcessInitializer();
John Reck66f0be62014-05-13 13:39:31 -0700887
888 private boolean mInitialized = false;
889
John Reckdf1742e2017-01-19 15:56:21 -0800890 private Context mAppContext;
891 private IGraphicsStats mGraphicsStatsService;
892 private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
893 @Override
894 public void onRotateGraphicsStatsBuffer() throws RemoteException {
895 rotateBuffer();
896 }
897 };
898
John Reckedc524c2015-03-18 15:24:33 -0700899 private ProcessInitializer() {}
John Reck66f0be62014-05-13 13:39:31 -0700900
John Reck3b202512014-06-23 13:13:08 -0700901 synchronized void init(Context context, long renderProxy) {
John Reck66f0be62014-05-13 13:39:31 -0700902 if (mInitialized) return;
John Reckedc524c2015-03-18 15:24:33 -0700903 mInitialized = true;
John Reckdf1742e2017-01-19 15:56:21 -0800904 mAppContext = context.getApplicationContext();
Tim Murray33eb07f2016-06-10 10:03:20 -0700905 initSched(context, renderProxy);
John Reckdf1742e2017-01-19 15:56:21 -0800906 initGraphicsStats();
John Reckedc524c2015-03-18 15:24:33 -0700907 }
908
John Reckdf1742e2017-01-19 15:56:21 -0800909 private void initSched(Context context, long renderProxy) {
Tim Murray33eb07f2016-06-10 10:03:20 -0700910 try {
911 int tid = nGetRenderThreadTid(renderProxy);
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800912 ActivityManager.getService().setRenderThread(tid);
Tim Murray33eb07f2016-06-10 10:03:20 -0700913 } catch (Throwable t) {
914 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
915 }
916 }
917
John Reckdf1742e2017-01-19 15:56:21 -0800918 private void initGraphicsStats() {
John Reckedc524c2015-03-18 15:24:33 -0700919 try {
John Reck828698b2015-06-30 12:56:03 -0700920 IBinder binder = ServiceManager.getService("graphicsstats");
921 if (binder == null) return;
John Reckdf1742e2017-01-19 15:56:21 -0800922 mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
923 requestBuffer();
924 } catch (Throwable t) {
925 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
926 }
927 }
928
929 private void rotateBuffer() {
930 nRotateProcessStatsBuffer();
931 requestBuffer();
932 }
933
934 private void requestBuffer() {
935 try {
936 final String pkg = mAppContext.getApplicationInfo().packageName;
937 ParcelFileDescriptor pfd = mGraphicsStatsService
938 .requestBufferForProcess(pkg, mGraphicsStatsCallback);
939 nSetProcessStatsBuffer(pfd.getFd());
John Reckedc524c2015-03-18 15:24:33 -0700940 pfd.close();
John Reck828698b2015-06-30 12:56:03 -0700941 } catch (Throwable t) {
942 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
John Reckedc524c2015-03-18 15:24:33 -0700943 }
944 }
John Reck66f0be62014-05-13 13:39:31 -0700945 }
946
Andres Morales910beb82016-02-02 16:19:40 -0800947 void addFrameMetricsObserver(FrameMetricsObserver observer) {
948 long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
949 observer.mNative = new VirtualRefBasePtr(nativeObserver);
Andres Morales06f5bc72015-12-15 15:21:31 -0800950 }
951
Andres Morales910beb82016-02-02 16:19:40 -0800952 void removeFrameMetricsObserver(FrameMetricsObserver observer) {
953 nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
954 observer.mNative = null;
Andres Morales06f5bc72015-12-15 15:21:31 -0800955 }
956
John Reck84a4c882014-05-30 14:34:03 -0700957 static native void setupShadersDiskCache(String cacheFile);
958
John Reckdf1742e2017-01-19 15:56:21 -0800959 private static native void nRotateProcessStatsBuffer();
960 private static native void nSetProcessStatsBuffer(int fd);
Tim Murray33eb07f2016-06-10 10:03:20 -0700961 private static native int nGetRenderThreadTid(long nativeProxy);
John Reck4f02bf42014-01-03 18:09:17 -0800962
John Recke45b1fd2014-04-15 09:50:16 -0700963 private static native long nCreateRootRenderNode();
964 private static native long nCreateProxy(boolean translucent, long rootRenderNode);
John Reck4f02bf42014-01-03 18:09:17 -0800965 private static native void nDeleteProxy(long nativeProxy);
966
John Recke4280ba2014-05-05 16:39:37 -0700967 private static native boolean nLoadSystemProperties(long nativeProxy);
John Reckb36016c2015-03-11 08:50:53 -0700968 private static native void nSetName(long nativeProxy, String name);
John Reck18f16e62014-05-02 16:46:41 -0700969
Thomas Buhot0bcd0cb2015-12-04 12:18:03 +0100970 private static native void nInitialize(long nativeProxy, Surface window);
John Reck4f02bf42014-01-03 18:09:17 -0800971 private static native void nUpdateSurface(long nativeProxy, Surface window);
John Reck01a5ea32014-12-03 13:01:07 -0800972 private static native boolean nPauseSurface(long nativeProxy, Surface window);
John Reck8afcc762016-04-13 10:24:06 -0700973 private static native void nSetStopped(long nativeProxy, boolean stopped);
John Reckab1080c2016-06-21 16:24:20 -0700974 private static native void nSetup(long nativeProxy,
Alan Viverette50210d92015-05-14 18:05:36 -0700975 float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
976 private static native void nSetLightCenter(long nativeProxy,
977 float lightX, float lightY, float lightZ);
John Reck63a06672014-05-07 13:45:54 -0700978 private static native void nSetOpaque(long nativeProxy, boolean opaque);
John Reck51f2d602016-04-06 07:50:47 -0700979 private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
Doris Liu350e6522016-02-19 14:20:37 -0800980 private static native void nDestroy(long nativeProxy, long rootRenderNode);
John Reck119907c2014-08-14 09:02:01 -0700981 private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
Doris Liu67ce99b2016-05-17 16:50:31 -0700982 private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
John Reck4f02bf42014-01-03 18:09:17 -0800983
John Reck3b202512014-06-23 13:13:08 -0700984 private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
John Reck19b6bcf2014-02-14 20:03:38 -0800985
John Reck19b6bcf2014-02-14 20:03:38 -0800986 private static native long nCreateTextureLayer(long nativeProxy);
John Reck3e824952014-08-20 10:08:39 -0700987 private static native void nBuildLayer(long nativeProxy, long node);
John Reck3731dc22015-04-13 15:20:29 -0700988 private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
John Reckd72e0a32014-05-29 18:56:11 -0700989 private static native void nPushLayerUpdate(long nativeProxy, long layer);
990 private static native void nCancelLayerUpdate(long nativeProxy, long layer);
John Reck918ad522014-06-27 14:45:25 -0700991 private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
John Reck28ad7b52014-04-07 16:59:25 -0700992
John Reckf47a5942014-06-30 16:20:04 -0700993 private static native void nDestroyHardwareResources(long nativeProxy);
994 private static native void nTrimMemory(int level);
Chris Craik2507c342015-05-04 14:36:49 -0700995 private static native void nOverrideProperty(String name, String value);
John Recke1628b72014-05-23 15:11:19 -0700996
John Reck28ad7b52014-04-07 16:59:25 -0700997 private static native void nFence(long nativeProxy);
John Reckf47a5942014-06-30 16:20:04 -0700998 private static native void nStopDrawing(long nativeProxy);
John Recka5dda642014-05-22 15:43:54 -0700999 private static native void nNotifyFramePending(long nativeProxy);
John Reckfe5e7b72014-05-23 17:42:28 -07001000
John Recke248bd12015-08-05 13:53:53 -07001001 private static native void nSerializeDisplayListTree(long nativeProxy);
1002
John Reckba6adf62015-02-19 14:36:50 -08001003 private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1004 @DumpFlags int dumpFlags);
Skuhneea7a7fb2015-08-28 07:10:31 -07001005
1006 private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1007 boolean placeFront);
1008 private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1009 private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
Skuhneb8160872015-09-22 09:51:39 -07001010 private static native void nSetContentDrawBounds(long nativeProxy, int left,
Skuhneea7a7fb2015-08-28 07:10:31 -07001011 int top, int right, int bottom);
Andres Morales06f5bc72015-12-15 15:21:31 -08001012
Andres Morales910beb82016-02-02 16:19:40 -08001013 private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
1014 private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
John Reck10dd0582016-03-31 16:36:16 -07001015
John Reck95801462016-09-01 09:44:09 -07001016 private static native int nCopySurfaceInto(Surface surface,
1017 int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
John Reckcec24ae2013-11-05 13:27:50 -08001018}