ThreadedRenderer.java revision ccb11e183763db5cbaca96abe461adf480ed8e44
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
19b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.content.Context;
20b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.content.res.Resources;
2104fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckimport android.graphics.Bitmap;
22ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viveretteimport android.graphics.Rect;
23b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.graphics.drawable.Drawable;
2466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.IBinder;
2566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.RemoteException;
2666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.ServiceManager;
27fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckimport android.os.SystemProperties;
28cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.os.Trace;
2966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.util.Log;
30b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.util.LongSparseArray;
31315c329544d7c593d1072b071cbb92d9afe74021John Reckimport android.util.TimeUtils;
32cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.Surface.OutOfResourcesException;
33cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.View.AttachInfo;
34cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
35fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckimport java.io.FileDescriptor;
36cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport java.io.PrintWriter;
37b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport java.util.HashSet;
38cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
39cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/**
40cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Hardware renderer that proxies the rendering to a render thread. Most calls
414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * are currently synchronous.
42cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
43cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * The UI thread can block on the RenderThread, but RenderThread must never
44cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * block on the UI thread.
45cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
464f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
474f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * by the lifecycle of the RenderProxy.
494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
50cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Note that although currently the EGL context & surfaces are created & managed
51cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * by the render thread, the goal is to move that into a shared structure that can
52cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * be managed by both threads. EGLSurface creation & deletion should ideally be
53cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * done on the UI thread and not the RenderThread to avoid stalling the
54cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * RenderThread with surface buffer allocation.
55cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
56cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * @hide
57cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
58cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpublic class ThreadedRenderer extends HardwareRenderer {
59cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private static final String LOGTAG = "ThreadedRenderer";
60cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
61f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Keep in sync with DrawFrameTask.h SYNC_* flags
62f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Nothing interesting to report
63cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_OK = 0;
64f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck    // Needs a ViewRoot invalidate
65cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck    private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
66f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck
67fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static final String[] VISUALIZERS = {
68fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        PROFILE_PROPERTY_VISUALIZE_BARS,
69fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    };
70fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
71ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Size of the rendered content.
72cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private int mWidth, mHeight;
73ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
74ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Actual size of the drawing surface.
75ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mSurfaceWidth, mSurfaceHeight;
76ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
77ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // Insets between the drawing surface and rendered content. These are
78ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    // applied as translation when updating the root render node.
79ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    private int mInsetTop, mInsetLeft;
80ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette
814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private long mNativeProxy;
82f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private boolean mInitialized = false;
83bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private RenderNode mRootNode;
8418f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    private Choreographer mChoreographer;
85fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private boolean mProfilingEnabled;
86cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
87b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck    ThreadedRenderer(Context context, boolean translucent) {
88e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        long rootNodePtr = nCreateRootRenderNode();
89e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mRootNode = RenderNode.adopt(rootNodePtr);
90bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        mRootNode.setClipToBounds(false);
91e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mNativeProxy = nCreateProxy(translucent, rootNodePtr);
9218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
933b20251a355c88193c439f928a84ae69483fb488John Reck        AtlasInitializer.sInstance.init(context, mNativeProxy);
943b20251a355c88193c439f928a84ae69483fb488John Reck
9518f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        // Setup timing
9618f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        mChoreographer = Choreographer.getInstance();
9718f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        nSetFrameInterval(mNativeProxy, mChoreographer.getFrameIntervalNanos());
98fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
99fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        loadSystemProperties();
100cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
101cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
102cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
103f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void destroy() {
104f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = false;
105f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(null);
106fae904d63947fe1687d1d44be29234cc3d538f24John Reck        nDestroyCanvasAndSurface(mNativeProxy);
107cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
108cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
109f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private void updateEnabledState(Surface surface) {
110f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        if (surface == null || !surface.isValid()) {
111f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(false);
112f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        } else {
113f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(mInitialized);
114f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        }
115f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
116f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
117cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
118cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean initialize(Surface surface) throws OutOfResourcesException {
119f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = true;
120f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
1215795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        boolean status = nInitialize(mNativeProxy, surface);
1225795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        surface.allocateBuffers();
1235795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza        return status;
124cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
125cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
126cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
127cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void updateSurface(Surface surface) throws OutOfResourcesException {
128f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
1294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        nUpdateSurface(mNativeProxy, surface);
130cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
131cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
132cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
133f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    void pauseSurface(Surface surface) {
134f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        nPauseSurface(mNativeProxy, surface);
135f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
136f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
137f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    @Override
138cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void destroyHardwareResources(View view) {
1394f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        destroyResources(view);
140f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nDestroyHardwareResources(mNativeProxy);
1414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
1424f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1434f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static void destroyResources(View view) {
1444f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        view.destroyHardwareResources();
1454f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1464f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (view instanceof ViewGroup) {
1474f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            ViewGroup group = (ViewGroup) view;
1484f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1494f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            int count = group.getChildCount();
1504f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            for (int i = 0; i < count; i++) {
1514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck                destroyResources(group.getChildAt(i));
1524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            }
1534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
154cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
155cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
156cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
157cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void invalidate(Surface surface) {
1584f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        updateSurface(surface);
159cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
160cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
161cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
162918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    void detachSurfaceTexture(long hardwareLayer) {
163918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck        nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
164cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
165cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
166cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
167ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette    void setup(int width, int height, Rect surfaceInsets, float lightX, float lightY, float lightZ,
168ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            float lightRadius) {
169cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mWidth = width;
170cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mHeight = height;
171ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        if (surfaceInsets != null) {
172ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = surfaceInsets.left;
173ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = surfaceInsets.top;
174ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width + mInsetLeft + surfaceInsets.right;
175ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom;
176ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        } else {
177ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetLeft = 0;
178ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mInsetTop = 0;
179ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceWidth = width;
180ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            mSurfaceHeight = height;
181ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        }
182ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
183ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, lightX, lightY, lightZ, lightRadius);
184cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
185cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
186cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
18763a06673253914510bbeebd500655008682dade1John Reck    void setOpaque(boolean opaque) {
18863a06673253914510bbeebd500655008682dade1John Reck        nSetOpaque(mNativeProxy, opaque);
18963a06673253914510bbeebd500655008682dade1John Reck    }
19063a06673253914510bbeebd500655008682dade1John Reck
19163a06673253914510bbeebd500655008682dade1John Reck    @Override
192cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getWidth() {
193cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mWidth;
194cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
195cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
196cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
197cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getHeight() {
198cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mHeight;
199cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
200cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
201cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
202fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    void dumpGfxInfo(PrintWriter pw, FileDescriptor fd) {
203fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        pw.flush();
204fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        nDumpProfileInfo(mNativeProxy, fd);
205cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
206cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
207fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static int search(String[] values, String value) {
208fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        for (int i = 0; i < values.length; i++) {
209fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            if (values[i].equals(value)) return i;
210fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
211fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return -1;
212fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    }
213fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
214fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static boolean checkIfProfilingRequested() {
215fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        String profiling = SystemProperties.get(HardwareRenderer.PROFILE_PROPERTY);
216fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        int graphType = search(VISUALIZERS, profiling);
217fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return (graphType >= 0) || Boolean.parseBoolean(profiling);
218cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
219cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
220cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
221cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean loadSystemProperties() {
222fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        boolean changed = nLoadSystemProperties(mNativeProxy);
223fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        boolean wantProfiling = checkIfProfilingRequested();
224fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        if (wantProfiling != mProfilingEnabled) {
225fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            mProfilingEnabled = wantProfiling;
226fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            changed = true;
227fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
228fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        return changed;
229cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
230cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
231bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
232cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags |= View.PFLAG_DRAWN;
233cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
234cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
235cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck                == View.PFLAG_INVALIDATED;
236cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
237cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
238cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
239ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette        HardwareCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
24005e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        try {
24186faf9ec3edc24a9d04548e151bca3a2510396a4John Reck            canvas.save();
242ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette            canvas.translate(mInsetLeft, mInsetTop);
243d5b2ec4ff15f828298290534c9d322c82f8d130cAlan Viverette            callbacks.onHardwarePreDraw(canvas);
244a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik            canvas.drawRenderNode(view.getDisplayList());
24505e858400adee0f579b1e27e321b48bd55843fbdJohn Reck            callbacks.onHardwarePostDraw(canvas);
24686faf9ec3edc24a9d04548e151bca3a2510396a4John Reck            canvas.restore();
24705e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        } finally {
24805e858400adee0f579b1e27e321b48bd55843fbdJohn Reck            mRootNode.end(canvas);
24905e858400adee0f579b1e27e321b48bd55843fbdJohn Reck            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
25005e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        }
251cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
252cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = false;
253bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    }
254bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
255bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    @Override
256e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
257bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        attachInfo.mIgnoreDirtyState = true;
25818f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck        long frameTimeNanos = mChoreographer.getFrameTimeNanos();
259315c329544d7c593d1072b071cbb92d9afe74021John Reck        attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS;
260bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
261fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        long recordDuration = 0;
262fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        if (mProfilingEnabled) {
263fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            recordDuration = System.nanoTime();
264fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
265fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
266bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        updateRootDisplayList(view, callbacks);
267cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
268fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        if (mProfilingEnabled) {
269fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck            recordDuration = System.nanoTime() - recordDuration;
270fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck        }
271fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
2726313b9259d37b59f3402058e197637aa3014516cJohn Reck        attachInfo.mIgnoreDirtyState = false;
2736313b9259d37b59f3402058e197637aa3014516cJohn Reck
274f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos,
275e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck                recordDuration, view.getResources().getDisplayMetrics().density);
276f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
277f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck            attachInfo.mViewRootImpl.invalidate();
278f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck        }
279cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
280cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
2813b20251a355c88193c439f928a84ae69483fb488John Reck    static void invokeFunctor(long functor, boolean waitForCompletion) {
2823b20251a355c88193c439f928a84ae69483fb488John Reck        nInvokeFunctor(functor, waitForCompletion);
2830d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    }
2840d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck
2850d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    @Override
28619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    HardwareLayer createTextureLayer() {
28719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        long layer = nCreateTextureLayer(mNativeProxy);
28819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return HardwareLayer.adoptTextureLayer(this, layer);
289cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
290cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
291cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
29219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
29319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return nCopyLayerInto(mNativeProxy,
29419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck                layer.getDeferredLayerUpdater(), bitmap.mNativeBitmap);
295cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
296cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
297cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
29819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void pushLayerUpdate(HardwareLayer layer) {
299d72e0a339b54af0c4e731513bbad120dff694723John Reck        nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
30019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
30119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
30219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    @Override
30319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void onLayerDestroyed(HardwareLayer layer) {
304d72e0a339b54af0c4e731513bbad120dff694723John Reck        nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
305cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
306cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
307cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
308cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void setName(String name) {
309cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
310cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
3114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    @Override
31228ad7b52e038ef0cdd89f753d9839444a434b299John Reck    void fence() {
31328ad7b52e038ef0cdd89f753d9839444a434b299John Reck        nFence(mNativeProxy);
31428ad7b52e038ef0cdd89f753d9839444a434b299John Reck    }
31528ad7b52e038ef0cdd89f753d9839444a434b299John Reck
31628ad7b52e038ef0cdd89f753d9839444a434b299John Reck    @Override
317f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    void stopDrawing() {
318f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nStopDrawing(mNativeProxy);
319f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    }
320f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck
321f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    @Override
322a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    public void notifyFramePending() {
323a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck        nNotifyFramePending(mNativeProxy);
324a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    }
325a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck
326a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    @Override
3274f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    protected void finalize() throws Throwable {
3284f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        try {
3294f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            nDeleteProxy(mNativeProxy);
3300ed751dd22a98f0c1f637570c5775b4f5e97d895John Reck            mNativeProxy = 0;
3314f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        } finally {
3324f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            super.finalize();
333cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        }
334cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
335cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
336f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    static void trimMemory(int level) {
337f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck        nTrimMemory(level);
33884a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    }
33984a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
34066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    private static class AtlasInitializer {
34166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        static AtlasInitializer sInstance = new AtlasInitializer();
34266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
34366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        private boolean mInitialized = false;
34466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
34566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        private AtlasInitializer() {}
34666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
3473b20251a355c88193c439f928a84ae69483fb488John Reck        synchronized void init(Context context, long renderProxy) {
34866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (mInitialized) return;
34966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IBinder binder = ServiceManager.getService("assetatlas");
35066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            if (binder == null) return;
35166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
35266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
35366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            try {
35466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                if (atlas.isCompatible(android.os.Process.myPpid())) {
35566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    GraphicBuffer buffer = atlas.getBuffer();
35666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    if (buffer != null) {
35766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        long[] map = atlas.getMap();
35866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (map != null) {
359b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                            // TODO Remove after fixing b/15425820
360b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                            validateMap(context, map);
3613b20251a355c88193c439f928a84ae69483fb488John Reck                            nSetAtlas(renderProxy, buffer, map);
36266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                            mInitialized = true;
36366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
36466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // If IAssetAtlas is not the same class as the IBinder
36566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // we are using a remote service and we can safely
36666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        // destroy the graphic buffer
36766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        if (atlas.getClass() != binder.getClass()) {
36866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                            buffer.destroy();
36966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                        }
37066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                    }
37166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                }
37266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            } catch (RemoteException e) {
37366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck                Log.w(LOG_TAG, "Could not acquire atlas", e);
37466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck            }
37566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck        }
376b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck
377b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck        private static void validateMap(Context context, long[] map) {
378b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            Log.d("Atlas", "Validating map...");
379b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            HashSet<Long> preloadedPointers = new HashSet<Long>();
380b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck
381b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            // We only care about drawables that hold bitmaps
382b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            final Resources resources = context.getResources();
383b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables();
384b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck
385b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            final int count = drawables.size();
386b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            for (int i = 0; i < count; i++) {
387b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                final Bitmap bitmap = drawables.valueAt(i).getBitmap();
388b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
389b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                    preloadedPointers.add(bitmap.mNativeBitmap);
390b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                }
391b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            }
392b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck
393b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            for (int i = 0; i < map.length; i += 4) {
394b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                if (!preloadedPointers.contains(map[i])) {
395b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                    Log.w("Atlas", String.format("Pointer 0x%X, not in getPreloadedDrawables?", map[i]));
396b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                    map[i] = 0;
397b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck                }
398b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck            }
399b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck        }
40066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck    }
40166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck
40284a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck    static native void setupShadersDiskCache(String cacheFile);
40384a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck
4043b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
405cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
406e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateRootRenderNode();
407e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateProxy(boolean translucent, long rootRenderNode);
4084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nDeleteProxy(long nativeProxy);
409cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
41018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck    private static native void nSetFrameInterval(long nativeProxy, long frameIntervalNanos);
411e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck    private static native boolean nLoadSystemProperties(long nativeProxy);
41218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck
4134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native boolean nInitialize(long nativeProxy, Surface window);
4144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nUpdateSurface(long nativeProxy, Surface window);
415f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private static native void nPauseSurface(long nativeProxy, Surface window);
416797b95b26bbb7557678af78b9a2a61830158920fChris Craik    private static native void nSetup(long nativeProxy, int width, int height,
417797b95b26bbb7557678af78b9a2a61830158920fChris Craik            float lightX, float lightY, float lightZ, float lightRadius);
41863a06673253914510bbeebd500655008682dade1John Reck    private static native void nSetOpaque(long nativeProxy, boolean opaque);
419fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static native int nSyncAndDrawFrame(long nativeProxy,
420e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck            long frameTimeNanos, long recordDuration, float density);
421fae904d63947fe1687d1d44be29234cc3d538f24John Reck    private static native void nDestroyCanvasAndSurface(long nativeProxy);
422cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
4233b20251a355c88193c439f928a84ae69483fb488John Reck    private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
42419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
42519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateDisplayListLayer(long nativeProxy, int width, int height);
42619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateTextureLayer(long nativeProxy);
42719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
428d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nPushLayerUpdate(long nativeProxy, long layer);
429d72e0a339b54af0c4e731513bbad120dff694723John Reck    private static native void nCancelLayerUpdate(long nativeProxy, long layer);
430918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck    private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
43128ad7b52e038ef0cdd89f753d9839444a434b299John Reck
432f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nDestroyHardwareResources(long nativeProxy);
433f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nTrimMemory(int level);
434e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck
43528ad7b52e038ef0cdd89f753d9839444a434b299John Reck    private static native void nFence(long nativeProxy);
436f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck    private static native void nStopDrawing(long nativeProxy);
437a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck    private static native void nNotifyFramePending(long nativeProxy);
438fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck
439fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck    private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd);
440cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}
441