diff options
| author | Romain Guy <romainguy@google.com> | 2012-10-23 19:17:15 -0700 |
|---|---|---|
| committer | Romain Guy <romainguy@google.com> | 2012-10-23 19:17:15 -0700 |
| commit | bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1 (patch) | |
| tree | 915363e650c64062b6b53f8076c14c19791efda8 | |
| parent | 3a2d6aaf8e71a89f82517369acc03d46ffe9bb22 (diff) | |
| download | frameworks_base-bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1.zip frameworks_base-bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1.tar.gz frameworks_base-bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1.tar.bz2 | |
Ensure we have a GL context before deleting View layers
Bug #7391098
The existing code was doing a make current to guarantee we have a
current context. This can however fail when the surface is destroyed
which could lead to GL calls without an EGL context, and therefore
potential leaks. This change fixes the issue by using a technique
found in HardwareRenderer.destroyHardwareResources(). If the surface
is not available then we use a special 1x1 pbuffer as a way to get
a valid context.
Change-Id: I716d3799bf90120d793d76e90a83956837ecd491
| -rw-r--r-- | core/java/android/view/HardwareRenderer.java | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 59f941d..1c613245 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -1526,30 +1526,6 @@ public abstract class HardwareRenderer { } @Override - void destroyLayers(View view) { - if (view != null && isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) { - if (mCanvas != null) { - mCanvas.clearLayerUpdates(); - } - destroyHardwareLayer(view); - GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS); - } - } - - private static void destroyHardwareLayer(View view) { - view.destroyLayer(true); - - if (view instanceof ViewGroup) { - ViewGroup group = (ViewGroup) view; - - int count = group.getChildCount(); - for (int i = 0; i < count; i++) { - destroyHardwareLayer(group.getChildAt(i)); - } - } - } - - @Override boolean safelyRun(Runnable action) { boolean needsContext = true; if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false; @@ -1574,6 +1550,35 @@ public abstract class HardwareRenderer { } @Override + void destroyLayers(final View view) { + if (view != null) { + safelyRun(new Runnable() { + @Override + public void run() { + if (mCanvas != null) { + mCanvas.clearLayerUpdates(); + } + destroyHardwareLayer(view); + GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS); + } + }); + } + } + + private static void destroyHardwareLayer(View view) { + view.destroyLayer(true); + + if (view instanceof ViewGroup) { + ViewGroup group = (ViewGroup) view; + + int count = group.getChildCount(); + for (int i = 0; i < count; i++) { + destroyHardwareLayer(group.getChildAt(i)); + } + } + } + + @Override void destroyHardwareResources(final View view) { if (view != null) { safelyRun(new Runnable() { |
