diff options
author | John Reck <jreck@google.com> | 2014-08-28 15:35:53 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2014-08-28 15:55:26 -0700 |
commit | 998a6d81896df8b662cc10ddeb35087b78b38d72 (patch) | |
tree | 33af22fd2b087c8935fc2f6b4b03a71495ed83ef /libs | |
parent | e9a204f04465c26a32a15c237b985def8c2b4a90 (diff) | |
download | frameworks_base-998a6d81896df8b662cc10ddeb35087b78b38d72.zip frameworks_base-998a6d81896df8b662cc10ddeb35087b78b38d72.tar.gz frameworks_base-998a6d81896df8b662cc10ddeb35087b78b38d72.tar.bz2 |
Track buildLayer calls, destroy if unused
Bug: 17208461
Change-Id: Ibdb104a493285d77a6891c5e74e38a52c7014da9
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/RenderNode.cpp | 8 | ||||
-rw-r--r-- | libs/hwui/TreeInfo.h | 8 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 32 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 7 | ||||
-rw-r--r-- | libs/hwui/renderthread/EglManager.cpp | 2 |
5 files changed, 55 insertions, 2 deletions
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index a79875e..cbb794e 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -34,6 +34,7 @@ #include "LayerRenderer.h" #include "OpenGLRenderer.h" #include "utils/MathUtils.h" +#include "renderthread/CanvasContext.h" namespace android { namespace uirenderer { @@ -208,6 +209,13 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { if (info.renderer && mLayer->deferredUpdateScheduled) { info.renderer->pushLayerUpdate(mLayer); } + + if (CC_UNLIKELY(info.canvasContext)) { + // If canvasContext is not null that means there are prefetched layers + // that need to be accounted for. That might be us, so tell CanvasContext + // that this layer is in the tree and should not be destroyed. + info.canvasContext->markLayerInUse(this); + } } void RenderNode::prepareTreeImpl(TreeInfo& info) { diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h index e78d8bd..ae6ea94 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -26,6 +26,10 @@ namespace android { namespace uirenderer { +namespace renderthread { +class CanvasContext; +} + class OpenGLRenderer; class RenderState; @@ -59,6 +63,7 @@ public: , renderState(renderState) , renderer(NULL) , errorHandler(NULL) + , canvasContext(NULL) {} explicit TreeInfo(TraversalMode mode, const TreeInfo& clone) @@ -69,6 +74,7 @@ public: , renderState(clone.renderState) , renderer(clone.renderer) , errorHandler(clone.errorHandler) + , canvasContext(clone.canvasContext) {} const TraversalMode mode; @@ -89,6 +95,8 @@ public: // layer updates or similar. May be NULL. OpenGLRenderer* renderer; ErrorHandler* errorHandler; + // TODO: Remove this? May be NULL + renderthread::CanvasContext* canvasContext; struct Out { Out() diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index d9fa0bc..ecfedf6 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -16,6 +16,7 @@ #include "CanvasContext.h" +#include <algorithm> #include <private/hwui/DrawGlInfo.h> #include <strings.h> @@ -53,6 +54,7 @@ CanvasContext::~CanvasContext() { destroyCanvasAndSurface(); mRenderThread.removeFrameCallback(this); delete mAnimationContext; + freePrefetechedLayers(); } void CanvasContext::destroyCanvasAndSurface() { @@ -142,10 +144,17 @@ void CanvasContext::prepareTree(TreeInfo& info) { info.damageAccumulator = &mDamageAccumulator; info.renderer = mCanvas; + if (mPrefetechedLayers.size() && info.mode == TreeInfo::MODE_FULL) { + info.canvasContext = this; + } mAnimationContext->startFrame(); mRootRenderNode->prepareTree(info); mAnimationContext->runRemainingAnimations(info); + if (info.canvasContext) { + freePrefetechedLayers(); + } + int runningBehind = 0; // TODO: This query is moderately expensive, investigate adding some sort // of fast-path based off when we last called eglSwapBuffers() as well as @@ -249,6 +258,26 @@ void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) { thread.renderState().invokeFunctor(functor, mode, NULL); } +void CanvasContext::markLayerInUse(RenderNode* node) { + if (mPrefetechedLayers.erase(node)) { + node->decStrong(0); + } +} + +static void destroyPrefetechedNode(RenderNode* node) { + ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...", node->getName()); + node->destroyHardwareResources(); + node->decStrong(0); +} + +void CanvasContext::freePrefetechedLayers() { + if (mPrefetechedLayers.size()) { + requireGlContext(); + std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode); + mPrefetechedLayers.clear(); + } +} + void CanvasContext::buildLayer(RenderNode* node) { ATRACE_CALL(); if (!mEglManager.hasEglContext() || !mCanvas) { @@ -270,6 +299,9 @@ void CanvasContext::buildLayer(RenderNode* node) { node->setPropertyFieldsDirty(RenderNode::GENERIC); mCanvas->flushLayerUpdates(); + + node->incStrong(0); + mPrefetechedLayers.insert(node); } bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) { diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 749da1b..7c27190 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -17,6 +17,8 @@ #ifndef CANVASCONTEXT_H_ #define CANVASCONTEXT_H_ +#include <set> + #include <cutils/compiler.h> #include <EGL/egl.h> #include <SkBitmap.h> @@ -71,6 +73,7 @@ public: void buildLayer(RenderNode* node); bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap); + void markLayerInUse(RenderNode* node); void destroyHardwareResources(); static void trimMemory(RenderThread& thread, int level); @@ -99,6 +102,8 @@ private: void requireGlContext(); + void freePrefetechedLayers(); + RenderThread& mRenderThread; EglManager& mEglManager; sp<ANativeWindow> mNativeWindow; @@ -114,6 +119,8 @@ private: const sp<RenderNode> mRootRenderNode; DrawProfiler mProfiler; + + std::set<RenderNode*> mPrefetechedLayers; }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 37f8e60..e030cdb 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "EglContext" - #include "EglManager.h" #include <cutils/log.h> |