1cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/*
2cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Copyright (C) 2013 The Android Open Source Project
3cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
4cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
5cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * you may not use this file except in compliance with the License.
6cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * You may obtain a copy of the License at
7cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
8cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
9cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
10cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Unless required by applicable law or agreed to in writing, software
11cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
12cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * See the License for the specific language governing permissions and
14cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * limitations under the License.
15cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
16cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
17cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpackage android.view;
18cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
1933eb07f5759b85a5617f8057d8a335019c7d24ddTim Murrayimport android.app.ActivityManagerNative;
20ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport android.annotation.IntDef;
212507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craikimport android.annotation.NonNull;
22b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.content.Context;
2358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viveretteimport android.content.res.TypedArray;
2404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckimport android.graphics.Bitmap;
2550210d912925aef14e4ce69be82e4949122a3cd9Alan Viveretteimport android.graphics.Point;
26ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viveretteimport android.graphics.Rect;
27718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liuimport android.graphics.drawable.AnimatedVectorDrawable;
28edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reckimport android.os.Binder;
2906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesimport android.os.Handler;
3066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.IBinder;
3106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesimport android.os.Message;
32edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reckimport android.os.ParcelFileDescriptor;
3366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.RemoteException;
3466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.ServiceManager;
35cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.os.Trace;
3666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.util.Log;
37cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.Surface.OutOfResourcesException;
38cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.View.AttachInfo;
39cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
40ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport com.android.internal.R;
4106f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesimport com.android.internal.util.VirtualRefBasePtr;
42ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
4351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reckimport java.io.File;
44fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckimport java.io.FileDescriptor;
45cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport java.io.PrintWriter;
46ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.Retention;
47ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.RetentionPolicy;
4806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesimport java.util.HashSet;
49cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
50cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/**
51cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Hardware renderer that proxies the rendering to a render thread. Most calls
524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * are currently synchronous.
53cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
54cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * The UI thread can block on the RenderThread, but RenderThread must never
55cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * block on the UI thread.
56cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * by the lifecycle of the RenderProxy.
604f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
61cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Note that although currently the EGL context & surfaces are created & managed
62cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * by the render thread, the goal is to move that into a shared structure that can
63cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * be managed by both threads. EGLSurface creation & deletion should ideally be
64cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * done on the UI thread and not the RenderThread to avoid stalling the
65cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * RenderThread with surface buffer allocation.
66cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
67cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * @hide
68cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
6951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reckpublic final class ThreadedRenderer {
7051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private static final String LOG_TAG = "ThreadedRenderer";
7151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
7251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
7351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Name of the file that holds the shaders cache.
7451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
7551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
7651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
7751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
7851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to enable or disable dirty regions invalidation.
7951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
8051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * The default value of this property is assumed to be true.
8151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
8251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
8351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable partial invalidates
8451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable partial invalidates
8551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
8651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    static final String RENDER_DIRTY_REGIONS_PROPERTY = "debug.hwui.render_dirty_regions";
8751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
8851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
8951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to enable or disable hardware rendering profiling.
9051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * The default value of this property is assumed to be false.
9151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
9251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * When profiling is enabled, the adb shell dumpsys gfxinfo command will
9351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * output extra information about the time taken to execute by the last
9451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * frames.
9551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
9651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
9751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable profiling
9851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "visual_bars", to enable profiling and visualize the results on screen
9951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable profiling
10051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
10151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @see #PROFILE_PROPERTY_VISUALIZE_BARS
10251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
10351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
10451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
10551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String PROFILE_PROPERTY = "debug.hwui.profile";
10651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
10751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
10851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Value for {@link #PROFILE_PROPERTY}. When the property is set to this
10951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * value, profiling data will be visualized on screen as a bar chart.
11051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
11151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
11251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
11351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars";
11451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
11551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
11651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to specify the number of frames to be used
11751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * when doing hardware rendering profiling.
11851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * The default value of this property is #PROFILE_MAX_FRAMES.
11951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
12051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * When profiling is enabled, the adb shell dumpsys gfxinfo command will
12151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * output extra information about the time taken to execute by the last
12251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * frames.
12351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
12451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
12551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "60", to set the limit of frames to 60
12651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
12751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes";
12851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
12951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
13051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to debug EGL configuration choice.
13151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
13251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
13351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "choice", print the chosen configuration only
13451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "all", print all possible configurations
13551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
13651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config";
13751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
13851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
13951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Turn on to draw dirty regions every other frame.
14051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
14151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
14251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable dirty regions debugging
14351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable dirty regions debugging
14451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
14551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
14651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
14751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
14851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
14951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
15051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Turn on to flash hardware layers when they update.
15151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
15251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
15351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable hardware layers updates debugging
15451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable hardware layers updates debugging
15551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
15651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
15751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
15851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
15951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            "debug.hwui.show_layers_updates";
16051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
16151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
16251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Controls overdraw debugging.
16351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
16451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
16551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable overdraw debugging
16651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "show", to show overdraw areas on screen
16751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "count", to display an overdraw counter
16851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
16951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
17051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
17151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
17251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
17351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
17451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
17551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * value, overdraw will be shown on screen by coloring pixels.
17651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
17751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
17851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
17951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String OVERDRAW_PROPERTY_SHOW = "show";
18051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
18151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
18251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Turn on to debug non-rectangular clip operations.
18351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
18451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
18551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "hide", to disable this debug mode
18651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "highlight", highlight drawing commands tested against a non-rectangular clip
18751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "stencil", renders the clip region on screen when set
18851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
18951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
19051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
19151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
19251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            "debug.hwui.show_non_rect_clip";
19351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
19451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
19551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * A process can set this flag to false to prevent the use of hardware
19651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * rendering.
19751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
19851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
19951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
20051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean sRendererDisabled = false;
20151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
20251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
20351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Further hardware renderer disabling for the system process.
20451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
20551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
20651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
20751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean sSystemRendererDisabled = false;
20851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
20951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
21051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Invoke this method to disable hardware rendering in the current process.
21151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
21251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
21351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
21451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void disable(boolean system) {
21551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        sRendererDisabled = true;
21651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (system) {
21751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            sSystemRendererDisabled = true;
21851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
21951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
22051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
22151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean sTrimForeground = false;
22251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
22351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
22451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Controls whether or not the hardware renderer should aggressively
22551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * trim memory. Note that this must not be set for any process that
22651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * uses WebView! This should be only used by system_process or similar
22751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * that do not go into the background.
22851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
22951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void enableForegroundTrimming() {
23051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        sTrimForeground = true;
23151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
23251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
23351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
23451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is available under any form for
23551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the view hierarchy.
23651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
23751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if the view hierarchy can potentially be hardware accelerated,
23851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *         false otherwise
23951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
24051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean isAvailable() {
24151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return DisplayListCanvas.isAvailable();
24251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
24351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
24451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
24551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Sets the directory to use as a persistent storage for hardware rendering
24651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * resources.
24751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
24851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param cacheDir A directory the current process can write to
24951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
25051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
25151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
25251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void setupDiskCache(File cacheDir) {
25351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
25451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
25551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
25651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
25751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Creates a hardware renderer using OpenGL.
25851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
25951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param translucent True if the surface is translucent, false otherwise
26051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
26151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return A hardware renderer backed by OpenGL.
26251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
26351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static ThreadedRenderer create(Context context, boolean translucent) {
26451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        ThreadedRenderer renderer = null;
26551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (DisplayListCanvas.isAvailable()) {
26651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            renderer = new ThreadedRenderer(context, translucent);
26751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
26851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return renderer;
26951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
27051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
27151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
27251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Invoke this method when the system is running out of memory. This
27351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * method will attempt to recover as much memory as possible, based on
27451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the specified hint.
27551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
27651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param level Hint about the amount of memory that should be trimmed,
27751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *              see {@link android.content.ComponentCallbacks}
27851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
27951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void trimMemory(int level) {
28051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        nTrimMemory(level);
28151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
28251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
28351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void overrideProperty(@NonNull String name, @NonNull String value) {
28451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (name == null || value == null) {
28551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            throw new IllegalArgumentException("name and value must be non-null");
28651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
28751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        nOverrideProperty(name, value);
28851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
28951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
29051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void dumpProfileData(byte[] data, FileDescriptor fd) {
29151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        nDumpProfileData(data, fd);
29251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
293cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
294f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Keep in sync with DrawFrameTask.h SYNC_* flags
295f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Nothing interesting to report
296cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_OK = 0;
297f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Needs a ViewRoot invalidate
298cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
299aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck    // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
300aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck    private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
3019a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // setStopped is true, drawing is false
3029a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // TODO: Remove this and SYNC_LOST_SURFACE_REWARD_IF_FOUND?
3039a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // This flag isn't really used as there's nothing that we care to do
3049a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // in response, so it really just exists to differentiate from LOST_SURFACE
3059a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // but possibly both can just be deleted.
3069a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
307f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck
308fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static final String[] VISUALIZERS = {
309fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        PROFILE_PROPERTY_VISUALIZE_BARS,
310fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    };
311fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
312ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_FRAMESTATS   = 1 << 0;
313ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_RESET        = 1 << 1;
314ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
315ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @IntDef(flag = true, value = {
316ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET })
317ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @Retention(RetentionPolicy.SOURCE)
318ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    public @interface DumpFlags {}
319ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
320ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Size of the rendered content.
321cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private int mWidth, mHeight;
322ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
323ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Actual size of the drawing surface.
324ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mSurfaceWidth, mSurfaceHeight;
325ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
326ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Insets between the drawing surface and rendered content. These are
327ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // applied as translation when updating the root render node.
328ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mInsetTop, mInsetLeft;
329ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
33057774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    // Whether the surface has insets. Used to protect opacity.
33157774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    private boolean mHasInsets;
33257774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
33358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    // Light and shadow properties specified by the theme.
33458c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightY;
33558c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightZ;
33658c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightRadius;
337058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mAmbientShadowAlpha;
338058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mSpotShadowAlpha;
33958c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
3404f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private long mNativeProxy;
341f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private boolean mInitialized = false;
342bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private RenderNode mRootNode;
34318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    private Choreographer mChoreographer;
3440a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private boolean mRootNodeNeedsUpdate;
345cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
34651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private boolean mEnabled;
34751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private boolean mRequested = true;
34851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
349b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck    ThreadedRenderer(Context context, boolean translucent) {
350ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
35158c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
35258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
35358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
354ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mAmbientShadowAlpha =
355ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette                (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
356ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
35758c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        a.recycle();
35858c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
359e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        long rootNodePtr = nCreateRootRenderNode();
360e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mRootNode = RenderNode.adopt(rootNodePtr);
361bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        mRootNode.setClipToBounds(false);
362e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mNativeProxy = nCreateProxy(translucent, rootNodePtr);
36318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
364edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        ProcessInitializer.sInstance.init(context, mNativeProxy);
3653b20251a355c88193c439f928a84ae69483fb488John Reck
366fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        loadSystemProperties();
367cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
368cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
36951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
37051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Destroys the hardware rendering context.
37151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
372f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void destroy() {
373f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = false;
374f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(null);
375350e65206cfbd86484fcfda77bb988e270606ddaDoris Liu        nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
376cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
377cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
37851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
37951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently enabled.
38051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
38151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if hardware acceleration is in use, false otherwise.
38251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
38351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean isEnabled() {
38451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return mEnabled;
38551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
38651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
38751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
38851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently enabled.
38951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
39051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param enabled True if the hardware renderer is in use, false otherwise.
39151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
39251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    void setEnabled(boolean enabled) {
39351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        mEnabled = enabled;
39451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
39551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
39651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
39751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently request but not
39851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * necessarily enabled yet.
39951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
40051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if requested, false otherwise.
40151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
40251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean isRequested() {
40351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return mRequested;
40451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
40551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
40651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
40751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently requested but not
40851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * necessarily enabled yet.
40951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
41051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True to request hardware acceleration, false otherwise.
41151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
41251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    void setRequested(boolean requested) {
41351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        mRequested = requested;
41451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
41551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
416f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private void updateEnabledState(Surface surface) {
417f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        if (surface == null || !surface.isValid()) {
418f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(false);
419f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        } else {
420f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(mInitialized);
421f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        }
422f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
423f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
42451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
42551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Initializes the hardware renderer for the specified surface.
42651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
42751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
42851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
42951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if the initialization was successful, false otherwise.
43051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
431cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean initialize(Surface surface) throws OutOfResourcesException {
4320bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot        boolean status = !mInitialized;
433f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = true;
434f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
4350bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot        nInitialize(mNativeProxy, surface);
4365795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        return status;
437cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
438cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
43951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
44051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Initializes the hardware renderer for the specified surface and setup the
44151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * renderer for drawing, if needed. This is invoked when the ViewAncestor has
44251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * potentially lost the hardware renderer. The hardware renderer should be
44351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * reinitialized and setup when the render {@link #isRequested()} and
44451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * {@link #isEnabled()}.
44551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
44651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param width The width of the drawing surface.
44751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param height The height of the drawing surface.
44851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
44951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
45051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surfaceInsets The drawing surface insets to apply
45151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
45251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return true if the surface was initialized, false otherwise. Returning
45351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *         false might mean that the surface was already initialized.
45451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
45551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
45651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
45751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (isRequested()) {
45851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            // We lost the gl context, so recreate it.
45951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            if (!isEnabled()) {
46051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                if (initialize(surface)) {
46151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                    setup(width, height, attachInfo, surfaceInsets);
46251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                    return true;
46351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                }
46451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            }
46551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
46651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return false;
46751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
46851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
46951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
47051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Updates the hardware renderer for the specified surface.
47151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
47251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
47351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
474cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void updateSurface(Surface surface) throws OutOfResourcesException {
475f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
4764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        nUpdateSurface(mNativeProxy, surface);
477cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
478cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
47951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
4808afcc76920499d0a384dba1470c5a377f80ed768John Reck     * Halts any current rendering into the surface. Use this if it is unclear whether
48151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * or not the surface used by the HardwareRenderer will be changing. It
4828afcc76920499d0a384dba1470c5a377f80ed768John Reck     * Suspends any rendering into the surface, but will not do any destruction.
4838afcc76920499d0a384dba1470c5a377f80ed768John Reck     *
4848afcc76920499d0a384dba1470c5a377f80ed768John Reck     * Any subsequent draws will override the pause, resuming normal operation.
48551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
48601a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    boolean pauseSurface(Surface surface) {
48701a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck        return nPauseSurface(mNativeProxy, surface);
488f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
489f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
49051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
4918afcc76920499d0a384dba1470c5a377f80ed768John Reck     * Hard stops or resumes rendering into the surface. This flag is used to
4928afcc76920499d0a384dba1470c5a377f80ed768John Reck     * determine whether or not it is safe to use the given surface *at all*
4938afcc76920499d0a384dba1470c5a377f80ed768John Reck     */
4948afcc76920499d0a384dba1470c5a377f80ed768John Reck    void setStopped(boolean stopped) {
4958afcc76920499d0a384dba1470c5a377f80ed768John Reck        nSetStopped(mNativeProxy, stopped);
4968afcc76920499d0a384dba1470c5a377f80ed768John Reck    }
4978afcc76920499d0a384dba1470c5a377f80ed768John Reck
4988afcc76920499d0a384dba1470c5a377f80ed768John Reck    /**
49951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Destroys all hardware rendering resources associated with the specified
50051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * view hierarchy.
50151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
50251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param view The root of the view hierarchy
50351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
504cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void destroyHardwareResources(View view) {
5054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        destroyResources(view);
506f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nDestroyHardwareResources(mNativeProxy);
5074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
5084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
5094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static void destroyResources(View view) {
5104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        view.destroyHardwareResources();
5114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
5124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (view instanceof ViewGroup) {
5134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            ViewGroup group = (ViewGroup) view;
5144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
5154f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            int count = group.getChildCount();
5164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            for (int i = 0; i < count; i++) {
5174f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck                destroyResources(group.getChildAt(i));
5184f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            }
5194f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
520cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
521cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
52251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
52351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Detaches the layer's surface texture from the GL context and releases
52451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the texture id
52551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
526918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    void detachSurfaceTexture(long hardwareLayer) {
527918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
528cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
529cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
53051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
53151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Sets up the renderer for drawing.
53251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
53351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param width The width of the drawing surface.
53451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param height The height of the drawing surface.
53551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
53651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surfaceInsets The drawing surface insets to apply
53751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
53850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
539cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mWidth = width;
540cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mHeight = height;
54150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
5423aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette        if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
5433aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette                || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
54457774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = true;
545ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = surfaceInsets.left;
546ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = surfaceInsets.top;
547ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
548ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
54957774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
55057774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            // If the surface has insets, it can't be opaque.
55157774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            setOpaque(false);
552ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        } else {
55357774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = false;
554ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = 0;
555ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = 0;
556ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width;
557ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height;
558ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        }
55950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
560ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
56150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, mLightRadius,
562b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck                mAmbientShadowAlpha, mSpotShadowAlpha);
56350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
56450210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        setLightCenter(attachInfo);
56550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    }
56650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
56751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
56851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Updates the light position based on the position of the window.
56951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
57051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
57151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
57250210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setLightCenter(AttachInfo attachInfo) {
57350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        // Adjust light position for window offsets.
57450210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final Point displaySize = attachInfo.mPoint;
57550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        attachInfo.mDisplay.getRealSize(displaySize);
57650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
57750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightY = mLightY - attachInfo.mWindowTop;
57850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
57950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
580cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
581cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
58251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
58351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Change the HardwareRenderer's opacity
58451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
58563a06673253914510bbeebd500655008682dade1John Reck    void setOpaque(boolean opaque) {
58657774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette        nSetOpaque(mNativeProxy, opaque && !mHasInsets);
58763a06673253914510bbeebd500655008682dade1John Reck    }
58863a06673253914510bbeebd500655008682dade1John Reck
58951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
59051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Gets the current width of the surface. This is the width that the surface
59151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
59251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
59351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return the current width of the surface
59451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
595cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getWidth() {
596cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mWidth;
597cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
598cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
59951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
60051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Gets the current height of the surface. This is the height that the surface
60151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
60251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
60351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return the current width of the surface
60451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
605cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getHeight() {
606cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mHeight;
607cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
608cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
60951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
61051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Outputs extra debugging information in the specified file descriptor.
61151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
612ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
613fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        pw.flush();
614ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        int flags = 0;
615ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        for (int i = 0; i < args.length; i++) {
616ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            switch (args[i]) {
617ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "framestats":
618ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_FRAMESTATS;
619ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
620ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "reset":
621ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_RESET;
622ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
623ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            }
624fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
625ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        nDumpProfileInfo(mNativeProxy, fd, flags);
626cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
627cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
62851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
62951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Loads system properties used by the renderer. This method is invoked
63051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * whenever system properties are modified. Implementations can use this
63151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * to trigger live updates of the renderer based on properties.
63251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
63351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if a property has changed.
63451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
635cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean loadSystemProperties() {
636fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        boolean changed = nLoadSystemProperties(mNativeProxy);
63723d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        if (changed) {
63823d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck            invalidateRoot();
63923d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        }
640fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return changed;
641cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
642cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
6430a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private void updateViewTreeDisplayList(View view) {
644cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags |= View.PFLAG_DRAWN;
645cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
646cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck                == View.PFLAG_INVALIDATED;
647cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
64831a2d063df5111e730abe7d07be064690deedc34Chris Craik        view.updateDisplayListIfDirty();
6490a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        view.mRecreateDisplayList = false;
6500a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
651cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
65261375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
65370850ea258cbf91477efa57a1f1a23cc0044cc93Chris Craik        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
6540a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        updateViewTreeDisplayList(view);
6550a97330b98dd633b58dcfff405d94476c89e867dJohn Reck
6560a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
657f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik            DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
6580a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            try {
659dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                final int saveCount = canvas.save();
6600a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                canvas.translate(mInsetLeft, mInsetTop);
6610a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePreDraw(canvas);
662abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
663abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertReorderBarrier();
66431a2d063df5111e730abe7d07be064690deedc34Chris Craik                canvas.drawRenderNode(view.updateDisplayListIfDirty());
665abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertInorderBarrier();
666abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
6670a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePostDraw(canvas);
668dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                canvas.restoreToCount(saveCount);
6690a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNodeNeedsUpdate = false;
6700a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            } finally {
6710a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNode.end(canvas);
6720a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            }
67305e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        }
6740a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
6750a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
676cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
677ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
678ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
679ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * rendernode of the UI thread.
680ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node to add.
681ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param placeFront If true, the render node will be placed in front of the content node,
682ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     *                   otherwise behind the content node.
683ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
684ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void addRenderNode(RenderNode node, boolean placeFront) {
685ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
686ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
687ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
688ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
689ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Only especially added render nodes can be removed.
690ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node which was added via addRenderNode which should get removed again.
691ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
692ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void removeRenderNode(RenderNode node) {
693ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
694ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
695ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
696ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
697ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Draws a particular render node. If the node is not the content node, only the additional
698ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * nodes will get drawn and the content remains untouched.
699ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node to be drawn.
700ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
701ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void drawRenderNode(RenderNode node) {
702ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
703ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
704ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
705ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
706ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
707ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * will be prevented to overdraw this area. It will be synchronized with the draw call.
708ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * This should be updated in the content view's draw call.
709ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param left The left side of the protected bounds.
710ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param top The top side of the protected bounds.
711ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param right The right side of the protected bounds.
712ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param bottom The bottom side of the protected bounds.
713ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
714b816087962aba0019b022303330f03b897b580edSkuhne    public void setContentDrawBounds(int left, int top, int right, int bottom) {
715e85ce990fe7bfa33d6b7d8bfd23b7336096466b9Jorim Jaggi        nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
716ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
717ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
71851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
71951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Interface used to receive callbacks whenever a view is drawn by
72051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * a hardware renderer instance.
72151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
72251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    interface HardwareDrawCallbacks {
72351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        /**
72451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * Invoked before a view is drawn by a hardware renderer.
72551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * This method can be used to apply transformations to the
72651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * canvas but no drawing command should be issued.
72751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         *
72851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * @param canvas The Canvas used to render the view.
72951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         */
73051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        void onHardwarePreDraw(DisplayListCanvas canvas);
73151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
73251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        /**
73351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * Invoked after a view is drawn by a hardware renderer.
73451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * It is safe to invoke drawing commands from this method.
73551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         *
73651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * @param canvas The Canvas used to render the view.
73751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         */
73851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        void onHardwarePostDraw(DisplayListCanvas canvas);
73951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
74051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
74151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
74251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *  Indicates that the content drawn by HardwareDrawCallbacks needs to
74351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *  be updated, which will be done by the next call to draw()
74451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
7450a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    void invalidateRoot() {
7460a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        mRootNodeNeedsUpdate = true;
747bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    }
748bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
74951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
75051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Draws the specified view.
75151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
75251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param view The view to draw.
75351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo AttachInfo tied to the specified view.
75451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param callbacks Callbacks invoked when drawing happens.
75551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
75661375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
757bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        attachInfo.mIgnoreDirtyState = true;
758bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
759ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
760ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        choreographer.mFrameInfo.markDrawStart();
761fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
76261375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck        updateRootDisplayList(view, callbacks);
763cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
7646313b9259d37b59f3402058e197637aa3014516cJohn Reck        attachInfo.mIgnoreDirtyState = false;
7656313b9259d37b59f3402058e197637aa3014516cJohn Reck
766119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // register animating rendernodes which started animating prior to renderer
767119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // creation, which is typical for animators started prior to first draw
768119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        if (attachInfo.mPendingAnimatingRenderNodes != null) {
769119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            final int count = attachInfo.mPendingAnimatingRenderNodes.size();
770119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            for (int i = 0; i < count; i++) {
771119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                registerAnimatingRenderNode(
772119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                        attachInfo.mPendingAnimatingRenderNodes.get(i));
773119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            }
774119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes.clear();
775119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // We don't need this anymore as subsequent calls to
776119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
777119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes = null;
778119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        }
779119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
780ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
78151f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reck        int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
782aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
783aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            setEnabled(false);
784b13de07f0b26953115f4315bc7417ca87c70594bJohn Reck            attachInfo.mViewRootImpl.mSurface.release();
785aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // Invalidate since we failed to draw. This should fetch a Surface
786aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // if it is still needed or do nothing if we are no longer drawing
787aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            attachInfo.mViewRootImpl.invalidate();
788aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        }
789f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
790f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            attachInfo.mViewRootImpl.invalidate();
791f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        }
792cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
793cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
7943b20251a355c88193c439f928a84ae69483fb488John Reck    static void invokeFunctor(long functor, boolean waitForCompletion) {
7953b20251a355c88193c439f928a84ae69483fb488John Reck        nInvokeFunctor(functor, waitForCompletion);
7960d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    }
7970d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck
79851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
79951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Creates a new hardware layer. A hardware layer built by calling this
80051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * method will be treated as a texture layer, instead of as a render target.
80151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
80251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return A hardware layer
80351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
80419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    HardwareLayer createTextureLayer() {
80519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        long layer = nCreateTextureLayer(mNativeProxy);
80619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return HardwareLayer.adoptTextureLayer(this, layer);
807cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
808cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
80951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
8103e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    void buildLayer(RenderNode node) {
8113e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck        nBuildLayer(mNativeProxy, node.getNativeDisplayList());
8123e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    }
8133e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
81451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
81519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
81619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return nCopyLayerInto(mNativeProxy,
8173731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck                layer.getDeferredLayerUpdater(), bitmap);
818cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
819cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
82051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
82151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates that the specified hardware layer needs to be updated
82251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * as soon as possible.
82351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
82451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param layer The hardware layer that needs an update
82551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
82619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void pushLayerUpdate(HardwareLayer layer) {
827d72e0a339b54af0c4e731513bbad120dff694723John Reck        nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
82819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
82919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
83051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
83151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Tells the HardwareRenderer that the layer is destroyed. The renderer
83251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * should remove the layer from any update queues.
83351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
83419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void onLayerDestroyed(HardwareLayer layer) {
835d72e0a339b54af0c4e731513bbad120dff694723John Reck        nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
836cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
837cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
83851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
83951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Optional, sets the name of the renderer. Useful for debugging purposes.
84051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
84151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param name The name of this renderer, can be null
84251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
843cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void setName(String name) {
844b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck        nSetName(mNativeProxy, name);
845cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
846cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
84751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
84851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Blocks until all previously queued work has completed.
84951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
85028ad7b52e038ef0cdd89f753d9839444a434b299John Reck    void fence() {
85128ad7b52e038ef0cdd89f753d9839444a434b299John Reck        nFence(mNativeProxy);
85228ad7b52e038ef0cdd89f753d9839444a434b299John Reck    }
85328ad7b52e038ef0cdd89f753d9839444a434b299John Reck
85451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
85551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Prevents any further drawing until draw() is called. This is a signal
85651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * that the contents of the RenderNode tree are no longer safe to play back.
85751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * In practice this usually means that there are Functor pointers in the
85851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * display list that are no longer valid.
85951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
860f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void stopDrawing() {
861f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nStopDrawing(mNativeProxy);
862f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    }
863f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
86451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
86551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
86651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
867a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    public void notifyFramePending() {
868a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        nNotifyFramePending(mNativeProxy);
869a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
870a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
87151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
872119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    void registerAnimatingRenderNode(RenderNode animator) {
873119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
874119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
875119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
876718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu    void registerVectorDrawableAnimator(
877718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu        AnimatedVectorDrawable.VectorDrawableAnimatorRT animator) {
878718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu        nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
879718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu                animator.getAnimatorNativePtr());
880718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu    }
881718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu
882e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    public void serializeDisplayListTree() {
883e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck        nSerializeDisplayListTree(mNativeProxy);
884e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    }
885e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck
886e94cbc76d560a157c0a0d47181b4ed2a0aadbeb1John Reck    public static int copySurfaceInto(Surface surface, Bitmap bitmap) {
88710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck        return nCopySurfaceInto(surface, bitmap);
88810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck    }
88910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck
890119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    @Override
8914f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    protected void finalize() throws Throwable {
8924f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        try {
8934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            nDeleteProxy(mNativeProxy);
8940ed751dd22a98f0c1f637570c5775b4f5e97d895John Reck            mNativeProxy = 0;
8954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        } finally {
8964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            super.finalize();
897cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        }
898cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
899cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
900edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static class ProcessInitializer {
901edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        static ProcessInitializer sInstance = new ProcessInitializer();
902edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static IBinder sProcToken;
90366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
90466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        private boolean mInitialized = false;
90566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
906edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private ProcessInitializer() {}
90766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
9083b20251a355c88193c439f928a84ae69483fb488John Reck        synchronized void init(Context context, long renderProxy) {
90966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (mInitialized) return;
910edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            mInitialized = true;
91133eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray            initSched(context, renderProxy);
912edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initGraphicsStats(context, renderProxy);
913edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initAssetAtlas(context, renderProxy);
914edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
915edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
91633eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray        private static void initSched(Context context, long renderProxy) {
91733eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray            try {
91833eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray                int tid = nGetRenderThreadTid(renderProxy);
91933eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray                ActivityManagerNative.getDefault().setRenderThread(tid);
92033eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray            } catch (Throwable t) {
92133eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray                Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
92233eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray            }
92333eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray        }
92433eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray
925edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initGraphicsStats(Context context, long renderProxy) {
926edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            try {
927828698b012e3c317073c0dbbe323d06fe9954af4John Reck                IBinder binder = ServiceManager.getService("graphicsstats");
928828698b012e3c317073c0dbbe323d06fe9954af4John Reck                if (binder == null) return;
929828698b012e3c317073c0dbbe323d06fe9954af4John Reck                IGraphicsStats graphicsStatsService = IGraphicsStats.Stub
930828698b012e3c317073c0dbbe323d06fe9954af4John Reck                        .asInterface(binder);
931828698b012e3c317073c0dbbe323d06fe9954af4John Reck                sProcToken = new Binder();
932edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                final String pkg = context.getApplicationInfo().packageName;
933828698b012e3c317073c0dbbe323d06fe9954af4John Reck                ParcelFileDescriptor pfd = graphicsStatsService.
934edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                        requestBufferForProcess(pkg, sProcToken);
935edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                nSetProcessStatsBuffer(renderProxy, pfd.getFd());
936edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                pfd.close();
937828698b012e3c317073c0dbbe323d06fe9954af4John Reck            } catch (Throwable t) {
938828698b012e3c317073c0dbbe323d06fe9954af4John Reck                Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
939edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            }
940edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
941edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
942edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initAssetAtlas(Context context, long renderProxy) {
94366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IBinder binder = ServiceManager.getService("assetatlas");
94466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (binder == null) return;
94566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
94666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
94766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            try {
94866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                if (atlas.isCompatible(android.os.Process.myPpid())) {
94966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    GraphicBuffer buffer = atlas.getBuffer();
95066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    if (buffer != null) {
95166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        long[] map = atlas.getMap();
95266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (map != null) {
9533b20251a355c88193c439f928a84ae69483fb488John Reck                            nSetAtlas(renderProxy, buffer, map);
95466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
95566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // If IAssetAtlas is not the same class as the IBinder
95666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // we are using a remote service and we can safely
95766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // destroy the graphic buffer
95866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (atlas.getClass() != binder.getClass()) {
95966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                            buffer.destroy();
96066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
96166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    }
96266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                }
96366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            } catch (RemoteException e) {
96466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                Log.w(LOG_TAG, "Could not acquire atlas", e);
96566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            }
96666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        }
96766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    }
96866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
969910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    void addFrameMetricsObserver(FrameMetricsObserver observer) {
970910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
971910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        observer.mNative = new VirtualRefBasePtr(nativeObserver);
97206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
97306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
974910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    void removeFrameMetricsObserver(FrameMetricsObserver observer) {
975910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
976910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        observer.mNative = null;
97706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
97806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
97984a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    static native void setupShadersDiskCache(String cacheFile);
98084a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
9813b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
982edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nSetProcessStatsBuffer(long nativeProxy, int fd);
98333eb07f5759b85a5617f8057d8a335019c7d24ddTim Murray    private static native int nGetRenderThreadTid(long nativeProxy);
984cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
985e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateRootRenderNode();
986e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateProxy(boolean translucent, long rootRenderNode);
9874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nDeleteProxy(long nativeProxy);
988cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
989e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    private static native boolean nLoadSystemProperties(long nativeProxy);
990b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    private static native void nSetName(long nativeProxy, String name);
99118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
9920bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot    private static native void nInitialize(long nativeProxy, Surface window);
9934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nUpdateSurface(long nativeProxy, Surface window);
99401a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    private static native boolean nPauseSurface(long nativeProxy, Surface window);
9958afcc76920499d0a384dba1470c5a377f80ed768John Reck    private static native void nSetStopped(long nativeProxy, boolean stopped);
996797b95b26bbb7557678af78b9a2a61830158920fChris Craik    private static native void nSetup(long nativeProxy, int width, int height,
99750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
99850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    private static native void nSetLightCenter(long nativeProxy,
99950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightX, float lightY, float lightZ);
100063a06673253914510bbeebd500655008682dade1John Reck    private static native void nSetOpaque(long nativeProxy, boolean opaque);
100151f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reck    private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
1002350e65206cfbd86484fcfda77bb988e270606ddaDoris Liu    private static native void nDestroy(long nativeProxy, long rootRenderNode);
1003119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
1004718cd3eb70703c43f29ca37907bbf0e153d8cca0Doris Liu    private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
1005cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
10063b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
100719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
100819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateTextureLayer(long nativeProxy);
10093e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    private static native void nBuildLayer(long nativeProxy, long node);
10103731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
1011d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nPushLayerUpdate(long nativeProxy, long layer);
1012d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nCancelLayerUpdate(long nativeProxy, long layer);
1013918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
101428ad7b52e038ef0cdd89f753d9839444a434b299John Reck
1015f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nDestroyHardwareResources(long nativeProxy);
1016f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nTrimMemory(int level);
10172507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    private static native void nOverrideProperty(String name, String value);
1018e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck
101928ad7b52e038ef0cdd89f753d9839444a434b299John Reck    private static native void nFence(long nativeProxy);
1020f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nStopDrawing(long nativeProxy);
1021a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    private static native void nNotifyFramePending(long nativeProxy);
1022fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
1023e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    private static native void nSerializeDisplayListTree(long nativeProxy);
1024e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck
1025ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1026ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            @DumpFlags int dumpFlags);
1027edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nDumpProfileData(byte[] data, FileDescriptor fd);
1028ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
1029ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1030ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne             boolean placeFront);
1031ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1032ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
1033b816087962aba0019b022303330f03b897b580edSkuhne    private static native void nSetContentDrawBounds(long nativeProxy, int left,
1034ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne             int top, int right, int bottom);
103506f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
1036910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
1037910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
103810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck
1039e94cbc76d560a157c0a0d47181b4ed2a0aadbeb1John Reck    private static native int nCopySurfaceInto(Surface surface, Bitmap bitmap);
1040cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}
1041