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

Side by Side Diff: third_party/WebKit/Source/modules/compositorworker/WorkletAnimation.cpp

Issue 2869183002: Initial implementation of WorkletAnimation (Closed)
Patch Set: Rebase Created 3 years, 6 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
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "modules/compositorworker/WorkletAnimation.h"
6
7 #include "core/animation/DocumentTimeline.h"
8 #include "core/animation/ElementAnimations.h"
9 #include "core/animation/KeyframeEffectModel.h"
10 #include "core/animation/ScrollTimeline.h"
11 #include "core/animation/Timing.h"
12 #include "core/dom/Node.h"
13 #include "core/dom/NodeComputedStyle.h"
14 #include "platform/animation/CompositorAnimationPlayer.h"
15 #include "platform/wtf/text/WTFString.h"
16 #include "public/platform/Platform.h"
17 #include "public/platform/WebCompositorSupport.h"
18
19 namespace blink {
20
21 namespace {
22 bool ValidateEffects(const HeapVector<Member<KeyframeEffectReadOnly>>& effects,
23 String* error_string) {
alancutter (OOO until 2018) 2017/06/26 11:57:02 Blink style is to use references instead of pointe
smcgruer 2017/06/26 21:14:08 Done.
24 if (effects.IsEmpty()) {
25 *error_string = "Effects array must be non-empty";
26 return false;
27 }
28
29 Document& target_document = effects.at(0)->Target()->GetDocument();
30 for (const auto& effect : effects) {
31 if (effect->Target()->GetDocument() != target_document) {
32 *error_string = "All effects must target elements in the same document";
33 return false;
34 }
35 }
36 return true;
37 }
38
39 bool ValidateTimelines(HeapVector<DocumentTimelineOrScrollTimeline>& timelines,
40 String* error_string) {
41 if (timelines.IsEmpty()) {
42 *error_string = "Timelines array must be non-empty";
43 return false;
44 }
45
46 for (const auto& timeline : timelines) {
47 if (timeline.isScrollTimeline()) {
48 DoubleOrScrollTimelineAutoKeyword time_range;
49 timeline.getAsScrollTimeline()->timeRange(time_range);
50 if (time_range.isScrollTimelineAutoKeyword()) {
51 *error_string = "ScrollTimeline timeRange must have non-auto value";
52 return false;
53 }
54 }
55 }
56 return true;
57 }
58
59 String AnimationPlayStateToString(
60 WorkletAnimation::AnimationPlayState play_state) {
61 switch (play_state) {
62 case WorkletAnimation::kIdle:
63 return "idle";
64 case WorkletAnimation::kPending:
65 return "pending";
66 case WorkletAnimation::kRunning:
67 return "running";
68 default:
69 NOTREACHED();
70 return "";
71 }
72 }
73 } // namespace
74
75 WorkletAnimation* WorkletAnimation::Create(
76 String animator_name,
77 const HeapVector<Member<KeyframeEffectReadOnly>>& effects,
78 HeapVector<DocumentTimelineOrScrollTimeline>& timelines,
79 RefPtr<SerializedScriptValue> options,
80 ExceptionState& exception_state) {
81 String error_string;
82 if (!ValidateEffects(effects, &error_string)) {
83 exception_state.ThrowDOMException(kNotSupportedError, error_string);
84 return nullptr;
85 }
86
87 if (!ValidateTimelines(timelines, &error_string)) {
88 exception_state.ThrowDOMException(kNotSupportedError, error_string);
89 return nullptr;
90 }
91
92 Document& document = effects.at(0)->Target()->GetDocument();
93 WorkletAnimation* animation = new WorkletAnimation(
94 animator_name, document, effects, timelines, std::move(options));
95 animation->AttachCompositorTimeline();
96
97 return animation;
98 }
99
100 WorkletAnimation::WorkletAnimation(
101 String animator_name,
102 Document& document,
103 const HeapVector<Member<KeyframeEffectReadOnly>>& effects,
104 HeapVector<DocumentTimelineOrScrollTimeline>& timelines,
105 RefPtr<SerializedScriptValue> options)
106 : animator_name_(animator_name),
107 document_(document),
108 effects_(effects),
109 timelines_(timelines),
110 options_(std::move(options)) {
111 DCHECK(Platform::Current()->IsThreadedAnimationEnabled());
112 DCHECK(Platform::Current()->CompositorSupport());
113 compositor_player_ = CompositorAnimationPlayerHolder::Create(this);
114 DCHECK(compositor_player_);
115 }
116
117 String WorkletAnimation::playState() {
118 return AnimationPlayStateToString(play_state_);
119 }
120
121 void WorkletAnimation::play() {
122 // TODO(smcgruer): Should this set NeedsCompositingUpdate?
flackr 2017/06/19 20:35:33 The WorkletAnimationController should I think.
smcgruer 2017/07/24 14:48:58 Ack added TODO on the WorkletAnimationController.
123 document_->GetWorkletAnimationController().AttachAnimation(*this);
124 play_state_ = kPending;
125 }
126
127 void WorkletAnimation::cancel() {
128 document_->GetWorkletAnimationController().DetachAnimation(*this);
129 play_state_ = kIdle;
130 }
131
132 bool WorkletAnimation::StartOnCompositor() {
133 int group = 0;
134 double start_time = 0;
135 double current_time = 0;
136 double animation_playback_rate = 1;
137 Element& target = *effects_.at(0)->Target();
138 static_cast<KeyframeEffectModelBase*>(effects_.at(0)->Model())
alancutter (OOO until 2018) 2017/06/26 11:57:02 Use ToKeyframeEffectModelBase().
smcgruer 2017/06/26 21:14:08 Done.
139 ->SnapshotAllCompositorKeyframes(target, target.ComputedStyleRef(),
140 target.ParentComputedStyle());
141 bool success = effects_.at(0)->MaybeStartAnimationOnCompositor(
alancutter (OOO until 2018) 2017/06/26 11:57:02 MaybeStartAnimationOnCompositor() is now CanStartA
smcgruer 2017/06/26 21:14:08 Ack; I see that there is now a new cl to make them
smcgruer 2017/06/27 18:02:43 Done.
142 group, start_time, current_time, animation_playback_rate,
143 compositor_player_->Player());
flackr 2017/06/19 20:35:33 I'm a bit confused about what this is doing. We're
smcgruer 2017/06/26 21:14:08 As far as I understand it, a lot of plumbing is st
smcgruer 2017/06/27 18:02:43 A question was raised today as to why this doesn't
flackr 2017/07/19 19:23:48 I think we should just assume success (or failure?
smcgruer 2017/07/24 14:48:58 Done.
144 play_state_ = success ? kRunning : kIdle;
145 return success;
146 }
147
148 void WorkletAnimation::AttachCompositorTimeline() {
149 document_->Timeline().CompositorTimeline()->PlayerAttached(*this);
150 }
151
152 void WorkletAnimation::DetachCompositorTimeline() {
153 document_->Timeline().CompositorTimeline()->PlayerDestroyed(*this);
154 }
alancutter (OOO until 2018) 2017/06/26 11:57:02 I'm not sure we need these two methods given they'
smcgruer 2017/06/26 21:14:08 Done.
155
156 void WorkletAnimation::Dispose() {
157 DetachCompositorTimeline();
158 compositor_player_->Detach();
159 compositor_player_ = nullptr;
160 }
161
162 void WorkletAnimation::SetEffectInheritedTimeForTesting(
163 Member<KeyframeEffectReadOnly> effect,
164 double inherited_time) {}
165
166 DEFINE_TRACE(WorkletAnimation) {
167 visitor->Trace(document_);
168 visitor->Trace(effects_);
169 visitor->Trace(timelines_);
170 visitor->Trace(compositor_player_);
171 WorkletAnimationBase::Trace(visitor);
172 }
173
174 WorkletAnimation::CompositorAnimationPlayerHolder*
175 WorkletAnimation::CompositorAnimationPlayerHolder::Create(
176 WorkletAnimation* animation) {
177 return new CompositorAnimationPlayerHolder(animation);
178 }
179
180 WorkletAnimation::CompositorAnimationPlayerHolder::
181 CompositorAnimationPlayerHolder(WorkletAnimation* animation)
182 : animation_(animation) {
183 compositor_player_ = CompositorAnimationPlayer::Create();
184 compositor_player_->SetAnimationDelegate(animation_);
185 }
186
187 void WorkletAnimation::CompositorAnimationPlayerHolder::Dispose() {
188 if (!animation_)
189 return;
190 animation_->Dispose();
191 DCHECK(!animation_);
192 DCHECK(!compositor_player_);
193 }
194
195 void WorkletAnimation::CompositorAnimationPlayerHolder::Detach() {
196 compositor_player_->SetAnimationDelegate(nullptr);
197 animation_ = nullptr;
198 compositor_player_.reset();
199 }
200
201 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698