From 6a2d17f71342f981c9df1dc5beff33e30eb3ae2b Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Sun, 30 Sep 2012 12:14:13 -0700 Subject: 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 --- libs/hwui/Caches.cpp | 4 +-- libs/hwui/DisplayListRenderer.cpp | 63 ++++++++++++++++++++------------------- libs/hwui/DisplayListRenderer.h | 3 +- 3 files changed, 36 insertions(+), 34 deletions(-) (limited to 'libs') 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(); -- cgit v1.1