1 /*
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 
17 package android.view;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.app.ActivityManager;
22 import android.content.Context;
23 import android.content.res.TypedArray;
24 import android.graphics.Bitmap;
25 import android.graphics.Point;
26 import android.graphics.Rect;
27 import android.graphics.drawable.AnimatedVectorDrawable;
28 import android.os.IBinder;
29 import android.os.ParcelFileDescriptor;
30 import android.os.RemoteException;
31 import android.os.ServiceManager;
32 import android.os.SystemProperties;
33 import android.os.Trace;
34 import android.util.Log;
35 import android.view.Surface.OutOfResourcesException;
36 import android.view.View.AttachInfo;
37 import android.view.animation.AnimationUtils;
38 
39 import com.android.internal.R;
40 import com.android.internal.util.VirtualRefBasePtr;
41 
42 import java.io.File;
43 import java.io.FileDescriptor;
44 import java.io.PrintWriter;
45 import java.lang.annotation.Retention;
46 import java.lang.annotation.RetentionPolicy;
47 
48 /**
49  * Threaded renderer that proxies the rendering to a render thread. Most calls
50  * are currently synchronous.
51  *
52  * The UI thread can block on the RenderThread, but RenderThread must never
53  * block on the UI thread.
54  *
55  * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
56  * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
57  * by the lifecycle of the RenderProxy.
58  *
59  * Note that although currently the EGL context & surfaces are created & managed
60  * by the render thread, the goal is to move that into a shared structure that can
61  * be managed by both threads. EGLSurface creation & deletion should ideally be
62  * done on the UI thread and not the RenderThread to avoid stalling the
63  * RenderThread with surface buffer allocation.
64  *
65  * @hide
66  */
67 public final class ThreadedRenderer {
68     private static final String LOG_TAG = "ThreadedRenderer";
69 
70     /**
71      * Name of the file that holds the shaders cache.
72      */
73     private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
74     private static final String CACHE_PATH_SKIASHADERS = "com.android.skia.shaders_cache";
75 
76     /**
77      * System property used to enable or disable threaded rendering profiling.
78      * The default value of this property is assumed to be false.
79      *
80      * When profiling is enabled, the adb shell dumpsys gfxinfo command will
81      * output extra information about the time taken to execute by the last
82      * frames.
83      *
84      * Possible values:
85      * "true", to enable profiling
86      * "visual_bars", to enable profiling and visualize the results on screen
87      * "false", to disable profiling
88      *
89      * @see #PROFILE_PROPERTY_VISUALIZE_BARS
90      *
91      * @hide
92      */
93     public static final String PROFILE_PROPERTY = "debug.hwui.profile";
94 
95     /**
96      * Value for {@link #PROFILE_PROPERTY}. When the property is set to this
97      * value, profiling data will be visualized on screen as a bar chart.
98      *
99      * @hide
100      */
101     public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars";
102 
103     /**
104      * System property used to specify the number of frames to be used
105      * when doing threaded rendering profiling.
106      * The default value of this property is #PROFILE_MAX_FRAMES.
107      *
108      * When profiling is enabled, the adb shell dumpsys gfxinfo command will
109      * output extra information about the time taken to execute by the last
110      * frames.
111      *
112      * Possible values:
113      * "60", to set the limit of frames to 60
114      */
115     static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes";
116 
117     /**
118      * System property used to debug EGL configuration choice.
119      *
120      * Possible values:
121      * "choice", print the chosen configuration only
122      * "all", print all possible configurations
123      */
124     static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config";
125 
126     /**
127      * Turn on to draw dirty regions every other frame.
128      *
129      * Possible values:
130      * "true", to enable dirty regions debugging
131      * "false", to disable dirty regions debugging
132      *
133      * @hide
134      */
135     public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
136 
137     /**
138      * Turn on to flash hardware layers when they update.
139      *
140      * Possible values:
141      * "true", to enable hardware layers updates debugging
142      * "false", to disable hardware layers updates debugging
143      *
144      * @hide
145      */
146     public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
147             "debug.hwui.show_layers_updates";
148 
149     /**
150      * Controls overdraw debugging.
151      *
152      * Possible values:
153      * "false", to disable overdraw debugging
154      * "show", to show overdraw areas on screen
155      * "count", to display an overdraw counter
156      *
157      * @hide
158      */
159     public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
160 
161     /**
162      * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
163      * value, overdraw will be shown on screen by coloring pixels.
164      *
165      * @hide
166      */
167     public static final String OVERDRAW_PROPERTY_SHOW = "show";
168 
169     /**
170      * Turn on to debug non-rectangular clip operations.
171      *
172      * Possible values:
173      * "hide", to disable this debug mode
174      * "highlight", highlight drawing commands tested against a non-rectangular clip
175      * "stencil", renders the clip region on screen when set
176      *
177      * @hide
178      */
179     public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
180             "debug.hwui.show_non_rect_clip";
181 
182     /**
183      * Sets the FPS devisor to lower the FPS.
184      *
185      * Sets a positive integer as a divisor. 1 (the default value) menas the full FPS, and 2
186      * means half the full FPS.
187      *
188      *
189      * @hide
190      */
191     public static final String DEBUG_FPS_DIVISOR = "debug.hwui.fps_divisor";
192 
193     public static int EGL_CONTEXT_PRIORITY_HIGH_IMG = 0x3101;
194     public static int EGL_CONTEXT_PRIORITY_MEDIUM_IMG = 0x3102;
195     public static int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;
196 
197     static {
198         // Try to check OpenGL support early if possible.
isAvailable()199         isAvailable();
200     }
201 
202     /**
203      * A process can set this flag to false to prevent the use of threaded
204      * rendering.
205      *
206      * @hide
207      */
208     public static boolean sRendererDisabled = false;
209 
210     /**
211      * Further threaded renderer disabling for the system process.
212      *
213      * @hide
214      */
215     public static boolean sSystemRendererDisabled = false;
216 
217     /**
218      * Invoke this method to disable threaded rendering in the current process.
219      *
220      * @hide
221      */
disable(boolean system)222     public static void disable(boolean system) {
223         sRendererDisabled = true;
224         if (system) {
225             sSystemRendererDisabled = true;
226         }
227     }
228 
229     public static boolean sTrimForeground = false;
230 
231     /**
232      * Controls whether or not the renderer should aggressively trim
233      * memory. Note that this must not be set for any process that uses
234      * WebView! This should be only used by system_process or similar
235      * that do not go into the background.
236      */
enableForegroundTrimming()237     public static void enableForegroundTrimming() {
238         sTrimForeground = true;
239     }
240 
241     private static Boolean sSupportsOpenGL;
242 
243     /**
244      * Indicates whether threaded rendering is available under any form for
245      * the view hierarchy.
246      *
247      * @return True if the view hierarchy can potentially be defer rendered,
248      *         false otherwise
249      */
isAvailable()250     public static boolean isAvailable() {
251         if (sSupportsOpenGL != null) {
252             return sSupportsOpenGL.booleanValue();
253         }
254         if (SystemProperties.getInt("ro.kernel.qemu", 0) == 0) {
255             // Device is not an emulator.
256             sSupportsOpenGL = true;
257             return true;
258         }
259         int qemu_gles = SystemProperties.getInt("qemu.gles", -1);
260         if (qemu_gles == -1) {
261             // In this case, the value of the qemu.gles property is not ready
262             // because the SurfaceFlinger service may not start at this point.
263             return false;
264         }
265         // In the emulator this property will be set > 0 when OpenGL ES 2.0 is
266         // enabled, 0 otherwise. On old emulator versions it will be undefined.
267         sSupportsOpenGL = qemu_gles > 0;
268         return sSupportsOpenGL.booleanValue();
269     }
270 
271     /**
272      * Sets the directory to use as a persistent storage for threaded rendering
273      * resources.
274      *
275      * @param cacheDir A directory the current process can write to
276      *
277      * @hide
278      */
setupDiskCache(File cacheDir)279     public static void setupDiskCache(File cacheDir) {
280         ThreadedRenderer.setupShadersDiskCache(
281                 new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(),
282                 new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath());
283     }
284 
285     /**
286      * Creates a threaded renderer using OpenGL.
287      *
288      * @param translucent True if the surface is translucent, false otherwise
289      *
290      * @return A threaded renderer backed by OpenGL.
291      */
create(Context context, boolean translucent, String name)292     public static ThreadedRenderer create(Context context, boolean translucent, String name) {
293         ThreadedRenderer renderer = null;
294         if (isAvailable()) {
295             renderer = new ThreadedRenderer(context, translucent, name);
296         }
297         return renderer;
298     }
299 
300     /**
301      * Invoke this method when the system is running out of memory. This
302      * method will attempt to recover as much memory as possible, based on
303      * the specified hint.
304      *
305      * @param level Hint about the amount of memory that should be trimmed,
306      *              see {@link android.content.ComponentCallbacks}
307      */
trimMemory(int level)308     public static void trimMemory(int level) {
309         nTrimMemory(level);
310     }
311 
overrideProperty(@onNull String name, @NonNull String value)312     public static void overrideProperty(@NonNull String name, @NonNull String value) {
313         if (name == null || value == null) {
314             throw new IllegalArgumentException("name and value must be non-null");
315         }
316         nOverrideProperty(name, value);
317     }
318 
319     // Keep in sync with DrawFrameTask.h SYNC_* flags
320     // Nothing interesting to report
321     private static final int SYNC_OK = 0;
322     // Needs a ViewRoot invalidate
323     private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
324     // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
325     private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
326     // setStopped is true, drawing is false
327     // TODO: Remove this and SYNC_LOST_SURFACE_REWARD_IF_FOUND?
328     // This flag isn't really used as there's nothing that we care to do
329     // in response, so it really just exists to differentiate from LOST_SURFACE
330     // but possibly both can just be deleted.
331     private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
332     private static final int SYNC_FRAME_DROPPED = 1 << 3;
333 
334     private static final String[] VISUALIZERS = {
335         PROFILE_PROPERTY_VISUALIZE_BARS,
336     };
337 
338     private static final int FLAG_DUMP_FRAMESTATS   = 1 << 0;
339     private static final int FLAG_DUMP_RESET        = 1 << 1;
340     private static final int FLAG_DUMP_ALL          = FLAG_DUMP_FRAMESTATS;
341 
342     @IntDef(flag = true, prefix = { "FLAG_DUMP_" }, value = {
343             FLAG_DUMP_FRAMESTATS,
344             FLAG_DUMP_RESET
345     })
346     @Retention(RetentionPolicy.SOURCE)
347     public @interface DumpFlags {}
348 
349     // Size of the rendered content.
350     private int mWidth, mHeight;
351 
352     // Actual size of the drawing surface.
353     private int mSurfaceWidth, mSurfaceHeight;
354 
355     // Insets between the drawing surface and rendered content. These are
356     // applied as translation when updating the root render node.
357     private int mInsetTop, mInsetLeft;
358 
359     // Whether the surface has insets. Used to protect opacity.
360     private boolean mHasInsets;
361 
362     // Light and shadow properties specified by the theme.
363     private final float mLightY;
364     private final float mLightZ;
365     private final float mLightRadius;
366     private final int mAmbientShadowAlpha;
367     private final int mSpotShadowAlpha;
368 
369     private long mNativeProxy;
370     private boolean mInitialized = false;
371     private RenderNode mRootNode;
372     private boolean mRootNodeNeedsUpdate;
373 
374     private boolean mEnabled;
375     private boolean mRequested = true;
376     private boolean mIsOpaque = false;
377 
ThreadedRenderer(Context context, boolean translucent, String name)378     ThreadedRenderer(Context context, boolean translucent, String name) {
379         final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
380         mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
381         mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
382         mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
383         mAmbientShadowAlpha =
384                 (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
385         mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
386         a.recycle();
387 
388         long rootNodePtr = nCreateRootRenderNode();
389         mRootNode = RenderNode.adopt(rootNodePtr);
390         mRootNode.setClipToBounds(false);
391         mIsOpaque = !translucent;
392         mNativeProxy = nCreateProxy(translucent, rootNodePtr);
393         nSetName(mNativeProxy, name);
394 
395         ProcessInitializer.sInstance.init(context, mNativeProxy);
396 
397         loadSystemProperties();
398     }
399 
400     /**
401      * Destroys the threaded rendering context.
402      */
destroy()403     void destroy() {
404         mInitialized = false;
405         updateEnabledState(null);
406         nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
407     }
408 
409     /**
410      * Indicates whether threaded rendering is currently enabled.
411      *
412      * @return True if threaded rendering  is in use, false otherwise.
413      */
isEnabled()414     boolean isEnabled() {
415         return mEnabled;
416     }
417 
418     /**
419      * Indicates whether threaded rendering  is currently enabled.
420      *
421      * @param enabled True if the threaded renderer is in use, false otherwise.
422      */
setEnabled(boolean enabled)423     void setEnabled(boolean enabled) {
424         mEnabled = enabled;
425     }
426 
427     /**
428      * Indicates whether threaded rendering is currently request but not
429      * necessarily enabled yet.
430      *
431      * @return True if requested, false otherwise.
432      */
isRequested()433     boolean isRequested() {
434         return mRequested;
435     }
436 
437     /**
438      * Indicates whether threaded rendering is currently requested but not
439      * necessarily enabled yet.
440      */
setRequested(boolean requested)441     void setRequested(boolean requested) {
442         mRequested = requested;
443     }
444 
updateEnabledState(Surface surface)445     private void updateEnabledState(Surface surface) {
446         if (surface == null || !surface.isValid()) {
447             setEnabled(false);
448         } else {
449             setEnabled(mInitialized);
450         }
451     }
452 
453     /**
454      * Initializes the threaded renderer for the specified surface.
455      *
456      * @param surface The surface to render
457      *
458      * @return True if the initialization was successful, false otherwise.
459      */
initialize(Surface surface)460     boolean initialize(Surface surface) throws OutOfResourcesException {
461         boolean status = !mInitialized;
462         mInitialized = true;
463         updateEnabledState(surface);
464         nInitialize(mNativeProxy, surface);
465         return status;
466     }
467 
468     /**
469      * Initializes the threaded renderer for the specified surface and setup the
470      * renderer for drawing, if needed. This is invoked when the ViewAncestor has
471      * potentially lost the threaded renderer. The threaded renderer should be
472      * reinitialized and setup when the render {@link #isRequested()} and
473      * {@link #isEnabled()}.
474      *
475      * @param width The width of the drawing surface.
476      * @param height The height of the drawing surface.
477      * @param attachInfo Information about the window.
478      * @param surface The surface to render
479      * @param surfaceInsets The drawing surface insets to apply
480      *
481      * @return true if the surface was initialized, false otherwise. Returning
482      *         false might mean that the surface was already initialized.
483      */
initializeIfNeeded(int width, int height, View.AttachInfo attachInfo, Surface surface, Rect surfaceInsets)484     boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
485             Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
486         if (isRequested()) {
487             // We lost the gl context, so recreate it.
488             if (!isEnabled()) {
489                 if (initialize(surface)) {
490                     setup(width, height, attachInfo, surfaceInsets);
491                     return true;
492                 }
493             }
494         }
495         return false;
496     }
497 
498     /**
499      * Updates the threaded renderer for the specified surface.
500      *
501      * @param surface The surface to render
502      */
updateSurface(Surface surface)503     void updateSurface(Surface surface) throws OutOfResourcesException {
504         updateEnabledState(surface);
505         nUpdateSurface(mNativeProxy, surface);
506     }
507 
508     /**
509      * Halts any current rendering into the surface. Use this if it is unclear whether
510      * or not the surface used by the ThreadedRenderer will be changing. It
511      * Suspends any rendering into the surface, but will not do any destruction.
512      *
513      * Any subsequent draws will override the pause, resuming normal operation.
514      */
pauseSurface(Surface surface)515     boolean pauseSurface(Surface surface) {
516         return nPauseSurface(mNativeProxy, surface);
517     }
518 
519     /**
520      * Hard stops or resumes rendering into the surface. This flag is used to
521      * determine whether or not it is safe to use the given surface *at all*
522      */
setStopped(boolean stopped)523     void setStopped(boolean stopped) {
524         nSetStopped(mNativeProxy, stopped);
525     }
526 
527     /**
528      * Destroys all hardware rendering resources associated with the specified
529      * view hierarchy.
530      *
531      * @param view The root of the view hierarchy
532      */
destroyHardwareResources(View view)533     void destroyHardwareResources(View view) {
534         destroyResources(view);
535         nDestroyHardwareResources(mNativeProxy);
536     }
537 
destroyResources(View view)538     private static void destroyResources(View view) {
539         view.destroyHardwareResources();
540     }
541 
542     /**
543      * Detaches the layer's surface texture from the GL context and releases
544      * the texture id
545      */
detachSurfaceTexture(long hardwareLayer)546     void detachSurfaceTexture(long hardwareLayer) {
547         nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
548     }
549 
550     /**
551      * Sets up the renderer for drawing.
552      *
553      * @param width The width of the drawing surface.
554      * @param height The height of the drawing surface.
555      * @param attachInfo Information about the window.
556      * @param surfaceInsets The drawing surface insets to apply
557      */
setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets)558     void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
559         mWidth = width;
560         mHeight = height;
561 
562         if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
563                 || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
564             mHasInsets = true;
565             mInsetLeft = surfaceInsets.left;
566             mInsetTop = surfaceInsets.top;
567             mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
568             mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
569 
570             // If the surface has insets, it can't be opaque.
571             setOpaque(false);
572         } else {
573             mHasInsets = false;
574             mInsetLeft = 0;
575             mInsetTop = 0;
576             mSurfaceWidth = width;
577             mSurfaceHeight = height;
578         }
579 
580         mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
581         nSetup(mNativeProxy, mLightRadius,
582                 mAmbientShadowAlpha, mSpotShadowAlpha);
583 
584         setLightCenter(attachInfo);
585     }
586 
587     /**
588      * Updates the light position based on the position of the window.
589      *
590      * @param attachInfo Information about the window.
591      */
setLightCenter(AttachInfo attachInfo)592     void setLightCenter(AttachInfo attachInfo) {
593         // Adjust light position for window offsets.
594         final Point displaySize = attachInfo.mPoint;
595         attachInfo.mDisplay.getRealSize(displaySize);
596         final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
597         final float lightY = mLightY - attachInfo.mWindowTop;
598 
599         nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
600     }
601 
602     /**
603      * Change the ThreadedRenderer's opacity
604      */
setOpaque(boolean opaque)605     void setOpaque(boolean opaque) {
606         mIsOpaque = opaque && !mHasInsets;
607         nSetOpaque(mNativeProxy, mIsOpaque);
608     }
609 
isOpaque()610     boolean isOpaque() {
611         return mIsOpaque;
612     }
613 
614     /**
615      * Enable/disable wide gamut rendering on this renderer.
616      */
setWideGamut(boolean wideGamut)617     void setWideGamut(boolean wideGamut) {
618         nSetWideGamut(mNativeProxy, wideGamut);
619     }
620 
621     /**
622      * Gets the current width of the surface. This is the width that the surface
623      * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
624      *
625      * @return the current width of the surface
626      */
getWidth()627     int getWidth() {
628         return mWidth;
629     }
630 
631     /**
632      * Gets the current height of the surface. This is the height that the surface
633      * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
634      *
635      * @return the current width of the surface
636      */
getHeight()637     int getHeight() {
638         return mHeight;
639     }
640 
641     /**
642      * Outputs extra debugging information in the specified file descriptor.
643      */
dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args)644     void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
645         pw.flush();
646         // If there's no arguments, eg 'dumpsys gfxinfo', then dump everything.
647         // If there's a targetted package, eg 'dumpsys gfxinfo com.android.systemui', then only
648         // dump the summary information
649         int flags = (args == null || args.length == 0) ? FLAG_DUMP_ALL : 0;
650         for (int i = 0; i < args.length; i++) {
651             switch (args[i]) {
652                 case "framestats":
653                     flags |= FLAG_DUMP_FRAMESTATS;
654                     break;
655                 case "reset":
656                     flags |= FLAG_DUMP_RESET;
657                     break;
658                 case "-a": // magic option passed when dumping a bugreport.
659                     flags = FLAG_DUMP_ALL;
660                     break;
661             }
662         }
663         nDumpProfileInfo(mNativeProxy, fd, flags);
664     }
665 
666     /**
667      * Loads system properties used by the renderer. This method is invoked
668      * whenever system properties are modified. Implementations can use this
669      * to trigger live updates of the renderer based on properties.
670      *
671      * @return True if a property has changed.
672      */
loadSystemProperties()673     boolean loadSystemProperties() {
674         boolean changed = nLoadSystemProperties(mNativeProxy);
675         if (changed) {
676             invalidateRoot();
677         }
678         return changed;
679     }
680 
updateViewTreeDisplayList(View view)681     private void updateViewTreeDisplayList(View view) {
682         view.mPrivateFlags |= View.PFLAG_DRAWN;
683         view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
684                 == View.PFLAG_INVALIDATED;
685         view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
686         view.updateDisplayListIfDirty();
687         view.mRecreateDisplayList = false;
688     }
689 
updateRootDisplayList(View view, DrawCallbacks callbacks)690     private void updateRootDisplayList(View view, DrawCallbacks callbacks) {
691         Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
692         updateViewTreeDisplayList(view);
693 
694         if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
695             DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
696             try {
697                 final int saveCount = canvas.save();
698                 canvas.translate(mInsetLeft, mInsetTop);
699                 callbacks.onPreDraw(canvas);
700 
701                 canvas.insertReorderBarrier();
702                 canvas.drawRenderNode(view.updateDisplayListIfDirty());
703                 canvas.insertInorderBarrier();
704 
705                 callbacks.onPostDraw(canvas);
706                 canvas.restoreToCount(saveCount);
707                 mRootNodeNeedsUpdate = false;
708             } finally {
709                 mRootNode.end(canvas);
710             }
711         }
712         Trace.traceEnd(Trace.TRACE_TAG_VIEW);
713     }
714 
715     /**
716      * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
717      * rendernode of the UI thread.
718      * @param node The node to add.
719      * @param placeFront If true, the render node will be placed in front of the content node,
720      *                   otherwise behind the content node.
721      */
addRenderNode(RenderNode node, boolean placeFront)722     public void addRenderNode(RenderNode node, boolean placeFront) {
723         nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
724     }
725 
726     /**
727      * Only especially added render nodes can be removed.
728      * @param node The node which was added via addRenderNode which should get removed again.
729      */
removeRenderNode(RenderNode node)730     public void removeRenderNode(RenderNode node) {
731         nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
732     }
733 
734     /**
735      * Draws a particular render node. If the node is not the content node, only the additional
736      * nodes will get drawn and the content remains untouched.
737      * @param node The node to be drawn.
738      */
drawRenderNode(RenderNode node)739     public void drawRenderNode(RenderNode node) {
740         nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
741     }
742 
743     /**
744      * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
745      * will be prevented to overdraw this area. It will be synchronized with the draw call.
746      * This should be updated in the content view's draw call.
747      * @param left The left side of the protected bounds.
748      * @param top The top side of the protected bounds.
749      * @param right The right side of the protected bounds.
750      * @param bottom The bottom side of the protected bounds.
751      */
setContentDrawBounds(int left, int top, int right, int bottom)752     public void setContentDrawBounds(int left, int top, int right, int bottom) {
753         nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
754     }
755 
756     /**
757      * Interface used to receive callbacks whenever a view is drawn by
758      * a threaded renderer instance.
759      */
760     interface DrawCallbacks {
761         /**
762          * Invoked before a view is drawn by a threaded renderer.
763          * This method can be used to apply transformations to the
764          * canvas but no drawing command should be issued.
765          *
766          * @param canvas The Canvas used to render the view.
767          */
onPreDraw(DisplayListCanvas canvas)768         void onPreDraw(DisplayListCanvas canvas);
769 
770         /**
771          * Invoked after a view is drawn by a threaded renderer.
772          * It is safe to invoke drawing commands from this method.
773          *
774          * @param canvas The Canvas used to render the view.
775          */
onPostDraw(DisplayListCanvas canvas)776         void onPostDraw(DisplayListCanvas canvas);
777     }
778 
779     /**
780      *  Indicates that the content drawn by DrawCallbacks needs to
781      *  be updated, which will be done by the next call to draw()
782      */
invalidateRoot()783     void invalidateRoot() {
784         mRootNodeNeedsUpdate = true;
785     }
786 
787     /**
788      * Draws the specified view.
789      *
790      * @param view The view to draw.
791      * @param attachInfo AttachInfo tied to the specified view.
792      * @param callbacks Callbacks invoked when drawing happens.
793      */
draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks, FrameDrawingCallback frameDrawingCallback)794     void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks,
795             FrameDrawingCallback frameDrawingCallback) {
796         attachInfo.mIgnoreDirtyState = true;
797 
798         final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
799         choreographer.mFrameInfo.markDrawStart();
800 
801         updateRootDisplayList(view, callbacks);
802 
803         attachInfo.mIgnoreDirtyState = false;
804 
805         // register animating rendernodes which started animating prior to renderer
806         // creation, which is typical for animators started prior to first draw
807         if (attachInfo.mPendingAnimatingRenderNodes != null) {
808             final int count = attachInfo.mPendingAnimatingRenderNodes.size();
809             for (int i = 0; i < count; i++) {
810                 registerAnimatingRenderNode(
811                         attachInfo.mPendingAnimatingRenderNodes.get(i));
812             }
813             attachInfo.mPendingAnimatingRenderNodes.clear();
814             // We don't need this anymore as subsequent calls to
815             // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
816             attachInfo.mPendingAnimatingRenderNodes = null;
817         }
818 
819         final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
820         if (frameDrawingCallback != null) {
821             nSetFrameCallback(mNativeProxy, frameDrawingCallback);
822         }
823         int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
824         if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
825             setEnabled(false);
826             attachInfo.mViewRootImpl.mSurface.release();
827             // Invalidate since we failed to draw. This should fetch a Surface
828             // if it is still needed or do nothing if we are no longer drawing
829             attachInfo.mViewRootImpl.invalidate();
830         }
831         if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
832             attachInfo.mViewRootImpl.invalidate();
833         }
834     }
835 
setFrameCompleteCallback(FrameCompleteCallback callback)836     void setFrameCompleteCallback(FrameCompleteCallback callback) {
837         nSetFrameCompleteCallback(mNativeProxy, callback);
838     }
839 
invokeFunctor(long functor, boolean waitForCompletion)840     static void invokeFunctor(long functor, boolean waitForCompletion) {
841         nInvokeFunctor(functor, waitForCompletion);
842     }
843 
844     /**
845      * Creates a new hardware layer. A hardware layer built by calling this
846      * method will be treated as a texture layer, instead of as a render target.
847      *
848      * @return A hardware layer
849      */
createTextureLayer()850     TextureLayer createTextureLayer() {
851         long layer = nCreateTextureLayer(mNativeProxy);
852         return TextureLayer.adoptTextureLayer(this, layer);
853     }
854 
855 
buildLayer(RenderNode node)856     void buildLayer(RenderNode node) {
857         nBuildLayer(mNativeProxy, node.getNativeDisplayList());
858     }
859 
860 
copyLayerInto(final TextureLayer layer, final Bitmap bitmap)861     boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
862         return nCopyLayerInto(mNativeProxy,
863                 layer.getDeferredLayerUpdater(), bitmap);
864     }
865 
866     /**
867      * Indicates that the specified hardware layer needs to be updated
868      * as soon as possible.
869      *
870      * @param layer The hardware layer that needs an update
871      */
pushLayerUpdate(TextureLayer layer)872     void pushLayerUpdate(TextureLayer layer) {
873         nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
874     }
875 
876     /**
877      * Tells the HardwareRenderer that the layer is destroyed. The renderer
878      * should remove the layer from any update queues.
879      */
onLayerDestroyed(TextureLayer layer)880     void onLayerDestroyed(TextureLayer layer) {
881         nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
882     }
883 
884     /**
885      * Blocks until all previously queued work has completed.
886      */
fence()887     void fence() {
888         nFence(mNativeProxy);
889     }
890 
891     /**
892      * Prevents any further drawing until draw() is called. This is a signal
893      * that the contents of the RenderNode tree are no longer safe to play back.
894      * In practice this usually means that there are Functor pointers in the
895      * display list that are no longer valid.
896      */
stopDrawing()897     void stopDrawing() {
898         nStopDrawing(mNativeProxy);
899     }
900 
901     /**
902      * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
903      */
notifyFramePending()904     public void notifyFramePending() {
905         nNotifyFramePending(mNativeProxy);
906     }
907 
908 
registerAnimatingRenderNode(RenderNode animator)909     void registerAnimatingRenderNode(RenderNode animator) {
910         nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
911     }
912 
registerVectorDrawableAnimator( AnimatedVectorDrawable.VectorDrawableAnimatorRT animator)913     void registerVectorDrawableAnimator(
914         AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
915         nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
916                 animator.getAnimatorNativePtr());
917     }
918 
serializeDisplayListTree()919     public void serializeDisplayListTree() {
920         nSerializeDisplayListTree(mNativeProxy);
921     }
922 
copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap)923     public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
924         if (srcRect == null) {
925             // Empty rect means entire surface
926             return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap);
927         } else {
928             return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
929                     srcRect.right, srcRect.bottom, bitmap);
930         }
931     }
932 
933     /**
934      * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given
935      * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and
936      * not the RenderNode from a View.
937      **/
createHardwareBitmap(RenderNode node, int width, int height)938     public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
939         return nCreateHardwareBitmap(node.getNativeDisplayList(), width, height);
940     }
941 
942     /**
943      * Sets whether or not high contrast text rendering is enabled. The setting is global
944      * but only affects content rendered after the change is made.
945      */
setHighContrastText(boolean highContrastText)946     public static void setHighContrastText(boolean highContrastText) {
947         nSetHighContrastText(highContrastText);
948     }
949 
950     /**
951      * If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source
952      */
setIsolatedProcess(boolean isIsolated)953     public static void setIsolatedProcess(boolean isIsolated) {
954         nSetIsolatedProcess(isIsolated);
955     }
956 
957     /**
958      * If set extra graphics debugging abilities will be enabled such as dumping skp
959      */
setDebuggingEnabled(boolean enable)960     public static void setDebuggingEnabled(boolean enable) {
961         nSetDebuggingEnabled(enable);
962     }
963 
964     @Override
finalize()965     protected void finalize() throws Throwable {
966         try {
967             nDeleteProxy(mNativeProxy);
968             mNativeProxy = 0;
969         } finally {
970             super.finalize();
971         }
972     }
973 
974     /**
975      * Basic synchronous renderer. Currently only used to render the Magnifier, so use with care.
976      * TODO: deduplicate against ThreadedRenderer.
977      *
978      * @hide
979      */
980     public static class SimpleRenderer {
981         private final RenderNode mRootNode;
982         private long mNativeProxy;
983         private final float mLightY, mLightZ;
984         private Surface mSurface;
985         private final FrameInfo mFrameInfo = new FrameInfo();
986 
SimpleRenderer(final Context context, final String name, final Surface surface)987         public SimpleRenderer(final Context context, final String name, final Surface surface) {
988             final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
989             mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
990             mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
991             final float lightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
992             final int ambientShadowAlpha =
993                     (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
994             final int spotShadowAlpha =
995                     (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
996             a.recycle();
997 
998             final long rootNodePtr = nCreateRootRenderNode();
999             mRootNode = RenderNode.adopt(rootNodePtr);
1000             mRootNode.setClipToBounds(false);
1001             mNativeProxy = nCreateProxy(true /* translucent */, rootNodePtr);
1002             nSetName(mNativeProxy, name);
1003 
1004             ProcessInitializer.sInstance.init(context, mNativeProxy);
1005             nLoadSystemProperties(mNativeProxy);
1006 
1007             nSetup(mNativeProxy, lightRadius, ambientShadowAlpha, spotShadowAlpha);
1008 
1009             mSurface = surface;
1010             nUpdateSurface(mNativeProxy, surface);
1011         }
1012 
1013         /**
1014          * Set the light center.
1015          */
setLightCenter(final Display display, final int windowLeft, final int windowTop)1016         public void setLightCenter(final Display display,
1017                 final int windowLeft, final int windowTop) {
1018             // Adjust light position for window offsets.
1019             final Point displaySize = new Point();
1020             display.getRealSize(displaySize);
1021             final float lightX = displaySize.x / 2f - windowLeft;
1022             final float lightY = mLightY - windowTop;
1023 
1024             nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
1025         }
1026 
getRootNode()1027         public RenderNode getRootNode() {
1028             return mRootNode;
1029         }
1030 
1031         /**
1032          * Draw the surface.
1033          */
draw(final FrameDrawingCallback callback)1034         public void draw(final FrameDrawingCallback callback) {
1035             final long vsync = AnimationUtils.currentAnimationTimeMillis() * 1000000L;
1036             mFrameInfo.setVsync(vsync, vsync);
1037             mFrameInfo.addFlags(1 << 2 /* VSYNC */);
1038             if (callback != null) {
1039                 nSetFrameCallback(mNativeProxy, callback);
1040             }
1041             nSyncAndDrawFrame(mNativeProxy, mFrameInfo.mFrameInfo, mFrameInfo.mFrameInfo.length);
1042         }
1043 
1044         /**
1045          * Destroy the renderer.
1046          */
destroy()1047         public void destroy() {
1048             mSurface = null;
1049             nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
1050         }
1051 
1052         @Override
finalize()1053         protected void finalize() throws Throwable {
1054             try {
1055                 nDeleteProxy(mNativeProxy);
1056                 mNativeProxy = 0;
1057             } finally {
1058                 super.finalize();
1059             }
1060         }
1061     }
1062 
1063     /**
1064      * Interface used to receive callbacks when a frame is being drawn.
1065      */
1066     public interface FrameDrawingCallback {
1067         /**
1068          * Invoked during a frame drawing.
1069          *
1070          * @param frame The id of the frame being drawn.
1071          */
onFrameDraw(long frame)1072         void onFrameDraw(long frame);
1073     }
1074 
1075     /**
1076      * Interface used to be notified when a frame has finished rendering
1077      */
1078     public interface FrameCompleteCallback {
1079         /**
1080          * Invoked after a frame draw
1081          *
1082          * @param frameNr The id of the frame that was drawn.
1083          */
onFrameComplete(long frameNr)1084         void onFrameComplete(long frameNr);
1085     }
1086 
1087     private static class ProcessInitializer {
1088         static ProcessInitializer sInstance = new ProcessInitializer();
1089 
1090         private boolean mInitialized = false;
1091 
1092         private Context mAppContext;
1093         private IGraphicsStats mGraphicsStatsService;
1094         private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
1095             @Override
1096             public void onRotateGraphicsStatsBuffer() throws RemoteException {
1097                 rotateBuffer();
1098             }
1099         };
1100 
ProcessInitializer()1101         private ProcessInitializer() {}
1102 
init(Context context, long renderProxy)1103         synchronized void init(Context context, long renderProxy) {
1104             if (mInitialized) return;
1105             mInitialized = true;
1106             mAppContext = context.getApplicationContext();
1107 
1108             initSched(renderProxy);
1109 
1110             if (mAppContext != null) {
1111                 initGraphicsStats();
1112             }
1113         }
1114 
initSched(long renderProxy)1115         private void initSched(long renderProxy) {
1116             try {
1117                 int tid = nGetRenderThreadTid(renderProxy);
1118                 ActivityManager.getService().setRenderThread(tid);
1119             } catch (Throwable t) {
1120                 Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
1121             }
1122         }
1123 
initGraphicsStats()1124         private void initGraphicsStats() {
1125             try {
1126                 IBinder binder = ServiceManager.getService("graphicsstats");
1127                 if (binder == null) return;
1128                 mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
1129                 requestBuffer();
1130             } catch (Throwable t) {
1131                 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
1132             }
1133         }
1134 
rotateBuffer()1135         private void rotateBuffer() {
1136             nRotateProcessStatsBuffer();
1137             requestBuffer();
1138         }
1139 
requestBuffer()1140         private void requestBuffer() {
1141             try {
1142                 final String pkg = mAppContext.getApplicationInfo().packageName;
1143                 ParcelFileDescriptor pfd = mGraphicsStatsService
1144                         .requestBufferForProcess(pkg, mGraphicsStatsCallback);
1145                 nSetProcessStatsBuffer(pfd.getFd());
1146                 pfd.close();
1147             } catch (Throwable t) {
1148                 Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
1149             }
1150         }
1151     }
1152 
addFrameMetricsObserver(FrameMetricsObserver observer)1153     void addFrameMetricsObserver(FrameMetricsObserver observer) {
1154         long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
1155         observer.mNative = new VirtualRefBasePtr(nativeObserver);
1156     }
1157 
removeFrameMetricsObserver(FrameMetricsObserver observer)1158     void removeFrameMetricsObserver(FrameMetricsObserver observer) {
1159         nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
1160         observer.mNative = null;
1161     }
1162 
1163     /** b/68769804: For low FPS experiments. */
setFPSDivisor(int divisor)1164     public static void setFPSDivisor(int divisor) {
1165         nHackySetRTAnimationsEnabled(divisor <= 1);
1166     }
1167 
1168     /**
1169      * Changes the OpenGL context priority if IMG_context_priority extension is available. Must be
1170      * called before any OpenGL context is created.
1171      *
1172      * @param priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values.
1173      */
setContextPriority(int priority)1174     public static void setContextPriority(int priority) {
1175         nSetContextPriority(priority);
1176     }
1177 
1178     /** Not actually public - internal use only. This doc to make lint happy */
disableVsync()1179     public static native void disableVsync();
1180 
setupShadersDiskCache(String cacheFile, String skiaCacheFile)1181     static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
1182 
nRotateProcessStatsBuffer()1183     private static native void nRotateProcessStatsBuffer();
nSetProcessStatsBuffer(int fd)1184     private static native void nSetProcessStatsBuffer(int fd);
nGetRenderThreadTid(long nativeProxy)1185     private static native int nGetRenderThreadTid(long nativeProxy);
1186 
nCreateRootRenderNode()1187     private static native long nCreateRootRenderNode();
nCreateProxy(boolean translucent, long rootRenderNode)1188     private static native long nCreateProxy(boolean translucent, long rootRenderNode);
nDeleteProxy(long nativeProxy)1189     private static native void nDeleteProxy(long nativeProxy);
1190 
nLoadSystemProperties(long nativeProxy)1191     private static native boolean nLoadSystemProperties(long nativeProxy);
nSetName(long nativeProxy, String name)1192     private static native void nSetName(long nativeProxy, String name);
1193 
nInitialize(long nativeProxy, Surface window)1194     private static native void nInitialize(long nativeProxy, Surface window);
nUpdateSurface(long nativeProxy, Surface window)1195     private static native void nUpdateSurface(long nativeProxy, Surface window);
nPauseSurface(long nativeProxy, Surface window)1196     private static native boolean nPauseSurface(long nativeProxy, Surface window);
nSetStopped(long nativeProxy, boolean stopped)1197     private static native void nSetStopped(long nativeProxy, boolean stopped);
nSetup(long nativeProxy, float lightRadius, int ambientShadowAlpha, int spotShadowAlpha)1198     private static native void nSetup(long nativeProxy,
1199             float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
nSetLightCenter(long nativeProxy, float lightX, float lightY, float lightZ)1200     private static native void nSetLightCenter(long nativeProxy,
1201             float lightX, float lightY, float lightZ);
nSetOpaque(long nativeProxy, boolean opaque)1202     private static native void nSetOpaque(long nativeProxy, boolean opaque);
nSetWideGamut(long nativeProxy, boolean wideGamut)1203     private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size)1204     private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
nDestroy(long nativeProxy, long rootRenderNode)1205     private static native void nDestroy(long nativeProxy, long rootRenderNode);
nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode)1206     private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
nRegisterVectorDrawableAnimator(long rootRenderNode, long animator)1207     private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
1208 
nInvokeFunctor(long functor, boolean waitForCompletion)1209     private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
1210 
nCreateTextureLayer(long nativeProxy)1211     private static native long nCreateTextureLayer(long nativeProxy);
nBuildLayer(long nativeProxy, long node)1212     private static native void nBuildLayer(long nativeProxy, long node);
nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap)1213     private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
nPushLayerUpdate(long nativeProxy, long layer)1214     private static native void nPushLayerUpdate(long nativeProxy, long layer);
nCancelLayerUpdate(long nativeProxy, long layer)1215     private static native void nCancelLayerUpdate(long nativeProxy, long layer);
nDetachSurfaceTexture(long nativeProxy, long layer)1216     private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
1217 
nDestroyHardwareResources(long nativeProxy)1218     private static native void nDestroyHardwareResources(long nativeProxy);
nTrimMemory(int level)1219     private static native void nTrimMemory(int level);
nOverrideProperty(String name, String value)1220     private static native void nOverrideProperty(String name, String value);
1221 
nFence(long nativeProxy)1222     private static native void nFence(long nativeProxy);
nStopDrawing(long nativeProxy)1223     private static native void nStopDrawing(long nativeProxy);
nNotifyFramePending(long nativeProxy)1224     private static native void nNotifyFramePending(long nativeProxy);
1225 
nSerializeDisplayListTree(long nativeProxy)1226     private static native void nSerializeDisplayListTree(long nativeProxy);
1227 
nDumpProfileInfo(long nativeProxy, FileDescriptor fd, @DumpFlags int dumpFlags)1228     private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1229             @DumpFlags int dumpFlags);
1230 
nAddRenderNode(long nativeProxy, long rootRenderNode, boolean placeFront)1231     private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1232              boolean placeFront);
nRemoveRenderNode(long nativeProxy, long rootRenderNode)1233     private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
nDrawRenderNode(long nativeProxy, long rootRenderNode)1234     private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
nSetContentDrawBounds(long nativeProxy, int left, int top, int right, int bottom)1235     private static native void nSetContentDrawBounds(long nativeProxy, int left,
1236              int top, int right, int bottom);
nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback)1237     private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
nSetFrameCompleteCallback(long nativeProxy, FrameCompleteCallback callback)1238     private static native void nSetFrameCompleteCallback(long nativeProxy,
1239             FrameCompleteCallback callback);
1240 
nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer)1241     private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver)1242     private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
1243 
nCopySurfaceInto(Surface surface, int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap)1244     private static native int nCopySurfaceInto(Surface surface,
1245             int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
1246 
nCreateHardwareBitmap(long renderNode, int width, int height)1247     private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
nSetHighContrastText(boolean enabled)1248     private static native void nSetHighContrastText(boolean enabled);
1249     // For temporary experimentation b/66945974
nHackySetRTAnimationsEnabled(boolean enabled)1250     private static native void nHackySetRTAnimationsEnabled(boolean enabled);
nSetDebuggingEnabled(boolean enabled)1251     private static native void nSetDebuggingEnabled(boolean enabled);
nSetIsolatedProcess(boolean enabled)1252     private static native void nSetIsolatedProcess(boolean enabled);
nSetContextPriority(int priority)1253     private static native void nSetContextPriority(int priority);
1254 }
1255