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

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) {
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 } // namespace
59
60 WorkletAnimation* WorkletAnimation::Create(
61 String animator_name,
62 const HeapVector<Member<KeyframeEffectReadOnly>>& effects,
63 HeapVector<DocumentTimelineOrScrollTimeline>& timelines,
64 RefPtr<SerializedScriptValue> user_data,
65 ExceptionState& exception_state) {
66 String error_string;
67 if (!ValidateEffects(effects, &error_string)) {
68 exception_state.ThrowDOMException(kNotSupportedError, error_string);
69 return nullptr;
70 }
71
72 if (!ValidateTimelines(timelines, &error_string)) {
73 exception_state.ThrowDOMException(kNotSupportedError, error_string);
74 return nullptr;
75 }
76
77 // TODO(smcgruer): Document.
78 Document& document = effects.at(0)->Target()->GetDocument();
79 AnimationTimeline& main_document_timeline = document.Timeline();
80
81 WorkletAnimation* animation =
82 new WorkletAnimation(animator_name, effects, timelines,
83 std::move(user_data), main_document_timeline);
84
85 document.RegisterWorkletAnimation(animation);
86 // TODO(smcgruer): Set needs compositing update?
87 animation->AttachCompositorTimeline();
88
89 return animation;
90 }
91
92 WorkletAnimation::WorkletAnimation(
93 String animator_name,
94 const HeapVector<Member<KeyframeEffectReadOnly>>& effects,
95 HeapVector<DocumentTimelineOrScrollTimeline>& timelines,
96 RefPtr<SerializedScriptValue> user_data,
97 AnimationTimeline& main_document_timeline)
98 : animator_name_(animator_name),
99 effects_(effects),
100 timelines_(timelines),
101 user_data_(std::move(user_data)),
102 main_document_timeline_(main_document_timeline),
103 on_compositor_(false) {
104 if (Platform::Current()->IsThreadedAnimationEnabled() &&
flackr 2017/06/05 19:08:39 Eventually we'd have to support running without th
smcgruer 2017/06/06 13:22:11 Sure, done. I vaguely wonder why we even have --di
105 !compositor_player_) {
106 DCHECK(Platform::Current()->CompositorSupport());
107 compositor_player_ = CompositorAnimationPlayerHolder::Create(this);
108 DCHECK(compositor_player_);
109 }
110 }
111
112 void WorkletAnimation::Update() {
113 if (!on_compositor_) {
114 int group = 0; // We don't know.
115 double start_time = 0;
116 double current_time = 0;
117 double animation_playback_rate = 1;
118 Element& target = *effects_.at(0)->Target();
119 static_cast<KeyframeEffectModelBase*>(effects_.at(0)->Model())
120 ->SnapshotAllCompositorKeyframes(target, target.ComputedStyleRef(),
121 target.ParentComputedStyle());
122 on_compositor_ = effects_.at(0)->MaybeStartAnimationOnCompositor(
123 group, start_time, current_time, animation_playback_rate,
124 compositor_player_->Player());
125 }
126 }
127
128 void WorkletAnimation::AttachCompositorTimeline() {
129 if (compositor_player_) {
130 CompositorAnimationTimeline* timeline =
131 main_document_timeline_ ? main_document_timeline_->CompositorTimeline()
132 : nullptr;
133 if (timeline)
134 timeline->PlayerAttached(*this);
135 }
136 }
137
138 void WorkletAnimation::DetachCompositorTimeline() {
139 if (compositor_player_) {
140 CompositorAnimationTimeline* timeline =
141 main_document_timeline_ ? main_document_timeline_->CompositorTimeline()
142 : nullptr;
143 if (timeline)
144 timeline->PlayerDestroyed(*this);
145 }
146 }
147
148 void WorkletAnimation::Dispose() {
149 if (compositor_player_) {
150 DetachCompositorTimeline();
151 compositor_player_->Detach();
152 compositor_player_ = nullptr;
153 }
154 }
155
156 void WorkletAnimation::SetEffectInheritedTimeForTesting(
157 Member<KeyframeEffectReadOnly> effect,
158 double inherited_time) {}
159
160 DEFINE_TRACE(WorkletAnimation) {
161 visitor->Trace(effects_);
162 visitor->Trace(timelines_);
163 visitor->Trace(main_document_timeline_);
164 visitor->Trace(compositor_player_);
165 WorkletAnimationBase::Trace(visitor);
166 }
167
168 WorkletAnimation::CompositorAnimationPlayerHolder*
169 WorkletAnimation::CompositorAnimationPlayerHolder::Create(
170 WorkletAnimation* animation) {
171 return new CompositorAnimationPlayerHolder(animation);
172 }
173
174 WorkletAnimation::CompositorAnimationPlayerHolder::
175 CompositorAnimationPlayerHolder(WorkletAnimation* animation)
176 : animation_(animation) {
177 compositor_player_ = CompositorAnimationPlayer::Create();
178 compositor_player_->SetAnimationDelegate(animation_);
179 }
180
181 void WorkletAnimation::CompositorAnimationPlayerHolder::Dispose() {
182 if (!animation_)
183 return;
184 animation_->Dispose();
185 DCHECK(!animation_);
186 DCHECK(!compositor_player_);
187 }
188
189 void WorkletAnimation::CompositorAnimationPlayerHolder::Detach() {
190 compositor_player_->SetAnimationDelegate(nullptr);
191 animation_ = nullptr;
192 compositor_player_.reset();
193 }
194
195 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698