diff options
author | 2014-09-05 15:23:38 -0700 | |
---|---|---|
committer | 2014-09-05 15:23:38 -0700 | |
commit | ec845a215e343cdb3b2e4c7b6aff7b24beb0236b (patch) | |
tree | 270a6f8ff4a8c6c03c207ebc6fca85168efc25b8 | |
parent | c237555c6cb89c347acf13eba45b875946473501 (diff) |
Fix race condition
Bug: 17372309
AnimationContext::startFrame() happens both with and without
the UI thread lock. Pass the TraversalMode into it so
that ThreadedRenderer's subclass can correctly decide
when it is safe to push over mPendingAnimatingRenderNodes, as doing
so outside of the lock is Very Bad.
Change-Id: Ife5dd3a2b46b0a207cd9234c159a674afdbf5efd
-rw-r--r-- | core/jni/android_view_ThreadedRenderer.cpp | 8 | ||||
-rw-r--r-- | libs/hwui/AnimationContext.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/AnimationContext.h | 4 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 2 |
4 files changed, 10 insertions, 9 deletions
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp index 7e6d3356d565..a8edb77b0212 100644 --- a/core/jni/android_view_ThreadedRenderer.cpp +++ b/core/jni/android_view_ThreadedRenderer.cpp @@ -158,9 +158,11 @@ public: // Marks the start of a frame, which will update the frame time and move all // next frame animations into the current frame - virtual void startFrame() { - mRootNode->doAttachAnimatingNodes(this); - AnimationContext::startFrame(); + virtual void startFrame(TreeInfo::TraversalMode mode) { + if (mode == TreeInfo::MODE_FULL) { + mRootNode->doAttachAnimatingNodes(this); + } + AnimationContext::startFrame(mode); } // Runs any animations still left in mCurrentFrameAnimations diff --git a/libs/hwui/AnimationContext.cpp b/libs/hwui/AnimationContext.cpp index 716dcf57de2d..a20bdae31f79 100644 --- a/libs/hwui/AnimationContext.cpp +++ b/libs/hwui/AnimationContext.cpp @@ -17,7 +17,6 @@ #include "Animator.h" #include "RenderNode.h" -#include "TreeInfo.h" #include "renderthread/TimeLord.h" namespace android { @@ -34,7 +33,7 @@ AnimationContext::~AnimationContext() { } void AnimationContext::destroy() { - startFrame(); + startFrame(TreeInfo::MODE_RT_ONLY); while (mCurrentFrameAnimations.mNextHandle) { AnimationHandle* current = mCurrentFrameAnimations.mNextHandle; AnimatorManager& animators = current->mRenderNode->animators(); @@ -55,7 +54,7 @@ void AnimationContext::addAnimationHandle(AnimationHandle* handle) { handle->insertAfter(&mNextFrameAnimations); } -void AnimationContext::startFrame() { +void AnimationContext::startFrame(TreeInfo::TraversalMode mode) { LOG_ALWAYS_FATAL_IF(mCurrentFrameAnimations.mNextHandle, "Missed running animations last frame!"); AnimationHandle* head = mNextFrameAnimations.mNextHandle; diff --git a/libs/hwui/AnimationContext.h b/libs/hwui/AnimationContext.h index 9b3d5f486464..909ed36a2127 100644 --- a/libs/hwui/AnimationContext.h +++ b/libs/hwui/AnimationContext.h @@ -20,6 +20,7 @@ #include <utils/RefBase.h> #include <utils/StrongPointer.h> +#include "TreeInfo.h" #include "renderthread/TimeLord.h" #include "utils/Macros.h" @@ -30,7 +31,6 @@ class AnimationContext; class AnimationListener; class BaseRenderNodeAnimator; class RenderNode; -class TreeInfo; /* * AnimationHandle is several classes merged into one. @@ -90,7 +90,7 @@ public: // Marks the start of a frame, which will update the frame time and move all // next frame animations into the current frame - ANDROID_API virtual void startFrame(); + ANDROID_API virtual void startFrame(TreeInfo::TraversalMode mode); // Runs any animations still left in mCurrentFrameAnimations that were not run // as part of the standard RenderNode:prepareTree pass. diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 4129a89b6ef8..5e6796c2b406 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -150,7 +150,7 @@ void CanvasContext::prepareTree(TreeInfo& info) { if (mPrefetechedLayers.size() && info.mode == TreeInfo::MODE_FULL) { info.canvasContext = this; } - mAnimationContext->startFrame(); + mAnimationContext->startFrame(info.mode); mRootRenderNode->prepareTree(info); mAnimationContext->runRemainingAnimations(info); |