summaryrefslogtreecommitdiffstats
path: root/libs/hwui/renderthread/CanvasContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/renderthread/CanvasContext.cpp')
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp43
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);
}