diff options
author | Romain Guy <romainguy@google.com> | 2012-03-05 13:44:35 -0800 |
---|---|---|
committer | Arne Coucheron <arco68@gmail.com> | 2012-04-26 10:05:24 +0200 |
commit | 41951f0d3bbc52bfa774db8788bc4b7d26fee5fc (patch) | |
tree | 70827017c1bdf44bfae94ab0f2b8f750ed031de0 | |
parent | c901f3c06b611f097d825f08dddde2c627039e3a (diff) | |
download | frameworks_base-41951f0d3bbc52bfa774db8788bc4b7d26fee5fc.zip frameworks_base-41951f0d3bbc52bfa774db8788bc4b7d26fee5fc.tar.gz frameworks_base-41951f0d3bbc52bfa774db8788bc4b7d26fee5fc.tar.bz2 |
libhwui: Delete display list objects and resources on the UI thread
Bug #6073717
Bug #6065504
Bug #6026515
Bug #5971725
Prior to this change, the destructor of DisplayList would always run
on the finalizer thread. This could cause a race condition if the UI
thread was busy rendering display lists at the same time leading to
various random native crashes.
CRs-Fixed: 353211, 343109
(cherry picked from commit 14baed35c789e53df7fd5150c90aa1c0c960ac6f)
Change-Id: Ib454326a8df9fc28ee140467a10d370ff21b9766
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/Caches.cpp | 13 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 8 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 8 |
5 files changed, 33 insertions, 5 deletions
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index 50affd1..eb3a87a 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -629,7 +629,7 @@ static void android_view_GLES20Canvas_resetDisplayListRenderer(JNIEnv* env, static void android_view_GLES20Canvas_destroyDisplayList(JNIEnv* env, jobject clazz, DisplayList* displayList) { - delete displayList; + DisplayList::destroyDisplayListDeferred(displayList); } static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env, diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index f293cba..d0c84bb 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -20,6 +20,7 @@ #include <utils/String8.h> #include "Caches.h" +#include "DisplayListRenderer.h" #include "Properties.h" #include "LayerRenderer.h" @@ -178,6 +179,13 @@ void Caches::clearGarbage() { LayerRenderer::destroyLayer(layer); } mLayerGarbage.clear(); + + count = mDisplayListGarbage.size(); + for (size_t i = 0; i < count; i++) { + DisplayList* displayList = mDisplayListGarbage.itemAt(i); + delete displayList; + } + mDisplayListGarbage.clear(); } void Caches::deleteLayerDeferred(Layer* layer) { @@ -185,6 +193,11 @@ void Caches::deleteLayerDeferred(Layer* layer) { mLayerGarbage.push(layer); } +void Caches::deleteDisplayListDeferred(DisplayList* displayList) { + Mutex::Autolock _l(mGarbageLock); + mDisplayListGarbage.push(displayList); +} + void Caches::flush(FlushMode mode) { FLUSH_LOGD("Flushing caches (mode %d)", mode); diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 5e58a9e..5a8b84f 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -84,6 +84,8 @@ struct CacheLogger { // Caches /////////////////////////////////////////////////////////////////////////////// +class DisplayList; + class ANDROID_API Caches: public Singleton<Caches> { Caches(); @@ -99,6 +101,7 @@ class ANDROID_API Caches: public Singleton<Caches> { mutable Mutex mGarbageLock; Vector<Layer*> mLayerGarbage; + Vector<DisplayList*> mDisplayListGarbage; public: enum FlushMode { @@ -144,6 +147,11 @@ public: */ void deleteLayerDeferred(Layer* layer); + /* + * Can be used to delete a display list from a non EGL thread. + */ + void deleteDisplayListDeferred(DisplayList* layer); + /** * Binds the VBO used to render simple textured quads. */ diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 3372d1c..163df5b 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -96,6 +96,13 @@ DisplayList::~DisplayList() { clearResources(); } +void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { + if (displayList) { + DISPLAY_LIST_LOGD("Deferring display list destruction"); + Caches::getInstance().deleteDisplayListDeferred(displayList); + } +} + void DisplayList::clearResources() { sk_free((void*) mReader.base()); diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index ab475bf..3053eaa 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -107,16 +107,16 @@ public: static const char* OP_NAMES[]; - void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); - ANDROID_API size_t getSize(); + ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList); + ANDROID_API static void outputLogBuffer(int fd); + + void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0); void output(OpenGLRenderer& renderer, uint32_t level = 0); - ANDROID_API static void outputLogBuffer(int fd); - void setRenderable(bool renderable) { mIsRenderable = renderable; } |