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