ThreadedRenderer.java revision 50210d912925aef14e4ce69be82e4949122a3cd9
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
38fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckimport java.io.FileDescriptor;
39cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport java.io.PrintWriter;
40ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.Retention;
41ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.RetentionPolicy;
42cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
43cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/**
44cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Hardware renderer that proxies the rendering to a render thread. Most calls
454f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * are currently synchronous.
46cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
47cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * The UI thread can block on the RenderThread, but RenderThread must never
48cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * block on the UI thread.
49cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * by the lifecycle of the RenderProxy.
534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
54cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Note that although currently the EGL context & surfaces are created & managed
55cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * by the render thread, the goal is to move that into a shared structure that can
56cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * be managed by both threads. EGLSurface creation & deletion should ideally be
57cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * done on the UI thread and not the RenderThread to avoid stalling the
58cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * RenderThread with surface buffer allocation.
59cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
60cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * @hide
61cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
62cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpublic class ThreadedRenderer extends HardwareRenderer {
63cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private static final String LOGTAG = "ThreadedRenderer";
64cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
65f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Keep in sync with DrawFrameTask.h SYNC_* flags
66f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Nothing interesting to report
67cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_OK = 0;
68f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Needs a ViewRoot invalidate
69cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
70aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck    // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
71aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck    private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
72f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck
73fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static final String[] VISUALIZERS = {
74fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        PROFILE_PROPERTY_VISUALIZE_BARS,
75fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    };
76fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
77ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_FRAMESTATS   = 1 << 0;
78ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static final int FLAG_DUMP_RESET        = 1 << 1;
79ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
80ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @IntDef(flag = true, value = {
81ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET })
82ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    @Retention(RetentionPolicy.SOURCE)
83ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    public @interface DumpFlags {}
84ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck
85ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Size of the rendered content.
86cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private int mWidth, mHeight;
87ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
88ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Actual size of the drawing surface.
89ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mSurfaceWidth, mSurfaceHeight;
90ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
91ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Insets between the drawing surface and rendered content. These are
92ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // applied as translation when updating the root render node.
93ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mInsetTop, mInsetLeft;
94ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
9557774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    // Whether the surface has insets. Used to protect opacity.
9657774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    private boolean mHasInsets;
9757774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
9858c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    // Light and shadow properties specified by the theme.
9958c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightY;
10058c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightZ;
10158c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightRadius;
102058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mAmbientShadowAlpha;
103058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mSpotShadowAlpha;
10458c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
1054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private long mNativeProxy;
106f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private boolean mInitialized = false;
107bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private RenderNode mRootNode;
10818f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    private Choreographer mChoreographer;
1090a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private boolean mRootNodeNeedsUpdate;
110cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
111b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck    ThreadedRenderer(Context context, boolean translucent) {
112ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
11358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
11458c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
11558c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
116ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mAmbientShadowAlpha =
117ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette                (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
118ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette        mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
11958c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        a.recycle();
12058c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
121e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        long rootNodePtr = nCreateRootRenderNode();
122e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mRootNode = RenderNode.adopt(rootNodePtr);
123bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        mRootNode.setClipToBounds(false);
124e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mNativeProxy = nCreateProxy(translucent, rootNodePtr);
12518f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
126edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        ProcessInitializer.sInstance.init(context, mNativeProxy);
1273b20251a355c88193c439f928a84ae69483fb488John Reck
128fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        loadSystemProperties();
129cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
130cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
131cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
132f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void destroy() {
133f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = false;
134f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(null);
13517035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck        nDestroy(mNativeProxy);
136cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
137cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
138f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private void updateEnabledState(Surface surface) {
139f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        if (surface == null || !surface.isValid()) {
140f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(false);
141f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        } else {
142f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(mInitialized);
143f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        }
144f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
145f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
146cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
147cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean initialize(Surface surface) throws OutOfResourcesException {
148f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = true;
149f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
1505795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        boolean status = nInitialize(mNativeProxy, surface);
1515795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        surface.allocateBuffers();
1525795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        return status;
153cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
154cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
155cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
156cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void updateSurface(Surface surface) throws OutOfResourcesException {
157f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
1584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        nUpdateSurface(mNativeProxy, surface);
159cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
160cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
161cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
16201a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    boolean pauseSurface(Surface surface) {
16301a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck        return nPauseSurface(mNativeProxy, surface);
164f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
165f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
166f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    @Override
167cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void destroyHardwareResources(View view) {
1684f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        destroyResources(view);
169f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nDestroyHardwareResources(mNativeProxy);
1704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
1714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static void destroyResources(View view) {
1734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        view.destroyHardwareResources();
1744f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (view instanceof ViewGroup) {
1764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            ViewGroup group = (ViewGroup) view;
1774f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1784f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            int count = group.getChildCount();
1794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            for (int i = 0; i < count; i++) {
1804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck                destroyResources(group.getChildAt(i));
1814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            }
1824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
183cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
184cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
185cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
186cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void invalidate(Surface surface) {
1874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        updateSurface(surface);
188cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
189cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
190cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
191918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    void detachSurfaceTexture(long hardwareLayer) {
192918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
193cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
194cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
195cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
19650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
197cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mWidth = width;
198cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mHeight = height;
19950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
2003aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette        if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
2013aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette                || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
20257774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = true;
203ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = surfaceInsets.left;
204ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = surfaceInsets.top;
205ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
206ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
20757774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
20857774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            // If the surface has insets, it can't be opaque.
20957774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            setOpaque(false);
210ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        } else {
21157774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = false;
212ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = 0;
213ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = 0;
214ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width;
215ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height;
216ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        }
21750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
218ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
21950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, mLightRadius,
220b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck                mAmbientShadowAlpha, mSpotShadowAlpha);
22150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
22250210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        setLightCenter(attachInfo);
22350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    }
22450210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
22550210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    @Override
22650210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    void setLightCenter(AttachInfo attachInfo) {
22750210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        // Adjust light position for window offsets.
22850210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final Point displaySize = attachInfo.mPoint;
22950210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        attachInfo.mDisplay.getRealSize(displaySize);
23050210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
23150210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        final float lightY = mLightY - attachInfo.mWindowTop;
23250210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette
23350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette        nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
234cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
235cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
236cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
23763a06673253914510bbeebd500655008682dade1John Reck    void setOpaque(boolean opaque) {
23857774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette        nSetOpaque(mNativeProxy, opaque && !mHasInsets);
23963a06673253914510bbeebd500655008682dade1John Reck    }
24063a06673253914510bbeebd500655008682dade1John Reck
24163a06673253914510bbeebd500655008682dade1John Reck    @Override
242cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getWidth() {
243cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mWidth;
244cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
245cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
246cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
247cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getHeight() {
248cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mHeight;
249cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
250cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
251cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
252ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) {
253fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        pw.flush();
254ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        int flags = 0;
255ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        for (int i = 0; i < args.length; i++) {
256ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            switch (args[i]) {
257ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "framestats":
258ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_FRAMESTATS;
259ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
260ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                case "reset":
261ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    flags |= FLAG_DUMP_RESET;
262ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck                    break;
263ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            }
264fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
265ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        nDumpProfileInfo(mNativeProxy, fd, flags);
266cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
267cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
268cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
269cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean loadSystemProperties() {
270fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        boolean changed = nLoadSystemProperties(mNativeProxy);
27123d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        if (changed) {
27223d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck            invalidateRoot();
27323d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck        }
274fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return changed;
275cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
276cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
2770a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private void updateViewTreeDisplayList(View view) {
278cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags |= View.PFLAG_DRAWN;
279cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
280cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck                == View.PFLAG_INVALIDATED;
281cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
28231a2d063df5111e730abe7d07be064690deedc34Chris Craik        view.updateDisplayListIfDirty();
2830a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        view.mRecreateDisplayList = false;
2840a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
285cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
28661375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
28770850ea258cbf91477efa57a1f1a23cc0044cc93Chris Craik        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()");
2880a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        updateViewTreeDisplayList(view);
2890a97330b98dd633b58dcfff405d94476c89e867dJohn Reck
2900a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
291f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik            DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
2920a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            try {
293dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                final int saveCount = canvas.save();
2940a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                canvas.translate(mInsetLeft, mInsetTop);
2950a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePreDraw(canvas);
296abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
297abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertReorderBarrier();
29831a2d063df5111e730abe7d07be064690deedc34Chris Craik                canvas.drawRenderNode(view.updateDisplayListIfDirty());
299abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik                canvas.insertInorderBarrier();
300abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik
3010a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePostDraw(canvas);
302dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                canvas.restoreToCount(saveCount);
3030a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNodeNeedsUpdate = false;
3040a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            } finally {
3050a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNode.end(canvas);
3060a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            }
30705e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        }
3080a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
3090a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
310cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
3110a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    @Override
3120a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    void invalidateRoot() {
3130a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        mRootNodeNeedsUpdate = true;
314bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    }
315bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
316bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    @Override
31761375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
318bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        attachInfo.mIgnoreDirtyState = true;
319bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
320ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;
321ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        choreographer.mFrameInfo.markDrawStart();
322fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
32361375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck        updateRootDisplayList(view, callbacks);
324cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
3256313b9259d37b59f3402058e197637aa3014516cJohn Reck        attachInfo.mIgnoreDirtyState = false;
3266313b9259d37b59f3402058e197637aa3014516cJohn Reck
327119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // register animating rendernodes which started animating prior to renderer
328119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        // creation, which is typical for animators started prior to first draw
329119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        if (attachInfo.mPendingAnimatingRenderNodes != null) {
330119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            final int count = attachInfo.mPendingAnimatingRenderNodes.size();
331119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            for (int i = 0; i < count; i++) {
332119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                registerAnimatingRenderNode(
333119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck                        attachInfo.mPendingAnimatingRenderNodes.get(i));
334119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            }
335119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes.clear();
336119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // We don't need this anymore as subsequent calls to
337119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            // ViewRootImpl#attachRenderNodeAnimator will go directly to us.
338119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck            attachInfo.mPendingAnimatingRenderNodes = null;
339119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        }
340119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
341ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
342ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck        int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
343aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
344aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            setEnabled(false);
345b13de07f0b26953115f4315bc7417ca87c70594bJohn Reck            attachInfo.mViewRootImpl.mSurface.release();
346aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // Invalidate since we failed to draw. This should fetch a Surface
347aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            // if it is still needed or do nothing if we are no longer drawing
348aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck            attachInfo.mViewRootImpl.invalidate();
349aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck        }
350f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
351f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            attachInfo.mViewRootImpl.invalidate();
352f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        }
353cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
354cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
3553b20251a355c88193c439f928a84ae69483fb488John Reck    static void invokeFunctor(long functor, boolean waitForCompletion) {
3563b20251a355c88193c439f928a84ae69483fb488John Reck        nInvokeFunctor(functor, waitForCompletion);
3570d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    }
3580d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck
3590d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    @Override
36019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    HardwareLayer createTextureLayer() {
36119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        long layer = nCreateTextureLayer(mNativeProxy);
36219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return HardwareLayer.adoptTextureLayer(this, layer);
363cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
364cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
365cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
3663e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    void buildLayer(RenderNode node) {
3673e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck        nBuildLayer(mNativeProxy, node.getNativeDisplayList());
3683e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    }
3693e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
3703e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    @Override
37119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
37219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return nCopyLayerInto(mNativeProxy,
3733731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck                layer.getDeferredLayerUpdater(), bitmap);
374cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
375cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
376cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
37719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void pushLayerUpdate(HardwareLayer layer) {
378d72e0a339b54af0c4e731513bbad120dff694723John Reck        nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
37919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
38019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
38119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    @Override
38219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void onLayerDestroyed(HardwareLayer layer) {
383d72e0a339b54af0c4e731513bbad120dff694723John Reck        nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
384cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
385cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
386cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
387cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void setName(String name) {
388b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck        nSetName(mNativeProxy, name);
389cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
390cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
3914f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    @Override
39228ad7b52e038ef0cdd89f753d9839444a434b299John Reck    void fence() {
39328ad7b52e038ef0cdd89f753d9839444a434b299John Reck        nFence(mNativeProxy);
39428ad7b52e038ef0cdd89f753d9839444a434b299John Reck    }
39528ad7b52e038ef0cdd89f753d9839444a434b299John Reck
39628ad7b52e038ef0cdd89f753d9839444a434b299John Reck    @Override
397f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void stopDrawing() {
398f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nStopDrawing(mNativeProxy);
399f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    }
400f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
401f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    @Override
402a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    public void notifyFramePending() {
403a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        nNotifyFramePending(mNativeProxy);
404a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
405a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
406a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    @Override
407119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    void registerAnimatingRenderNode(RenderNode animator) {
408119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck        nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
409119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    }
410119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck
411119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    @Override
4124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    protected void finalize() throws Throwable {
4134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        try {
4144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            nDeleteProxy(mNativeProxy);
4150ed751dd22a98f0c1f637570c5775b4f5e97d895John Reck            mNativeProxy = 0;
4164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        } finally {
4174f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            super.finalize();
418cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        }
419cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
420cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
421f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    static void trimMemory(int level) {
422f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nTrimMemory(level);
42384a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    }
42484a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
4252507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    public static void overrideProperty(@NonNull String name, @NonNull String value) {
4262507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik        if (name == null || value == null) {
4272507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik            throw new IllegalArgumentException("name and value must be non-null");
4282507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik        }
4292507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik        nOverrideProperty(name, value);
4302507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    }
4312507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik
432edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    public static void dumpProfileData(byte[] data, FileDescriptor fd) {
433edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        nDumpProfileData(data, fd);
434edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    }
435edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
436edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static class ProcessInitializer {
437edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        static ProcessInitializer sInstance = new ProcessInitializer();
438edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        static IGraphicsStats sGraphicsStatsService;
439edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static IBinder sProcToken;
44066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
44166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        private boolean mInitialized = false;
44266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
443edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private ProcessInitializer() {}
44466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
4453b20251a355c88193c439f928a84ae69483fb488John Reck        synchronized void init(Context context, long renderProxy) {
44666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (mInitialized) return;
447edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            mInitialized = true;
448edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initGraphicsStats(context, renderProxy);
449edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            initAssetAtlas(context, renderProxy);
450edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
451edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
452edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initGraphicsStats(Context context, long renderProxy) {
453edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            IBinder binder = ServiceManager.getService("graphicsstats");
454edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            if (binder == null) return;
455edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
456edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            sGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
457edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            sProcToken = new Binder();
458edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            try {
459edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                final String pkg = context.getApplicationInfo().packageName;
460edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                ParcelFileDescriptor pfd = sGraphicsStatsService.
461edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                        requestBufferForProcess(pkg, sProcToken);
462edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                nSetProcessStatsBuffer(renderProxy, pfd.getFd());
463edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                pfd.close();
464edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            } catch (Exception e) {
465edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck                Log.w(LOG_TAG, "Could not acquire gfx stats buffer", e);
466edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck            }
467edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        }
468edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck
469edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck        private static void initAssetAtlas(Context context, long renderProxy) {
47066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IBinder binder = ServiceManager.getService("assetatlas");
47166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (binder == null) return;
47266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
47366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
47466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            try {
47566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                if (atlas.isCompatible(android.os.Process.myPpid())) {
47666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    GraphicBuffer buffer = atlas.getBuffer();
47766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    if (buffer != null) {
47866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        long[] map = atlas.getMap();
47966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (map != null) {
4803b20251a355c88193c439f928a84ae69483fb488John Reck                            nSetAtlas(renderProxy, buffer, map);
48166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
48266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // If IAssetAtlas is not the same class as the IBinder
48366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // we are using a remote service and we can safely
48466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // destroy the graphic buffer
48566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (atlas.getClass() != binder.getClass()) {
48666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                            buffer.destroy();
48766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
48866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    }
48966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                }
49066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            } catch (RemoteException e) {
49166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                Log.w(LOG_TAG, "Could not acquire atlas", e);
49266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            }
49366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        }
49466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    }
49566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
49684a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    static native void setupShadersDiskCache(String cacheFile);
49784a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
4983b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
499edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nSetProcessStatsBuffer(long nativeProxy, int fd);
500cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
501e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateRootRenderNode();
502e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateProxy(boolean translucent, long rootRenderNode);
5034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nDeleteProxy(long nativeProxy);
504cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
505e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    private static native boolean nLoadSystemProperties(long nativeProxy);
506b36016c65f1d1b5846dba0349aab491dbd3a746aJohn Reck    private static native void nSetName(long nativeProxy, String name);
50718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
5084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native boolean nInitialize(long nativeProxy, Surface window);
5094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nUpdateSurface(long nativeProxy, Surface window);
51001a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck    private static native boolean nPauseSurface(long nativeProxy, Surface window);
511797b95b26bbb7557678af78b9a2a61830158920fChris Craik    private static native void nSetup(long nativeProxy, int width, int height,
51250210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
51350210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette    private static native void nSetLightCenter(long nativeProxy,
51450210d912925aef14e4ce69be82e4949122a3cd9Alan Viverette            float lightX, float lightY, float lightZ);
51563a06673253914510bbeebd500655008682dade1John Reck    private static native void nSetOpaque(long nativeProxy, boolean opaque);
516ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
51717035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck    private static native void nDestroy(long nativeProxy);
518119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck    private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
519cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
5203b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
52119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
52219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateTextureLayer(long nativeProxy);
5233e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    private static native void nBuildLayer(long nativeProxy, long node);
5243731dc220ed457e0f1e99d7ec2589e0a43872b59John Reck    private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
525d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nPushLayerUpdate(long nativeProxy, long layer);
526d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nCancelLayerUpdate(long nativeProxy, long layer);
527918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
52828ad7b52e038ef0cdd89f753d9839444a434b299John Reck
529f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nDestroyHardwareResources(long nativeProxy);
530f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nTrimMemory(int level);
5312507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik    private static native void nOverrideProperty(String name, String value);
532e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck
53328ad7b52e038ef0cdd89f753d9839444a434b299John Reck    private static native void nFence(long nativeProxy);
534f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nStopDrawing(long nativeProxy);
535a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    private static native void nNotifyFramePending(long nativeProxy);
536fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
537ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck    private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
538ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck            @DumpFlags int dumpFlags);
539edc524c90506d80e0fc5fb67e8de7b8f3ef53439John Reck    private static native void nDumpProfileData(byte[] data, FileDescriptor fd);
540cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}
541