ThreadedRenderer.java revision 3e8249568cc428296ac76c7ddce3f0382d40fe5b
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
1958c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viveretteimport com.android.internal.R;
2058c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
21b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.content.Context;
22b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.content.res.Resources;
2358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viveretteimport android.content.res.TypedArray;
2404fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckimport android.graphics.Bitmap;
25ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viveretteimport android.graphics.Rect;
26b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.graphics.drawable.Drawable;
2766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.IBinder;
2866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.RemoteException;
2966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.ServiceManager;
30fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckimport android.os.SystemProperties;
31cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.os.Trace;
3266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.util.Log;
33b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.util.LongSparseArray;
34315c329544d7c593d1072b071cbb92d9afe74021John Reckimport android.util.TimeUtils;
35cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.Surface.OutOfResourcesException;
36cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.View.AttachInfo;
37cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
38fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckimport java.io.FileDescriptor;
39cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport java.io.PrintWriter;
40b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport java.util.HashSet;
41cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
42cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/**
43cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Hardware renderer that proxies the rendering to a render thread. Most calls
444f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * are currently synchronous.
45cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
46cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * The UI thread can block on the RenderThread, but RenderThread must never
47cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * block on the UI thread.
48cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * by the lifecycle of the RenderProxy.
524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
53cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Note that although currently the EGL context & surfaces are created & managed
54cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * by the render thread, the goal is to move that into a shared structure that can
55cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * be managed by both threads. EGLSurface creation & deletion should ideally be
56cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * done on the UI thread and not the RenderThread to avoid stalling the
57cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * RenderThread with surface buffer allocation.
58cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
59cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * @hide
60cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
61cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpublic class ThreadedRenderer extends HardwareRenderer {
62cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private static final String LOGTAG = "ThreadedRenderer";
63cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
64f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Keep in sync with DrawFrameTask.h SYNC_* flags
65f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Nothing interesting to report
66cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_OK = 0;
67f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Needs a ViewRoot invalidate
68cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
69f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck
70fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static final String[] VISUALIZERS = {
71fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        PROFILE_PROPERTY_VISUALIZE_BARS,
72fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    };
73fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
74ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Size of the rendered content.
75cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private int mWidth, mHeight;
76ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
77ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Actual size of the drawing surface.
78ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mSurfaceWidth, mSurfaceHeight;
79ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
80ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Insets between the drawing surface and rendered content. These are
81ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // applied as translation when updating the root render node.
82ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mInsetTop, mInsetLeft;
83ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
8457774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    // Whether the surface has insets. Used to protect opacity.
8557774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette    private boolean mHasInsets;
8657774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
8758c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    // Light and shadow properties specified by the theme.
8858c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightY;
8958c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightZ;
9058c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    private final float mLightRadius;
91058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mAmbientShadowAlpha;
92058fc640017c90120c599d378a4cbc55668b05b7Chris Craik    private final int mSpotShadowAlpha;
9358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private long mNativeProxy;
95f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private boolean mInitialized = false;
96bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private RenderNode mRootNode;
9718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    private Choreographer mChoreographer;
98fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private boolean mProfilingEnabled;
990a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private boolean mRootNodeNeedsUpdate;
100cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
101b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck    ThreadedRenderer(Context context, boolean translucent) {
10258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        final TypedArray a = context.obtainStyledAttributes(
10358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette                null, R.styleable.Lighting, R.attr.lightingStyle, 0);
10458c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
10558c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
10658c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
107058fc640017c90120c599d378a4cbc55668b05b7Chris Craik        mAmbientShadowAlpha = Math.round(
108058fc640017c90120c599d378a4cbc55668b05b7Chris Craik                255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0));
109058fc640017c90120c599d378a4cbc55668b05b7Chris Craik        mSpotShadowAlpha = Math.round(
110058fc640017c90120c599d378a4cbc55668b05b7Chris Craik                255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0));
11158c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        a.recycle();
11258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette
113e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        long rootNodePtr = nCreateRootRenderNode();
114e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mRootNode = RenderNode.adopt(rootNodePtr);
115bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        mRootNode.setClipToBounds(false);
116e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mNativeProxy = nCreateProxy(translucent, rootNodePtr);
11718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
1183b20251a355c88193c439f928a84ae69483fb488John Reck        AtlasInitializer.sInstance.init(context, mNativeProxy);
1193b20251a355c88193c439f928a84ae69483fb488John Reck
12018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        // Setup timing
12118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        mChoreographer = Choreographer.getInstance();
12218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        nSetFrameInterval(mNativeProxy, mChoreographer.getFrameIntervalNanos());
123fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
124fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        loadSystemProperties();
125cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
126cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
127cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
128f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void destroy() {
129f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = false;
130f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(null);
131fae904d63947fe1687d1d44be29234cc3d538f24John Reck        nDestroyCanvasAndSurface(mNativeProxy);
132cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
133cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
134f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private void updateEnabledState(Surface surface) {
135f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        if (surface == null || !surface.isValid()) {
136f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(false);
137f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        } else {
138f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(mInitialized);
139f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        }
140f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
141f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
142cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
143cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean initialize(Surface surface) throws OutOfResourcesException {
144f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = true;
145f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
1465795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        boolean status = nInitialize(mNativeProxy, surface);
1475795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        surface.allocateBuffers();
1485795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        return status;
149cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
150cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
151cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
152cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void updateSurface(Surface surface) throws OutOfResourcesException {
153f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
1544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        nUpdateSurface(mNativeProxy, surface);
155cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
156cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
157cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
158f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    void pauseSurface(Surface surface) {
159f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        nPauseSurface(mNativeProxy, surface);
160f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
161f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
162f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    @Override
163cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void destroyHardwareResources(View view) {
1644f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        destroyResources(view);
165f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nDestroyHardwareResources(mNativeProxy);
1664f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
1674f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1684f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static void destroyResources(View view) {
1694f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        view.destroyHardwareResources();
1704f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1714f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (view instanceof ViewGroup) {
1724f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            ViewGroup group = (ViewGroup) view;
1734f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1744f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            int count = group.getChildCount();
1754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            for (int i = 0; i < count; i++) {
1764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck                destroyResources(group.getChildAt(i));
1774f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            }
1784f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
179cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
180cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
181cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
182cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void invalidate(Surface surface) {
1834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        updateSurface(surface);
184cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
185cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
186cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
187918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    void detachSurfaceTexture(long hardwareLayer) {
188918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
189cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
190cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
191cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
19258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette    void setup(int width, int height, Rect surfaceInsets) {
19358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette        final float lightX = width / 2.0f;
194cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mWidth = width;
195cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mHeight = height;
19657774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette        if (surfaceInsets != null && !surfaceInsets.isEmpty()) {
19757774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = true;
198ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = surfaceInsets.left;
199ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = surfaceInsets.top;
200ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
201ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
20257774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette
20357774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            // If the surface has insets, it can't be opaque.
20457774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            setOpaque(false);
205ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        } else {
20657774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette            mHasInsets = false;
207ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = 0;
208ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = 0;
209ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width;
210ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height;
211ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        }
212ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
213058fc640017c90120c599d378a4cbc55668b05b7Chris Craik        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight,
214058fc640017c90120c599d378a4cbc55668b05b7Chris Craik                lightX, mLightY, mLightZ, mLightRadius,
215058fc640017c90120c599d378a4cbc55668b05b7Chris Craik                mAmbientShadowAlpha, mSpotShadowAlpha);
216cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
217cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
218cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
21963a06673253914510bbeebd500655008682dade1John Reck    void setOpaque(boolean opaque) {
22057774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette        nSetOpaque(mNativeProxy, opaque && !mHasInsets);
22163a06673253914510bbeebd500655008682dade1John Reck    }
22263a06673253914510bbeebd500655008682dade1John Reck
22363a06673253914510bbeebd500655008682dade1John Reck    @Override
224cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getWidth() {
225cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mWidth;
226cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
227cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
228cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
229cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getHeight() {
230cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mHeight;
231cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
232cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
233cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
234fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    void dumpGfxInfo(PrintWriter pw, FileDescriptor fd) {
235fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        pw.flush();
236fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        nDumpProfileInfo(mNativeProxy, fd);
237cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
238cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
239fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static int search(String[] values, String value) {
240fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        for (int i = 0; i < values.length; i++) {
241fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            if (values[i].equals(value)) return i;
242fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
243fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return -1;
244fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    }
245fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
246fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static boolean checkIfProfilingRequested() {
247fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        String profiling = SystemProperties.get(HardwareRenderer.PROFILE_PROPERTY);
248fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        int graphType = search(VISUALIZERS, profiling);
249fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return (graphType >= 0) || Boolean.parseBoolean(profiling);
250cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
251cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
252cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
253cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean loadSystemProperties() {
254fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        boolean changed = nLoadSystemProperties(mNativeProxy);
255fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        boolean wantProfiling = checkIfProfilingRequested();
256fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        if (wantProfiling != mProfilingEnabled) {
257fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            mProfilingEnabled = wantProfiling;
258fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            changed = true;
259fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
260fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return changed;
261cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
262cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
2630a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private void updateViewTreeDisplayList(View view) {
264cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags |= View.PFLAG_DRAWN;
265cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
266cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck                == View.PFLAG_INVALIDATED;
267cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
2680a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        view.getDisplayList();
2690a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        view.mRecreateDisplayList = false;
2700a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
271cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
2720a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
273cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
2740a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        updateViewTreeDisplayList(view);
2750a97330b98dd633b58dcfff405d94476c89e867dJohn Reck
2760a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
2770a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            HardwareCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
2780a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            try {
279dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                final int saveCount = canvas.save();
2800a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                canvas.translate(mInsetLeft, mInsetTop);
2810a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePreDraw(canvas);
2820a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                canvas.drawRenderNode(view.getDisplayList());
2830a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                callbacks.onHardwarePostDraw(canvas);
284dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette                canvas.restoreToCount(saveCount);
2850a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNodeNeedsUpdate = false;
2860a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            } finally {
2870a97330b98dd633b58dcfff405d94476c89e867dJohn Reck                mRootNode.end(canvas);
2880a97330b98dd633b58dcfff405d94476c89e867dJohn Reck            }
28905e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        }
2900a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
2910a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    }
292cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
2930a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    @Override
2940a97330b98dd633b58dcfff405d94476c89e867dJohn Reck    void invalidateRoot() {
2950a97330b98dd633b58dcfff405d94476c89e867dJohn Reck        mRootNodeNeedsUpdate = true;
296bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    }
297bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
298bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    @Override
299e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
300bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        attachInfo.mIgnoreDirtyState = true;
30118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        long frameTimeNanos = mChoreographer.getFrameTimeNanos();
302315c329544d7c593d1072b071cbb92d9afe74021John Reck        attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS;
303bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
304fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        long recordDuration = 0;
305fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        if (mProfilingEnabled) {
306fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            recordDuration = System.nanoTime();
307fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
308fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
309bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        updateRootDisplayList(view, callbacks);
310cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
311fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        if (mProfilingEnabled) {
312fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            recordDuration = System.nanoTime() - recordDuration;
313fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
314fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
3156313b9259d37b59f3402058e197637aa3014516cJohn Reck        attachInfo.mIgnoreDirtyState = false;
3166313b9259d37b59f3402058e197637aa3014516cJohn Reck
317f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos,
318e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck                recordDuration, view.getResources().getDisplayMetrics().density);
319f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
320f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            attachInfo.mViewRootImpl.invalidate();
321f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        }
322cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
323cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
3243b20251a355c88193c439f928a84ae69483fb488John Reck    static void invokeFunctor(long functor, boolean waitForCompletion) {
3253b20251a355c88193c439f928a84ae69483fb488John Reck        nInvokeFunctor(functor, waitForCompletion);
3260d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    }
3270d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck
3280d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    @Override
32919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    HardwareLayer createTextureLayer() {
33019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        long layer = nCreateTextureLayer(mNativeProxy);
33119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return HardwareLayer.adoptTextureLayer(this, layer);
332cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
333cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
334cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
3353e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    void buildLayer(RenderNode node) {
3363e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck        nBuildLayer(mNativeProxy, node.getNativeDisplayList());
3373e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    }
3383e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck
3393e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    @Override
34019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
34119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return nCopyLayerInto(mNativeProxy,
34219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck                layer.getDeferredLayerUpdater(), bitmap.mNativeBitmap);
343cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
344cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
345cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
34619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void pushLayerUpdate(HardwareLayer layer) {
347d72e0a339b54af0c4e731513bbad120dff694723John Reck        nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
34819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
34919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
35019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    @Override
35119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void onLayerDestroyed(HardwareLayer layer) {
352d72e0a339b54af0c4e731513bbad120dff694723John Reck        nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
353cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
354cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
355cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
356cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void setName(String name) {
357cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
358cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
3594f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    @Override
36028ad7b52e038ef0cdd89f753d9839444a434b299John Reck    void fence() {
36128ad7b52e038ef0cdd89f753d9839444a434b299John Reck        nFence(mNativeProxy);
36228ad7b52e038ef0cdd89f753d9839444a434b299John Reck    }
36328ad7b52e038ef0cdd89f753d9839444a434b299John Reck
36428ad7b52e038ef0cdd89f753d9839444a434b299John Reck    @Override
365f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void stopDrawing() {
366f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nStopDrawing(mNativeProxy);
367f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    }
368f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
369f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    @Override
370a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    public void notifyFramePending() {
371a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        nNotifyFramePending(mNativeProxy);
372a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
373a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
374a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    @Override
3754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    protected void finalize() throws Throwable {
3764f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        try {
3774f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            nDeleteProxy(mNativeProxy);
3780ed751dd22a98f0c1f637570c5775b4f5e97d895John Reck            mNativeProxy = 0;
3794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        } finally {
3804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            super.finalize();
381cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        }
382cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
383cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
384f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    static void trimMemory(int level) {
385f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nTrimMemory(level);
38684a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    }
38784a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
38866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    private static class AtlasInitializer {
38966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        static AtlasInitializer sInstance = new AtlasInitializer();
39066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
39166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        private boolean mInitialized = false;
39266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
39366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        private AtlasInitializer() {}
39466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
3953b20251a355c88193c439f928a84ae69483fb488John Reck        synchronized void init(Context context, long renderProxy) {
39666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (mInitialized) return;
39766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IBinder binder = ServiceManager.getService("assetatlas");
39866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (binder == null) return;
39966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
40066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
40166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            try {
40266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                if (atlas.isCompatible(android.os.Process.myPpid())) {
40366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    GraphicBuffer buffer = atlas.getBuffer();
40466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    if (buffer != null) {
40566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        long[] map = atlas.getMap();
40666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (map != null) {
407b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                            // TODO Remove after fixing b/15425820
408b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                            validateMap(context, map);
4093b20251a355c88193c439f928a84ae69483fb488John Reck                            nSetAtlas(renderProxy, buffer, map);
41066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                            mInitialized = true;
41166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
41266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // If IAssetAtlas is not the same class as the IBinder
41366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // we are using a remote service and we can safely
41466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // destroy the graphic buffer
41566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (atlas.getClass() != binder.getClass()) {
41666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                            buffer.destroy();
41766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
41866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    }
41966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                }
42066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            } catch (RemoteException e) {
42166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                Log.w(LOG_TAG, "Could not acquire atlas", e);
42266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            }
42366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        }
424b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck
425b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck        private static void validateMap(Context context, long[] map) {
426b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            Log.d("Atlas", "Validating map...");
427b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            HashSet<Long> preloadedPointers = new HashSet<Long>();
428b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck
429b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            // We only care about drawables that hold bitmaps
430b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            final Resources resources = context.getResources();
431b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables();
432b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck
433b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            final int count = drawables.size();
434b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            for (int i = 0; i < count; i++) {
435b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                final Bitmap bitmap = drawables.valueAt(i).getBitmap();
436b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
437b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                    preloadedPointers.add(bitmap.mNativeBitmap);
438b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                }
439b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            }
440b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck
441b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            for (int i = 0; i < map.length; i += 4) {
442b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                if (!preloadedPointers.contains(map[i])) {
443b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                    Log.w("Atlas", String.format("Pointer 0x%X, not in getPreloadedDrawables?", map[i]));
444b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                    map[i] = 0;
445b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                }
446b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            }
447b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck        }
44866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    }
44966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
45084a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    static native void setupShadersDiskCache(String cacheFile);
45184a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
4523b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
453cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
454e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateRootRenderNode();
455e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateProxy(boolean translucent, long rootRenderNode);
4564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nDeleteProxy(long nativeProxy);
457cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
45818f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    private static native void nSetFrameInterval(long nativeProxy, long frameIntervalNanos);
459e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    private static native boolean nLoadSystemProperties(long nativeProxy);
46018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
4614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native boolean nInitialize(long nativeProxy, Surface window);
4624f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nUpdateSurface(long nativeProxy, Surface window);
463f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private static native void nPauseSurface(long nativeProxy, Surface window);
464797b95b26bbb7557678af78b9a2a61830158920fChris Craik    private static native void nSetup(long nativeProxy, int width, int height,
465058fc640017c90120c599d378a4cbc55668b05b7Chris Craik            float lightX, float lightY, float lightZ, float lightRadius,
466058fc640017c90120c599d378a4cbc55668b05b7Chris Craik            int ambientShadowAlpha, int spotShadowAlpha);
46763a06673253914510bbeebd500655008682dade1John Reck    private static native void nSetOpaque(long nativeProxy, boolean opaque);
468fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static native int nSyncAndDrawFrame(long nativeProxy,
469e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck            long frameTimeNanos, long recordDuration, float density);
470fae904d63947fe1687d1d44be29234cc3d538f24John Reck    private static native void nDestroyCanvasAndSurface(long nativeProxy);
471cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
4723b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
47319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
47419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateDisplayListLayer(long nativeProxy, int width, int height);
47519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateTextureLayer(long nativeProxy);
4763e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck    private static native void nBuildLayer(long nativeProxy, long node);
47719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
478d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nPushLayerUpdate(long nativeProxy, long layer);
479d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nCancelLayerUpdate(long nativeProxy, long layer);
480918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
48128ad7b52e038ef0cdd89f753d9839444a434b299John Reck
482f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nDestroyHardwareResources(long nativeProxy);
483f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nTrimMemory(int level);
484e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck
48528ad7b52e038ef0cdd89f753d9839444a434b299John Reck    private static native void nFence(long nativeProxy);
486f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nStopDrawing(long nativeProxy);
487a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    private static native void nNotifyFramePending(long nativeProxy);
488fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
489fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd);
490cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}
491