diff options
author | John Reck <jreck@google.com> | 2014-06-30 16:20:04 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2014-06-30 16:36:26 -0700 |
commit | f47a594f5250b1914c36423ee6b371f0b8db09d0 (patch) | |
tree | f86289c7b515c2111fde3ce11e7fca384bc2f603 /libs | |
parent | dd59aba6c7e142eae14d5f29ea6873a5b9790174 (diff) | |
download | frameworks_base-f47a594f5250b1914c36423ee6b371f0b8db09d0.zip frameworks_base-f47a594f5250b1914c36423ee6b371f0b8db09d0.tar.gz frameworks_base-f47a594f5250b1914c36423ee6b371f0b8db09d0.tar.bz2 |
Fix onTrimMemory for HardwareRenderer
Also fixes detachFunctor possibly drawing after return
Bug: 15189843
Bug: 15990672
Change-Id: I64c48cb674c461a8eeaba407b697e09f72c98ce3
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/RenderNode.cpp | 19 | ||||
-rw-r--r-- | libs/hwui/TreeInfo.h | 3 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 34 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 4 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 33 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 4 |
6 files changed, 76 insertions, 21 deletions
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index e803ec3..89105ea 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -195,17 +195,28 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { void RenderNode::prepareTreeImpl(TreeInfo& info) { info.damageAccumulator->pushTransform(this); - if (info.mode == TreeInfo::MODE_FULL) { + + switch (info.mode) { + case TreeInfo::MODE_FULL: pushStagingPropertiesChanges(info); mAnimatorManager.animate(info); - } else if (info.mode == TreeInfo::MODE_MAYBE_DETACHING) { + break; + case TreeInfo::MODE_MAYBE_DETACHING: pushStagingPropertiesChanges(info); - } else if (info.mode == TreeInfo::MODE_RT_ONLY) { + break; + case TreeInfo::MODE_RT_ONLY: mAnimatorManager.animate(info); + break; + case TreeInfo::MODE_DESTROY_RESOURCES: + // This will also release the hardware layer if we have one as + // isRenderable() will return false, thus causing pushLayerUpdate + // to recycle the hardware layer + setStagingDisplayList(NULL); + break; } prepareLayer(info); - if (info.mode == TreeInfo::MODE_FULL) { + if (info.mode == TreeInfo::MODE_FULL || info.mode == TreeInfo::MODE_DESTROY_RESOURCES) { pushStagingDisplayListChanges(info); } prepareSubTree(info, mDisplayListData); diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h index 083100e..9746ac53 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -65,7 +65,8 @@ public: // but don't evaluate animators and such as if it isn't detached as a // MODE_FULL will follow shortly. MODE_MAYBE_DETACHING, - // TODO: TRIM_MEMORY? + // Destroy all hardware resources, including DisplayListData, in the tree. + MODE_DESTROY_RESOURCES, }; explicit TreeInfo(TraversalMode mode, RenderState& renderState) diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 9c3cf44..524ee62 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -30,6 +30,9 @@ #include "../OpenGLRenderer.h" #include "../Stencil.h" +#define TRIM_MEMORY_COMPLETE 80 +#define TRIM_MEMORY_UI_HIDDEN 20 + namespace android { namespace uirenderer { namespace renderthread { @@ -156,6 +159,10 @@ void CanvasContext::prepareTree(TreeInfo& info) { } } +void CanvasContext::stopDrawing() { + mRenderThread.removeFrameCallback(this); +} + void CanvasContext::notifyFramePending() { ATRACE_CALL(); mRenderThread.pushBackFrameCallback(this); @@ -216,8 +223,6 @@ void CanvasContext::doFrame() { profiler().startFrame(); TreeInfo info(TreeInfo::MODE_RT_ONLY, mRenderThread.renderState()); - info.prepareTextures = false; - prepareTree(info); if (info.out.canDrawThisFrame) { draw(); @@ -241,10 +246,25 @@ bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap); } -void CanvasContext::flushCaches(Caches::FlushMode flushMode) { +void CanvasContext::destroyHardwareResources() { + stopDrawing(); if (mEglManager.hasEglContext()) { requireGlContext(); - Caches::getInstance().flush(flushMode); + TreeInfo info(TreeInfo::MODE_DESTROY_RESOURCES, mRenderThread.renderState()); + mRootRenderNode->prepareTree(info); + Caches::getInstance().flush(Caches::kFlushMode_Layers); + } +} + +void CanvasContext::trimMemory(RenderThread& thread, int level) { + // No context means nothing to free + if (!thread.eglManager().hasEglContext()) return; + + if (level >= TRIM_MEMORY_COMPLETE) { + Caches::getInstance().flush(Caches::kFlushMode_Full); + thread.eglManager().destroy(); + } else if (level >= TRIM_MEMORY_UI_HIDDEN) { + Caches::getInstance().flush(Caches::kFlushMode_Moderate); } } @@ -264,11 +284,7 @@ Layer* CanvasContext::createTextureLayer() { } void CanvasContext::requireGlContext() { - if (mEglSurface != EGL_NO_SURFACE) { - makeCurrent(); - } else { - mEglManager.usePBufferSurface(); - } + mEglManager.requireGlContext(); } void CanvasContext::setTextureAtlas(RenderThread& thread, diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index dbfb3d2..1bab1b1 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -66,7 +66,8 @@ public: bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap); - void flushCaches(Caches::FlushMode flushMode); + void destroyHardwareResources(); + static void trimMemory(RenderThread& thread, int level); static void invokeFunctor(RenderThread& thread, Functor* functor); @@ -78,6 +79,7 @@ public: ANDROID_API static void setTextureAtlas(RenderThread& thread, const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); + void stopDrawing(); void notifyFramePending(); DrawProfiler& profiler() { return mProfiler; } diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index e1ee620..6cd3d0b 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -312,18 +312,30 @@ void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) { postAndWait(task); } -CREATE_BRIDGE2(flushCaches, CanvasContext* context, Caches::FlushMode flushMode) { - args->context->flushCaches(args->flushMode); +CREATE_BRIDGE1(destroyHardwareResources, CanvasContext* context) { + args->context->destroyHardwareResources(); return NULL; } -void RenderProxy::flushCaches(Caches::FlushMode flushMode) { - SETUP_TASK(flushCaches); +void RenderProxy::destroyHardwareResources() { + SETUP_TASK(destroyHardwareResources); args->context = mContext; - args->flushMode = flushMode; post(task); } +CREATE_BRIDGE2(timMemory, RenderThread* thread, int level) { + CanvasContext::trimMemory(*args->thread, args->level); + return NULL; +} + +void RenderProxy::trimMemory(int level) { + RenderThread& thread = RenderThread::getInstance(); + SETUP_TASK(timMemory); + args->thread = &thread; + args->level = level; + thread.queue(task); +} + CREATE_BRIDGE0(fence) { // Intentionally empty return NULL; @@ -334,6 +346,17 @@ void RenderProxy::fence() { postAndWait(task); } +CREATE_BRIDGE1(stopDrawing, CanvasContext* context) { + args->context->stopDrawing(); + return NULL; +} + +void RenderProxy::stopDrawing() { + SETUP_TASK(stopDrawing); + args->context = mContext; + postAndWait(task); +} + CREATE_BRIDGE1(notifyFramePending, CanvasContext* context) { args->context->notifyFramePending(); return NULL; diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index c7358e6..0027403 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -85,9 +85,11 @@ public: ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer); ANDROID_API void detachSurfaceTexture(DeferredLayerUpdater* layer); - ANDROID_API void flushCaches(Caches::FlushMode flushMode); + ANDROID_API void destroyHardwareResources(); + ANDROID_API static void trimMemory(int level); ANDROID_API void fence(); + ANDROID_API void stopDrawing(); ANDROID_API void notifyFramePending(); ANDROID_API void dumpProfileInfo(int fd); |