diff options
Diffstat (limited to 'libs/hwui/renderthread/CanvasContext.cpp')
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 4bf5a8a..491a295 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -16,11 +16,13 @@ #include "CanvasContext.h" +#include <algorithm> #include <private/hwui/DrawGlInfo.h> #include <strings.h> #include "EglManager.h" #include "RenderThread.h" +#include "../AnimationContext.h" #include "../Caches.h" #include "../DeferredLayerUpdater.h" #include "../RenderState.h" @@ -35,7 +37,8 @@ namespace android { namespace uirenderer { namespace renderthread { -CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode) +CanvasContext::CanvasContext(RenderThread& thread, bool translucent, + RenderNode* rootRenderNode, IContextFactory* contextFactory) : mRenderThread(thread) , mEglManager(thread.eglManager()) , mEglSurface(EGL_NO_SURFACE) @@ -44,11 +47,14 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* , mCanvas(NULL) , mHaveNewSurface(false) , mRootRenderNode(rootRenderNode) { + mAnimationContext = contextFactory->createAnimationContext(mRenderThread.timeLord()); } CanvasContext::~CanvasContext() { destroyCanvasAndSurface(); mRenderThread.removeFrameCallback(this); + delete mAnimationContext; + freePrefetechedLayers(); } void CanvasContext::destroyCanvasAndSurface() { @@ -136,10 +142,18 @@ void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater) { void CanvasContext::prepareTree(TreeInfo& info) { mRenderThread.removeFrameCallback(this); - info.frameTimeMs = mRenderThread.timeLord().frameTimeMs(); 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 @@ -244,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) { @@ -254,7 +288,6 @@ void CanvasContext::buildLayer(RenderNode* node) { stopDrawing(); TreeInfo info(TreeInfo::MODE_FULL, mRenderThread.renderState()); - info.frameTimeMs = mRenderThread.timeLord().frameTimeMs(); info.damageAccumulator = &mDamageAccumulator; info.renderer = mCanvas; info.runAnimations = false; @@ -266,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) { @@ -278,6 +314,7 @@ void CanvasContext::destroyHardwareResources() { stopDrawing(); if (mEglManager.hasEglContext()) { requireGlContext(); + freePrefetechedLayers(); mRootRenderNode->destroyHardwareResources(); Caches::getInstance().flush(Caches::kFlushMode_Layers); } |
