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

Side by Side 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: Fix Windows build 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "platform/scroll/ProgrammaticScrollAnimator.h" 6 #include "platform/scroll/ProgrammaticScrollAnimator.h"
7 7
8 #include "platform/geometry/IntPoint.h" 8 #include "platform/geometry/IntPoint.h"
9 #include "platform/graphics/GraphicsLayer.h"
9 #include "platform/scroll/ScrollableArea.h" 10 #include "platform/scroll/ScrollableArea.h"
10 #include "public/platform/Platform.h" 11 #include "public/platform/Platform.h"
12 #include "public/platform/WebCompositorAnimation.h"
11 #include "public/platform/WebCompositorSupport.h" 13 #include "public/platform/WebCompositorSupport.h"
12 #include "public/platform/WebScrollOffsetAnimationCurve.h" 14 #include "public/platform/WebScrollOffsetAnimationCurve.h"
13 15
14 namespace blink { 16 namespace blink {
15 17
16 PassOwnPtr<ProgrammaticScrollAnimator> ProgrammaticScrollAnimator::create(Scroll ableArea* scrollableArea) 18 PassOwnPtr<ProgrammaticScrollAnimator> ProgrammaticScrollAnimator::create(Scroll ableArea* scrollableArea)
17 { 19 {
18 return adoptPtr(new ProgrammaticScrollAnimator(scrollableArea)); 20 return adoptPtr(new ProgrammaticScrollAnimator(scrollableArea));
19 } 21 }
20 22
21 ProgrammaticScrollAnimator::ProgrammaticScrollAnimator(ScrollableArea* scrollabl eArea) 23 ProgrammaticScrollAnimator::ProgrammaticScrollAnimator(ScrollableArea* scrollabl eArea)
22 : m_scrollableArea(scrollableArea) 24 : m_scrollableArea(scrollableArea)
23 , m_startTime(0.0) 25 , m_startTime(0.0)
26 , m_runState(RunState::Idle)
27 , m_compositorAnimationId(0)
28 , m_compositorAnimationGroupId(0)
24 { 29 {
25 } 30 }
26 31
27 ProgrammaticScrollAnimator::~ProgrammaticScrollAnimator() 32 ProgrammaticScrollAnimator::~ProgrammaticScrollAnimator()
28 { 33 {
29 } 34 }
30 35
31 void ProgrammaticScrollAnimator::resetAnimationState() 36 void ProgrammaticScrollAnimator::resetAnimationState()
32 { 37 {
33 m_animationCurve.clear(); 38 m_animationCurve.clear();
34 m_startTime = 0.0; 39 m_startTime = 0.0;
40 m_runState = RunState::Idle;
41 m_compositorAnimationId = 0;
42 m_compositorAnimationGroupId = 0;
35 } 43 }
36 44
37 void ProgrammaticScrollAnimator::animateToOffset(FloatPoint offset) 45 void ProgrammaticScrollAnimator::animateToOffset(FloatPoint offset)
38 { 46 {
39 m_startTime = 0.0; 47 m_startTime = 0.0;
40 m_targetOffset = offset; 48 m_targetOffset = offset;
41 m_animationCurve = adoptPtr(Platform::current()->compositorSupport()->create ScrollOffsetAnimationCurve(m_targetOffset, WebCompositorAnimationCurve::TimingFu nctionTypeEaseInOut)); 49 m_animationCurve = adoptPtr(Platform::current()->compositorSupport()->create ScrollOffsetAnimationCurve(m_targetOffset, WebCompositorAnimationCurve::TimingFu nctionTypeEaseInOut));
42 50
43 m_animationCurve->setInitialValue(FloatPoint(m_scrollableArea->scrollPositio n())); 51 m_animationCurve->setInitialValue(FloatPoint(m_scrollableArea->scrollPositio n()));
44 m_scrollableArea->registerForAnimation(); 52 m_scrollableArea->registerForAnimation();
45 if (!m_scrollableArea->scheduleAnimation()) { 53 if (!m_scrollableArea->scheduleAnimation()) {
46 resetAnimationState(); 54 resetAnimationState();
47 m_scrollableArea->notifyScrollPositionChanged(IntPoint(offset.x(), offse t.y())); 55 m_scrollableArea->notifyScrollPositionChanged(IntPoint(offset.x(), offse t.y()));
48 } 56 }
57 m_runState = RunState::WaitingToSendToCompositor;
49 } 58 }
50 59
51 void ProgrammaticScrollAnimator::cancelAnimation() 60 void ProgrammaticScrollAnimator::cancelAnimation()
52 { 61 {
53 resetAnimationState(); 62 switch (m_runState) {
63 case RunState::Idle:
64 case RunState::WaitingToCancelOnCompositor:
65 break;
66 case RunState::WaitingToSendToCompositor:
67 if (m_compositorAnimationId) {
68 // We still have a previous animation running on the compositor.
69 m_runState = RunState::WaitingToCancelOnCompositor;
70 } else {
71 resetAnimationState();
72 }
73 break;
74 case RunState::RunningOnMainThread:
75 resetAnimationState();
76 break;
77 case RunState::RunningOnCompositor:
78 m_runState = RunState::WaitingToCancelOnCompositor;
79
80 // Get serviced the next time compositor updates are allowed.
81 m_scrollableArea->registerForAnimation();
82 }
54 } 83 }
55 84
56 void ProgrammaticScrollAnimator::tickAnimation(double monotonicTime) 85 void ProgrammaticScrollAnimator::tickAnimation(double monotonicTime)
57 { 86 {
58 if (m_animationCurve) { 87 if (m_runState != RunState::RunningOnMainThread)
59 if (!m_startTime) 88 return;
60 m_startTime = monotonicTime;
61 double elapsedTime = monotonicTime - m_startTime;
62 bool isFinished = (elapsedTime > m_animationCurve->duration());
63 FloatPoint offset = m_animationCurve->getValue(elapsedTime);
64 m_scrollableArea->notifyScrollPositionChanged(IntPoint(offset.x(), offse t.y()));
65 89
66 if (isFinished) { 90 if (!m_startTime)
91 m_startTime = monotonicTime;
92 double elapsedTime = monotonicTime - m_startTime;
93 bool isFinished = (elapsedTime > m_animationCurve->duration());
94 FloatPoint offset = m_animationCurve->getValue(elapsedTime);
95 m_scrollableArea->notifyScrollPositionChanged(IntPoint(offset.x(), offset.y( )));
96
97 if (isFinished) {
98 resetAnimationState();
99 } else if (!m_scrollableArea->scheduleAnimation()) {
100 m_scrollableArea->notifyScrollPositionChanged(IntPoint(m_targetOffset.x( ), m_targetOffset.y()));
101 resetAnimationState();
102 }
103 }
104
105 bool ProgrammaticScrollAnimator::hasAnimationThatRequiresService() const
106 {
107 switch (m_runState) {
108 case RunState::Idle:
109 case RunState::RunningOnCompositor:
110 return false;
111 case RunState::WaitingToSendToCompositor:
112 case RunState::RunningOnMainThread:
113 case RunState::WaitingToCancelOnCompositor:
114 return true;
115 }
116 ASSERT_NOT_REACHED();
117 return false;
118 }
119
120 void ProgrammaticScrollAnimator::updateCompositorAnimations()
121 {
122 if (m_compositorAnimationId && m_runState != RunState::RunningOnCompositor) {
123 ASSERT(m_runState == RunState::WaitingToCancelOnCompositor || m_runState == RunState::WaitingToSendToCompositor);
124 if (GraphicsLayer* layer = m_scrollableArea->layerForScrolling())
125 layer->removeAnimation(m_compositorAnimationId);
Ian Vollick 2015/01/17 15:17:41 It took me a moment to realize that removing here
ajuma 2015/01/19 14:22:34 Done.
126 m_compositorAnimationId = 0;
127 m_compositorAnimationGroupId = 0;
128 if (m_runState == RunState::WaitingToCancelOnCompositor) {
67 resetAnimationState(); 129 resetAnimationState();
68 } else if (!m_scrollableArea->scheduleAnimation()) { 130 return;
69 m_scrollableArea->notifyScrollPositionChanged(IntPoint(m_targetOffse t.x(), m_targetOffset.y())); 131 }
70 resetAnimationState(); 132 }
133
134 if (m_runState == RunState::WaitingToSendToCompositor) {
135 bool sentToCompositor = false;
136
137 if (GraphicsLayer* layer = m_scrollableArea->layerForScrolling()) {
138 if (!layer->platformLayer()->shouldScrollOnMainThread()) {
139 OwnPtr<WebCompositorAnimation> animation = adoptPtr(Platform::cu rrent()->compositorSupport()->createAnimation(*m_animationCurve, WebCompositorAn imation::TargetPropertyScrollOffset));
140
141 int animationId = animation->id();
142 int animationGroupId = animation->group();
143 if (m_scrollableArea->layerForScrolling()->addAnimation(animatio n.release())) {
144 sentToCompositor = true;
145 m_runState = RunState::RunningOnCompositor;
146 m_compositorAnimationId = animationId;
147 m_compositorAnimationGroupId = animationGroupId;
148 }
149 }
150 }
151
152 if (!sentToCompositor) {
153 m_runState = RunState::RunningOnMainThread;
154 if (!m_scrollableArea->scheduleAnimation()) {
155 m_scrollableArea->notifyScrollPositionChanged(IntPoint(m_targetO ffset.x(), m_targetOffset.y()));
156 resetAnimationState();
157 }
71 } 158 }
72 } 159 }
73 } 160 }
74 161
75 bool ProgrammaticScrollAnimator::hasRunningAnimation() const 162 void ProgrammaticScrollAnimator::notifyCompositorAnimationFinished(int groupId)
76 { 163 {
77 return !!m_animationCurve; 164 if (m_compositorAnimationGroupId != groupId)
165 return;
166
167 m_compositorAnimationId = 0;
168 m_compositorAnimationGroupId = 0;
169
170 switch (m_runState) {
171 case RunState::Idle:
172 case RunState::RunningOnMainThread:
173 ASSERT_NOT_REACHED();
174 break;
175 case RunState::WaitingToSendToCompositor:
176 break;
177 case RunState::RunningOnCompositor:
178 case RunState::WaitingToCancelOnCompositor:
179 resetAnimationState();
180 }
78 } 181 }
79 182
80 } // namespace blink 183 } // namespace blink
OLDNEW
« 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