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

Side by Side Diff: Source/core/animation/CompositorAnimations.cpp

Issue 881183003: Animation: Cancel same-property animations on compositor (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Add manual test. Improve code a bit. Created 5 years, 10 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
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 13 matching lines...) Expand all
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "core/animation/CompositorAnimations.h" 32 #include "core/animation/CompositorAnimations.h"
33 33
34 #include "core/animation/ActiveAnimations.h"
34 #include "core/animation/AnimationNode.h" 35 #include "core/animation/AnimationNode.h"
35 #include "core/animation/AnimationTranslationUtil.h" 36 #include "core/animation/AnimationTranslationUtil.h"
36 #include "core/animation/CompositorAnimationsImpl.h" 37 #include "core/animation/CompositorAnimationsImpl.h"
37 #include "core/animation/animatable/AnimatableDouble.h" 38 #include "core/animation/animatable/AnimatableDouble.h"
38 #include "core/animation/animatable/AnimatableFilterOperations.h" 39 #include "core/animation/animatable/AnimatableFilterOperations.h"
39 #include "core/animation/animatable/AnimatableTransform.h" 40 #include "core/animation/animatable/AnimatableTransform.h"
40 #include "core/animation/animatable/AnimatableValue.h" 41 #include "core/animation/animatable/AnimatableValue.h"
41 #include "core/rendering/RenderBoxModelObject.h" 42 #include "core/rendering/RenderBoxModelObject.h"
42 #include "core/rendering/RenderLayer.h" 43 #include "core/rendering/RenderLayer.h"
43 #include "core/rendering/RenderObject.h" 44 #include "core/rendering/RenderObject.h"
(...skipping 19 matching lines...) Expand all
63 void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, CSSProp ertyID id, double scale, PropertySpecificKeyframeVector& values) 64 void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, CSSProp ertyID id, double scale, PropertySpecificKeyframeVector& values)
64 { 65 {
65 ASSERT(values.isEmpty()); 66 ASSERT(values.isEmpty());
66 67
67 for (const auto& keyframe : effect->getPropertySpecificKeyframes(id)) { 68 for (const auto& keyframe : effect->getPropertySpecificKeyframes(id)) {
68 double offset = keyframe->offset() * scale; 69 double offset = keyframe->offset() * scale;
69 values.append(keyframe->cloneWithOffset(offset)); 70 values.append(keyframe->cloneWithOffset(offset));
70 } 71 }
71 } 72 }
72 73
74 bool considerPlayerAsIncompatible(const AnimationPlayer& player, const Animation Player& playerToAdd)
75 {
76 if (&player == &playerToAdd)
77 return false;
78
79 switch (player.playStateInternal()) {
80 case AnimationPlayer::Idle:
81 return false;
82 case AnimationPlayer::Pending:
83 case AnimationPlayer::Running:
84 return true;
85 case AnimationPlayer::Paused:
86 case AnimationPlayer::Finished:
87 return AnimationPlayer::hasLowerPriority(&playerToAdd, &player);
88 default:
89 ASSERT_NOT_REACHED();
90 return true;
91 }
92 }
93
94 bool hasIncompatibleAnimations(const Element& targetElement, const AnimationPlay er& playerToAdd, const AnimationEffect& effectToAdd)
95 {
96 const bool affectsOpacity = effectToAdd.affects(CSSPropertyOpacity);
97 const bool affectsTransform = effectToAdd.affects(CSSPropertyTransform);
98 const bool affectsFilter = effectToAdd.affects(CSSPropertyWebkitFilter);
99
100 if (!targetElement.hasActiveAnimations())
101 return false;
102
103 ActiveAnimations* activeAnimations = targetElement.activeAnimations();
104 ASSERT(activeAnimations);
105
106 for (const auto& entry : activeAnimations->players()) {
107 const AnimationPlayer* attachedPlayer = entry.key;
108 if (!considerPlayerAsIncompatible(*attachedPlayer, playerToAdd))
109 continue;
110
111 if ((affectsOpacity && attachedPlayer->affects(targetElement, CSSPropert yOpacity))
112 || (affectsTransform && attachedPlayer->affects(targetElement, CSSPr opertyTransform))
113 || (affectsFilter && attachedPlayer->affects(targetElement, CSSPrope rtyWebkitFilter)))
114 return true;
115 }
116
117 return false;
118 }
119
73 } 120 }
74 121
75 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const Animation Effect& effect, double minValue, double maxValue) const 122 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const Animation Effect& effect, double minValue, double maxValue) const
76 { 123 {
77 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect); 124 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect);
78 125
79 PropertySet properties = keyframeEffect.properties(); 126 PropertySet properties = keyframeEffect.properties();
80 127
81 if (properties.isEmpty()) 128 if (properties.isEmpty())
82 return true; 129 return true;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 box.expandTo(bounds); 173 box.expandTo(bounds);
127 } 174 }
128 } 175 }
129 return true; 176 return true;
130 } 177 }
131 178
132 // ----------------------------------------------------------------------- 179 // -----------------------------------------------------------------------
133 // CompositorAnimations public API 180 // CompositorAnimations public API
134 // ----------------------------------------------------------------------- 181 // -----------------------------------------------------------------------
135 182
136 bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim ing, const AnimationEffect& effect, double playerPlaybackRate) 183 bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim ing, const Element& targetElement, const AnimationPlayer* playerToAdd, const Ani mationEffect& effect, double playerPlaybackRate)
137 { 184 {
138 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect); 185 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect);
139 186
140 PropertySet properties = keyframeEffect.properties(); 187 PropertySet properties = keyframeEffect.properties();
141
142 if (properties.isEmpty()) 188 if (properties.isEmpty())
143 return false; 189 return false;
144 190
145 for (const auto& property : properties) { 191 for (const auto& property : properties) {
146 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp ertySpecificKeyframes(property); 192 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp ertySpecificKeyframes(property);
147 ASSERT(keyframes.size() >= 2); 193 ASSERT(keyframes.size() >= 2);
148 for (const auto& keyframe : keyframes) { 194 for (const auto& keyframe : keyframes) {
149 // FIXME: Determine candidacy based on the CSSValue instead of a sna pshot AnimatableValue. 195 // FIXME: Determine candidacy based on the CSSValue instead of a sna pshot AnimatableValue.
150 if (keyframe->composite() != AnimationEffect::CompositeReplace || !k eyframe->getAnimatableValue()) 196 if (keyframe->composite() != AnimationEffect::CompositeReplace || !k eyframe->getAnimatableValue())
151 return false; 197 return false;
152 198
153 switch (property) { 199 switch (property) {
154 case CSSPropertyOpacity: 200 case CSSPropertyOpacity:
155 break; 201 break;
156 case CSSPropertyTransform: 202 case CSSPropertyTransform:
157 if (toAnimatableTransform(keyframe->getAnimatableValue().get())- >transformOperations().dependsOnBoxSize()) 203 if (toAnimatableTransform(keyframe->getAnimatableValue().get())- >transformOperations().dependsOnBoxSize())
158 return false; 204 return false;
159 break; 205 break;
160 case CSSPropertyWebkitFilter: { 206 case CSSPropertyWebkitFilter: {
161 const FilterOperations& operations = toAnimatableFilterOperation s(keyframe->getAnimatableValue().get())->operations(); 207 const FilterOperations& operations = toAnimatableFilterOperation s(keyframe->getAnimatableValue().get())->operations();
162 if (operations.hasFilterThatMovesPixels()) 208 if (operations.hasFilterThatMovesPixels())
163 return false; 209 return false;
164 break; 210 break;
165 } 211 }
166 default: 212 default:
213 // any other types are not allowed to run on compositor.
167 return false; 214 return false;
168 } 215 }
169 } 216 }
170 } 217 }
171 218
219 if (playerToAdd && hasIncompatibleAnimations(targetElement, *playerToAdd, ef fect))
220 return false;
221
172 CompositorAnimationsImpl::CompositorTiming out; 222 CompositorAnimationsImpl::CompositorTiming out;
173 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, pl ayerPlaybackRate)) 223 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, pl ayerPlaybackRate))
174 return false; 224 return false;
175 225
176 return true; 226 return true;
177 } 227 }
178 228
229 void CompositorAnimations::cancelIncompatibleAnimationsOnCompositor(const Elemen t& targetElement, const AnimationPlayer& playerToAdd, const AnimationEffect& eff ectToAdd)
230 {
231 const bool affectsOpacity = effectToAdd.affects(CSSPropertyOpacity);
232 const bool affectsTransform = effectToAdd.affects(CSSPropertyTransform);
233 const bool affectsFilter = effectToAdd.affects(CSSPropertyWebkitFilter);
234
235 if (!targetElement.hasActiveAnimations())
236 return;
237
238 ActiveAnimations* activeAnimations = targetElement.activeAnimations();
239 ASSERT(activeAnimations);
240
241 for (const auto& entry : activeAnimations->players()) {
242 AnimationPlayer* attachedPlayer = entry.key;
243 if (!considerPlayerAsIncompatible(*attachedPlayer, playerToAdd))
244 continue;
245
246 if ((affectsOpacity && attachedPlayer->affects(targetElement, CSSPropert yOpacity))
247 || (affectsTransform && attachedPlayer->affects(targetElement, CSSPr opertyTransform))
248 || (affectsFilter && attachedPlayer->affects(targetElement, CSSPrope rtyWebkitFilter)))
249 attachedPlayer->cancelAnimationOnCompositor();
250 }
251 }
252
179 bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element) 253 bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element)
180 { 254 {
181 return element.renderer() && element.renderer()->compositingState() == Paint sIntoOwnBacking; 255 return element.renderer() && element.renderer()->compositingState() == Paint sIntoOwnBacking;
182 } 256 }
183 257
184 bool CompositorAnimations::startAnimationOnCompositor(const Element& element, in t group, double startTime, double timeOffset, const Timing& timing, const Animat ionEffect& effect, Vector<int>& startedAnimationIds, double playerPlaybackRate) 258 bool CompositorAnimations::startAnimationOnCompositor(const Element& element, in t group, double startTime, double timeOffset, const Timing& timing, const Animat ionPlayer* player, const AnimationEffect& effect, Vector<int>& startedAnimationI ds, double playerPlaybackRate)
185 { 259 {
186 ASSERT(startedAnimationIds.isEmpty()); 260 ASSERT(startedAnimationIds.isEmpty());
187 ASSERT(isCandidateForAnimationOnCompositor(timing, effect, playerPlaybackRat e)); 261 ASSERT(isCandidateForAnimationOnCompositor(timing, element, player, effect, playerPlaybackRate));
188 ASSERT(canStartAnimationOnCompositor(element)); 262 ASSERT(canStartAnimationOnCompositor(element));
189 263
190 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect); 264 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect);
191 265
192 RenderLayer* layer = toRenderBoxModelObject(element.renderer())->layer(); 266 RenderLayer* layer = toRenderBoxModelObject(element.renderer())->layer();
193 ASSERT(layer); 267 ASSERT(layer);
194 268
195 Vector<OwnPtr<WebCompositorAnimation>> animations; 269 Vector<OwnPtr<WebCompositorAnimation>> animations;
196 CompositorAnimationsImpl::getAnimationOnCompositor(timing, group, startTime, timeOffset, keyframeEffect, animations, playerPlaybackRate); 270 CompositorAnimationsImpl::getAnimationOnCompositor(timing, group, startTime, timeOffset, keyframeEffect, animations, playerPlaybackRate);
197 ASSERT(!animations.isEmpty()); 271 ASSERT(!animations.isEmpty());
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 break; 616 break;
543 default: 617 default:
544 ASSERT_NOT_REACHED(); 618 ASSERT_NOT_REACHED();
545 } 619 }
546 animations.append(animation.release()); 620 animations.append(animation.release());
547 } 621 }
548 ASSERT(!animations.isEmpty()); 622 ASSERT(!animations.isEmpty());
549 } 623 }
550 624
551 } // namespace blink 625 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/animation/CompositorAnimations.h ('k') | Source/core/animation/CompositorAnimationsTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698