diff options
Diffstat (limited to 'libs/hwui/AnimationContext.cpp')
-rw-r--r-- | libs/hwui/AnimationContext.cpp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/libs/hwui/AnimationContext.cpp b/libs/hwui/AnimationContext.cpp new file mode 100644 index 0000000..ec44de3 --- /dev/null +++ b/libs/hwui/AnimationContext.cpp @@ -0,0 +1,126 @@ +/* + * 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 "AnimationContext.h" + +#include "Animator.h" +#include "RenderNode.h" +#include "TreeInfo.h" +#include "renderthread/TimeLord.h" + +namespace android { +namespace uirenderer { + +AnimationContext::AnimationContext(renderthread::TimeLord& clock) + : mClock(clock) + , mCurrentFrameAnimations(*this) + , mNextFrameAnimations(*this) + , mFrameTimeMs(0) { +} + +AnimationContext::~AnimationContext() { +} + +void AnimationContext::addAnimatingRenderNode(RenderNode& node) { + if (!node.animators().hasAnimationHandle()) { + AnimationHandle* handle = new AnimationHandle(node, *this); + addAnimationHandle(handle); + } +} + +void AnimationContext::addAnimationHandle(AnimationHandle* handle) { + handle->insertAfter(&mNextFrameAnimations); +} + +void AnimationContext::startFrame() { + LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle, + "Missed running animations last frame!"); + AnimationHandle* head = mNextFrameAnimations.mNextHandle; + if (head) { + mNextFrameAnimations.mNextHandle = NULL; + mCurrentFrameAnimations.mNextHandle = head; + head->mPreviousHandle = &mCurrentFrameAnimations; + } + mFrameTimeMs = mClock.computeFrameTimeMs(); +} + +void AnimationContext::runRemainingAnimations(TreeInfo& info) { + while (mCurrentFrameAnimations.mNextHandle) { + AnimationHandle* current = mCurrentFrameAnimations.mNextHandle; + AnimatorManager& animators = current->mRenderNode->animators(); + animators.pushStaging(); + animators.animateNoDamage(info); + LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle == current, + "Animate failed to remove from current frame list!"); + } +} + +void AnimationContext::callOnFinished(BaseRenderNodeAnimator* animator, + AnimationListener* listener) { + listener->onAnimationFinished(animator); +} + +AnimationHandle::AnimationHandle(AnimationContext& context) + : mContext(context) + , mPreviousHandle(NULL) + , mNextHandle(NULL) { +} + +AnimationHandle::AnimationHandle(RenderNode& animatingNode, AnimationContext& context) + : mRenderNode(&animatingNode) + , mContext(context) + , mPreviousHandle(NULL) + , mNextHandle(NULL) { + mRenderNode->animators().setAnimationHandle(this); +} + +AnimationHandle::~AnimationHandle() { + LOG_ALWAYS_FATAL_IF(mPreviousHandle || mNextHandle, + "AnimationHandle destroyed while still animating!"); +} + +void AnimationHandle::notifyAnimationsRan() { + removeFromList(); + if (mRenderNode->animators().hasAnimators()) { + mContext.addAnimationHandle(this); + } else { + mRenderNode->animators().setAnimationHandle(NULL); + delete this; + } +} + +void AnimationHandle::insertAfter(AnimationHandle* prev) { + removeFromList(); + mNextHandle = prev->mNextHandle; + if (mNextHandle) { + mNextHandle->mPreviousHandle = this; + } + prev->mNextHandle = this; + mPreviousHandle = prev; +} + +void AnimationHandle::removeFromList() { + if (mPreviousHandle) { + mPreviousHandle->mNextHandle = mNextHandle; + } + if (mNextHandle) { + mNextHandle->mPreviousHandle = mPreviousHandle; + } + mPreviousHandle = NULL; + mNextHandle = NULL; +} + +} /* namespace uirenderer */ +} /* namespace android */ |