ThreadedRenderer.java revision 51aaf906f9f5fb2f117f5ccfae8be6974f7cb903
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;
2766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.IBinder;
28edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reckimport android.os.ParcelFileDescriptor;
2966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.RemoteException;
3066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.ServiceManager;
31cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.os.Trace;
3266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.util.Log;
33cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.Surface.OutOfResourcesException;
34cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.View.AttachInfo;
35cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
36ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport com.android.internal.R;
37ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
3851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reckimport java.io.File;
39fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckimport java.io.FileDescriptor;
40cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport java.io.PrintWriter;
41ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.Retention;
42ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.RetentionPolicy;
43cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
44cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/**
45cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Hardware renderer that proxies the rendering to a render thread. Most calls
464f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * are currently synchronous.
47cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
48cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * The UI thread can block on the RenderThread, but RenderThread must never
49cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * block on the UI thread.
50cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * by the lifecycle of the RenderProxy.
544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
55cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Note that although currently the EGL context & surfaces are created & managed
56cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * by the render thread, the goal is to move that into a shared structure that can
57cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * be managed by both threads. EGLSurface creation & deletion should ideally be
58cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * done on the UI thread and not the RenderThread to avoid stalling the
59cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * RenderThread with surface buffer allocation.
60cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
61cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * @hide
62cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
6351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reckpublic final class ThreadedRenderer {
6451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private static final String LOG_TAG = "ThreadedRenderer";
6551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
6651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
6751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Name of the file that holds the shaders cache.
6851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
6951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
7051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
7151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
7251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to enable or disable dirty regions invalidation.
7351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
7451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * The default value of this property is assumed to be true.
7551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
7651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
7751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable partial invalidates
7851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable partial invalidates
7951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
8051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    static final String RENDER_DIRTY_REGIONS_PROPERTY = "debug.hwui.render_dirty_regions";
8151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
8251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
8351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to enable or disable hardware rendering profiling.
8451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * The default value of this property is assumed to be false.
8551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
8651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * When profiling is enabled, the adb shell dumpsys gfxinfo command will
8751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * output extra information about the time taken to execute by the last
8851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * frames.
8951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
9051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
9151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable profiling
9251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "visual_bars", to enable profiling and visualize the results on screen
9351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable profiling
9451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
9551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @see #PROFILE_PROPERTY_VISUALIZE_BARS
9651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
9751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
9851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
9951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String PROFILE_PROPERTY = "debug.hwui.profile";
10051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
10151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
10251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Value for {@link #PROFILE_PROPERTY}. When the property is set to this
10351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * value, profiling data will be visualized on screen as a bar chart.
10451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
10551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
10651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
10751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars";
10851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
10951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
11051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to specify the number of frames to be used
11151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * when doing hardware rendering profiling.
11251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * The default value of this property is #PROFILE_MAX_FRAMES.
11351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
11451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * When profiling is enabled, the adb shell dumpsys gfxinfo command will
11551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * output extra information about the time taken to execute by the last
11651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * frames.
11751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
11851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
11951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "60", to set the limit of frames to 60
12051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
12151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes";
12251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
12351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
12451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * System property used to debug EGL configuration choice.
12551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
12651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
12751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "choice", print the chosen configuration only
12851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "all", print all possible configurations
12951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
13051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config";
13151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
13251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
13351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Turn on to draw dirty regions every other frame.
13451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
13551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
13651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable dirty regions debugging
13751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable dirty regions debugging
13851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
13951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
14051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
14151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
14251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
14351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
14451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Turn on to flash hardware layers when they update.
14551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
14651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
14751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "true", to enable hardware layers updates debugging
14851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable hardware layers updates debugging
14951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
15051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
15151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
15251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
15351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            "debug.hwui.show_layers_updates";
15451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
15551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
15651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Controls overdraw debugging.
15751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
15851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
15951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "false", to disable overdraw debugging
16051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "show", to show overdraw areas on screen
16151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "count", to display an overdraw counter
16251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
16351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
16451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
16551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
16651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
16751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
16851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
16951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * value, overdraw will be shown on screen by coloring pixels.
17051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
17151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
17251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
17351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String OVERDRAW_PROPERTY_SHOW = "show";
17451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
17551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
17651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Turn on to debug non-rectangular clip operations.
17751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
17851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Possible values:
17951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "hide", to disable this debug mode
18051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "highlight", highlight drawing commands tested against a non-rectangular clip
18151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * "stencil", renders the clip region on screen when set
18251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
18351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
18451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
18551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
18651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            "debug.hwui.show_non_rect_clip";
18751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
18851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
18951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * A process can set this flag to false to prevent the use of hardware
19051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * rendering.
19151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
19251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
19351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
19451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean sRendererDisabled = false;
19551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
19651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
19751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Further hardware renderer disabling for the system process.
19851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
19951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
20051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
20151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean sSystemRendererDisabled = false;
20251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
20351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
20451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Invoke this method to disable hardware rendering in the current process.
20551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
20651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
20751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
20851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void disable(boolean system) {
20951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        sRendererDisabled = true;
21051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (system) {
21151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            sSystemRendererDisabled = true;
21251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
21351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
21451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
21551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean sTrimForeground = false;
21651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
21751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
21851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Controls whether or not the hardware renderer should aggressively
21951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * trim memory. Note that this must not be set for any process that
22051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * uses WebView! This should be only used by system_process or similar
22151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * that do not go into the background.
22251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
22351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void enableForegroundTrimming() {
22451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        sTrimForeground = true;
22551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
22651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
22751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
22851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is available under any form for
22951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the view hierarchy.
23051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
23151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if the view hierarchy can potentially be hardware accelerated,
23251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *         false otherwise
23351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
23451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static boolean isAvailable() {
23551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return DisplayListCanvas.isAvailable();
23651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
23751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
23851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
23951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Sets the directory to use as a persistent storage for hardware rendering
24051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * resources.
24151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
24251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param cacheDir A directory the current process can write to
24351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
24451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @hide
24551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
24651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void setupDiskCache(File cacheDir) {
24751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
24851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
24951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
25051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
25151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Creates a hardware renderer using OpenGL.
25251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
25351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param translucent True if the surface is translucent, false otherwise
25451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
25551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return A hardware renderer backed by OpenGL.
25651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
25751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static ThreadedRenderer create(Context context, boolean translucent) {
25851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        ThreadedRenderer renderer = null;
25951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (DisplayListCanvas.isAvailable()) {
26051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            renderer = new ThreadedRenderer(context, translucent);
26151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
26251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return renderer;
26351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
26451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
26551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
26651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Invoke this method when the system is running out of memory. This
26751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * method will attempt to recover as much memory as possible, based on
26851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the specified hint.
26951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
27051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param level Hint about the amount of memory that should be trimmed,
27151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *              see {@link android.content.ComponentCallbacks}
27251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
27351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void trimMemory(int level) {
27451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        nTrimMemory(level);
27551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
27651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
27751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void overrideProperty(@NonNull String name, @NonNull String value) {
27851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (name == null || value == null) {
27951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            throw new IllegalArgumentException("name and value must be non-null");
28051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
28151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        nOverrideProperty(name, value);
28251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
28351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
28451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    public static void dumpProfileData(byte[] data, FileDescriptor fd) {
28551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        nDumpProfileData(data, fd);
28651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
287cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
288f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Keep in sync with DrawFrameTask.h SYNC_* flags
289f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Nothing interesting to report
290cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_OK = 0;
291f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Needs a ViewRoot invalidate
292cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
293aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck    // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
294aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck    private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
295f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck
296fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static final String[] VISUALIZERS = {
297fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        PROFILE_PROPERTY_VISUALIZE_BARS,
298fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    };
299fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
300ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_FRAMESTATS   = 1 << 0;
301ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_RESET        = 1 << 1;
302ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
303ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @IntDef(flag = true, value = {
304ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET })
305ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @Retention(RetentionPolicy.SOURCE)
306ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    public @interface DumpFlags {}
307ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
308ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Size of the rendered content.
309cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private int mWidth, mHeight;
310ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
311ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Actual size of the drawing surface.
312ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mSurfaceWidth, mSurfaceHeight;
313ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
314ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Insets between the drawing surface and rendered content. These are
315ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // applied as translation when updating the root render node.
316ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mInsetTop, mInsetLeft;
317ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
31857774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    // Whether the surface has insets. Used to protect opacity.
31957774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    private boolean mHasInsets;
32057774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
32158c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    // Light and shadow properties specified by the theme.
32258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightY;
32358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightZ;
32458c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightRadius;
325058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mAmbientShadowAlpha;
326058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mSpotShadowAlpha;
32758c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
3284f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private long mNativeProxy;
329f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private boolean mInitialized = false;
330bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private RenderNode mRootNode;
33118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    private Choreographer mChoreographer;
3320a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private boolean mRootNodeNeedsUpdate;
333cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
334ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    // In case of multi threaded render nodes, these bounds indicate the content bounds against
335ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    // which the backdrop needs to be cropped against.
336ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private final Rect mCurrentContentBounds = new Rect();
337ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private final Rect mStagedContentBounds = new Rect();
338ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
33951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private boolean mEnabled;
34051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    private boolean mRequested = true;
34151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
342b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck    ThreadedRenderer(Context context, boolean translucent) {
343ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
34458c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
34558c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
34658c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
347ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mAmbientShadowAlpha =
348ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette                (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
349ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
35058c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        a.recycle();
35158c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
352e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        long rootNodePtr = nCreateRootRenderNode();
353e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mRootNode = RenderNode.adopt(rootNodePtr);
354bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        mRootNode.setClipToBounds(false);
355e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mNativeProxy = nCreateProxy(translucent, rootNodePtr);
35618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
357edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        ProcessInitializer.sInstance.init(context, mNativeProxy);
3583b20251a355c88193c439f928a84ae69483fb488John Reck
359fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        loadSystemProperties();
360cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
361cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
36251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
36351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Destroys the hardware rendering context.
36451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
365f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void destroy() {
366f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = false;
367f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(null);
36817035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck        nDestroy(mNativeProxy);
369cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
370cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
37151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
37251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently enabled.
37351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
37451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if hardware acceleration is in use, false otherwise.
37551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
37651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean isEnabled() {
37751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return mEnabled;
37851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
37951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
38051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
38151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently enabled.
38251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
38351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param enabled True if the hardware renderer is in use, false otherwise.
38451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
38551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    void setEnabled(boolean enabled) {
38651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        mEnabled = enabled;
38751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
38851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
38951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
39051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently request but not
39151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * necessarily enabled yet.
39251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
39351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if requested, false otherwise.
39451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
39551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean isRequested() {
39651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return mRequested;
39751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
39851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
39951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
40051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates whether hardware acceleration is currently requested but not
40151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * necessarily enabled yet.
40251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
40351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True to request hardware acceleration, false otherwise.
40451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
40551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    void setRequested(boolean requested) {
40651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        mRequested = requested;
40751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
40851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
409f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private void updateEnabledState(Surface surface) {
410f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        if (surface == null || !surface.isValid()) {
411f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(false);
412f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        } else {
413f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(mInitialized);
414f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        }
415f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
416f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
41751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
41851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Initializes the hardware renderer for the specified surface.
41951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
42051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
42151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
42251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if the initialization was successful, false otherwise.
42351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
424cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean initialize(Surface surface) throws OutOfResourcesException {
425f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = true;
426f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
4275795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        boolean status = nInitialize(mNativeProxy, surface);
4285795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        return status;
429cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
430cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
43151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
43251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Initializes the hardware renderer for the specified surface and setup the
43351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * renderer for drawing, if needed. This is invoked when the ViewAncestor has
43451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * potentially lost the hardware renderer. The hardware renderer should be
43551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * reinitialized and setup when the render {@link #isRequested()} and
43651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * {@link #isEnabled()}.
43751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
43851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param width The width of the drawing surface.
43951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param height The height of the drawing surface.
44051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
44151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
44251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surfaceInsets The drawing surface insets to apply
44351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
44451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return true if the surface was initialized, false otherwise. Returning
44551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *         false might mean that the surface was already initialized.
44651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
44751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
44851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
44951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        if (isRequested()) {
45051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            // We lost the gl context, so recreate it.
45151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            if (!isEnabled()) {
45251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                if (initialize(surface)) {
45351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                    setup(width, height, attachInfo, surfaceInsets);
45451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                    return true;
45551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck                }
45651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck            }
45751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        }
45851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        return false;
45951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
46051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
46151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
46251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Updates the hardware renderer for the specified surface.
46351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
46451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
46551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
466cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void updateSurface(Surface surface) throws OutOfResourcesException {
467f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
4684f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        nUpdateSurface(mNativeProxy, surface);
469cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
470cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
47151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
47251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Stops any rendering into the surface. Use this if it is unclear whether
47351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * or not the surface used by the HardwareRenderer will be changing. It
47451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Suspends any rendering into the surface, but will not do any destruction
47551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
47601a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    boolean pauseSurface(Surface surface) {
47701a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck        return nPauseSurface(mNativeProxy, surface);
478f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
479f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
48051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
48151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Destroys all hardware rendering resources associated with the specified
48251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * view hierarchy.
48351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
48451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param view The root of the view hierarchy
48551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
486cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void destroyHardwareResources(View view) {
4874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        destroyResources(view);
488f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nDestroyHardwareResources(mNativeProxy);
4894f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
4904f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
4914f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static void destroyResources(View view) {
4924f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        view.destroyHardwareResources();
4934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
4944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (view instanceof ViewGroup) {
4954f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            ViewGroup group = (ViewGroup) view;
4964f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
4974f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            int count = group.getChildCount();
4984f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            for (int i = 0; i < count; i++) {
4994f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck                destroyResources(group.getChildAt(i));
5004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            }
5014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
502cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
503cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
50451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
50551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * This method should be invoked whenever the current hardware renderer
50651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * context should be reset.
50751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
50851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surface The surface to hardware accelerate
50951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
510cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void invalidate(Surface surface) {
5114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        updateSurface(surface);
512cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
513cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
51451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
51551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Detaches the layer's surface texture from the GL context and releases
51651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * the texture id
51751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
518918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    void detachSurfaceTexture(long hardwareLayer) {
519918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
520cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
521cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
52251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
52351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Sets up the renderer for drawing.
52451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
52551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param width The width of the drawing surface.
52651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param height The height of the drawing surface.
52751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
52851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param surfaceInsets The drawing surface insets to apply
52951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
53050210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
531cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mWidth = width;
532cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mHeight = height;
53350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
5343aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette        if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
5353aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette                || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
53657774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = true;
537ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = surfaceInsets.left;
538ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = surfaceInsets.top;
539ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
540ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
54157774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
54257774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            // If the surface has insets, it can't be opaque.
54357774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            setOpaque(false);
544ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        } else {
54557774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = false;
546ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = 0;
547ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = 0;
548ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width;
549ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height;
550ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        }
55150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
552ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
55350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, mLightRadius,
554b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck                mAmbientShadowAlpha, mSpotShadowAlpha);
55550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
55650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        setLightCenter(attachInfo);
55750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    }
55850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
55951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
56051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Updates the light position based on the position of the window.
56151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
56251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo Information about the window.
56351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
56450210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setLightCenter(AttachInfo attachInfo) {
56550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        // Adjust light position for window offsets.
56650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final Point displaySize = attachInfo.mPoint;
56750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        attachInfo.mDisplay.getRealSize(displaySize);
56850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
56950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightY = mLightY - attachInfo.mWindowTop;
57050210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
57150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
572cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
573cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
57451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
57551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Change the HardwareRenderer's opacity
57651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
57763a06673253914510bbeebd500655008682dade1John Reck    void setOpaque(boolean opaque) {
57857774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette        nSetOpaque(mNativeProxy, opaque && !mHasInsets);
57963a06673253914510bbeebd500655008682dade1John Reck    }
58063a06673253914510bbeebd500655008682dade1John Reck
58151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
58251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Gets the current width of the surface. This is the width that the surface
58351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
58451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
58551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return the current width of the surface
58651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
587cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getWidth() {
588cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mWidth;
589cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
590cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
59151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
59251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Gets the current height of the surface. This is the height that the surface
59351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
59451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
59551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return the current width of the surface
59651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
597cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getHeight() {
598cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mHeight;
599cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
600cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
60151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
60251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Outputs extra debugging information in the specified file descriptor.
60351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
604ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
605fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        pw.flush();
606ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        int flags = 0;
607ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        for (int i = 0; i < args.length; i++) {
608ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            switch (args[i]) {
609ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "framestats":
610ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_FRAMESTATS;
611ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
612ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "reset":
613ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_RESET;
614ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
615ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            }
616fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
617ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        nDumpProfileInfo(mNativeProxy, fd, flags);
618cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
619cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
62051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
62151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Loads system properties used by the renderer. This method is invoked
62251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * whenever system properties are modified. Implementations can use this
62351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * to trigger live updates of the renderer based on properties.
62451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
62551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return True if a property has changed.
62651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
627cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean loadSystemProperties() {
628fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        boolean changed = nLoadSystemProperties(mNativeProxy);
62923d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        if (changed) {
63023d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck            invalidateRoot();
63123d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        }
632fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return changed;
633cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
634cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
6350a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private void updateViewTreeDisplayList(View view) {
636cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags |= View.PFLAG_DRAWN;
637cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
638cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck                == View.PFLAG_INVALIDATED;
639cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
64031a2d063df5111e730abe7d07be064690deedc34Chris Craik        view.updateDisplayListIfDirty();
6410a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        view.mRecreateDisplayList = false;
6420a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
643cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
64461375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
64570850ea258cbf91477efa57a1f1a23cc0044cc93Chris Craik        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
6460a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        updateViewTreeDisplayList(view);
6470a97330b98dd633b58dcfff405d94476c89e867dJohn Reck
6480a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
649f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik            DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
6500a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            try {
651dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                final int saveCount = canvas.save();
6520a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                canvas.translate(mInsetLeft, mInsetTop);
6530a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePreDraw(canvas);
654abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
655abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertReorderBarrier();
65631a2d063df5111e730abe7d07be064690deedc34Chris Craik                canvas.drawRenderNode(view.updateDisplayListIfDirty());
657abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertInorderBarrier();
658abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
6590a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePostDraw(canvas);
660dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                canvas.restoreToCount(saveCount);
6610a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNodeNeedsUpdate = false;
6620a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            } finally {
6630a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNode.end(canvas);
6640a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            }
66505e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        }
6660a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
6670a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
668cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
669ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
670ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
671ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * rendernode of the UI thread.
672ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node to add.
673ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param placeFront If true, the render node will be placed in front of the content node,
674ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     *                   otherwise behind the content node.
675ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
676ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void addRenderNode(RenderNode node, boolean placeFront) {
677ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
678ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
679ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
680ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
681ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Only especially added render nodes can be removed.
682ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node which was added via addRenderNode which should get removed again.
683ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
684ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void removeRenderNode(RenderNode node) {
685ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
686ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
687ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
688ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
689ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * Draws a particular render node. If the node is not the content node, only the additional
690ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * nodes will get drawn and the content remains untouched.
691ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param node The node to be drawn.
692ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
693ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    public void drawRenderNode(RenderNode node) {
694ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
695ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
696ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
697ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    /**
698ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
699ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * will be prevented to overdraw this area. It will be synchronized with the draw call.
700ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * This should be updated in the content view's draw call.
701ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param left The left side of the protected bounds.
702ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param top The top side of the protected bounds.
703ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param right The right side of the protected bounds.
704ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     * @param bottom The bottom side of the protected bounds.
705ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne     */
706b816087962aba0019b022303330f03b897b580edSkuhne    public void setContentDrawBounds(int left, int top, int right, int bottom) {
707ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        mStagedContentBounds.set(left, top, right, bottom);
708ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    }
709ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
71051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
71151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Interface used to receive callbacks whenever a view is drawn by
71251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * a hardware renderer instance.
71351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
71451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    interface HardwareDrawCallbacks {
71551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        /**
71651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * Invoked before a view is drawn by a hardware renderer.
71751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * This method can be used to apply transformations to the
71851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * canvas but no drawing command should be issued.
71951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         *
72051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * @param canvas The Canvas used to render the view.
72151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         */
72251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        void onHardwarePreDraw(DisplayListCanvas canvas);
72351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
72451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        /**
72551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * Invoked after a view is drawn by a hardware renderer.
72651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * It is safe to invoke drawing commands from this method.
72751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         *
72851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         * @param canvas The Canvas used to render the view.
72951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck         */
73051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck        void onHardwarePostDraw(DisplayListCanvas canvas);
73151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    }
73251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
73351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
73451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *  Indicates that the content drawn by HardwareDrawCallbacks needs to
73551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *  be updated, which will be done by the next call to draw()
73651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
7370a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    void invalidateRoot() {
7380a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        mRootNodeNeedsUpdate = true;
739bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    }
740bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
74151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
74251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Draws the specified view.
74351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
74451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param view The view to draw.
74551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param attachInfo AttachInfo tied to the specified view.
74651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param callbacks Callbacks invoked when drawing happens.
74751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
74861375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
749bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        attachInfo.mIgnoreDirtyState = true;
750bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
751ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
752ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        choreographer.mFrameInfo.markDrawStart();
753fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
75461375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck        updateRootDisplayList(view, callbacks);
755ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        // The main content view was updating the content bounds and we transfer them to the
756ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        // renderer.
757ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        if (!mCurrentContentBounds.equals(mStagedContentBounds)) {
758ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne            mCurrentContentBounds.set(mStagedContentBounds);
759b816087962aba0019b022303330f03b897b580edSkuhne            nSetContentDrawBounds(mNativeProxy, mCurrentContentBounds.left,
760b816087962aba0019b022303330f03b897b580edSkuhne                    mCurrentContentBounds.top, mCurrentContentBounds.right,
761b816087962aba0019b022303330f03b897b580edSkuhne                    mCurrentContentBounds.bottom);
762ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne        }
763cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
7646313b9259d37b59f3402058e197637aa3014516cJohn Reck        attachInfo.mIgnoreDirtyState = false;
7656313b9259d37b59f3402058e197637aa3014516cJohn Reck
766119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // register animating rendernodes which started animating prior to renderer
767119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // creation, which is typical for animators started prior to first draw
768119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        if (attachInfo.mPendingAnimatingRenderNodes != null) {
769119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            final int count = attachInfo.mPendingAnimatingRenderNodes.size();
770119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            for (int i = 0; i < count; i++) {
771119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                registerAnimatingRenderNode(
772119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                        attachInfo.mPendingAnimatingRenderNodes.get(i));
773119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            }
774119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes.clear();
775119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // We don't need this anymore as subsequent calls to
776119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
777119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes = null;
778119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        }
779119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
780ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
781ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
782aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
783aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            setEnabled(false);
784b13de07f0b26953115f4315bc7417ca87c70594bJohn Reck            attachInfo.mViewRootImpl.mSurface.release();
785aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // Invalidate since we failed to draw. This should fetch a Surface
786aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // if it is still needed or do nothing if we are no longer drawing
787aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            attachInfo.mViewRootImpl.invalidate();
788aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        }
789f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
790f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            attachInfo.mViewRootImpl.invalidate();
791f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        }
792cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
793cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
7943b20251a355c88193c439f928a84ae69483fb488John Reck    static void invokeFunctor(long functor, boolean waitForCompletion) {
7953b20251a355c88193c439f928a84ae69483fb488John Reck        nInvokeFunctor(functor, waitForCompletion);
7960d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    }
7970d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck
79851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
79951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Creates a new hardware layer. A hardware layer built by calling this
80051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * method will be treated as a texture layer, instead of as a render target.
80151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
80251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @return A hardware layer
80351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
80419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    HardwareLayer createTextureLayer() {
80519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        long layer = nCreateTextureLayer(mNativeProxy);
80619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return HardwareLayer.adoptTextureLayer(this, layer);
807cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
808cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
80951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
8103e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    void buildLayer(RenderNode node) {
8113e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck        nBuildLayer(mNativeProxy, node.getNativeDisplayList());
8123e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    }
8133e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
81451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
81519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
81619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return nCopyLayerInto(mNativeProxy,
8173731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck                layer.getDeferredLayerUpdater(), bitmap);
818cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
819cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
82051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
82151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Indicates that the specified hardware layer needs to be updated
82251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * as soon as possible.
82351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
82451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param layer The hardware layer that needs an update
82551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
82619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void pushLayerUpdate(HardwareLayer layer) {
827d72e0a339b54af0c4e731513bbad120dff694723John Reck        nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
82819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
82919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
83051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
83151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Tells the HardwareRenderer that the layer is destroyed. The renderer
83251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * should remove the layer from any update queues.
83351aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
83419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void onLayerDestroyed(HardwareLayer layer) {
835d72e0a339b54af0c4e731513bbad120dff694723John Reck        nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
836cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
837cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
83851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
83951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Optional, sets the name of the renderer. Useful for debugging purposes.
84051aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     *
84151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * @param name The name of this renderer, can be null
84251aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
843cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void setName(String name) {
844b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck        nSetName(mNativeProxy, name);
845cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
846cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
84751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
84851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Blocks until all previously queued work has completed.
84951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
85028ad7b52e038ef0cdd89f753d9839444a434b299John Reck    void fence() {
85128ad7b52e038ef0cdd89f753d9839444a434b299John Reck        nFence(mNativeProxy);
85228ad7b52e038ef0cdd89f753d9839444a434b299John Reck    }
85328ad7b52e038ef0cdd89f753d9839444a434b299John Reck
85451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
85551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Prevents any further drawing until draw() is called. This is a signal
85651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * that the contents of the RenderNode tree are no longer safe to play back.
85751aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * In practice this usually means that there are Functor pointers in the
85851aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * display list that are no longer valid.
85951aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
860f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void stopDrawing() {
861f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nStopDrawing(mNativeProxy);
862f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    }
863f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
86451aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck    /**
86551aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
86651aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck     */
867a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    public void notifyFramePending() {
868a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        nNotifyFramePending(mNativeProxy);
869a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
870a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
87151aaf906f9f5fb2f117f5ccfae8be6974f7cb903John Reck
872119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    void registerAnimatingRenderNode(RenderNode animator) {
873119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
874119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
875119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
876e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    public void serializeDisplayListTree() {
877e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck        nSerializeDisplayListTree(mNativeProxy);
878e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    }
879e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck
880119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    @Override
8814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    protected void finalize() throws Throwable {
8824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        try {
8834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            nDeleteProxy(mNativeProxy);
8840ed751dd22a98f0c1f637570c5775b4f5e97d895John Reck            mNativeProxy = 0;
8854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        } finally {
8864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            super.finalize();
887cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        }
888cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
889cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
890edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static class ProcessInitializer {
891edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        static ProcessInitializer sInstance = new ProcessInitializer();
892edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static IBinder sProcToken;
89366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
89466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        private boolean mInitialized = false;
89566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
896edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private ProcessInitializer() {}
89766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
8983b20251a355c88193c439f928a84ae69483fb488John Reck        synchronized void init(Context context, long renderProxy) {
89966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (mInitialized) return;
900edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            mInitialized = true;
901edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initGraphicsStats(context, renderProxy);
902edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initAssetAtlas(context, renderProxy);
903edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
904edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
905edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initGraphicsStats(Context context, long renderProxy) {
906edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            try {
907828698b012e3c317073c0dbbe323d06fe9954af4John Reck                IBinder binder = ServiceManager.getService("graphicsstats");
908828698b012e3c317073c0dbbe323d06fe9954af4John Reck                if (binder == null) return;
909828698b012e3c317073c0dbbe323d06fe9954af4John Reck                IGraphicsStats graphicsStatsService = IGraphicsStats.Stub
910828698b012e3c317073c0dbbe323d06fe9954af4John Reck                        .asInterface(binder);
911828698b012e3c317073c0dbbe323d06fe9954af4John Reck                sProcToken = new Binder();
912edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                final String pkg = context.getApplicationInfo().packageName;
913828698b012e3c317073c0dbbe323d06fe9954af4John Reck                ParcelFileDescriptor pfd = graphicsStatsService.
914edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                        requestBufferForProcess(pkg, sProcToken);
915edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                nSetProcessStatsBuffer(renderProxy, pfd.getFd());
916edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                pfd.close();
917828698b012e3c317073c0dbbe323d06fe9954af4John Reck            } catch (Throwable t) {
918828698b012e3c317073c0dbbe323d06fe9954af4John Reck                Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
919edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            }
920edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
921edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
922edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initAssetAtlas(Context context, long renderProxy) {
92366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IBinder binder = ServiceManager.getService("assetatlas");
92466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (binder == null) return;
92566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
92666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
92766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            try {
92866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                if (atlas.isCompatible(android.os.Process.myPpid())) {
92966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    GraphicBuffer buffer = atlas.getBuffer();
93066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    if (buffer != null) {
93166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        long[] map = atlas.getMap();
93266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (map != null) {
9333b20251a355c88193c439f928a84ae69483fb488John Reck                            nSetAtlas(renderProxy, buffer, map);
93466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
93566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // If IAssetAtlas is not the same class as the IBinder
93666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // we are using a remote service and we can safely
93766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // destroy the graphic buffer
93866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (atlas.getClass() != binder.getClass()) {
93966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                            buffer.destroy();
94066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
94166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    }
94266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                }
94366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            } catch (RemoteException e) {
94466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                Log.w(LOG_TAG, "Could not acquire atlas", e);
94566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            }
94666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        }
94766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    }
94866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
94984a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    static native void setupShadersDiskCache(String cacheFile);
95084a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
9513b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
952edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nSetProcessStatsBuffer(long nativeProxy, int fd);
953cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
954e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateRootRenderNode();
955e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateProxy(boolean translucent, long rootRenderNode);
9564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nDeleteProxy(long nativeProxy);
957cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
958e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    private static native boolean nLoadSystemProperties(long nativeProxy);
959b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    private static native void nSetName(long nativeProxy, String name);
96018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
9614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native boolean nInitialize(long nativeProxy, Surface window);
9624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nUpdateSurface(long nativeProxy, Surface window);
96301a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    private static native boolean nPauseSurface(long nativeProxy, Surface window);
964797b95b26bbb7557678af78b9a2a61830158920fChris Craik    private static native void nSetup(long nativeProxy, int width, int height,
96550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
96650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    private static native void nSetLightCenter(long nativeProxy,
96750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightX, float lightY, float lightZ);
96863a06673253914510bbeebd500655008682dade1John Reck    private static native void nSetOpaque(long nativeProxy, boolean opaque);
969ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
97017035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck    private static native void nDestroy(long nativeProxy);
971119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
972cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
9733b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
97419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
97519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateTextureLayer(long nativeProxy);
9763e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    private static native void nBuildLayer(long nativeProxy, long node);
9773731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
978d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nPushLayerUpdate(long nativeProxy, long layer);
979d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nCancelLayerUpdate(long nativeProxy, long layer);
980918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
98128ad7b52e038ef0cdd89f753d9839444a434b299John Reck
982f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nDestroyHardwareResources(long nativeProxy);
983f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nTrimMemory(int level);
9842507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    private static native void nOverrideProperty(String name, String value);
985e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck
98628ad7b52e038ef0cdd89f753d9839444a434b299John Reck    private static native void nFence(long nativeProxy);
987f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nStopDrawing(long nativeProxy);
988a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    private static native void nNotifyFramePending(long nativeProxy);
989fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
990e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck    private static native void nSerializeDisplayListTree(long nativeProxy);
991e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck
992ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
993ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            @DumpFlags int dumpFlags);
994edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nDumpProfileData(byte[] data, FileDescriptor fd);
995ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne
996ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
997ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne             boolean placeFront);
998ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
999ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne    private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
1000b816087962aba0019b022303330f03b897b580edSkuhne    private static native void nSetContentDrawBounds(long nativeProxy, int left,
1001ea7a7fb75acb7305eb774ca7bc7e96103bd49323Skuhne             int top, int right, int bottom);
1002cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}
1003