ThreadedRenderer.java revision f6829a0a618b4523619ec53c996b04d67e3186b9
1cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/* 2cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Copyright (C) 2013 The Android Open Source Project 3cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * 4cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Licensed under the Apache License, Version 2.0 (the "License"); 5cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * you may not use this file except in compliance with the License. 6cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * You may obtain a copy of the License at 7cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * 8cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * http://www.apache.org/licenses/LICENSE-2.0 9cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * 10cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Unless required by applicable law or agreed to in writing, software 11cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * distributed under the License is distributed on an "AS IS" BASIS, 12cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * See the License for the specific language governing permissions and 14cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * limitations under the License. 15cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */ 16cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 17cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpackage android.view; 18cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 19ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport android.annotation.IntDef; 20b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.content.Context; 21b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.content.res.Resources; 2258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viveretteimport android.content.res.TypedArray; 2304fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckimport android.graphics.Bitmap; 24ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viveretteimport android.graphics.Rect; 25b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.graphics.drawable.Drawable; 2666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.IBinder; 2766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.RemoteException; 2866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.os.ServiceManager; 29cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.os.Trace; 3066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reckimport android.util.Log; 31b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport android.util.LongSparseArray; 32cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.Surface.OutOfResourcesException; 33cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.View.AttachInfo; 34cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 35ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport com.android.internal.R; 36ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck 37fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckimport java.io.FileDescriptor; 38cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport java.io.PrintWriter; 39ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.Retention; 40ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reckimport java.lang.annotation.RetentionPolicy; 41dad7d84c04c5954b63ea8bb58c52b2291f44b4dfJohn Reckimport java.util.ArrayList; 42b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reckimport java.util.HashSet; 43cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 44cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/** 45cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Hardware renderer that proxies the rendering to a render thread. Most calls 464f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * are currently synchronous. 47cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * 48cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * The UI thread can block on the RenderThread, but RenderThread must never 49cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * block on the UI thread. 50cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * 514f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates 524f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed 534f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * by the lifecycle of the RenderProxy. 544f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * 55cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Note that although currently the EGL context & surfaces are created & managed 56cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * by the render thread, the goal is to move that into a shared structure that can 57cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * be managed by both threads. EGLSurface creation & deletion should ideally be 58cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * done on the UI thread and not the RenderThread to avoid stalling the 59cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * RenderThread with surface buffer allocation. 60cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * 61cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * @hide 62cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */ 63cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpublic class ThreadedRenderer extends HardwareRenderer { 64cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck private static final String LOGTAG = "ThreadedRenderer"; 65cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 66f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck // Keep in sync with DrawFrameTask.h SYNC_* flags 67f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck // Nothing interesting to report 68cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck private static final int SYNC_OK = 0; 69f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck // Needs a ViewRoot invalidate 70cd028f336e36b22dbe8cf623eb5bd2361314495cJohn Reck private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0; 71aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck // Spoiler: the reward is GPU-accelerated drawing, better find that Surface! 72aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1; 73f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck 74fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck private static final String[] VISUALIZERS = { 75fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck PROFILE_PROPERTY_VISUALIZE_BARS, 76fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck }; 77fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 78ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck private static final int FLAG_DUMP_FRAMESTATS = 1 << 0; 79ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck private static final int FLAG_DUMP_RESET = 1 << 1; 80ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck 81ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck @IntDef(flag = true, value = { 82ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck FLAG_DUMP_FRAMESTATS, FLAG_DUMP_RESET }) 83ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck @Retention(RetentionPolicy.SOURCE) 84ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck public @interface DumpFlags {} 85ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck 86ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette // Size of the rendered content. 87cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck private int mWidth, mHeight; 88ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 89ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette // Actual size of the drawing surface. 90ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette private int mSurfaceWidth, mSurfaceHeight; 91ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 92ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette // Insets between the drawing surface and rendered content. These are 93ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette // applied as translation when updating the root render node. 94ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette private int mInsetTop, mInsetLeft; 95ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette 9657774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette // Whether the surface has insets. Used to protect opacity. 9757774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette private boolean mHasInsets; 9857774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette 9958c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette // Light and shadow properties specified by the theme. 10058c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette private final float mLightY; 10158c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette private final float mLightZ; 10258c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette private final float mLightRadius; 103058fc640017c90120c599d378a4cbc55668b05b7Chris Craik private final int mAmbientShadowAlpha; 104058fc640017c90120c599d378a4cbc55668b05b7Chris Craik private final int mSpotShadowAlpha; 105ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck private final float mDensity; 10658c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette 1074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck private long mNativeProxy; 108f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck private boolean mInitialized = false; 109bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck private RenderNode mRootNode; 11018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck private Choreographer mChoreographer; 1110a97330b98dd633b58dcfff405d94476c89e867dJohn Reck private boolean mRootNodeNeedsUpdate; 112cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 113b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck ThreadedRenderer(Context context, boolean translucent) { 114ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0); 11558c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette mLightY = a.getDimension(R.styleable.Lighting_lightY, 0); 11658c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0); 11758c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0); 118ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette mAmbientShadowAlpha = 119ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f); 120ed6f14a20c69da3d221cc1acbaa31e74e837917cAlan Viverette mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f); 12158c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette a.recycle(); 122ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck mDensity = context.getResources().getDisplayMetrics().density; 12358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette 124e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck long rootNodePtr = nCreateRootRenderNode(); 125e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck mRootNode = RenderNode.adopt(rootNodePtr); 126bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck mRootNode.setClipToBounds(false); 127e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck mNativeProxy = nCreateProxy(translucent, rootNodePtr); 12818f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck 1293b20251a355c88193c439f928a84ae69483fb488John Reck AtlasInitializer.sInstance.init(context, mNativeProxy); 1303b20251a355c88193c439f928a84ae69483fb488John Reck 13118f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck // Setup timing 13218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck mChoreographer = Choreographer.getInstance(); 13318f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck nSetFrameInterval(mNativeProxy, mChoreographer.getFrameIntervalNanos()); 134fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 135fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck loadSystemProperties(); 136cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 137cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 138cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 139f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck void destroy() { 140f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck mInitialized = false; 141f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck updateEnabledState(null); 14217035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck nDestroy(mNativeProxy); 143cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 144cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 145f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck private void updateEnabledState(Surface surface) { 146f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck if (surface == null || !surface.isValid()) { 147f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck setEnabled(false); 148f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck } else { 149f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck setEnabled(mInitialized); 150f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck } 151f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck } 152f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck 153cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 154cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck boolean initialize(Surface surface) throws OutOfResourcesException { 155f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck mInitialized = true; 156f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck updateEnabledState(surface); 1575795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza boolean status = nInitialize(mNativeProxy, surface); 1585795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza surface.allocateBuffers(); 1595795d6408d8bf44ffe2f49a25f9f333069b59a49Dan Stoza return status; 160cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 161cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 162cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 163cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck void updateSurface(Surface surface) throws OutOfResourcesException { 164f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck updateEnabledState(surface); 1654f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck nUpdateSurface(mNativeProxy, surface); 166cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 167cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 168cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 16901a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck boolean pauseSurface(Surface surface) { 17001a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck return nPauseSurface(mNativeProxy, surface); 171f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck } 172f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck 173f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck @Override 174cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck void destroyHardwareResources(View view) { 1754f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck destroyResources(view); 176f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck nDestroyHardwareResources(mNativeProxy); 1774f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 1784f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 1794f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck private static void destroyResources(View view) { 1804f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck view.destroyHardwareResources(); 1814f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 1824f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck if (view instanceof ViewGroup) { 1834f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck ViewGroup group = (ViewGroup) view; 1844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck 1854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck int count = group.getChildCount(); 1864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck for (int i = 0; i < count; i++) { 1874f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck destroyResources(group.getChildAt(i)); 1884f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 1894f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } 190cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 191cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 192cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 193cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck void invalidate(Surface surface) { 1944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck updateSurface(surface); 195cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 196cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 197cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 198918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck void detachSurfaceTexture(long hardwareLayer) { 199918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck nDetachSurfaceTexture(mNativeProxy, hardwareLayer); 200cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 201cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 202cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 20358c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette void setup(int width, int height, Rect surfaceInsets) { 20458c42c3596a2b79184c9a6b7beffc6e94cce112cAlan Viverette final float lightX = width / 2.0f; 205cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck mWidth = width; 206cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck mHeight = height; 2073aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0 2083aa1ffbc75e39b8e53b64256775ea917ca0c6beeAlan Viverette || surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) { 20957774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette mHasInsets = true; 210ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mInsetLeft = surfaceInsets.left; 211ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mInsetTop = surfaceInsets.top; 212ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mSurfaceWidth = width + mInsetLeft + surfaceInsets.right; 213ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mSurfaceHeight = height + mInsetTop + surfaceInsets.bottom; 21457774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette 21557774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette // If the surface has insets, it can't be opaque. 21657774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette setOpaque(false); 217ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } else { 21857774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette mHasInsets = false; 219ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mInsetLeft = 0; 220ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mInsetTop = 0; 221ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mSurfaceWidth = width; 222ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mSurfaceHeight = height; 223ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette } 224ccb11e183763db5cbaca96abe461adf480ed8e44Alan Viverette mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight); 225058fc640017c90120c599d378a4cbc55668b05b7Chris Craik nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, 226058fc640017c90120c599d378a4cbc55668b05b7Chris Craik lightX, mLightY, mLightZ, mLightRadius, 227ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck mAmbientShadowAlpha, mSpotShadowAlpha, mDensity); 228cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 229cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 230cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 23163a06673253914510bbeebd500655008682dade1John Reck void setOpaque(boolean opaque) { 23257774a82f02c225941f81cf89c7a03bf899df2c1Alan Viverette nSetOpaque(mNativeProxy, opaque && !mHasInsets); 23363a06673253914510bbeebd500655008682dade1John Reck } 23463a06673253914510bbeebd500655008682dade1John Reck 23563a06673253914510bbeebd500655008682dade1John Reck @Override 236cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck int getWidth() { 237cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck return mWidth; 238cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 239cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 240cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 241cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck int getHeight() { 242cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck return mHeight; 243cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 244cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 245cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 246ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) { 247fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck pw.flush(); 248ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck int flags = 0; 249ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck for (int i = 0; i < args.length; i++) { 250ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck switch (args[i]) { 251ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck case "framestats": 252ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck flags |= FLAG_DUMP_FRAMESTATS; 253ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck break; 254ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck case "reset": 255ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck flags |= FLAG_DUMP_RESET; 256ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck break; 257ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck } 258fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck } 259ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck nDumpProfileInfo(mNativeProxy, fd, flags); 260cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 261cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 262cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 263cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck boolean loadSystemProperties() { 264fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck boolean changed = nLoadSystemProperties(mNativeProxy); 26523d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck if (changed) { 26623d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck invalidateRoot(); 26723d307c8d88f4a3849163b9e5b7cd11d0d4f372cJohn Reck } 268fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck return changed; 269cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 270cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 2710a97330b98dd633b58dcfff405d94476c89e867dJohn Reck private void updateViewTreeDisplayList(View view) { 272cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck view.mPrivateFlags |= View.PFLAG_DRAWN; 273cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED) 274cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck == View.PFLAG_INVALIDATED; 275cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck view.mPrivateFlags &= ~View.PFLAG_INVALIDATED; 2760a97330b98dd633b58dcfff405d94476c89e867dJohn Reck view.getDisplayList(); 2770a97330b98dd633b58dcfff405d94476c89e867dJohn Reck view.mRecreateDisplayList = false; 2780a97330b98dd633b58dcfff405d94476c89e867dJohn Reck } 279cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 28061375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) { 28170850ea258cbf91477efa57a1f1a23cc0044cc93Chris Craik Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Record View#draw()"); 2820a97330b98dd633b58dcfff405d94476c89e867dJohn Reck updateViewTreeDisplayList(view); 2830a97330b98dd633b58dcfff405d94476c89e867dJohn Reck 2840a97330b98dd633b58dcfff405d94476c89e867dJohn Reck if (mRootNodeNeedsUpdate || !mRootNode.isValid()) { 285f6829a0a618b4523619ec53c996b04d67e3186b9Chris Craik DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight); 2860a97330b98dd633b58dcfff405d94476c89e867dJohn Reck try { 287dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette final int saveCount = canvas.save(); 2880a97330b98dd633b58dcfff405d94476c89e867dJohn Reck canvas.translate(mInsetLeft, mInsetTop); 2890a97330b98dd633b58dcfff405d94476c89e867dJohn Reck callbacks.onHardwarePreDraw(canvas); 290abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik 291abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik canvas.insertReorderBarrier(); 2920a97330b98dd633b58dcfff405d94476c89e867dJohn Reck canvas.drawRenderNode(view.getDisplayList()); 293abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik canvas.insertInorderBarrier(); 294abedca398334236f9f03b5af04c58d4bb00a1247Chris Craik 2950a97330b98dd633b58dcfff405d94476c89e867dJohn Reck callbacks.onHardwarePostDraw(canvas); 296dbed893ba88b76f88ea51d8666653458955cdc67Alan Viverette canvas.restoreToCount(saveCount); 2970a97330b98dd633b58dcfff405d94476c89e867dJohn Reck mRootNodeNeedsUpdate = false; 2980a97330b98dd633b58dcfff405d94476c89e867dJohn Reck } finally { 2990a97330b98dd633b58dcfff405d94476c89e867dJohn Reck mRootNode.end(canvas); 3000a97330b98dd633b58dcfff405d94476c89e867dJohn Reck } 30105e858400adee0f579b1e27e321b48bd55843fbdJohn Reck } 3020a97330b98dd633b58dcfff405d94476c89e867dJohn Reck Trace.traceEnd(Trace.TRACE_TAG_VIEW); 3030a97330b98dd633b58dcfff405d94476c89e867dJohn Reck } 304cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 3050a97330b98dd633b58dcfff405d94476c89e867dJohn Reck @Override 3060a97330b98dd633b58dcfff405d94476c89e867dJohn Reck void invalidateRoot() { 3070a97330b98dd633b58dcfff405d94476c89e867dJohn Reck mRootNodeNeedsUpdate = true; 308bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck } 309bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck 310bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck @Override 31161375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) { 312bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck attachInfo.mIgnoreDirtyState = true; 313bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck 314ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer; 315ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck choreographer.mFrameInfo.markDrawStart(); 316fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 31761375a8bb5e112d4e79ee4240699ffe7e3f4c8e5John Reck updateRootDisplayList(view, callbacks); 318cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 3196313b9259d37b59f3402058e197637aa3014516cJohn Reck attachInfo.mIgnoreDirtyState = false; 3206313b9259d37b59f3402058e197637aa3014516cJohn Reck 321119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck // register animating rendernodes which started animating prior to renderer 322119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck // creation, which is typical for animators started prior to first draw 323119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck if (attachInfo.mPendingAnimatingRenderNodes != null) { 324119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck final int count = attachInfo.mPendingAnimatingRenderNodes.size(); 325119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck for (int i = 0; i < count; i++) { 326119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck registerAnimatingRenderNode( 327119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck attachInfo.mPendingAnimatingRenderNodes.get(i)); 328119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck } 329119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck attachInfo.mPendingAnimatingRenderNodes.clear(); 330119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck // We don't need this anymore as subsequent calls to 331119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck // ViewRootImpl#attachRenderNodeAnimator will go directly to us. 332119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck attachInfo.mPendingAnimatingRenderNodes = null; 333119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck } 334119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 335ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo; 336ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length); 337aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) { 338aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck setEnabled(false); 339b13de07f0b26953115f4315bc7417ca87c70594bJohn Reck attachInfo.mViewRootImpl.mSurface.release(); 340aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck // Invalidate since we failed to draw. This should fetch a Surface 341aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck // if it is still needed or do nothing if we are no longer drawing 342aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck attachInfo.mViewRootImpl.invalidate(); 343aa95a88327d9a3ac8a4a00b065b78ac0f28b3a19John Reck } 344f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) { 345f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck attachInfo.mViewRootImpl.invalidate(); 346f9be77940e365036fecd8cc0e491e8545c34e79bJohn Reck } 347cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 348cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 3493b20251a355c88193c439f928a84ae69483fb488John Reck static void invokeFunctor(long functor, boolean waitForCompletion) { 3503b20251a355c88193c439f928a84ae69483fb488John Reck nInvokeFunctor(functor, waitForCompletion); 3510d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck } 3520d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck 3530d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck @Override 35419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck HardwareLayer createTextureLayer() { 35519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck long layer = nCreateTextureLayer(mNativeProxy); 35619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck return HardwareLayer.adoptTextureLayer(this, layer); 357cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 358cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 359cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 3603e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck void buildLayer(RenderNode node) { 3613e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck nBuildLayer(mNativeProxy, node.getNativeDisplayList()); 3623e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck } 3633e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck 3643e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck @Override 36519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) { 36619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck return nCopyLayerInto(mNativeProxy, 367f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck layer.getDeferredLayerUpdater(), bitmap.getSkBitmap()); 368cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 369cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 370cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 37119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck void pushLayerUpdate(HardwareLayer layer) { 372d72e0a339b54af0c4e731513bbad120dff694723John Reck nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater()); 37319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck } 37419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 37519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck @Override 37619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck void onLayerDestroyed(HardwareLayer layer) { 377d72e0a339b54af0c4e731513bbad120dff694723John Reck nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater()); 378cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 379cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 380cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck @Override 381cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck void setName(String name) { 382cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 383cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 3844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck @Override 38528ad7b52e038ef0cdd89f753d9839444a434b299John Reck void fence() { 38628ad7b52e038ef0cdd89f753d9839444a434b299John Reck nFence(mNativeProxy); 38728ad7b52e038ef0cdd89f753d9839444a434b299John Reck } 38828ad7b52e038ef0cdd89f753d9839444a434b299John Reck 38928ad7b52e038ef0cdd89f753d9839444a434b299John Reck @Override 390f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck void stopDrawing() { 391f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck nStopDrawing(mNativeProxy); 392f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck } 393f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck 394f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck @Override 395a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck public void notifyFramePending() { 396a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck nNotifyFramePending(mNativeProxy); 397a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck } 398a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck 399a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck @Override 400119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck void registerAnimatingRenderNode(RenderNode animator) { 401119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode); 402119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck } 403119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck 404119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck @Override 4054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck protected void finalize() throws Throwable { 4064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck try { 4074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck nDeleteProxy(mNativeProxy); 4080ed751dd22a98f0c1f637570c5775b4f5e97d895John Reck mNativeProxy = 0; 4094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck } finally { 4104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck super.finalize(); 411cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 412cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck } 413cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 414f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck static void trimMemory(int level) { 415f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck nTrimMemory(level); 41684a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck } 41784a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck 41866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck private static class AtlasInitializer { 41966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck static AtlasInitializer sInstance = new AtlasInitializer(); 42066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 42166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck private boolean mInitialized = false; 42266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 42366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck private AtlasInitializer() {} 42466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 4253b20251a355c88193c439f928a84ae69483fb488John Reck synchronized void init(Context context, long renderProxy) { 42666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck if (mInitialized) return; 42766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck IBinder binder = ServiceManager.getService("assetatlas"); 42866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck if (binder == null) return; 42966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 43066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder); 43166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck try { 43266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck if (atlas.isCompatible(android.os.Process.myPpid())) { 43366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck GraphicBuffer buffer = atlas.getBuffer(); 43466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck if (buffer != null) { 43566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck long[] map = atlas.getMap(); 43666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck if (map != null) { 437b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck // TODO Remove after fixing b/15425820 438b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck validateMap(context, map); 4393b20251a355c88193c439f928a84ae69483fb488John Reck nSetAtlas(renderProxy, buffer, map); 44066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck mInitialized = true; 44166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } 44266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck // If IAssetAtlas is not the same class as the IBinder 44366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck // we are using a remote service and we can safely 44466f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck // destroy the graphic buffer 44566f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck if (atlas.getClass() != binder.getClass()) { 44666f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck buffer.destroy(); 44766f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } 44866f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } 44966f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } 45066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } catch (RemoteException e) { 45166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck Log.w(LOG_TAG, "Could not acquire atlas", e); 45266f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } 45366f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } 454b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck 455b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck private static void validateMap(Context context, long[] map) { 456b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck Log.d("Atlas", "Validating map..."); 457b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck HashSet<Long> preloadedPointers = new HashSet<Long>(); 458b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck 459b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck // We only care about drawables that hold bitmaps 460b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck final Resources resources = context.getResources(); 461b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables(); 462b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck 463b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck final int count = drawables.size(); 464dad7d84c04c5954b63ea8bb58c52b2291f44b4dfJohn Reck ArrayList<Bitmap> tmpList = new ArrayList<Bitmap>(); 465b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck for (int i = 0; i < count; i++) { 466dad7d84c04c5954b63ea8bb58c52b2291f44b4dfJohn Reck drawables.valueAt(i).addAtlasableBitmaps(tmpList); 467dad7d84c04c5954b63ea8bb58c52b2291f44b4dfJohn Reck for (int j = 0; j < tmpList.size(); j++) { 468f4faeac3525fe1ce3707ab785a1651aec367589dJohn Reck preloadedPointers.add(tmpList.get(j).getSkBitmap()); 469b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck } 470dad7d84c04c5954b63ea8bb58c52b2291f44b4dfJohn Reck tmpList.clear(); 471b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck } 472b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck 473b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck for (int i = 0; i < map.length; i += 4) { 474b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck if (!preloadedPointers.contains(map[i])) { 475b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck Log.w("Atlas", String.format("Pointer 0x%X, not in getPreloadedDrawables?", map[i])); 476b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck map[i] = 0; 477b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck } 478b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck } 479b8802b1293c05a14399005aeaeb93b82ec2e2f27John Reck } 48066f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck } 48166f0be65a1046f54ddce0498b242c1fa0776b1eaJohn Reck 48284a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck static native void setupShadersDiskCache(String cacheFile); 48384a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck 4843b20251a355c88193c439f928a84ae69483fb488John Reck private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map); 485cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 486e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck private static native long nCreateRootRenderNode(); 487e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck private static native long nCreateProxy(boolean translucent, long rootRenderNode); 4884f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck private static native void nDeleteProxy(long nativeProxy); 489cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 49018f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck private static native void nSetFrameInterval(long nativeProxy, long frameIntervalNanos); 491e4280baaa709c74d86cf6a389a4674ca665f5af6John Reck private static native boolean nLoadSystemProperties(long nativeProxy); 49218f16e6fba74eda173e1e7c869e6e2e2acc073ffJohn Reck 4934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck private static native boolean nInitialize(long nativeProxy, Surface window); 4944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck private static native void nUpdateSurface(long nativeProxy, Surface window); 49501a5ea35fbba4c5bb1d7790ae1677a2fa752e042John Reck private static native boolean nPauseSurface(long nativeProxy, Surface window); 496797b95b26bbb7557678af78b9a2a61830158920fChris Craik private static native void nSetup(long nativeProxy, int width, int height, 497058fc640017c90120c599d378a4cbc55668b05b7Chris Craik float lightX, float lightY, float lightZ, float lightRadius, 498ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck int ambientShadowAlpha, int spotShadowAlpha, float density); 49963a06673253914510bbeebd500655008682dade1John Reck private static native void nSetOpaque(long nativeProxy, boolean opaque); 500ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size); 50117035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck private static native void nDestroy(long nativeProxy); 502119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode); 503cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck 5043b20251a355c88193c439f928a84ae69483fb488John Reck private static native void nInvokeFunctor(long functor, boolean waitForCompletion); 50519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck 50619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck private static native long nCreateTextureLayer(long nativeProxy); 5073e8249568cc428296ac76c7ddce3f0382d40fe5bJohn Reck private static native void nBuildLayer(long nativeProxy, long node); 50819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap); 509d72e0a339b54af0c4e731513bbad120dff694723John Reck private static native void nPushLayerUpdate(long nativeProxy, long layer); 510d72e0a339b54af0c4e731513bbad120dff694723John Reck private static native void nCancelLayerUpdate(long nativeProxy, long layer); 511918ad523b2780e0c893f3d2a32d4ec13f2a7e921John Reck private static native void nDetachSurfaceTexture(long nativeProxy, long layer); 51228ad7b52e038ef0cdd89f753d9839444a434b299John Reck 513f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck private static native void nDestroyHardwareResources(long nativeProxy); 514f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck private static native void nTrimMemory(int level); 515e1628b7c6fc3822fa83cf02028ce8ad67abb0afeJohn Reck 51628ad7b52e038ef0cdd89f753d9839444a434b299John Reck private static native void nFence(long nativeProxy); 517f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck private static native void nStopDrawing(long nativeProxy); 518a5dda645da738da7b4ae15e28fa7d93d3b04b94fJohn Reck private static native void nNotifyFramePending(long nativeProxy); 519fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 520ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd, 521ba6adf66d3c44c0aa2fd8a224862ff1901d64300John Reck @DumpFlags int dumpFlags); 522cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck} 523