ThreadedRenderer.java revision 9a17da8125c36c82ba73e7f4b3ed80b9c633767f
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;
3109a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // setStopped is true, drawing is false
3119a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // TODO: Remove this and SYNC_LOST_SURFACE_REWARD_IF_FOUND?
3129a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // This flag isn't really used as there's nothing that we care to do
3139a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // in response, so it really just exists to differentiate from LOST_SURFACE
3149a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    // but possibly both can just be deleted.
3159a17da8125c36c82ba73e7f4b3ed80b9c633767fJohn Reck    private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
316f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck
317fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static final String[] VISUALIZERS = {
318fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        PROFILE_PROPERTY_VISUALIZE_BARS,
319fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    };
320fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
321ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_FRAMESTATS   = 1 << 0;
322ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_RESET        = 1 << 1;
323ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
324ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @IntDef(flag = true, value = {
325ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET })
326ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @Retention(RetentionPolicy.SOURCE)
327ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    public @interface DumpFlags {}
328ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
329ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Size of the rendered content.
330cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private int mWidth, mHeight;
331ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
332ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Actual size of the drawing surface.
333ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mSurfaceWidth, mSurfaceHeight;
334ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
335ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Insets between the drawing surface and rendered content. These are
336ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // applied as translation when updating the root render node.
337ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mInsetTop, mInsetLeft;
338ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
33957774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    // Whether the surface has insets. Used to protect opacity.
34057774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    private boolean mHasInsets;
34157774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
34258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    // Light and shadow properties specified by the theme.
34358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightY;
34458c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightZ;
34558c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightRadius;
346058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mAmbientShadowAlpha;
347058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mSpotShadowAlpha;
34858c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
3494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private long mNativeProxy;
350f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private boolean mInitialized = false;
351bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private RenderNode mRootNode;
35218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    private Choreographer mChoreographer;
3530a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private boolean mRootNodeNeedsUpdate;
354cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
355ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    // In case of multi threaded render nodes, these bounds indicate the content bounds against
356ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    // which the backdrop needs to be cropped against.
357ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private final Rect mCurrentContentBounds = new Rect();
358ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private final Rect mStagedContentBounds = new Rect();
359ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
36051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private boolean mEnabled;
36151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private boolean mRequested = true;
36251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
363b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck    ThreadedRenderer(Context context, boolean translucent) {
364ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
36558c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
36658c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
36758c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
368ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mAmbientShadowAlpha =
369ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette                (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
370ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
37158c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        a.recycle();
37258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
373e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        long rootNodePtr = nCreateRootRenderNode();
374e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mRootNode = RenderNode.adopt(rootNodePtr);
375bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        mRootNode.setClipToBounds(false);
376e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mNativeProxy = nCreateProxy(translucent, rootNodePtr);
37718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
378edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        ProcessInitializer.sInstance.init(context, mNativeProxy);
3793b20251a355c88193c439f928a84ae69483fb488John Reck
380fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        loadSystemProperties();
381cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
382cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
38351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
38451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Destroys the hardware rendering context.
38551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
386f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void destroy() {
387f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = false;
388f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(null);
389350e65206cfbd86484fcfda77bb988e270606ddaDoris Liu        nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
390cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
391cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
39251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
39351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently enabled.
39451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
39551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if hardware acceleration is in use, false otherwise.
39651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
39751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean isEnabled() {
39851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return mEnabled;
39951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
40051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
40151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
40251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently enabled.
40351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
40451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param enabled True if the hardware renderer is in use, false otherwise.
40551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
40651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    void setEnabled(boolean enabled) {
40751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        mEnabled = enabled;
40851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
40951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
41051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
41151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently request but not
41251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * necessarily enabled yet.
41351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
41451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if requested, false otherwise.
41551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
41651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean isRequested() {
41751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return mRequested;
41851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
41951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
42051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
42151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently requested but not
42251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * necessarily enabled yet.
42351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
42451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True to request hardware acceleration, false otherwise.
42551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
42651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    void setRequested(boolean requested) {
42751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        mRequested = requested;
42851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
42951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
430f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private void updateEnabledState(Surface surface) {
431f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        if (surface == null || !surface.isValid()) {
432f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(false);
433f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        } else {
434f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(mInitialized);
435f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        }
436f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
437f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
43851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
43951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Initializes the hardware renderer for the specified surface.
44051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
44151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
44251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
44351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if the initialization was successful, false otherwise.
44451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
445cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean initialize(Surface surface) throws OutOfResourcesException {
4460bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot        boolean status = !mInitialized;
447f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = true;
448f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
4490bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot        nInitialize(mNativeProxy, surface);
4505795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        return status;
451cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
452cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
45351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
45451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Initializes the hardware renderer for the specified surface and setup the
45551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * renderer for drawing, if needed. This is invoked when the ViewAncestor has
45651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * potentially lost the hardware renderer. The hardware renderer should be
45751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * reinitialized and setup when the render {@link #isRequested()} and
45851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * {@link #isEnabled()}.
45951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
46051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param width The width of the drawing surface.
46151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param height The height of the drawing surface.
46251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
46351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
46451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surfaceInsets The drawing surface insets to apply
46551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
46651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return true if the surface was initialized, false otherwise. Returning
46751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *         false might mean that the surface was already initialized.
46851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
46951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
47051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
47151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (isRequested()) {
47251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            // We lost the gl context, so recreate it.
47351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            if (!isEnabled()) {
47451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                if (initialize(surface)) {
47551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                    setup(width, height, attachInfo, surfaceInsets);
47651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                    return true;
47751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                }
47851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            }
47951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
48051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return false;
48151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
48251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
48351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
48451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Updates the hardware renderer for the specified surface.
48551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
48651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
48751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
488cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void updateSurface(Surface surface) throws OutOfResourcesException {
489f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
4904f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        nUpdateSurface(mNativeProxy, surface);
491cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
492cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
49351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
4948afcc76920499d0a384dba1470c5a377f80ed768John Reck     * Halts any current rendering into the surface. Use this if it is unclear whether
49551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * or not the surface used by the HardwareRenderer will be changing. It
4968afcc76920499d0a384dba1470c5a377f80ed768John Reck     * Suspends any rendering into the surface, but will not do any destruction.
4978afcc76920499d0a384dba1470c5a377f80ed768John Reck     *
4988afcc76920499d0a384dba1470c5a377f80ed768John Reck     * Any subsequent draws will override the pause, resuming normal operation.
49951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
50001a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    boolean pauseSurface(Surface surface) {
50101a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck        return nPauseSurface(mNativeProxy, surface);
502f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
503f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
50451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
5058afcc76920499d0a384dba1470c5a377f80ed768John Reck     * Hard stops or resumes rendering into the surface. This flag is used to
5068afcc76920499d0a384dba1470c5a377f80ed768John Reck     * determine whether or not it is safe to use the given surface *at all*
5078afcc76920499d0a384dba1470c5a377f80ed768John Reck     */
5088afcc76920499d0a384dba1470c5a377f80ed768John Reck    void setStopped(boolean stopped) {
5098afcc76920499d0a384dba1470c5a377f80ed768John Reck        nSetStopped(mNativeProxy, stopped);
5108afcc76920499d0a384dba1470c5a377f80ed768John Reck    }
5118afcc76920499d0a384dba1470c5a377f80ed768John Reck
5128afcc76920499d0a384dba1470c5a377f80ed768John Reck    /**
51351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Destroys all hardware rendering resources associated with the specified
51451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * view hierarchy.
51551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
51651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param view The root of the view hierarchy
51751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
518cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void destroyHardwareResources(View view) {
5194f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        destroyResources(view);
520f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nDestroyHardwareResources(mNativeProxy);
5214f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
5224f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
5234f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static void destroyResources(View view) {
5244f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        view.destroyHardwareResources();
5254f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
5264f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (view instanceof ViewGroup) {
5274f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            ViewGroup group = (ViewGroup) view;
5284f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
5294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            int count = group.getChildCount();
5304f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            for (int i = 0; i < count; i++) {
5314f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck                destroyResources(group.getChildAt(i));
5324f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            }
5334f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
534cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
535cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
53651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
53751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * This method should be invoked whenever the current hardware renderer
53851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * context should be reset.
53951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
54051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
54151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
542cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void invalidate(Surface surface) {
5434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        updateSurface(surface);
544cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
545cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
54651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
54751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Detaches the layer's surface texture from the GL context and releases
54851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the texture id
54951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
550918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    void detachSurfaceTexture(long hardwareLayer) {
551918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
552cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
553cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
55451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
55551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Sets up the renderer for drawing.
55651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
55751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param width The width of the drawing surface.
55851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param height The height of the drawing surface.
55951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
56051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surfaceInsets The drawing surface insets to apply
56151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
56250210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
563cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mWidth = width;
564cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mHeight = height;
56550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
5663aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette        if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
5673aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette                || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
56857774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = true;
569ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = surfaceInsets.left;
570ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = surfaceInsets.top;
571ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
572ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
57357774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
57457774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            // If the surface has insets, it can't be opaque.
57557774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            setOpaque(false);
576ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        } else {
57757774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = false;
578ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = 0;
579ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = 0;
580ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width;
581ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height;
582ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        }
58350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
584ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
58550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, mLightRadius,
586b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck                mAmbientShadowAlpha, mSpotShadowAlpha);
58750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
58850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        setLightCenter(attachInfo);
58950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    }
59050210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
59151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
59251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Updates the light position based on the position of the window.
59351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
59451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
59551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
59650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setLightCenter(AttachInfo attachInfo) {
59750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        // Adjust light position for window offsets.
59850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final Point displaySize = attachInfo.mPoint;
59950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        attachInfo.mDisplay.getRealSize(displaySize);
60050210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
60150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightY = mLightY - attachInfo.mWindowTop;
60250210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
60350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
604cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
605cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
60651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
60751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Change the HardwareRenderer's opacity
60851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
60963a06673253914510bbeebd500655008682dade1John Reck    void setOpaque(boolean opaque) {
61057774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette        nSetOpaque(mNativeProxy, opaque && !mHasInsets);
61163a06673253914510bbeebd500655008682dade1John Reck    }
61263a06673253914510bbeebd500655008682dade1John Reck
61351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
61451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Gets the current width of the surface. This is the width that the surface
61551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
61651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
61751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return the current width of the surface
61851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
619cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getWidth() {
620cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mWidth;
621cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
622cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
62351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
62451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Gets the current height of the surface. This is the height that the surface
62551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
62651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
62751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return the current width of the surface
62851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
629cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getHeight() {
630cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mHeight;
631cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
632cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
63351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
63451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Outputs extra debugging information in the specified file descriptor.
63551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
636ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
637fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        pw.flush();
638ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        int flags = 0;
639ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        for (int i = 0; i < args.length; i++) {
640ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            switch (args[i]) {
641ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "framestats":
642ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_FRAMESTATS;
643ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
644ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "reset":
645ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_RESET;
646ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
647ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            }
648fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
649ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        nDumpProfileInfo(mNativeProxy, fd, flags);
650cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
651cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
65251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
65351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Loads system properties used by the renderer. This method is invoked
65451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * whenever system properties are modified. Implementations can use this
65551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * to trigger live updates of the renderer based on properties.
65651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
65751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if a property has changed.
65851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
659cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean loadSystemProperties() {
660fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        boolean changed = nLoadSystemProperties(mNativeProxy);
66123d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        if (changed) {
66223d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck            invalidateRoot();
66323d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        }
664fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return changed;
665cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
666cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
6670a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private void updateViewTreeDisplayList(View view) {
668cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags |= View.PFLAG_DRAWN;
669cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
670cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck                == View.PFLAG_INVALIDATED;
671cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
67231a2d063df5111e730abe7d07be064690deedc34Chris Craik        view.updateDisplayListIfDirty();
6730a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        view.mRecreateDisplayList = false;
6740a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
675cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
67661375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
67770850ea258cbf91477efa57a1f1a23cc0044cc93Chris Craik        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
6780a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        updateViewTreeDisplayList(view);
6790a97330b98dd633b58dcfff405d94476c89e867dJohn Reck
6800a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
681f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik            DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
6820a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            try {
683dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                final int saveCount = canvas.save();
6840a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                canvas.translate(mInsetLeft, mInsetTop);
6850a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePreDraw(canvas);
686abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
687abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertReorderBarrier();
68831a2d063df5111e730abe7d07be064690deedc34Chris Craik                canvas.drawRenderNode(view.updateDisplayListIfDirty());
689abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertInorderBarrier();
690abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
6910a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePostDraw(canvas);
692dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                canvas.restoreToCount(saveCount);
6930a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNodeNeedsUpdate = false;
6940a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            } finally {
6950a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNode.end(canvas);
6960a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            }
69705e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        }
6980a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
6990a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
700cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
701ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
702ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
703ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * rendernode of the UI thread.
704ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node to add.
705ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param placeFront If true, the render node will be placed in front of the content node,
706ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     *                   otherwise behind the content node.
707ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
708ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void addRenderNode(RenderNode node, boolean placeFront) {
709ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
710ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
711ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
712ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
713ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Only especially added render nodes can be removed.
714ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node which was added via addRenderNode which should get removed again.
715ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
716ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void removeRenderNode(RenderNode node) {
717ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
718ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
719ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
720ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
721ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Draws a particular render node. If the node is not the content node, only the additional
722ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * nodes will get drawn and the content remains untouched.
723ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node to be drawn.
724ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
725ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void drawRenderNode(RenderNode node) {
726ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
727ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
728ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
729ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
730ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
731ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * will be prevented to overdraw this area. It will be synchronized with the draw call.
732ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * This should be updated in the content view's draw call.
733ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param left The left side of the protected bounds.
734ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param top The top side of the protected bounds.
735ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param right The right side of the protected bounds.
736ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param bottom The bottom side of the protected bounds.
737ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
738b816087962aba0019b022303330f03b897b580edSkuhne    public void setContentDrawBounds(int left, int top, int right, int bottom) {
739ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        mStagedContentBounds.set(left, top, right, bottom);
740ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
741ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
74251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
74351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Interface used to receive callbacks whenever a view is drawn by
74451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * a hardware renderer instance.
74551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
74651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    interface HardwareDrawCallbacks {
74751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        /**
74851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * Invoked before a view is drawn by a hardware renderer.
74951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * This method can be used to apply transformations to the
75051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * canvas but no drawing command should be issued.
75151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         *
75251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * @param canvas The Canvas used to render the view.
75351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         */
75451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        void onHardwarePreDraw(DisplayListCanvas canvas);
75551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
75651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        /**
75751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * Invoked after a view is drawn by a hardware renderer.
75851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * It is safe to invoke drawing commands from this method.
75951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         *
76051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * @param canvas The Canvas used to render the view.
76151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         */
76251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        void onHardwarePostDraw(DisplayListCanvas canvas);
76351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
76451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
76551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
76651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *  Indicates that the content drawn by HardwareDrawCallbacks needs to
76751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *  be updated, which will be done by the next call to draw()
76851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
7690a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    void invalidateRoot() {
7700a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        mRootNodeNeedsUpdate = true;
771bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    }
772bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
77351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
77451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Draws the specified view.
77551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
77651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param view The view to draw.
77751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo AttachInfo tied to the specified view.
77851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param callbacks Callbacks invoked when drawing happens.
77951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
78061375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
781bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        attachInfo.mIgnoreDirtyState = true;
782bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
783ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
784ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        choreographer.mFrameInfo.markDrawStart();
785fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
78661375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck        updateRootDisplayList(view, callbacks);
787ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        // The main content view was updating the content bounds and we transfer them to the
788ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        // renderer.
789ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        if (!mCurrentContentBounds.equals(mStagedContentBounds)) {
790ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne            mCurrentContentBounds.set(mStagedContentBounds);
791b816087962aba0019b022303330f03b897b580edSkuhne            nSetContentDrawBounds(mNativeProxy, mCurrentContentBounds.left,
792b816087962aba0019b022303330f03b897b580edSkuhne                    mCurrentContentBounds.top, mCurrentContentBounds.right,
793b816087962aba0019b022303330f03b897b580edSkuhne                    mCurrentContentBounds.bottom);
794ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        }
795cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
7966313b9259d37b59f3402058e197637aa3014516cJohn Reck        attachInfo.mIgnoreDirtyState = false;
7976313b9259d37b59f3402058e197637aa3014516cJohn Reck
798119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // register animating rendernodes which started animating prior to renderer
799119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // creation, which is typical for animators started prior to first draw
800119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        if (attachInfo.mPendingAnimatingRenderNodes != null) {
801119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            final int count = attachInfo.mPendingAnimatingRenderNodes.size();
802119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            for (int i = 0; i < count; i++) {
803119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                registerAnimatingRenderNode(
804119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                        attachInfo.mPendingAnimatingRenderNodes.get(i));
805119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            }
806119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes.clear();
807119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // We don't need this anymore as subsequent calls to
808119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
809119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes = null;
810119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        }
811119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
812ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
81351f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reck        int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
814aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
815aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            setEnabled(false);
816b13de07f0b26953115f4315bc7417ca87c70594bJohn Reck            attachInfo.mViewRootImpl.mSurface.release();
817aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // Invalidate since we failed to draw. This should fetch a Surface
818aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // if it is still needed or do nothing if we are no longer drawing
819aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            attachInfo.mViewRootImpl.invalidate();
820aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        }
821f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
822f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            attachInfo.mViewRootImpl.invalidate();
823f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        }
824cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
825cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
8263b20251a355c88193c439f928a84ae69483fb488John Reck    static void invokeFunctor(long functor, boolean waitForCompletion) {
8273b20251a355c88193c439f928a84ae69483fb488John Reck        nInvokeFunctor(functor, waitForCompletion);
8280d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    }
8290d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck
83051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
83151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Creates a new hardware layer. A hardware layer built by calling this
83251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * method will be treated as a texture layer, instead of as a render target.
83351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
83451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return A hardware layer
83551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
83619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    HardwareLayer createTextureLayer() {
83719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        long layer = nCreateTextureLayer(mNativeProxy);
83819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return HardwareLayer.adoptTextureLayer(this, layer);
839cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
840cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
84151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
8423e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    void buildLayer(RenderNode node) {
8433e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck        nBuildLayer(mNativeProxy, node.getNativeDisplayList());
8443e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    }
8453e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
84651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
84719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
84819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return nCopyLayerInto(mNativeProxy,
8493731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck                layer.getDeferredLayerUpdater(), bitmap);
850cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
851cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
85251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
85351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates that the specified hardware layer needs to be updated
85451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * as soon as possible.
85551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
85651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param layer The hardware layer that needs an update
85751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
85819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void pushLayerUpdate(HardwareLayer layer) {
859d72e0a339b54af0c4e731513bbad120dff694723John Reck        nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
86019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
86119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
86251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
86351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Tells the HardwareRenderer that the layer is destroyed. The renderer
86451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * should remove the layer from any update queues.
86551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
86619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void onLayerDestroyed(HardwareLayer layer) {
867d72e0a339b54af0c4e731513bbad120dff694723John Reck        nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
868cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
869cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
87051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
87151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Optional, sets the name of the renderer. Useful for debugging purposes.
87251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
87351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param name The name of this renderer, can be null
87451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
875cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void setName(String name) {
876b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck        nSetName(mNativeProxy, name);
877cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
878cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
87951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
88051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Blocks until all previously queued work has completed.
88151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
88228ad7b52e038ef0cdd89f753d9839444a434b299John Reck    void fence() {
88328ad7b52e038ef0cdd89f753d9839444a434b299John Reck        nFence(mNativeProxy);
88428ad7b52e038ef0cdd89f753d9839444a434b299John Reck    }
88528ad7b52e038ef0cdd89f753d9839444a434b299John Reck
88651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
88751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Prevents any further drawing until draw() is called. This is a signal
88851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * that the contents of the RenderNode tree are no longer safe to play back.
88951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * In practice this usually means that there are Functor pointers in the
89051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * display list that are no longer valid.
89151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
892f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void stopDrawing() {
893f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nStopDrawing(mNativeProxy);
894f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    }
895f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
89651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
89751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
89851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
899a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    public void notifyFramePending() {
900a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        nNotifyFramePending(mNativeProxy);
901a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
902a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
90351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
904119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    void registerAnimatingRenderNode(RenderNode animator) {
905119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
906119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
907119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
908e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    public void serializeDisplayListTree() {
909e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck        nSerializeDisplayListTree(mNativeProxy);
910e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    }
911e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck
91210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck    public static boolean copySurfaceInto(Surface surface, Bitmap bitmap) {
91310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck        return nCopySurfaceInto(surface, bitmap);
91410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck    }
91510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck
916119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    @Override
9174f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    protected void finalize() throws Throwable {
9184f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        try {
9194f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            nDeleteProxy(mNativeProxy);
9200ed751dd22a98f0c1f637570c5775b4f5e97d895John Reck            mNativeProxy = 0;
9214f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        } finally {
9224f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            super.finalize();
923cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        }
924cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
925cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
926edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static class ProcessInitializer {
927edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        static ProcessInitializer sInstance = new ProcessInitializer();
928edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static IBinder sProcToken;
92966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
93066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        private boolean mInitialized = false;
93166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
932edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private ProcessInitializer() {}
93366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
9343b20251a355c88193c439f928a84ae69483fb488John Reck        synchronized void init(Context context, long renderProxy) {
93566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (mInitialized) return;
936edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            mInitialized = true;
937edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initGraphicsStats(context, renderProxy);
938edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initAssetAtlas(context, renderProxy);
939edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
940edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
941edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initGraphicsStats(Context context, long renderProxy) {
942edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            try {
943828698b012e3c317073c0dbbe323d06fe9954af4John Reck                IBinder binder = ServiceManager.getService("graphicsstats");
944828698b012e3c317073c0dbbe323d06fe9954af4John Reck                if (binder == null) return;
945828698b012e3c317073c0dbbe323d06fe9954af4John Reck                IGraphicsStats graphicsStatsService = IGraphicsStats.Stub
946828698b012e3c317073c0dbbe323d06fe9954af4John Reck                        .asInterface(binder);
947828698b012e3c317073c0dbbe323d06fe9954af4John Reck                sProcToken = new Binder();
948edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                final String pkg = context.getApplicationInfo().packageName;
949828698b012e3c317073c0dbbe323d06fe9954af4John Reck                ParcelFileDescriptor pfd = graphicsStatsService.
950edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                        requestBufferForProcess(pkg, sProcToken);
951edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                nSetProcessStatsBuffer(renderProxy, pfd.getFd());
952edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                pfd.close();
953828698b012e3c317073c0dbbe323d06fe9954af4John Reck            } catch (Throwable t) {
954828698b012e3c317073c0dbbe323d06fe9954af4John Reck                Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
955edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            }
956edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
957edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
958edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initAssetAtlas(Context context, long renderProxy) {
95966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IBinder binder = ServiceManager.getService("assetatlas");
96066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (binder == null) return;
96166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
96266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
96366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            try {
96466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                if (atlas.isCompatible(android.os.Process.myPpid())) {
96566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    GraphicBuffer buffer = atlas.getBuffer();
96666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    if (buffer != null) {
96766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        long[] map = atlas.getMap();
96866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (map != null) {
9693b20251a355c88193c439f928a84ae69483fb488John Reck                            nSetAtlas(renderProxy, buffer, map);
97066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
97166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // If IAssetAtlas is not the same class as the IBinder
97266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // we are using a remote service and we can safely
97366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // destroy the graphic buffer
97466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (atlas.getClass() != binder.getClass()) {
97566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                            buffer.destroy();
97666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
97766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    }
97866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                }
97966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            } catch (RemoteException e) {
98066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                Log.w(LOG_TAG, "Could not acquire atlas", e);
98166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            }
98266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        }
98366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    }
98466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
985910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    void addFrameMetricsObserver(FrameMetricsObserver observer) {
986910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
987910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        observer.mNative = new VirtualRefBasePtr(nativeObserver);
98806f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
98906f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
990910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    void removeFrameMetricsObserver(FrameMetricsObserver observer) {
991910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
992910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales        observer.mNative = null;
99306f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales    }
99406f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
99584a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    static native void setupShadersDiskCache(String cacheFile);
99603d8f76836c5950374bc9030a78706d25ac233e9Michael Lentine    static native void setupVulkanLayerPath(String layerPath);
99784a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
9983b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
999edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nSetProcessStatsBuffer(long nativeProxy, int fd);
1000cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
1001e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateRootRenderNode();
1002e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateProxy(boolean translucent, long rootRenderNode);
10034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nDeleteProxy(long nativeProxy);
1004cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
1005e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    private static native boolean nLoadSystemProperties(long nativeProxy);
1006b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    private static native void nSetName(long nativeProxy, String name);
100718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
10080bcd0cb6b1193168fa2840855195347488daab9eThomas Buhot    private static native void nInitialize(long nativeProxy, Surface window);
10094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nUpdateSurface(long nativeProxy, Surface window);
101001a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    private static native boolean nPauseSurface(long nativeProxy, Surface window);
10118afcc76920499d0a384dba1470c5a377f80ed768John Reck    private static native void nSetStopped(long nativeProxy, boolean stopped);
1012797b95b26bbb7557678af78b9a2a61830158920fChris Craik    private static native void nSetup(long nativeProxy, int width, int height,
101350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
101450210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    private static native void nSetLightCenter(long nativeProxy,
101550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightX, float lightY, float lightZ);
101663a06673253914510bbeebd500655008682dade1John Reck    private static native void nSetOpaque(long nativeProxy, boolean opaque);
101751f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reck    private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
1018350e65206cfbd86484fcfda77bb988e270606ddaDoris Liu    private static native void nDestroy(long nativeProxy, long rootRenderNode);
1019119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
1020cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
10213b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
102219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
102319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateTextureLayer(long nativeProxy);
10243e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    private static native void nBuildLayer(long nativeProxy, long node);
10253731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
1026d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nPushLayerUpdate(long nativeProxy, long layer);
1027d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nCancelLayerUpdate(long nativeProxy, long layer);
1028918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
102928ad7b52e038ef0cdd89f753d9839444a434b299John Reck
1030f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nDestroyHardwareResources(long nativeProxy);
1031f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nTrimMemory(int level);
10322507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    private static native void nOverrideProperty(String name, String value);
1033e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck
103428ad7b52e038ef0cdd89f753d9839444a434b299John Reck    private static native void nFence(long nativeProxy);
1035f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nStopDrawing(long nativeProxy);
1036a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    private static native void nNotifyFramePending(long nativeProxy);
1037fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
1038e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    private static native void nSerializeDisplayListTree(long nativeProxy);
1039e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck
1040ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
1041ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            @DumpFlags int dumpFlags);
1042edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nDumpProfileData(byte[] data, FileDescriptor fd);
1043ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
1044ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
1045ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne             boolean placeFront);
1046ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
1047ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
1048b816087962aba0019b022303330f03b897b580edSkuhne    private static native void nSetContentDrawBounds(long nativeProxy, int left,
1049ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne             int top, int right, int bottom);
105006f5bc70a667a02b14e31d3f53f91d3661e30666Andres Morales
1051910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
1052910beb8f5d9042163e2ad0dbb744d9f147db9604Andres Morales    private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
105310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck
105410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck    private static native boolean nCopySurfaceInto(Surface surface, Bitmap bitmap);
1055cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}
1056