summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2012-10-23 19:17:15 -0700
committerRomain Guy <romainguy@google.com>2012-10-23 19:17:15 -0700
commitbd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1 (patch)
tree915363e650c64062b6b53f8076c14c19791efda8
parent3a2d6aaf8e71a89f82517369acc03d46ffe9bb22 (diff)
downloadframeworks_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.java53
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() {