diff options
author | Romain Guy <romainguy@google.com> | 2013-06-17 13:14:51 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2013-06-17 13:35:03 -0700 |
commit | e93482f5eac3df581d57e64c2a771a96aa868585 (patch) | |
tree | 009afbdf49655b35ee29f857aa554a42c4e96048 | |
parent | 6410c0aaf13c9aec606b90ee942f2ac2d98b1609 (diff) | |
download | frameworks_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.java | 6 | ||||
-rw-r--r-- | core/java/android/view/HardwareCanvas.java | 13 | ||||
-rw-r--r-- | core/java/android/view/HardwareRenderer.java | 16 | ||||
-rw-r--r-- | core/java/android/view/View.java | 2 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/Layer.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/Layer.h | 1 | ||||
-rw-r--r-- | libs/hwui/LayerCache.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 12 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 1 |
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(); |