Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2135)

Unified Diff: Source/platform/scroll/ProgrammaticScrollAnimator.cpp

Issue 802383003: Run CSSOM smooth scroll animations on the compositor when possible (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Add comment Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/platform/scroll/ProgrammaticScrollAnimator.h ('k') | Source/platform/scroll/ScrollableArea.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/scroll/ProgrammaticScrollAnimator.cpp
diff --git a/Source/platform/scroll/ProgrammaticScrollAnimator.cpp b/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
index 574018064f1a97aeb528ca6e7a317ae5dec6e2aa..7b2332936a21758aa06070ec8d54633bc147ff9b 100644
--- a/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
+++ b/Source/platform/scroll/ProgrammaticScrollAnimator.cpp
@@ -6,8 +6,10 @@
#include "platform/scroll/ProgrammaticScrollAnimator.h"
#include "platform/geometry/IntPoint.h"
+#include "platform/graphics/GraphicsLayer.h"
#include "platform/scroll/ScrollableArea.h"
#include "public/platform/Platform.h"
+#include "public/platform/WebCompositorAnimation.h"
#include "public/platform/WebCompositorSupport.h"
#include "public/platform/WebScrollOffsetAnimationCurve.h"
@@ -21,6 +23,9 @@ PassOwnPtr<ProgrammaticScrollAnimator> ProgrammaticScrollAnimator::create(Scroll
ProgrammaticScrollAnimator::ProgrammaticScrollAnimator(ScrollableArea* scrollableArea)
: m_scrollableArea(scrollableArea)
, m_startTime(0.0)
+ , m_runState(RunState::Idle)
+ , m_compositorAnimationId(0)
+ , m_compositorAnimationGroupId(0)
{
}
@@ -32,6 +37,9 @@ void ProgrammaticScrollAnimator::resetAnimationState()
{
m_animationCurve.clear();
m_startTime = 0.0;
+ m_runState = RunState::Idle;
+ m_compositorAnimationId = 0;
+ m_compositorAnimationGroupId = 0;
}
void ProgrammaticScrollAnimator::animateToOffset(FloatPoint offset)
@@ -46,35 +54,134 @@ void ProgrammaticScrollAnimator::animateToOffset(FloatPoint offset)
resetAnimationState();
m_scrollableArea->notifyScrollPositionChanged(IntPoint(offset.x(), offset.y()));
}
+ m_runState = RunState::WaitingToSendToCompositor;
}
void ProgrammaticScrollAnimator::cancelAnimation()
{
- resetAnimationState();
+ switch (m_runState) {
+ case RunState::Idle:
+ case RunState::WaitingToCancelOnCompositor:
+ break;
+ case RunState::WaitingToSendToCompositor:
+ if (m_compositorAnimationId) {
+ // We still have a previous animation running on the compositor.
+ m_runState = RunState::WaitingToCancelOnCompositor;
+ } else {
+ resetAnimationState();
+ }
+ break;
+ case RunState::RunningOnMainThread:
+ resetAnimationState();
+ break;
+ case RunState::RunningOnCompositor:
+ m_runState = RunState::WaitingToCancelOnCompositor;
+
+ // Get serviced the next time compositor updates are allowed.
+ m_scrollableArea->registerForAnimation();
+ }
}
void ProgrammaticScrollAnimator::tickAnimation(double monotonicTime)
{
- if (m_animationCurve) {
- if (!m_startTime)
- m_startTime = monotonicTime;
- double elapsedTime = monotonicTime - m_startTime;
- bool isFinished = (elapsedTime > m_animationCurve->duration());
- FloatPoint offset = m_animationCurve->getValue(elapsedTime);
- m_scrollableArea->notifyScrollPositionChanged(IntPoint(offset.x(), offset.y()));
+ if (m_runState != RunState::RunningOnMainThread)
+ return;
- if (isFinished) {
- resetAnimationState();
- } else if (!m_scrollableArea->scheduleAnimation()) {
- m_scrollableArea->notifyScrollPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y()));
+ if (!m_startTime)
+ m_startTime = monotonicTime;
+ double elapsedTime = monotonicTime - m_startTime;
+ bool isFinished = (elapsedTime > m_animationCurve->duration());
+ FloatPoint offset = m_animationCurve->getValue(elapsedTime);
+ m_scrollableArea->notifyScrollPositionChanged(IntPoint(offset.x(), offset.y()));
+
+ if (isFinished) {
+ resetAnimationState();
+ } else if (!m_scrollableArea->scheduleAnimation()) {
+ m_scrollableArea->notifyScrollPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y()));
+ resetAnimationState();
+ }
+}
+
+bool ProgrammaticScrollAnimator::hasAnimationThatRequiresService() const
+{
+ switch (m_runState) {
+ case RunState::Idle:
+ case RunState::RunningOnCompositor:
+ return false;
+ case RunState::WaitingToSendToCompositor:
+ case RunState::RunningOnMainThread:
+ case RunState::WaitingToCancelOnCompositor:
+ return true;
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+void ProgrammaticScrollAnimator::updateCompositorAnimations()
+{
+ if (m_compositorAnimationId && m_runState != RunState::RunningOnCompositor) {
+ // If the current run state is WaitingToSendToCompositor but we have a
+ // non-zero compositor animation id, there's a currently running
+ // compositor animation that needs to be removed here before the new
+ // animation is added below.
+ ASSERT(m_runState == RunState::WaitingToCancelOnCompositor || m_runState == RunState::WaitingToSendToCompositor);
+ if (GraphicsLayer* layer = m_scrollableArea->layerForScrolling())
+ layer->removeAnimation(m_compositorAnimationId);
+ m_compositorAnimationId = 0;
+ m_compositorAnimationGroupId = 0;
+ if (m_runState == RunState::WaitingToCancelOnCompositor) {
resetAnimationState();
+ return;
+ }
+ }
+
+ if (m_runState == RunState::WaitingToSendToCompositor) {
+ bool sentToCompositor = false;
+
+ if (GraphicsLayer* layer = m_scrollableArea->layerForScrolling()) {
+ if (!layer->platformLayer()->shouldScrollOnMainThread()) {
+ OwnPtr<WebCompositorAnimation> animation = adoptPtr(Platform::current()->compositorSupport()->createAnimation(*m_animationCurve, WebCompositorAnimation::TargetPropertyScrollOffset));
+
+ int animationId = animation->id();
+ int animationGroupId = animation->group();
+ if (m_scrollableArea->layerForScrolling()->addAnimation(animation.release())) {
+ sentToCompositor = true;
+ m_runState = RunState::RunningOnCompositor;
+ m_compositorAnimationId = animationId;
+ m_compositorAnimationGroupId = animationGroupId;
+ }
+ }
+ }
+
+ if (!sentToCompositor) {
+ m_runState = RunState::RunningOnMainThread;
+ if (!m_scrollableArea->scheduleAnimation()) {
+ m_scrollableArea->notifyScrollPositionChanged(IntPoint(m_targetOffset.x(), m_targetOffset.y()));
+ resetAnimationState();
+ }
}
}
}
-bool ProgrammaticScrollAnimator::hasRunningAnimation() const
+void ProgrammaticScrollAnimator::notifyCompositorAnimationFinished(int groupId)
{
- return !!m_animationCurve;
+ if (m_compositorAnimationGroupId != groupId)
+ return;
+
+ m_compositorAnimationId = 0;
+ m_compositorAnimationGroupId = 0;
+
+ switch (m_runState) {
+ case RunState::Idle:
+ case RunState::RunningOnMainThread:
+ ASSERT_NOT_REACHED();
+ break;
+ case RunState::WaitingToSendToCompositor:
+ break;
+ case RunState::RunningOnCompositor:
+ case RunState::WaitingToCancelOnCompositor:
+ resetAnimationState();
+ }
}
} // namespace blink
« no previous file with comments | « Source/platform/scroll/ProgrammaticScrollAnimator.h ('k') | Source/platform/scroll/ScrollableArea.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698