diff options
author | Chet Haase <chet@google.com> | 2012-09-30 12:14:13 -0700 |
---|---|---|
committer | Chet Haase <chet@google.com> | 2012-09-30 15:35:08 -0700 |
commit | 6a2d17f71342f981c9df1dc5beff33e30eb3ae2b (patch) | |
tree | aaf68defc949273eccdd48aa40927fe8895ad37d /libs | |
parent | 933a7546c857dba7704a15b7f7f7847934f14912 (diff) | |
download | frameworks_base-6a2d17f71342f981c9df1dc5beff33e30eb3ae2b.zip frameworks_base-6a2d17f71342f981c9df1dc5beff33e30eb3ae2b.tar.gz frameworks_base-6a2d17f71342f981c9df1dc5beff33e30eb3ae2b.tar.bz2 |
Fix texture corruption
When memory gets low on a device, activities flush everything they can.
Hardware-accelerated activites, such as Launcher, flush GL resources and destroy
the GL context. However, some resources were still hanging around, due to deferred
destruction policies (we don't delete layers until the DisplayLists they are in
are finalized, to ensure we don't deref deleted objects). This meant that we were
referring to obsolete GL data in these objects. in particular, it meant that we might
come around later, after a new GL context was created, and delete a texture object
that was incorrect. We use the layer's "texture id" to refer to the texture underlying the
layer. But if there's a new GL context, then this texture ID is no longer valid, and
we may be deleting the texture that a different object (layer, icon, whatever) is referring
to, because the driver may return that same ID under the new GL context.
The fix is to more aggressively delete things that we know will not be used again
when the GL context is destroyed. In particular, we delete all resources being used
by all DisplayLists at GL context destruction time.
Issue #7195815 Textures corruption on all devices, in many apps
Change-Id: I52d2d208173690dbb794a83402d38f14ea4c6c22
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/Caches.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 63 | ||||
-rw-r--r-- | libs/hwui/DisplayListRenderer.h | 3 |
3 files changed, 36 insertions, 34 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index e443294..7853ae4 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -268,8 +268,6 @@ void Caches::deleteDisplayListDeferred(DisplayList* displayList) { void Caches::flush(FlushMode mode) { FLUSH_LOGD("Flushing caches (mode %d)", mode); - clearGarbage(); - switch (mode) { case kFlushMode_Full: textureCache.clear(); @@ -293,6 +291,8 @@ void Caches::flush(FlushMode mode) { layerCache.clear(); break; } + + clearGarbage(); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index f84c847..589d5c2 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -105,35 +105,6 @@ DisplayList::~DisplayList() { clearResources(); } -void DisplayList::initProperties() { - mLeft = 0; - mTop = 0; - mRight = 0; - mBottom = 0; - mClipChildren = true; - mAlpha = 1; - mMultipliedAlpha = 255; - mHasOverlappingRendering = true; - mTranslationX = 0; - mTranslationY = 0; - mRotation = 0; - mRotationX = 0; - mRotationY= 0; - mScaleX = 1; - mScaleY = 1; - mPivotX = 0; - mPivotY = 0; - mCameraDistance = 0; - mMatrixDirty = false; - mMatrixFlags = 0; - mPrevWidth = -1; - mPrevHeight = -1; - mWidth = 0; - mHeight = 0; - mPivotExplicitlySet = false; - mCaching = false; -} - void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { if (displayList) { DISPLAY_LIST_LOGD("Deferring display list destruction"); @@ -215,8 +186,12 @@ void DisplayList::clearResources() { mLayers.clear(); } +void DisplayList::reset() { + clearResources(); + init(); +} + void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) { - const SkWriter32& writer = recorder.writeStream(); if (reusing) { // re-using display list - clear out previous allocations @@ -224,8 +199,8 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde } init(); - initProperties(); + const SkWriter32& writer = recorder.writeStream(); if (writer.size() == 0) { return; } @@ -303,6 +278,32 @@ void DisplayList::init() { mSize = 0; mIsRenderable = true; mFunctorCount = 0; + mLeft = 0; + mTop = 0; + mRight = 0; + mBottom = 0; + mClipChildren = true; + mAlpha = 1; + mMultipliedAlpha = 255; + mHasOverlappingRendering = true; + mTranslationX = 0; + mTranslationY = 0; + mRotation = 0; + mRotationX = 0; + mRotationY= 0; + mScaleX = 1; + mScaleY = 1; + mPivotX = 0; + mPivotY = 0; + mCameraDistance = 0; + mMatrixDirty = false; + mMatrixFlags = 0; + mPrevWidth = -1; + mPrevHeight = -1; + mWidth = 0; + mHeight = 0; + mPivotExplicitlySet = false; + mCaching = false; } size_t DisplayList::getSize() { diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 39061f4..2610055 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -137,6 +137,8 @@ public: void output(OpenGLRenderer& renderer, uint32_t level = 0); + ANDROID_API void reset(); + void setRenderable(bool renderable) { mIsRenderable = renderable; } @@ -399,7 +401,6 @@ public: private: void init(); - void initProperties(); void clearResources(); |