ThreadedRenderer.java revision 10dd0585c11dcedb5a271d54e645594f1d215d5c
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
19ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport android.annotation.IntDef;
202507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craikimport android.annotation.NonNull;
21b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.content.Context;
2258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viveretteimport android.content.res.TypedArray;
2304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckimport android.graphics.Bitmap;
2450210d912925aef14e4ce69be82e4949122a3cd9Alan Viveretteimport android.graphics.Point;
25ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viveretteimport android.graphics.Rect;
26edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reckimport android.os.Binder;
2706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesimport android.os.Handler;
2866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.IBinder;
2906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesimport android.os.Message;
30edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reckimport android.os.ParcelFileDescriptor;
3166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.RemoteException;
3266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.ServiceManager;
33cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.os.Trace;
3466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.util.Log;
35cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.Surface.OutOfResourcesException;
36cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.View.AttachInfo;
37cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
38ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport com.android.internal.R;
3906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesimport com.android.internal.util.VirtualRefBasePtr;
40ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
4151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reckimport java.io.File;
42fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckimport java.io.FileDescriptor;
43cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport java.io.PrintWriter;
44ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.Retention;
45ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.RetentionPolicy;
4606f5bc70a667a02b14e31d3f53f91d3661e30666Andres Moralesimport java.util.HashSet;
47cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
48cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/**
49cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Hardware renderer that proxies the rendering to a render thread. Most calls
504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * are currently synchronous.
51cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
52cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * The UI thread can block on the RenderThread, but RenderThread must never
53cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * block on the UI thread.
54cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
554f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
574f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * by the lifecycle of the RenderProxy.
584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
59cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Note that although currently the EGL context & surfaces are created & managed
60cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * by the render thread, the goal is to move that into a shared structure that can
61cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * be managed by both threads. EGLSurface creation & deletion should ideally be
62cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * done on the UI thread and not the RenderThread to avoid stalling the
63cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * RenderThread with surface buffer allocation.
64cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
65cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * @hide
66cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
6751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reckpublic final class ThreadedRenderer {
6851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private static final String LOG_TAG = "ThreadedRenderer";
6951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
7051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
7151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Name of the file that holds the shaders cache.
7251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
7351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
7451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
7551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
7651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to enable or disable dirty regions invalidation.
7751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
7851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * The default value of this property is assumed to be true.
7951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
8051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
8151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable partial invalidates
8251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable partial invalidates
8351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
8451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    static final String RENDER_DIRTY_REGIONS_PROPERTY = "debug.hwui.render_dirty_regions";
8551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
8651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
8751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to enable or disable hardware rendering profiling.
8851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * The default value of this property is assumed to be false.
8951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
9051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * When profiling is enabled, the adb shell dumpsys gfxinfo command will
9151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * output extra information about the time taken to execute by the last
9251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * frames.
9351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
9451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
9551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable profiling
9651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "visual_bars", to enable profiling and visualize the results on screen
9751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable profiling
9851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
9951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @see #PROFILE_PROPERTY_VISUALIZE_BARS
10051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
10151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
10251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
10351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String PROFILE_PROPERTY = "debug.hwui.profile";
10451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
10551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
10651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Value for {@link #PROFILE_PROPERTY}. When the property is set to this
10751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * value, profiling data will be visualized on screen as a bar chart.
10851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
10951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
11051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
11151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars";
11251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
11351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
11451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to specify the number of frames to be used
11551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * when doing hardware rendering profiling.
11651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * The default value of this property is #PROFILE_MAX_FRAMES.
11751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
11851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * When profiling is enabled, the adb shell dumpsys gfxinfo command will
11951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * output extra information about the time taken to execute by the last
12051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * frames.
12151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
12251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
12351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "60", to set the limit of frames to 60
12451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
12551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes";
12651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
12751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
12851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to debug EGL configuration choice.
12951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
13051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
13151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "choice", print the chosen configuration only
13251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "all", print all possible configurations
13351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
13451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config";
13551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
13651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
13751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Turn on to draw dirty regions every other frame.
13851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
13951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
14051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable dirty regions debugging
14151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable dirty regions debugging
14251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
14351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
14451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
14551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
14651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
14751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
14851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Turn on to flash hardware layers when they update.
14951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
15051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
15151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable hardware layers updates debugging
15251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable hardware layers updates debugging
15351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
15451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
15551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
15651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
15751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            "debug.hwui.show_layers_updates";
15851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
15951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
16051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Controls overdraw debugging.
16151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
16251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
16351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable overdraw debugging
16451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "show", to show overdraw areas on screen
16551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "count", to display an overdraw counter
16651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
16751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
16851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
16951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
17051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
17151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
17251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
17351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * value, overdraw will be shown on screen by coloring pixels.
17451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
17551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
17651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
17751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String OVERDRAW_PROPERTY_SHOW = "show";
17851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
17951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
18051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Turn on to debug non-rectangular clip operations.
18151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
18251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
18351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "hide", to disable this debug mode
18451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "highlight", highlight drawing commands tested against a non-rectangular clip
18551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "stencil", renders the clip region on screen when set
18651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
18751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
18851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
18951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
19051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            "debug.hwui.show_non_rect_clip";
19151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
19251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
19351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * A process can set this flag to false to prevent the use of hardware
19451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * rendering.
19551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
19651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
19751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
19851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean sRendererDisabled = false;
19951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
20051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
20151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Further hardware renderer disabling for the system process.
20251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
20351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
20451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
20551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean sSystemRendererDisabled = false;
20651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
20751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
20851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Invoke this method to disable hardware rendering in the current process.
20951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
21051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
21151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
21251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void disable(boolean system) {
21351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        sRendererDisabled = true;
21451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (system) {
21551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            sSystemRendererDisabled = true;
21651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
21751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
21851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
21951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean sTrimForeground = false;
22051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
22151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
22251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Controls whether or not the hardware renderer should aggressively
22351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * trim memory. Note that this must not be set for any process that
22451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * uses WebView! This should be only used by system_process or similar
22551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * that do not go into the background.
22651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
22751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void enableForegroundTrimming() {
22851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        sTrimForeground = true;
22951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
23051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
23151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
23251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is available under any form for
23351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the view hierarchy.
23451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
23551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if the view hierarchy can potentially be hardware accelerated,
23651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *         false otherwise
23751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
23851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean isAvailable() {
23951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return DisplayListCanvas.isAvailable();
24051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
24151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
24251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
24351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Sets the directory to use as a persistent storage for hardware rendering
24451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * resources.
24551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
24651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param cacheDir A directory the current process can write to
24751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
24851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
24951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
25051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void setupDiskCache(File cacheDir) {
25151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
25251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
25351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
25451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
25503d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine     * Sets the library directory to use as a search path for vulkan layers.
25603d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine     *
25703d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine     * @param libDir A directory that contains vulkan layers
25803d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine     *
25903d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine     * @hide
26003d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine     */
26103d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine    public static void setLibDir(String libDir) {
26203d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine        ThreadedRenderer.setupVulkanLayerPath(libDir);
26303d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine    }
26403d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine
26503d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine    /**
26651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Creates a hardware renderer using OpenGL.
26751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
26851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param translucent True if the surface is translucent, false otherwise
26951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
27051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return A hardware renderer backed by OpenGL.
27151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
27251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static ThreadedRenderer create(Context context, boolean translucent) {
27351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        ThreadedRenderer renderer = null;
27451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (DisplayListCanvas.isAvailable()) {
27551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            renderer = new ThreadedRenderer(context, translucent);
27651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
27751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return renderer;
27851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
27951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
28051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
28151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Invoke this method when the system is running out of memory. This
28251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * method will attempt to recover as much memory as possible, based on
28351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the specified hint.
28451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
28551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param level Hint about the amount of memory that should be trimmed,
28651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *              see {@link android.content.ComponentCallbacks}
28751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
28851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void trimMemory(int level) {
28951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        nTrimMemory(level);
29051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
29151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
29251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void overrideProperty(@NonNull String name, @NonNull String value) {
29351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (name == null || value == null) {
29451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            throw new IllegalArgumentException("name and value must be non-null");
29551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
29651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        nOverrideProperty(name, value);
29751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
29851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
29951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void dumpProfileData(byte[] data, FileDescriptor fd) {
30051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        nDumpProfileData(data, fd);
30151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
302cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
303f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Keep in sync with DrawFrameTask.h SYNC_* flags
304f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Nothing interesting to report
305cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_OK = 0;
306f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Needs a ViewRoot invalidate
307cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
308aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck    // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
309aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck    private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
310f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck
311fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static final String[] VISUALIZERS = {
312fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        PROFILE_PROPERTY_VISUALIZE_BARS,
313fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    };
314fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
315ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_FRAMESTATS   = 1 << 0;
316ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_RESET        = 1 << 1;
317ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
318ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @IntDef(flag = true, value = {
319ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET })
320ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @Retention(RetentionPolicy.SOURCE)
321ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    public @interface DumpFlags {}
322ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
323ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Size of the rendered content.
324cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private int mWidth, mHeight;
325ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
326ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Actual size of the drawing surface.
327ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mSurfaceWidth, mSurfaceHeight;
328ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
329ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Insets between the drawing surface and rendered content. These are
330ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // applied as translation when updating the root render node.
331ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mInsetTop, mInsetLeft;
332ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
33357774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    // Whether the surface has insets. Used to protect opacity.
33457774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    private boolean mHasInsets;
33557774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
33658c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    // Light and shadow properties specified by the theme.
33758c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightY;
33858c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightZ;
33958c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightRadius;
340058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mAmbientShadowAlpha;
341058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mSpotShadowAlpha;
34258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
3434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private long mNativeProxy;
344f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private boolean mInitialized = false;
345bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private RenderNode mRootNode;
34618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    private Choreographer mChoreographer;
3470a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private boolean mRootNodeNeedsUpdate;
348cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
349ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    // In case of multi threaded render nodes, these bounds indicate the content bounds against
350ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    // which the backdrop needs to be cropped against.
351ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private final Rect mCurrentContentBounds = new Rect();
352ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private final Rect mStagedContentBounds = new Rect();
353ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
35451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private boolean mEnabled;
35551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private boolean mRequested = true;
35651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
357b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck    ThreadedRenderer(Context context, boolean translucent) {
358ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
35958c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
36058c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
36158c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
362ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mAmbientShadowAlpha =
363ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette                (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
364ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
36558c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        a.recycle();
36658c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
367e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        long rootNodePtr = nCreateRootRenderNode();
368e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mRootNode = RenderNode.adopt(rootNodePtr);
369bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        mRootNode.setClipToBounds(false);
370e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mNativeProxy = nCreateProxy(translucent, rootNodePtr);
37118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
372edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        ProcessInitializer.sInstance.init(context, mNativeProxy);
3733b20251a355c88193c439f928a84ae69483fb488John Reck
374fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        loadSystemProperties();
375cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
376cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
37751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
37851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Destroys the hardware rendering context.
37951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
380f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void destroy() {
381f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = false;
382f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(null);
383350e65206cfbd86484fcfda77bb988e270606ddaDoris Liu        nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
384cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
385cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
38651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
38751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently enabled.
38851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
38951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if hardware acceleration is in use, false otherwise.
39051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
39151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean isEnabled() {
39251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return mEnabled;
39351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
39451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
39551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
39651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently enabled.
39751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
39851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param enabled True if the hardware renderer is in use, false otherwise.
39951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
40051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    void setEnabled(boolean enabled) {
40151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        mEnabled = enabled;
40251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
40351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
40451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
40551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently request but not
40651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * necessarily enabled yet.
40751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
40851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if requested, false otherwise.
40951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
41051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean isRequested() {
41151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return mRequested;
41251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
41351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
41451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
41551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently requested but not
41651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * necessarily enabled yet.
41751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
41851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True to request hardware acceleration, false otherwise.
41951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
42051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    void setRequested(boolean requested) {
42151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        mRequested = requested;
42251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
42351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
424f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private void updateEnabledState(Surface surface) {
425f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        if (surface == null || !surface.isValid()) {
426f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(false);
427f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        } else {
428f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(mInitialized);
429f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        }
430f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
431f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
43251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
43351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Initializes the hardware renderer for the specified surface.
43451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
43551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
43651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
43751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if the initialization was successful, false otherwise.
43851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
439cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean initialize(Surface surface) throws OutOfResourcesException {
4400bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot        boolean status = !mInitialized;
441f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = true;
442f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
4430bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot        nInitialize(mNativeProxy, surface);
4445795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        return status;
445cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
446cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
44751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
44851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Initializes the hardware renderer for the specified surface and setup the
44951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * renderer for drawing, if needed. This is invoked when the ViewAncestor has
45051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * potentially lost the hardware renderer. The hardware renderer should be
45151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * reinitialized and setup when the render {@link #isRequested()} and
45251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * {@link #isEnabled()}.
45351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
45451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param width The width of the drawing surface.
45551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param height The height of the drawing surface.
45651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
45751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
45851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surfaceInsets The drawing surface insets to apply
45951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
46051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return true if the surface was initialized, false otherwise. Returning
46151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *         false might mean that the surface was already initialized.
46251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
46351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
46451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
46551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (isRequested()) {
46651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            // We lost the gl context, so recreate it.
46751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            if (!isEnabled()) {
46851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                if (initialize(surface)) {
46951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                    setup(width, height, attachInfo, surfaceInsets);
47051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                    return true;
47151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                }
47251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            }
47351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
47451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return false;
47551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
47651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
47751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
47851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Updates the hardware renderer for the specified surface.
47951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
48051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
48151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
482cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void updateSurface(Surface surface) throws OutOfResourcesException {
483f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
4844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        nUpdateSurface(mNativeProxy, surface);
485cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
486cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
48751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
488945961f78a78eced823d5ba78505c781b079703dJohn Reck     * Halts any current rendering into the surface. Use this if it is unclear whether
48951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * or not the surface used by the HardwareRenderer will be changing. It
490945961f78a78eced823d5ba78505c781b079703dJohn Reck     * Suspends any rendering into the surface, but will not do any destruction.
491945961f78a78eced823d5ba78505c781b079703dJohn Reck     *
492945961f78a78eced823d5ba78505c781b079703dJohn Reck     * Any subsequent draws will override the pause, resuming normal operation.
49351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
49401a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    boolean pauseSurface(Surface surface) {
49501a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck        return nPauseSurface(mNativeProxy, surface);
496f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
497f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
49851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
499945961f78a78eced823d5ba78505c781b079703dJohn Reck     * Hard stops or resumes rendering into the surface. This flag is used to
500945961f78a78eced823d5ba78505c781b079703dJohn Reck     * determine whether or not it is safe to use the given surface *at all*
501945961f78a78eced823d5ba78505c781b079703dJohn Reck     */
502945961f78a78eced823d5ba78505c781b079703dJohn Reck    void setStopped(boolean stopped) {
503945961f78a78eced823d5ba78505c781b079703dJohn Reck        nSetStopped(mNativeProxy, stopped);
504945961f78a78eced823d5ba78505c781b079703dJohn Reck    }
505945961f78a78eced823d5ba78505c781b079703dJohn Reck
506945961f78a78eced823d5ba78505c781b079703dJohn Reck    /**
50751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Destroys all hardware rendering resources associated with the specified
50851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * view hierarchy.
50951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
51051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param view The root of the view hierarchy
51151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
512cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void destroyHardwareResources(View view) {
5134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        destroyResources(view);
514f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nDestroyHardwareResources(mNativeProxy);
5154f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
5164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
5174f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static void destroyResources(View view) {
5184f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        view.destroyHardwareResources();
5194f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
5204f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (view instanceof ViewGroup) {
5214f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            ViewGroup group = (ViewGroup) view;
5224f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
5234f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            int count = group.getChildCount();
5244f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            for (int i = 0; i < count; i++) {
5254f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck                destroyResources(group.getChildAt(i));
5264f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            }
5274f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
528cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
529cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
53051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
53151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * This method should be invoked whenever the current hardware renderer
53251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * context should be reset.
53351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
53451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
53551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
536cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void invalidate(Surface surface) {
5374f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        updateSurface(surface);
538cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
539cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
54051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
54151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Detaches the layer's surface texture from the GL context and releases
54251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the texture id
54351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
544918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    void detachSurfaceTexture(long hardwareLayer) {
545918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
546cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
547cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
54851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
54951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Sets up the renderer for drawing.
55051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
55151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param width The width of the drawing surface.
55251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param height The height of the drawing surface.
55351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
55451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surfaceInsets The drawing surface insets to apply
55551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
55650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
557cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mWidth = width;
558cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mHeight = height;
55950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
5603aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette        if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
5613aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette                || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
56257774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = true;
563ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = surfaceInsets.left;
564ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = surfaceInsets.top;
565ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
566ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
56757774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
56857774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            // If the surface has insets, it can't be opaque.
56957774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            setOpaque(false);
570ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        } else {
57157774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = false;
572ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = 0;
573ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = 0;
574ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width;
575ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height;
576ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        }
57750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
578ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
57950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, mLightRadius,
580b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck                mAmbientShadowAlpha, mSpotShadowAlpha);
58150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
58250210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        setLightCenter(attachInfo);
58350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    }
58450210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
58551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
58651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Updates the light position based on the position of the window.
58751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
58851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
58951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
59050210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setLightCenter(AttachInfo attachInfo) {
59150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        // Adjust light position for window offsets.
59250210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final Point displaySize = attachInfo.mPoint;
59350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        attachInfo.mDisplay.getRealSize(displaySize);
59450210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
59550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightY = mLightY - attachInfo.mWindowTop;
59650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
59750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
598cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
599cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
60051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
60151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Change the HardwareRenderer's opacity
60251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
60363a06673253914510bbeebd500655008682dade1John Reck    void setOpaque(boolean opaque) {
60457774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette        nSetOpaque(mNativeProxy, opaque && !mHasInsets);
60563a06673253914510bbeebd500655008682dade1John Reck    }
60663a06673253914510bbeebd500655008682dade1John Reck
60751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
60851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Gets the current width of the surface. This is the width that the surface
60951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
61051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
61151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return the current width of the surface
61251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
613cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getWidth() {
614cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mWidth;
615cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
616cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
61751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
61851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Gets the current height of the surface. This is the height that the surface
61951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
62051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
62151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return the current width of the surface
62251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
623cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getHeight() {
624cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mHeight;
625cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
626cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
62751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
62851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Outputs extra debugging information in the specified file descriptor.
62951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
630ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
631fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        pw.flush();
632ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        int flags = 0;
633ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        for (int i = 0; i < args.length; i++) {
634ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            switch (args[i]) {
635ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "framestats":
636ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_FRAMESTATS;
637ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
638ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "reset":
639ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_RESET;
640ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
641ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            }
642fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
643ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        nDumpProfileInfo(mNativeProxy, fd, flags);
644cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
645cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
64651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
64751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Loads system properties used by the renderer. This method is invoked
64851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * whenever system properties are modified. Implementations can use this
64951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * to trigger live updates of the renderer based on properties.
65051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
65151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if a property has changed.
65251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
653cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean loadSystemProperties() {
654fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        boolean changed = nLoadSystemProperties(mNativeProxy);
65523d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        if (changed) {
65623d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck            invalidateRoot();
65723d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        }
658fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return changed;
659cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
660cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
6610a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private void updateViewTreeDisplayList(View view) {
662cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags |= View.PFLAG_DRAWN;
663cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
664cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck                == View.PFLAG_INVALIDATED;
665cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
66631a2d063df5111e730abe7d07be064690deedc34Chris Craik        view.updateDisplayListIfDirty();
6670a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        view.mRecreateDisplayList = false;
6680a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
669cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
67061375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
67170850ea258cbf91477efa57a1f1a23cc0044cc93Chris Craik        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
6720a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        updateViewTreeDisplayList(view);
6730a97330b98dd633b58dcfff405d94476c89e867dJohn Reck
6740a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
675f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik            DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
6760a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            try {
677dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                final int saveCount = canvas.save();
6780a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                canvas.translate(mInsetLeft, mInsetTop);
6790a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePreDraw(canvas);
680abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
681abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertReorderBarrier();
68231a2d063df5111e730abe7d07be064690deedc34Chris Craik                canvas.drawRenderNode(view.updateDisplayListIfDirty());
683abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertInorderBarrier();
684abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
6850a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePostDraw(canvas);
686dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                canvas.restoreToCount(saveCount);
6870a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNodeNeedsUpdate = false;
6880a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            } finally {
6890a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNode.end(canvas);
6900a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            }
69105e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        }
6920a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
6930a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
694cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
695ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
696ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
697ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * rendernode of the UI thread.
698ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node to add.
699ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param placeFront If true, the render node will be placed in front of the content node,
700ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     *                   otherwise behind the content node.
701ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
702ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void addRenderNode(RenderNode node, boolean placeFront) {
703ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
704ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
705ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
706ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
707ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Only especially added render nodes can be removed.
708ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node which was added via addRenderNode which should get removed again.
709ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
710ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void removeRenderNode(RenderNode node) {
711ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
712ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
713ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
714ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
715ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Draws a particular render node. If the node is not the content node, only the additional
716ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * nodes will get drawn and the content remains untouched.
717ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node to be drawn.
718ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
719ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void drawRenderNode(RenderNode node) {
720ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
721ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
722ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
723ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
724ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
725ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * will be prevented to overdraw this area. It will be synchronized with the draw call.
726ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * This should be updated in the content view's draw call.
727ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param left The left side of the protected bounds.
728ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param top The top side of the protected bounds.
729ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param right The right side of the protected bounds.
730ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param bottom The bottom side of the protected bounds.
731ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
732b816087962aba0019b022303330f03b897b580edSkuhne    public void setContentDrawBounds(int left, int top, int right, int bottom) {
733ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        mStagedContentBounds.set(left, top, right, bottom);
734ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
735ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
73651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
73751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Interface used to receive callbacks whenever a view is drawn by
73851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * a hardware renderer instance.
73951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
74051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    interface HardwareDrawCallbacks {
74151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        /**
74251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * Invoked before a view is drawn by a hardware renderer.
74351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * This method can be used to apply transformations to the
74451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * canvas but no drawing command should be issued.
74551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         *
74651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * @param canvas The Canvas used to render the view.
74751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         */
74851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        void onHardwarePreDraw(DisplayListCanvas canvas);
74951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
75051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        /**
75151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * Invoked after a view is drawn by a hardware renderer.
75251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * It is safe to invoke drawing commands from this method.
75351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         *
75451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * @param canvas The Canvas used to render the view.
75551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         */
75651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        void onHardwarePostDraw(DisplayListCanvas canvas);
75751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
75851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
75951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
76051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *  Indicates that the content drawn by HardwareDrawCallbacks needs to
76151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *  be updated, which will be done by the next call to draw()
76251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
7630a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    void invalidateRoot() {
7640a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        mRootNodeNeedsUpdate = true;
765bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    }
766bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
76751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
76851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Draws the specified view.
76951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
77051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param view The view to draw.
77151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo AttachInfo tied to the specified view.
77251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param callbacks Callbacks invoked when drawing happens.
77351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
77461375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
775bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        attachInfo.mIgnoreDirtyState = true;
776bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
777ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
778ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        choreographer.mFrameInfo.markDrawStart();
779fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
78061375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck        updateRootDisplayList(view, callbacks);
781ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        // The main content view was updating the content bounds and we transfer them to the
782ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        // renderer.
783ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        if (!mCurrentContentBounds.equals(mStagedContentBounds)) {
784ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne            mCurrentContentBounds.set(mStagedContentBounds);
785b816087962aba0019b022303330f03b897b580edSkuhne            nSetContentDrawBounds(mNativeProxy, mCurrentContentBounds.left,
786b816087962aba0019b022303330f03b897b580edSkuhne                    mCurrentContentBounds.top, mCurrentContentBounds.right,
787b816087962aba0019b022303330f03b897b580edSkuhne                    mCurrentContentBounds.bottom);
788ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        }
789cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
7906313b9259d37b59f3402058e197637aa3014516cJohn Reck        attachInfo.mIgnoreDirtyState = false;
7916313b9259d37b59f3402058e197637aa3014516cJohn Reck
792119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // register animating rendernodes which started animating prior to renderer
793119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // creation, which is typical for animators started prior to first draw
794119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        if (attachInfo.mPendingAnimatingRenderNodes != null) {
795119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            final int count = attachInfo.mPendingAnimatingRenderNodes.size();
796119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            for (int i = 0; i < count; i++) {
797119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                registerAnimatingRenderNode(
798119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                        attachInfo.mPendingAnimatingRenderNodes.get(i));
799119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            }
800119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes.clear();
801119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // We don't need this anymore as subsequent calls to
802119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
803119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes = null;
804119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        }
805119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
806ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
80751f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reck        int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
808aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
809aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            setEnabled(false);
810b13de07f0b26953115f4315bc7417ca87c70594bJohn Reck            attachInfo.mViewRootImpl.mSurface.release();
811aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // Invalidate since we failed to draw. This should fetch a Surface
812aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // if it is still needed or do nothing if we are no longer drawing
813aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            attachInfo.mViewRootImpl.invalidate();
814aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        }
815f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
816f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            attachInfo.mViewRootImpl.invalidate();
817f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        }
818cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
819cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
8203b20251a355c88193c439f928a84ae69483fb488John Reck    static void invokeFunctor(long functor, boolean waitForCompletion) {
8213b20251a355c88193c439f928a84ae69483fb488John Reck        nInvokeFunctor(functor, waitForCompletion);
8220d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    }
8230d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck
82451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
82551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Creates a new hardware layer. A hardware layer built by calling this
82651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * method will be treated as a texture layer, instead of as a render target.
82751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
82851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return A hardware layer
82951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
83019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    HardwareLayer createTextureLayer() {
83119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        long layer = nCreateTextureLayer(mNativeProxy);
83219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return HardwareLayer.adoptTextureLayer(this, layer);
833cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
834cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
83551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
8363e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    void buildLayer(RenderNode node) {
8373e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck        nBuildLayer(mNativeProxy, node.getNativeDisplayList());
8383e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    }
8393e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
84051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
84119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
84219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return nCopyLayerInto(mNativeProxy,
8433731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck                layer.getDeferredLayerUpdater(), bitmap);
844cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
845cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
84651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
84751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates that the specified hardware layer needs to be updated
84851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * as soon as possible.
84951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
85051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param layer The hardware layer that needs an update
85151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
85219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void pushLayerUpdate(HardwareLayer layer) {
853d72e0a339b54af0c4e731513bbad120dff694723John Reck        nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
85419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
85519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
85651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
85751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Tells the HardwareRenderer that the layer is destroyed. The renderer
85851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * should remove the layer from any update queues.
85951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
86019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void onLayerDestroyed(HardwareLayer layer) {
861d72e0a339b54af0c4e731513bbad120dff694723John Reck        nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
862cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
863cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
86451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
86551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Optional, sets the name of the renderer. Useful for debugging purposes.
86651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
86751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param name The name of this renderer, can be null
86851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
869cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void setName(String name) {
870b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck        nSetName(mNativeProxy, name);
871cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
872cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
87351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
87451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Blocks until all previously queued work has completed.
87551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
87628ad7b52e038ef0cdd89f753d9839444a434b299John Reck    void fence() {
87728ad7b52e038ef0cdd89f753d9839444a434b299John Reck        nFence(mNativeProxy);
87828ad7b52e038ef0cdd89f753d9839444a434b299John Reck    }
87928ad7b52e038ef0cdd89f753d9839444a434b299John Reck
88051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
88151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Prevents any further drawing until draw() is called. This is a signal
88251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * that the contents of the RenderNode tree are no longer safe to play back.
88351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * In practice this usually means that there are Functor pointers in the
88451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * display list that are no longer valid.
88551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
886f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void stopDrawing() {
887f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nStopDrawing(mNativeProxy);
888f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    }
889f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
89051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
89151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
89251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
893a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    public void notifyFramePending() {
894a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        nNotifyFramePending(mNativeProxy);
895a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
896a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
89751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
898119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    void registerAnimatingRenderNode(RenderNode animator) {
899119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
900119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
901119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
902e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    public void serializeDisplayListTree() {
903e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck        nSerializeDisplayListTree(mNativeProxy);
904e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    }
905e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck
90610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck    public static boolean copySurfaceInto(Surface surface, Bitmap bitmap) {
90710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck        return nCopySurfaceInto(surface, bitmap);
90810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck    }
90910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck
910119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    @Override
9114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    protected void finalize() throws Throwable {
9124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        try {
9134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            nDeleteProxy(mNativeProxy);
9140ed751dd22a98f0c1f637570c5775b4f5e97d895John Reck            mNativeProxy = 0;
9154f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        } finally {
9164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            super.finalize();
917cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        }
918cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
919cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
920edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static class ProcessInitializer {
921edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        static ProcessInitializer sInstance = new ProcessInitializer();
922edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static IBinder sProcToken;
92366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
92466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        private boolean mInitialized = false;
92566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
926edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private ProcessInitializer() {}
92766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
9283b20251a355c88193c439f928a84ae69483fb488John Reck        synchronized void init(Context context, long renderProxy) {
92966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (mInitialized) return;
930edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            mInitialized = true;
931edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initGraphicsStats(context, renderProxy);
932edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initAssetAtlas(context, renderProxy);
933edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
934edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
935edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initGraphicsStats(Context context, long renderProxy) {
936edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            try {
937828698b012e3c317073c0dbbe323d06fe9954af4John Reck                IBinder binder = ServiceManager.getService("graphicsstats");
938828698b012e3c317073c0dbbe323d06fe9954af4John Reck                if (binder == null) return;
939828698b012e3c317073c0dbbe323d06fe9954af4John Reck                IGraphicsStats graphicsStatsService = IGraphicsStats.Stub
940828698b012e3c317073c0dbbe323d06fe9954af4John Reck                        .asInterface(binder);
941828698b012e3c317073c0dbbe323d06fe9954af4John Reck                sProcToken = new Binder();
942edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                final String pkg = context.getApplicationInfo().packageName;
943828698b012e3c317073c0dbbe323d06fe9954af4John Reck                ParcelFileDescriptor pfd = graphicsStatsService.
944edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                        requestBufferForProcess(pkg, sProcToken);
945edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                nSetProcessStatsBuffer(renderProxy, pfd.getFd());
946edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                pfd.close();
947828698b012e3c317073c0dbbe323d06fe9954af4John Reck            } catch (Throwable t) {
948828698b012e3c317073c0dbbe323d06fe9954af4John Reck                Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
949edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            }
950edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
951edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
952edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initAssetAtlas(Context context, long renderProxy) {
95366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IBinder binder = ServiceManager.getService("assetatlas");
95466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (binder == null) return;
95566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
95666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
95766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            try {
95866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                if (atlas.isCompatible(android.os.Process.myPpid())) {
95966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    GraphicBuffer buffer = atlas.getBuffer();
96066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    if (buffer != null) {
96166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        long[] map = atlas.getMap();
96266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (map != null) {
9633b20251a355c88193c439f928a84ae69483fb488John Reck                            nSetAtlas(renderProxy, buffer, map);
96466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
96566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // If IAssetAtlas is not the same class as the IBinder
96666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // we are using a remote service and we can safely
96766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // destroy the graphic buffer
96866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (atlas.getClass() != binder.getClass()) {
96966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                            buffer.destroy();
97066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
97166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    }
97266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                }
97366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            } catch (RemoteException e) {
97466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                Log.w(LOG_TAG, "Could not acquire atlas", e);
97566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            }
97666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        }
97766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    }
97866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
979910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    void addFrameMetricsObserver(FrameMetricsObserver observer) {
980910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
981910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        observer.mNative = new VirtualRefBasePtr(nativeObserver);
98206f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
98306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
984910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    void removeFrameMetricsObserver(FrameMetricsObserver observer) {
985910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
986910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        observer.mNative = null;
98706f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
98806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
98984a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    static native void setupShadersDiskCache(String cacheFile);
99003d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine    static native void setupVulkanLayerPath(String layerPath);
99184a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
9923b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
993edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nSetProcessStatsBuffer(long nativeProxy, int fd);
994cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
995e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateRootRenderNode();
996e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateProxy(boolean translucent, long rootRenderNode);
9974f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nDeleteProxy(long nativeProxy);
998cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
999e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    private static native boolean nLoadSystemProperties(long nativeProxy);
1000b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    private static native void nSetName(long nativeProxy, String name);
100118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
10020bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot    private static native void nInitialize(long nativeProxy, Surface window);
10034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nUpdateSurface(long nativeProxy, Surface window);
100401a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    private static native boolean nPauseSurface(long nativeProxy, Surface window);
1005945961f78a78eced823d5ba78505c781b079703dJohn Reck    private static native void nSetStopped(long nativeProxy, boolean stopped);
1006797b95b26bbb7557678af78b9a2a61830158920fChris Craik    private static native void nSetup(long nativeProxy, int width, int height,
100750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
100850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    private static native void nSetLightCenter(long nativeProxy,
100950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightX, float lightY, float lightZ);
101063a06673253914510bbeebd500655008682dade1John Reck    private static native void nSetOpaque(long nativeProxy, boolean opaque);
101151f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reck    private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
1012350e65206cfbd86484fcfda77bb988e270606ddaDoris Liu    private static native void nDestroy(long nativeProxy, long rootRenderNode);
1013119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
1014cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
10153b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
101619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
101719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateTextureLayer(long nativeProxy);
10183e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    private static native void nBuildLayer(long nativeProxy, long node);
10193731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
1020d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nPushLayerUpdate(long nativeProxy, long layer);
1021d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nCancelLayerUpdate(long nativeProxy, long layer);
1022918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
102328ad7b52e038ef0cdd89f753d9839444a434b299John Reck
1024f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nDestroyHardwareResources(long nativeProxy);
1025f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nTrimMemory(int level);
10262507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    private static native void nOverrideProperty(String name, String value);
1027e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck
102828ad7b52e038ef0cdd89f753d9839444a434b299John Reck    private static native void nFence(long nativeProxy);
1029f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nStopDrawing(long nativeProxy);
1030a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    private static native void nNotifyFramePending(long nativeProxy);
1031fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
1032e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    private static native void nSerializeDisplayListTree(long nativeProxy);
1033e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck
1034ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1035ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            @DumpFlags int dumpFlags);
1036edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nDumpProfileData(byte[] data, FileDescriptor fd);
1037ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
1038ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1039ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne             boolean placeFront);
1040ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1041ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
1042b816087962aba0019b022303330f03b897b580edSkuhne    private static native void nSetContentDrawBounds(long nativeProxy, int left,
1043ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne             int top, int right, int bottom);
104406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
1045910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
1046910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
104710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck
104810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck    private static native boolean nCopySurfaceInto(Surface surface, Bitmap bitmap);
1049cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}
1050