diff options
| author | Romain Guy <romainguy@google.com> | 2012-03-23 18:58:36 -0700 |
|---|---|---|
| committer | Romain Guy <romainguy@google.com> | 2012-03-23 19:04:36 -0700 |
| commit | a998dff5d49a423aaf7097aa8f96bf5bdc681d25 (patch) | |
| tree | a76c4185a5c57c4f2e4aa423845b7e42bc59fe83 /core/java | |
| parent | 5d6999e1ca457948e06792ea6259ffa947c9fa81 (diff) | |
| download | frameworks_base-a998dff5d49a423aaf7097aa8f96bf5bdc681d25.zip frameworks_base-a998dff5d49a423aaf7097aa8f96bf5bdc681d25.tar.gz frameworks_base-a998dff5d49a423aaf7097aa8f96bf5bdc681d25.tar.bz2 | |
Destroy the hardware renderer when ViewRootImpl's die is post-poned
Bug #6109035
ViewRootImpl.die() can be invoked in such a way that doDie() will be
executed later. On memory limited device, an eglTerminate() may happen
before doDie() is executed which leads to unstable behaviors. This
change makes sure the renderer is destroyed as soon as possible.
Change-Id: I3322410cdd744b464951e2055aeade6069d1d673
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 54 | ||||
| -rw-r--r-- | core/java/android/view/HardwareRenderer.java | 4 | ||||
| -rw-r--r-- | core/java/android/view/TextureView.java | 2 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 11 | ||||
| -rw-r--r-- | core/java/android/view/ViewGroup.java | 2 | ||||
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 27 | ||||
| -rw-r--r-- | core/java/android/view/WindowManagerImpl.java | 2 |
7 files changed, 48 insertions, 54 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 2a3e213..deb711d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -404,6 +404,7 @@ public final class ActivityThread { try { fd.close(); } catch (IOException e) { + // Ignore } } return; @@ -412,6 +413,7 @@ public final class ActivityThread { try { profileFd.close(); } catch (IOException e) { + // Ignore } } profileFile = file; @@ -843,14 +845,13 @@ public final class ActivityThread { FileOutputStream fout = new FileOutputStream(fd); PrintWriter pw = new PrintWriter(fout); try { - return dumpMemInfo(pw, checkin, all, args); + return dumpMemInfo(pw, checkin, all); } finally { pw.flush(); } } - private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all, - String[] args) { + private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) { long nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; @@ -1458,17 +1459,6 @@ public final class ActivityThread { return dm; } - static Configuration applyConfigCompat(Configuration config, CompatibilityInfo compat) { - if (config == null) { - return null; - } - if (compat != null && !compat.supportsScreen()) { - config = new Configuration(config); - compat.applyToConfiguration(config); - } - return config; - } - private Configuration mMainThreadConfig = new Configuration(); Configuration applyConfigCompatMainThread(Configuration config, CompatibilityInfo compat) { if (config == null) { @@ -2509,7 +2499,7 @@ public final class ActivityThread { return r; } - final void cleanUpPendingRemoveWindows(ActivityClientRecord r) { + static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) { if (r.mPendingRemoveWindow != null) { r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow); IBinder wtoken = r.mPendingRemoveWindow.getWindowToken(); @@ -3437,15 +3427,12 @@ public final class ActivityThread { = new ArrayList<ComponentCallbacks2>(); if (mActivities.size() > 0) { - Iterator<ActivityClientRecord> it = mActivities.values().iterator(); - while (it.hasNext()) { - ActivityClientRecord ar = it.next(); + for (ActivityClientRecord ar : mActivities.values()) { Activity a = ar.activity; if (a != null) { Configuration thisConfig = applyConfigCompatMainThread(newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded()); - if (!ar.activity.mFinished && (allActivities || - (a != null && !ar.paused))) { + if (!ar.activity.mFinished && (allActivities || !ar.paused)) { // If the activity is currently resumed, its configuration // needs to change right now. callbacks.add(a); @@ -3455,24 +3442,24 @@ public final class ActivityThread { // the activity manager may, before then, decide the // activity needs to be destroyed to handle its new // configuration. - if (DEBUG_CONFIGURATION) Slog.v(TAG, "Setting activity " - + ar.activityInfo.name + " newConfig=" + thisConfig); + if (DEBUG_CONFIGURATION) { + Slog.v(TAG, "Setting activity " + + ar.activityInfo.name + " newConfig=" + thisConfig); + } ar.newConfig = thisConfig; } } } } if (mServices.size() > 0) { - Iterator<Service> it = mServices.values().iterator(); - while (it.hasNext()) { - callbacks.add(it.next()); + for (Service service : mServices.values()) { + callbacks.add(service); } } synchronized (mProviderMap) { if (mLocalProviders.size() > 0) { - Iterator<ProviderClientRecord> it = mLocalProviders.values().iterator(); - while (it.hasNext()) { - callbacks.add(it.next().mLocalProvider); + for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) { + callbacks.add(providerClientRecord.mLocalProvider); } } } @@ -3484,8 +3471,7 @@ public final class ActivityThread { return callbacks; } - private final void performConfigurationChanged( - ComponentCallbacks2 cb, Configuration config) { + private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) { // Only for Activity objects, check that they actually call up to their // superclass implementation. ComponentCallbacks2 is an interface, so // we check the runtime type and act accordingly. @@ -3692,7 +3678,7 @@ public final class ActivityThread { } } - final void handleDumpHeap(boolean managed, DumpHeapData dhd) { + static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { if (managed) { try { Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); @@ -3769,7 +3755,7 @@ public final class ActivityThread { } final int N = callbacks.size(); - for (int i=0; i<N; i++) { + for (int i = 0; i < N; i++) { callbacks.get(i).onTrimMemory(level); } WindowManagerImpl.getDefault().terminateEgl(); @@ -4057,9 +4043,7 @@ public final class ActivityThread { final ArrayList<IActivityManager.ContentProviderHolder> results = new ArrayList<IActivityManager.ContentProviderHolder>(); - Iterator<ProviderInfo> i = providers.iterator(); - while (i.hasNext()) { - ProviderInfo cpi = i.next(); + for (ProviderInfo cpi : providers) { StringBuilder buf = new StringBuilder(128); buf.append("Pub "); buf.append(cpi.authority); diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 1f140e9..f98cfc0 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -1121,6 +1121,7 @@ public abstract class HardwareRenderer { GLES20Canvas.terminateCaches(); sEgl.eglDestroyContext(sEglDisplay, eglContext); + sEglContextStorage.set(null); sEglContextStorage.remove(); sEgl.eglDestroySurface(sEglDisplay, sPbuffer); @@ -1134,7 +1135,6 @@ public abstract class HardwareRenderer { sEglDisplay = null; sEglConfig = null; sPbuffer = null; - sEglContextStorage.set(null); } } } @@ -1238,7 +1238,7 @@ public abstract class HardwareRenderer { } private static void destroyHardwareLayer(View view) { - view.destroyLayer(); + view.destroyLayer(true); if (view instanceof ViewGroup) { ViewGroup group = (ViewGroup) view; diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index fc02cc1..83999a1 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -299,7 +299,7 @@ public class TextureView extends View { } @Override - boolean destroyLayer() { + boolean destroyLayer(boolean valid) { return false; } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index ffffc73..63cf4ae 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -10018,7 +10018,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal destroyDrawingCache(); - destroyLayer(); + destroyLayer(false); if (mAttachInfo != null) { if (mDisplayList != null) { @@ -10394,7 +10394,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal // Destroy any previous software drawing cache if needed switch (mLayerType) { case LAYER_TYPE_HARDWARE: - destroyLayer(); + destroyLayer(false); // fall through - non-accelerated views may use software layer mechanism instead case LAYER_TYPE_SOFTWARE: destroyDrawingCache(); @@ -10532,11 +10532,12 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * @see #setLayerType(int, android.graphics.Paint) * @see #LAYER_TYPE_HARDWARE */ - boolean destroyLayer() { + boolean destroyLayer(boolean valid) { if (mHardwareLayer != null) { AttachInfo info = mAttachInfo; if (info != null && info.mHardwareRenderer != null && - info.mHardwareRenderer.isEnabled() && info.mHardwareRenderer.validate()) { + info.mHardwareRenderer.isEnabled() && + (valid || info.mHardwareRenderer.validate())) { mHardwareLayer.destroy(); mHardwareLayer = null; @@ -10560,7 +10561,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * @hide */ protected void destroyHardwareResources() { - destroyLayer(); + destroyLayer(true); } /** diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index b8fbf17..6ccac78 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -1820,7 +1820,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * Resets the cancel next up flag. * Returns true if the flag was previously set. */ - private boolean resetCancelNextUpFlag(View view) { + private static boolean resetCancelNextUpFlag(View view) { if ((view.mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) { view.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT; return true; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 14b8084..befc1c6 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1809,7 +1809,7 @@ public final class ViewRootImpl implements ViewParent, * * @return The measure spec to use to measure the root view. */ - private int getRootMeasureSpec(int windowSize, int rootDimension) { + private static int getRootMeasureSpec(int windowSize, int rootDimension) { int measureSpec; switch (rootDimension) { @@ -2432,12 +2432,12 @@ public final class ViewRootImpl implements ViewParent, mAccessibilityInteractionConnectionManager); removeSendWindowContentChangedCallback(); + destroyHardwareRenderer(); + mView = null; mAttachInfo.mRootView = null; mAttachInfo.mSurface = null; - destroyHardwareRenderer(); - mSurface.release(); if (mInputQueueCallback != null && mInputQueue != null) { @@ -2893,7 +2893,7 @@ public final class ViewRootImpl implements ViewParent, * @param focused The currently focused view. * @return An appropriate view, or null if no such view exists. */ - private ViewGroup findAncestorToTakeFocusInTouchMode(View focused) { + private static ViewGroup findAncestorToTakeFocusInTouchMode(View focused) { ViewParent parent = focused.getParent(); while (parent instanceof ViewGroup) { final ViewGroup vgParent = (ViewGroup) parent; @@ -3763,7 +3763,7 @@ public final class ViewRootImpl implements ViewParent, } } - private void getGfxInfo(View view, int[] info) { + private static void getGfxInfo(View view, int[] info) { DisplayList displayList = view.mDisplayList; info[0]++; if (displayList != null) { @@ -3784,6 +3784,7 @@ public final class ViewRootImpl implements ViewParent, if (immediate) { doDie(); } else { + destroyHardwareRenderer(); mHandler.sendEmptyMessage(MSG_DIE); } } @@ -3826,10 +3827,18 @@ public final class ViewRootImpl implements ViewParent, } private void destroyHardwareRenderer() { - if (mAttachInfo.mHardwareRenderer != null) { - mAttachInfo.mHardwareRenderer.destroy(true); - mAttachInfo.mHardwareRenderer = null; - mAttachInfo.mHardwareAccelerated = false; + AttachInfo attachInfo = mAttachInfo; + HardwareRenderer hardwareRenderer = attachInfo.mHardwareRenderer; + + if (hardwareRenderer != null) { + if (mView != null) { + hardwareRenderer.destroyHardwareResources(mView); + } + hardwareRenderer.destroy(true); + hardwareRenderer.setRequested(false); + + attachInfo.mHardwareRenderer = null; + attachInfo.mHardwareAccelerated = false; } } diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java index 0e4a30f..f2ee9f9 100644 --- a/core/java/android/view/WindowManagerImpl.java +++ b/core/java/android/view/WindowManagerImpl.java @@ -354,7 +354,7 @@ public class WindowManagerImpl implements WindowManager { View removeViewLocked(int index) { ViewRootImpl root = mRoots[index]; View view = root.getView(); - + // Don't really remove until we have matched all calls to add(). root.mAddNesting--; if (root.mAddNesting > 0) { |
