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

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

Issue 2869183002: Initial implementation of WorkletAnimation (Closed)
Patch Set: Use CheckCanStartAnimationOnCompositor Created 3 years, 5 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/ElementAnimations.h"
8 #include "core/animation/KeyframeEffectModel.h"
9 #include "core/animation/ScrollTimeline.h"
10 #include "core/animation/Timing.h"
11 #include "core/dom/Node.h"
12 #include "core/dom/NodeComputedStyle.h"
13 #include "platform/animation/CompositorAnimationPlayer.h"
14 #include "platform/wtf/text/WTFString.h"
15 #include "public/platform/Platform.h"
16 #include "public/platform/WebCompositorSupport.h"
17
18 namespace blink {
19
20 namespace {
21 bool ValidateEffects(const HeapVector<Member<KeyframeEffectReadOnly>>& effects,
22 String& error_string) {
23 if (effects.IsEmpty()) {
24 error_string = "Effects array must be non-empty";
25 return false;
26 }
27
28 Document& target_document = effects.at(0)->Target()->GetDocument();
29 for (const auto& effect : effects) {
30 if (effect->Target()->GetDocument() != target_document) {
31 error_string = "All effects must target elements in the same document";
32 return false;
33 }
34 }
35 return true;
36 }
37
38 bool ValidateTimelines(HeapVector<DocumentTimelineOrScrollTimeline>& timelines,
39 String& error_string) {
40 if (timelines.IsEmpty()) {
41 error_string = "Timelines array must be non-empty";
42 return false;
43 }
44
45 for (const auto& timeline : timelines) {
46 if (timeline.isScrollTimeline()) {
47 DoubleOrScrollTimelineAutoKeyword time_range;
48 timeline.getAsScrollTimeline()->timeRange(time_range);
49 if (time_range.isScrollTimelineAutoKeyword()) {
50 error_string = "ScrollTimeline timeRange must have non-auto value";
51 return false;
52 }
53 }
54 }
55 return true;
56 }
57
58 String AnimationPlayStateToString(
59 WorkletAnimation::AnimationPlayState play_state) {
60 switch (play_state) {
61 case WorkletAnimation::kIdle:
62 return "idle";
63 case WorkletAnimation::kPending:
64 return "pending";
65 case WorkletAnimation::kRunning:
66 return "running";
67 default:
68 NOTREACHED();
69 return "";
70 }
71 }
72 } // namespace
73
74 WorkletAnimation* WorkletAnimation::Create(
75 String animator_name,
76 const HeapVector<Member<KeyframeEffectReadOnly>>& effects,
77 HeapVector<DocumentTimelineOrScrollTimeline>& timelines,
78 RefPtr<SerializedScriptValue> options,
79 ExceptionState& exception_state) {
80 String error_string;
81 if (!ValidateEffects(effects, error_string)) {
82 exception_state.ThrowDOMException(kNotSupportedError, error_string);
83 return nullptr;
84 }
85
86 if (!ValidateTimelines(timelines, error_string)) {
87 exception_state.ThrowDOMException(kNotSupportedError, error_string);
88 return nullptr;
89 }
90
91 Document& document = effects.at(0)->Target()->GetDocument();
92 WorkletAnimation* animation = new WorkletAnimation(
93 animator_name, document, effects, timelines, std::move(options));
94 document.Timeline().CompositorTimeline()->PlayerAttached(*animation);
95
96 return animation;
97 }
98
99 WorkletAnimation::WorkletAnimation(
100 String animator_name,
101 Document& document,
102 const HeapVector<Member<KeyframeEffectReadOnly>>& effects,
103 HeapVector<DocumentTimelineOrScrollTimeline>& timelines,
104 RefPtr<SerializedScriptValue> options)
105 : animator_name_(animator_name),
106 document_(document),
107 effects_(effects),
108 timelines_(timelines),
109 options_(std::move(options)) {
110 DCHECK(Platform::Current()->IsThreadedAnimationEnabled());
111 DCHECK(Platform::Current()->CompositorSupport());
112 compositor_player_ = CompositorAnimationPlayerHolder::Create(this);
113 DCHECK(compositor_player_);
114 }
115
116 String WorkletAnimation::playState() {
117 return AnimationPlayStateToString(play_state_);
118 }
119
120 void WorkletAnimation::play() {
121 // TODO(smcgruer): Should this set NeedsCompositingUpdate?
122 document_->GetWorkletAnimationController().AttachAnimation(*this);
123 play_state_ = kPending;
124 }
125
126 void WorkletAnimation::cancel() {
127 document_->GetWorkletAnimationController().DetachAnimation(*this);
128 play_state_ = kIdle;
129 }
130
131 bool WorkletAnimation::StartOnCompositor() {
132 int group = 0;
133 double start_time = 0;
134 double current_time = 0;
135 double animation_playback_rate = 1;
136 Element& target = *effects_.at(0)->Target();
137 ToKeyframeEffectModelBase(effects_.at(0)->Model())
138 ->SnapshotAllCompositorKeyframes(target, target.ComputedStyleRef(),
139 target.ParentComputedStyle());
140 bool success =
141 effects_.at(0)
142 ->CheckCanStartAnimationOnCompositor(animation_playback_rate)
143 .Ok();
144 if (success) {
145 effects_.at(0)->StartAnimationOnCompositor(group, start_time, current_time,
146 animation_playback_rate,
147 compositor_player_->Player());
148 }
149 play_state_ = success ? kRunning : kIdle;
150 return success;
151 }
152
153 void WorkletAnimation::Dispose() {
154 document_->Timeline().CompositorTimeline()->PlayerDestroyed(*this);
155 compositor_player_->Detach();
156 compositor_player_ = nullptr;
157 }
158
159 DEFINE_TRACE(WorkletAnimation) {
160 visitor->Trace(document_);
161 visitor->Trace(effects_);
162 visitor->Trace(timelines_);
163 visitor->Trace(compositor_player_);
164 WorkletAnimationBase::Trace(visitor);
165 }
166
167 WorkletAnimation::CompositorAnimationPlayerHolder*
168 WorkletAnimation::CompositorAnimationPlayerHolder::Create(
169 WorkletAnimation* animation) {
170 return new CompositorAnimationPlayerHolder(animation);
171 }
172
173 WorkletAnimation::CompositorAnimationPlayerHolder::
174 CompositorAnimationPlayerHolder(WorkletAnimation* animation)
175 : animation_(animation) {
176 compositor_player_ = CompositorAnimationPlayer::Create();
177 compositor_player_->SetAnimationDelegate(animation_);
178 }
179
180 void WorkletAnimation::CompositorAnimationPlayerHolder::Dispose() {
181 if (!animation_)
182 return;
183 animation_->Dispose();
184 DCHECK(!animation_);
185 DCHECK(!compositor_player_);
186 }
187
188 void WorkletAnimation::CompositorAnimationPlayerHolder::Detach() {
189 compositor_player_->SetAnimationDelegate(nullptr);
190 animation_ = nullptr;
191 compositor_player_.reset();
192 }
193
194 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698