summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2013-06-17 13:14:51 -0700
committerRomain Guy <romainguy@google.com>2013-06-17 13:35:03 -0700
commite93482f5eac3df581d57e64c2a771a96aa868585 (patch)
tree009afbdf49655b35ee29f857aa554a42c4e96048
parent6410c0aaf13c9aec606b90ee942f2ac2d98b1609 (diff)
downloadframeworks_base-e93482f5eac3df581d57e64c2a771a96aa868585.zip
frameworks_base-e93482f5eac3df581d57e64c2a771a96aa868585.tar.gz
frameworks_base-e93482f5eac3df581d57e64c2a771a96aa868585.tar.bz2
Cancel layer update when a layer is about to be destroyed
Bug #9310706 Change-Id: I73eea6314c326f15a979617e3a05b525935f0d3f
-rw-r--r--core/java/android/view/GLES20Canvas.java6
-rw-r--r--core/java/android/view/HardwareCanvas.java13
-rw-r--r--core/java/android/view/HardwareRenderer.java16
-rw-r--r--core/java/android/view/View.java2
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp6
-rw-r--r--libs/hwui/Layer.cpp10
-rw-r--r--libs/hwui/Layer.h1
-rw-r--r--libs/hwui/LayerCache.cpp4
-rw-r--r--libs/hwui/OpenGLRenderer.cpp12
-rw-r--r--libs/hwui/OpenGLRenderer.h1
10 files changed, 68 insertions, 3 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 831b914..1f35c1d 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -163,6 +163,11 @@ class GLES20Canvas extends HardwareCanvas {
}
@Override
+ void cancelLayerUpdate(HardwareLayer layer) {
+ nCancelLayerUpdate(mRenderer, ((GLES20RenderLayer) layer).mLayer);
+ }
+
+ @Override
void flushLayerUpdates() {
nFlushLayerUpdates(mRenderer);
}
@@ -191,6 +196,7 @@ class GLES20Canvas extends HardwareCanvas {
private static native void nClearLayerUpdates(int renderer);
private static native void nFlushLayerUpdates(int renderer);
private static native void nPushLayerUpdate(int renderer, int layer);
+ private static native void nCancelLayerUpdate(int renderer, int layer);
///////////////////////////////////////////////////////////////////////////
// Canvas management
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index 88b0986..259e1cd 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -202,6 +202,19 @@ public abstract class HardwareCanvas extends Canvas {
abstract void pushLayerUpdate(HardwareLayer layer);
/**
+ * Cancels a queued layer update. If the specified layer was not
+ * queued for update, this method has no effect.
+ *
+ * @param layer The layer whose update to cancel
+ *
+ * @see #pushLayerUpdate(HardwareLayer)
+ * @see #clearLayerUpdates()
+ *
+ * @hide
+ */
+ abstract void cancelLayerUpdate(HardwareLayer layer);
+
+ /**
* Immediately executes all enqueued layer updates.
*
* @see #pushLayerUpdate(HardwareLayer)
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 4bbf1a6..03428c7 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -451,10 +451,21 @@ public abstract class HardwareRenderer {
* @param layer The hardware layer that needs an update
*
* @see #flushLayerUpdates()
+ * @see #cancelLayerUpdate(HardwareLayer)
*/
abstract void pushLayerUpdate(HardwareLayer layer);
/**
+ * Cancels a queued layer update. If the specified layer was not
+ * queued for update, this method has no effect.
+ *
+ * @param layer The layer whose update to cancel
+ *
+ * @see #pushLayerUpdate(HardwareLayer)
+ */
+ abstract void cancelLayerUpdate(HardwareLayer layer);
+
+ /**
* Forces all enqueued layer updates to be executed immediately.
*
* @see #pushLayerUpdate(HardwareLayer)
@@ -2133,6 +2144,11 @@ public abstract class HardwareRenderer {
}
@Override
+ void cancelLayerUpdate(HardwareLayer layer) {
+ mGlCanvas.cancelLayerUpdate(layer);
+ }
+
+ @Override
void flushLayerUpdates() {
mGlCanvas.flushLayerUpdates();
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c246cd4..525b58f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12709,6 +12709,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (info != null && info.mHardwareRenderer != null &&
info.mHardwareRenderer.isEnabled() &&
(valid || info.mHardwareRenderer.validate())) {
+
+ info.mHardwareRenderer.cancelLayerUpdate(mHardwareLayer);
mHardwareLayer.destroy();
mHardwareLayer = null;
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index f3592a3..a2f7dbe 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -911,6 +911,11 @@ static void android_view_GLES20Canvas_pushLayerUpdate(JNIEnv* env, jobject clazz
renderer->pushLayerUpdate(layer);
}
+static void android_view_GLES20Canvas_cancelLayerUpdate(JNIEnv* env, jobject clazz,
+ OpenGLRenderer* renderer, Layer* layer) {
+ renderer->cancelLayerUpdate(layer);
+}
+
static void android_view_GLES20Canvas_clearLayerUpdates(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer) {
renderer->clearLayerUpdates();
@@ -1095,6 +1100,7 @@ static JNINativeMethod gMethods[] = {
{ "nClearLayerUpdates", "(I)V", (void*) android_view_GLES20Canvas_clearLayerUpdates },
{ "nFlushLayerUpdates", "(I)V", (void*) android_view_GLES20Canvas_flushLayerUpdates },
{ "nPushLayerUpdate", "(II)V", (void*) android_view_GLES20Canvas_pushLayerUpdate },
+ { "nCancelLayerUpdate", "(II)V", (void*) android_view_GLES20Canvas_cancelLayerUpdate },
{ "nSetTextureLayerTransform", "(II)V", (void*) android_view_GLES20Canvas_setTextureLayerTransform },
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 7c22bbb..f409d3e 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -213,6 +213,16 @@ void Layer::defer() {
deferredUpdateScheduled = false;
}
+void Layer::cancelDefer() {
+ renderer = NULL;
+ displayList = NULL;
+ deferredUpdateScheduled = false;
+ if (deferredList) {
+ delete deferredList;
+ deferredList = NULL;
+ }
+}
+
void Layer::flush() {
if (deferredList) {
renderer->setViewport(layer.getWidth(), layer.getHeight());
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 326b25a..ebd5543 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -245,6 +245,7 @@ struct Layer {
}
void defer();
+ void cancelDefer();
void flush();
void render();
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index a0709af..6be0146 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -155,9 +155,7 @@ bool LayerCache::put(Layer* layer) {
victim->layer.getHeight());
}
- layer->deferredUpdateScheduled = false;
- layer->renderer = NULL;
- layer->displayList = NULL;
+ layer->cancelDefer();
LayerEntry entry(layer);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 05f43a9..a704b3d 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -655,6 +655,18 @@ void OpenGLRenderer::pushLayerUpdate(Layer* layer) {
}
}
+void OpenGLRenderer::cancelLayerUpdate(Layer* layer) {
+ if (layer) {
+ for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
+ if (mLayerUpdates.itemAt(i) == layer) {
+ mLayerUpdates.removeAt(i);
+ mCaches.resourceCache.decrementRefcount(layer);
+ break;
+ }
+ }
+ }
+}
+
void OpenGLRenderer::clearLayerUpdates() {
size_t count = mLayerUpdates.size();
if (count > 0) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 5b7f90d..18d39ef 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -217,6 +217,7 @@ public:
virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
ANDROID_API void pushLayerUpdate(Layer* layer);
+ ANDROID_API void cancelLayerUpdate(Layer* layer);
ANDROID_API void clearLayerUpdates();
ANDROID_API void flushLayerUpdates();