summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2014-06-24 15:34:58 -0700
committerJohn Reck <jreck@google.com>2014-06-26 10:45:43 -0700
commit68bfe0a37a0dcef52abd81688d8520c5d16e1a85 (patch)
treeb67e0671dba8221a16fcf880daeaf1e271499e9f /libs
parent6507f2e03a90244e08fb62f9b55653ba3230d0b7 (diff)
downloadframeworks_base-68bfe0a37a0dcef52abd81688d8520c5d16e1a85.zip
frameworks_base-68bfe0a37a0dcef52abd81688d8520c5d16e1a85.tar.gz
frameworks_base-68bfe0a37a0dcef52abd81688d8520c5d16e1a85.tar.bz2
Animator refactoring & fixes
Tweaks animators to have less unnecessary refcounting Pull animator management out into seperate class More control to tweak animator lifecycle, such as doing Java-side handling of start delay by attaching but not starting the animator Change-Id: I4ff8207580ca11fb38f45ef0007b406e0097281c
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/Animator.cpp100
-rw-r--r--libs/hwui/Animator.h22
-rw-r--r--libs/hwui/AnimatorManager.cpp102
-rw-r--r--libs/hwui/AnimatorManager.h57
-rw-r--r--libs/hwui/DeferredLayerUpdater.cpp2
-rw-r--r--libs/hwui/DeferredLayerUpdater.h2
-rw-r--r--libs/hwui/RenderNode.cpp70
-rw-r--r--libs/hwui/RenderNode.h28
-rw-r--r--libs/hwui/TreeInfo.h11
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp7
-rw-r--r--libs/hwui/renderthread/CanvasContext.h2
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.cpp2
13 files changed, 272 insertions, 134 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index a704e19..1a96b2f 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -13,6 +13,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
font/Font.cpp \
AmbientShadow.cpp \
Animator.cpp \
+ AnimatorManager.cpp \
AssetAtlas.cpp \
DamageAccumulator.cpp \
FontRenderer.cpp \
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index dc6d852..4a8c122 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -18,6 +18,7 @@
#include "Animator.h"
+#include <inttypes.h>
#include <set>
#include "RenderNode.h"
@@ -35,72 +36,105 @@ BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
, mDeltaValue(0)
, mFromValue(0)
, mInterpolator(0)
- , mPlayState(NEEDS_START)
+ , mStagingPlayState(NOT_STARTED)
+ , mPlayState(NOT_STARTED)
+ , mHasStartValue(false)
, mStartTime(0)
- , mDelayUntil(0)
, mDuration(300)
, mStartDelay(0) {
-
}
BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
- setInterpolator(NULL);
+ delete mInterpolator;
+}
+
+void BaseRenderNodeAnimator::checkMutable() {
+ // Should be impossible to hit as the Java-side also has guards for this
+ LOG_ALWAYS_FATAL_IF(mStagingPlayState != NOT_STARTED,
+ "Animator has already been started!");
}
void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) {
+ checkMutable();
delete mInterpolator;
mInterpolator = interpolator;
}
void BaseRenderNodeAnimator::setStartValue(float value) {
- LOG_ALWAYS_FATAL_IF(mPlayState != NEEDS_START,
- "Cannot set the start value after the animator has started!");
- mFromValue = value;
- mDeltaValue = (mFinalValue - mFromValue);
- mPlayState = PENDING;
+ checkMutable();
+ doSetStartValue(value);
}
-void BaseRenderNodeAnimator::setupStartValueIfNecessary(RenderNode* target, TreeInfo& info) {
- if (mPlayState == NEEDS_START) {
- setStartValue(getValue(target));
- }
+void BaseRenderNodeAnimator::doSetStartValue(float value) {
+ mFromValue = value;
+ mDeltaValue = (mFinalValue - mFromValue);
+ mHasStartValue = true;
}
void BaseRenderNodeAnimator::setDuration(nsecs_t duration) {
+ checkMutable();
mDuration = duration;
}
void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) {
+ checkMutable();
mStartDelay = startDelay;
}
-bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) {
- if (mPlayState == PENDING && mStartDelay > 0 && mDelayUntil == 0) {
- mDelayUntil = info.frameTimeMs + mStartDelay;
- return false;
+void BaseRenderNodeAnimator::pushStaging(RenderNode* target, TreeInfo& info) {
+ if (!mHasStartValue) {
+ doSetStartValue(getValue(target));
}
+ if (mStagingPlayState > mPlayState) {
+ mPlayState = mStagingPlayState;
+ // Oh boy, we're starting! Man the battle stations!
+ if (mPlayState == RUNNING) {
+ transitionToRunning(info);
+ }
+ }
+}
- if (mDelayUntil > info.frameTimeMs) {
+void BaseRenderNodeAnimator::transitionToRunning(TreeInfo& info) {
+ LOG_ALWAYS_FATAL_IF(info.frameTimeMs <= 0, "%" PRId64 " isn't a real frame time!", info.frameTimeMs);
+ if (mStartDelay < 0 || mStartDelay > 50000) {
+ ALOGW("Your start delay is strange and confusing: %" PRId64, mStartDelay);
+ }
+ mStartTime = info.frameTimeMs + mStartDelay;
+ if (mStartTime < 0) {
+ ALOGW("Ended up with a really weird start time of %" PRId64
+ " with frame time %" PRId64 " and start delay %" PRId64,
+ mStartTime, info.frameTimeMs, mStartDelay);
+ // Set to 0 so that the animate() basically instantly finishes
+ mStartTime = 0;
+ }
+ // No interpolator was set, use the default
+ if (!mInterpolator) {
+ setInterpolator(Interpolator::createDefaultInterpolator());
+ }
+ if (mDuration < 0 || mDuration > 50000) {
+ ALOGW("Your duration is strange and confusing: %" PRId64, mDuration);
+ }
+}
+
+bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) {
+ if (mPlayState < RUNNING) {
return false;
}
- if (mPlayState == PENDING) {
- mPlayState = RUNNING;
- mStartTime = info.frameTimeMs;
- // No interpolator was set, use the default
- if (!mInterpolator) {
- setInterpolator(Interpolator::createDefaultInterpolator());
- }
+ if (mStartTime > info.frameTimeMs) {
+ info.out.hasAnimations |= true;
+ return false;
}
float fraction = 1.0f;
- if (mPlayState == RUNNING) {
- fraction = mDuration > 0 ? (float)(info.frameTimeMs - mStartTime) / mDuration : 1.0f;
- if (fraction >= 1.0f) {
- fraction = 1.0f;
- mPlayState = FINISHED;
- }
+ if (mPlayState == RUNNING && mDuration > 0) {
+ fraction = (float)(info.frameTimeMs - mStartTime) / mDuration;
}
+ if (fraction >= 1.0f) {
+ fraction = 1.0f;
+ mPlayState = FINISHED;
+ }
+
fraction = mInterpolator->interpolate(fraction);
setValue(target, mFromValue + (mDeltaValue * fraction));
@@ -108,6 +142,8 @@ bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) {
callOnFinishedListener(info);
return true;
}
+
+ info.out.hasAnimations |= true;
return false;
}
@@ -153,7 +189,7 @@ RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float fi
}
void RenderPropertyAnimator::onAttached(RenderNode* target) {
- if (mPlayState == NEEDS_START
+ if (!mHasStartValue
&& target->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
setStartValue((target->stagingProperties().*mPropertyAccess->getter)());
}
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index 6cb72c4c..a981b5a 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -50,12 +50,11 @@ public:
ANDROID_API void setListener(AnimationListener* listener) {
mListener = listener;
}
+ ANDROID_API void start() { mStagingPlayState = RUNNING; }
+ ANDROID_API void cancel() { mStagingPlayState = FINISHED; }
- ANDROID_API virtual void onAttached(RenderNode* target) {}
-
- // Guaranteed to happen before the staging push
- void setupStartValueIfNecessary(RenderNode* target, TreeInfo& info);
-
+ virtual void onAttached(RenderNode* target) {}
+ virtual void pushStaging(RenderNode* target, TreeInfo& info);
bool animate(RenderNode* target, TreeInfo& info);
bool isFinished() { return mPlayState == FINISHED; }
@@ -73,8 +72,7 @@ protected:
void callOnFinishedListener(TreeInfo& info);
enum PlayState {
- NEEDS_START,
- PENDING,
+ NOT_STARTED,
RUNNING,
FINISHED,
};
@@ -84,13 +82,19 @@ protected:
float mFromValue;
Interpolator* mInterpolator;
+ PlayState mStagingPlayState;
PlayState mPlayState;
+ bool mHasStartValue;
nsecs_t mStartTime;
- nsecs_t mDelayUntil;
nsecs_t mDuration;
nsecs_t mStartDelay;
sp<AnimationListener> mListener;
+
+private:
+ void doSetStartValue(float value);
+ inline void checkMutable();
+ void transitionToRunning(TreeInfo& info);
};
class RenderPropertyAnimator : public BaseRenderNodeAnimator {
@@ -112,7 +116,7 @@ public:
ANDROID_API RenderPropertyAnimator(RenderProperty property, float finalValue);
- ANDROID_API virtual void onAttached(RenderNode* target);
+ virtual void onAttached(RenderNode* target);
ANDROID_API virtual uint32_t dirtyMask();
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
new file mode 100644
index 0000000..6a10cf8
--- /dev/null
+++ b/libs/hwui/AnimatorManager.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "AnimatorManager.h"
+
+#include <algorithm>
+
+#include "RenderNode.h"
+
+namespace android {
+namespace uirenderer {
+
+using namespace std;
+
+static void unref(BaseRenderNodeAnimator* animator) {
+ animator->decStrong(0);
+}
+
+AnimatorManager::AnimatorManager(RenderNode& parent)
+ : mParent(parent) {
+}
+
+AnimatorManager::~AnimatorManager() {
+ for_each(mNewAnimators.begin(), mNewAnimators.end(), unref);
+ for_each(mAnimators.begin(), mAnimators.end(), unref);
+}
+
+void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
+ animator->incStrong(0);
+ animator->onAttached(&mParent);
+ mNewAnimators.push_back(animator.get());
+}
+
+template<typename T>
+static void move_all(T& source, T& dest) {
+ dest.reserve(source.size() + dest.size());
+ for (typename T::iterator it = source.begin(); it != source.end(); it++) {
+ dest.push_back(*it);
+ }
+ source.clear();
+}
+
+void AnimatorManager::pushStaging(TreeInfo& info) {
+ if (mNewAnimators.size()) {
+ // Since this is a straight move, we don't need to inc/dec the ref count
+ move_all(mNewAnimators, mAnimators);
+ }
+ for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) {
+ (*it)->pushStaging(&mParent, info);
+ }
+}
+
+class AnimateFunctor {
+public:
+ AnimateFunctor(RenderNode& target, TreeInfo& info)
+ : mTarget(target), mInfo(info) {}
+
+ bool operator() (BaseRenderNodeAnimator* animator) {
+ bool remove = animator->animate(&mTarget, mInfo);
+ if (remove) {
+ animator->decStrong(0);
+ }
+ return remove;
+ }
+private:
+ RenderNode& mTarget;
+ TreeInfo& mInfo;
+};
+
+void AnimatorManager::animate(TreeInfo& info) {
+ if (!mAnimators.size()) return;
+
+ // TODO: Can we target this better? For now treat it like any other staging
+ // property push and just damage self before and after animators are run
+
+ mParent.damageSelf(info);
+ info.damageAccumulator->popTransform();
+
+ AnimateFunctor functor(mParent, info);
+ std::vector< BaseRenderNodeAnimator* >::iterator newEnd;
+ newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
+ mAnimators.erase(newEnd, mAnimators.end());
+
+ mParent.mProperties.updateMatrix();
+ info.damageAccumulator->pushTransform(&mParent);
+ mParent.damageSelf(info);
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h
new file mode 100644
index 0000000..2568121
--- /dev/null
+++ b/libs/hwui/AnimatorManager.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANIMATORMANAGER_H
+#define ANIMATORMANAGER_H
+
+#include <vector>
+
+#include <cutils/compiler.h>
+#include <utils/StrongPointer.h>
+
+#include "TreeInfo.h"
+#include "utils/Macros.h"
+
+namespace android {
+namespace uirenderer {
+
+class BaseRenderNodeAnimator;
+class RenderNode;
+
+// Responsible for managing the animators for a single RenderNode
+class AnimatorManager {
+ PREVENT_COPY_AND_ASSIGN(AnimatorManager);
+public:
+ AnimatorManager(RenderNode& parent);
+ ~AnimatorManager();
+
+ void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
+
+ void pushStaging(TreeInfo& info);
+ void animate(TreeInfo& info);
+
+private:
+ RenderNode& mParent;
+
+ // To improve the efficiency of resizing & removing from the vector
+ // use manual ref counting instead of sp<>.
+ std::vector<BaseRenderNodeAnimator*> mNewAnimators;
+ std::vector<BaseRenderNodeAnimator*> mAnimators;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* ANIMATORMANAGER_H */
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 8e99b9a..02b0372 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -58,7 +58,7 @@ void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
SkRefCnt_SafeAssign(mColorFilter, colorFilter);
}
-bool DeferredLayerUpdater::apply(TreeInfo& info) {
+bool DeferredLayerUpdater::apply() {
bool success = true;
// These properties are applied the same to both layer types
mLayer->setColorFilter(mColorFilter);
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index c76bd5e..5905b95 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -75,7 +75,7 @@ public:
ANDROID_API void setPaint(const SkPaint* paint);
- ANDROID_API bool apply(TreeInfo& info);
+ ANDROID_API bool apply();
ANDROID_API Layer* backingLayer() {
return mLayer;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 131384a..e803ec3 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -62,7 +62,7 @@ RenderNode::RenderNode()
, mNeedsDisplayListDataSync(false)
, mDisplayListData(0)
, mStagingDisplayListData(0)
- , mNeedsAnimatorsSync(false)
+ , mAnimatorManager(*this)
, mLayer(0) {
}
@@ -117,6 +117,10 @@ void RenderNode::prepareTree(TreeInfo& info) {
prepareTreeImpl(info);
}
+void RenderNode::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
+ mAnimatorManager.addAnimator(animator);
+}
+
void RenderNode::damageSelf(TreeInfo& info) {
if (isRenderable()) {
if (properties().getClipDamageToBounds()) {
@@ -193,11 +197,11 @@ void RenderNode::prepareTreeImpl(TreeInfo& info) {
info.damageAccumulator->pushTransform(this);
if (info.mode == TreeInfo::MODE_FULL) {
pushStagingPropertiesChanges(info);
- evaluateAnimations(info);
+ mAnimatorManager.animate(info);
} else if (info.mode == TreeInfo::MODE_MAYBE_DETACHING) {
pushStagingPropertiesChanges(info);
} else if (info.mode == TreeInfo::MODE_RT_ONLY) {
- evaluateAnimations(info);
+ mAnimatorManager.animate(info);
}
prepareLayer(info);
@@ -210,33 +214,11 @@ void RenderNode::prepareTreeImpl(TreeInfo& info) {
info.damageAccumulator->popTransform();
}
-class PushAnimatorsFunctor {
-public:
- PushAnimatorsFunctor(RenderNode* target, TreeInfo& info)
- : mTarget(target), mInfo(info) {}
-
- bool operator() (const sp<BaseRenderNodeAnimator>& animator) {
- animator->setupStartValueIfNecessary(mTarget, mInfo);
- return animator->isFinished();
- }
-private:
- RenderNode* mTarget;
- TreeInfo& mInfo;
-};
-
void RenderNode::pushStagingPropertiesChanges(TreeInfo& info) {
// Push the animators first so that setupStartValueIfNecessary() is called
// before properties() is trampled by stagingProperties(), as they are
// required by some animators.
- if (mNeedsAnimatorsSync) {
- mAnimators.resize(mStagingAnimators.size());
- std::vector< sp<BaseRenderNodeAnimator> >::iterator it;
- PushAnimatorsFunctor functor(this, info);
- // hint: this means copy_if_not()
- it = std::remove_copy_if(mStagingAnimators.begin(), mStagingAnimators.end(),
- mAnimators.begin(), functor);
- mAnimators.resize(std::distance(mAnimators.begin(), it));
- }
+ mAnimatorManager.pushStaging(info);
if (mDirtyPropertyFields) {
mDirtyPropertyFields = 0;
damageSelf(info);
@@ -267,8 +249,7 @@ void RenderNode::pushStagingDisplayListChanges(TreeInfo& info) {
mNeedsDisplayListDataSync = false;
// Do a push pass on the old tree to handle freeing DisplayListData
// that are no longer used
- TreeInfo oldTreeInfo(TreeInfo::MODE_MAYBE_DETACHING, info.renderState);
- oldTreeInfo.damageAccumulator = info.damageAccumulator;
+ TreeInfo oldTreeInfo(TreeInfo::MODE_MAYBE_DETACHING, info);
prepareSubTree(oldTreeInfo, mDisplayListData);
delete mDisplayListData;
mDisplayListData = mStagingDisplayListData;
@@ -277,39 +258,6 @@ void RenderNode::pushStagingDisplayListChanges(TreeInfo& info) {
}
}
-class AnimateFunctor {
-public:
- AnimateFunctor(RenderNode* target, TreeInfo& info)
- : mTarget(target), mInfo(info) {}
-
- bool operator() (const sp<BaseRenderNodeAnimator>& animator) {
- return animator->animate(mTarget, mInfo);
- }
-private:
- RenderNode* mTarget;
- TreeInfo& mInfo;
-};
-
-void RenderNode::evaluateAnimations(TreeInfo& info) {
- if (!mAnimators.size()) return;
-
- // TODO: Can we target this better? For now treat it like any other staging
- // property push and just damage self before and after animators are run
-
- damageSelf(info);
- info.damageAccumulator->popTransform();
-
- AnimateFunctor functor(this, info);
- std::vector< sp<BaseRenderNodeAnimator> >::iterator newEnd;
- newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
- mAnimators.erase(newEnd, mAnimators.end());
- mProperties.updateMatrix();
- info.out.hasAnimations |= mAnimators.size();
-
- info.damageAccumulator->pushTransform(this);
- damageSelf(info);
-}
-
void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
if (subtree) {
TextureCache& cache = Caches::getInstance().textureCache;
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 3980dad..7d42b59 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -20,18 +20,11 @@
#define LOG_TAG "OpenGLRenderer"
#endif
-#include <set>
-#include <vector>
-
#include <SkCamera.h>
#include <SkMatrix.h>
-#include <private/hwui/DrawGlInfo.h>
-
-#include <utils/KeyedVector.h>
#include <utils/LinearAllocator.h>
#include <utils/RefBase.h>
-#include <utils/SortedVector.h>
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -39,6 +32,7 @@
#include <androidfw/ResourceTypes.h>
+#include "AnimatorManager.h"
#include "DamageAccumulator.h"
#include "Debug.h"
#include "Matrix.h"
@@ -176,19 +170,7 @@ public:
ANDROID_API virtual void prepareTree(TreeInfo& info);
// UI thread only!
- ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
- animator->onAttached(this);
- mStagingAnimators.insert(animator);
- mNeedsAnimatorsSync = true;
- }
-
- // UI thread only!
- ANDROID_API void removeAnimator(const sp<BaseRenderNodeAnimator>& animator) {
- mStagingAnimators.erase(animator);
- // Force a sync of the staging property value
- mDirtyPropertyFields |= animator->dirtyMask();
- mNeedsAnimatorsSync = true;
- }
+ ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
protected:
virtual void damageSelf(TreeInfo& info);
@@ -262,7 +244,6 @@ private:
void prepareTreeImpl(TreeInfo& info);
void pushStagingPropertiesChanges(TreeInfo& info);
void pushStagingDisplayListChanges(TreeInfo& info);
- void evaluateAnimations(TreeInfo& info);
void prepareSubTree(TreeInfo& info, DisplayListData* subtree);
void applyLayerPropertiesToLayer(TreeInfo& info);
void prepareLayer(TreeInfo& info);
@@ -278,9 +259,8 @@ private:
DisplayListData* mDisplayListData;
DisplayListData* mStagingDisplayListData;
- bool mNeedsAnimatorsSync;
- std::set< sp<BaseRenderNodeAnimator> > mStagingAnimators;
- std::vector< sp<BaseRenderNodeAnimator> > mAnimators;
+ friend class AnimatorManager;
+ AnimatorManager mAnimatorManager;
// Owned by RT. Lifecycle is managed by prepareTree(), with the exception
// being in ~RenderNode() which may happen on any thread.
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index 249e525..083100e 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -79,6 +79,17 @@ public:
, errorHandler(NULL)
{}
+ explicit TreeInfo(TraversalMode mode, const TreeInfo& clone)
+ : mode(mode)
+ , frameTimeMs(clone.frameTimeMs)
+ , animationHook(clone.animationHook)
+ , prepareTextures(mode == MODE_FULL)
+ , damageAccumulator(clone.damageAccumulator)
+ , renderState(clone.renderState)
+ , renderer(clone.renderer)
+ , errorHandler(clone.errorHandler)
+ {}
+
const TraversalMode mode;
nsecs_t frameTimeMs;
AnimationHook* animationHook;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 281a8e1..9c3cf44 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -123,8 +123,8 @@ void CanvasContext::makeCurrent() {
mHaveNewSurface |= mEglManager.makeCurrent(mEglSurface);
}
-void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info) {
- bool success = layerUpdater->apply(info);
+void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater) {
+ bool success = layerUpdater->apply();
LOG_ALWAYS_FATAL_IF(!success, "Failed to update layer!");
if (layerUpdater->backingLayer()->deferredUpdateScheduled) {
mCanvas->pushLayerUpdate(layerUpdater->backingLayer());
@@ -237,8 +237,7 @@ void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
requireGlContext();
- TreeInfo info(TreeInfo::MODE_FULL, mRenderThread.renderState());
- layer->apply(info);
+ layer->apply();
return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index d2ce1a6..dbfb3d2 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -56,7 +56,7 @@ public:
void setup(int width, int height, const Vector3& lightCenter, float lightRadius);
void setOpaque(bool opaque);
void makeCurrent();
- void processLayerUpdate(DeferredLayerUpdater* layerUpdater, TreeInfo& info);
+ void processLayerUpdate(DeferredLayerUpdater* layerUpdater);
void prepareTree(TreeInfo& info);
void draw();
void destroyCanvasAndSurface();
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index fddffd5..dd34e09 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -127,7 +127,7 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) {
Caches::getInstance().textureCache.resetMarkInUse();
for (size_t i = 0; i < mLayers.size(); i++) {
- mContext->processLayerUpdate(mLayers[i].get(), info);
+ mContext->processLayerUpdate(mLayers[i].get());
}
mLayers.clear();
mContext->prepareTree(info);