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

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: Major fix. 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 player.sequenceNumber() > playerToAdd.sequenceNumber();
88 default:
89 ASSERT_NOT_REACHED();
90 return true;
91 }
92
93 return true;
94 }
95
96 bool hasIncompatatibleAnimations(const Element& targetElement, const AnimationPl ayer& playerToAdd, const AnimationEffect& effectToAdd)
dstockwell 2015/01/30 02:39:23 Incompatatible -> Incompatible
loyso (OOO) 2015/01/30 02:53:11 Done.
97 {
98 const bool affectsOpacity = effectToAdd.affects(CSSPropertyOpacity);
99 const bool affectsTransform = effectToAdd.affects(CSSPropertyTransform);
100 const bool affectsFilter = effectToAdd.affects(CSSPropertyWebkitFilter);
101
102 if (targetElement.hasActiveAnimations()) {
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, CSSPro pertyOpacity))
112 || (affectsTransform && attachedPlayer->affects(targetElement, C SSPropertyTransform))
113 || (affectsFilter && attachedPlayer->affects(targetElement, CSSP ropertyWebkitFilter)))
114 return true;
115 }
116 }
117
118 return false;
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 {
185 if (playerToAdd && hasIncompatatibleAnimations(targetElement, *playerToAdd, effect))
dstockwell 2015/01/30 02:39:23 Perhaps we should move this check to the end -- ar
loyso (OOO) 2015/01/30 02:53:11 Done.
186 return false;
187
138 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect); 188 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect);
139 189
140 PropertySet properties = keyframeEffect.properties(); 190 PropertySet properties = keyframeEffect.properties();
141
142 if (properties.isEmpty()) 191 if (properties.isEmpty())
143 return false; 192 return false;
144 193
145 for (const auto& property : properties) { 194 for (const auto& property : properties) {
146 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp ertySpecificKeyframes(property); 195 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp ertySpecificKeyframes(property);
147 ASSERT(keyframes.size() >= 2); 196 ASSERT(keyframes.size() >= 2);
148 for (const auto& keyframe : keyframes) { 197 for (const auto& keyframe : keyframes) {
149 // FIXME: Determine candidacy based on the CSSValue instead of a sna pshot AnimatableValue. 198 // FIXME: Determine candidacy based on the CSSValue instead of a sna pshot AnimatableValue.
150 if (keyframe->composite() != AnimationEffect::CompositeReplace || !k eyframe->getAnimatableValue()) 199 if (keyframe->composite() != AnimationEffect::CompositeReplace || !k eyframe->getAnimatableValue())
151 return false; 200 return false;
152 201
153 switch (property) { 202 switch (property) {
154 case CSSPropertyOpacity: 203 case CSSPropertyOpacity:
155 break; 204 break;
156 case CSSPropertyTransform: 205 case CSSPropertyTransform:
157 if (toAnimatableTransform(keyframe->getAnimatableValue().get())- >transformOperations().dependsOnBoxSize()) 206 if (toAnimatableTransform(keyframe->getAnimatableValue().get())- >transformOperations().dependsOnBoxSize())
158 return false; 207 return false;
159 break; 208 break;
160 case CSSPropertyWebkitFilter: { 209 case CSSPropertyWebkitFilter: {
161 const FilterOperations& operations = toAnimatableFilterOperation s(keyframe->getAnimatableValue().get())->operations(); 210 const FilterOperations& operations = toAnimatableFilterOperation s(keyframe->getAnimatableValue().get())->operations();
162 if (operations.hasFilterThatMovesPixels()) 211 if (operations.hasFilterThatMovesPixels())
163 return false; 212 return false;
164 break; 213 break;
165 } 214 }
166 default: 215 default:
216 // any other types are not allowed to run on compositor.
167 return false; 217 return false;
168 } 218 }
169 } 219 }
170 } 220 }
171 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 propertyOpacityCancel = effectToAdd.affects(CSSPropertyOpacity);
232 const bool propertyTransformCancel = effectToAdd.affects(CSSPropertyTransfor m);
233 const bool propertyFilterCancel = effectToAdd.affects(CSSPropertyWebkitFilte r);
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 ((propertyOpacityCancel && attachedPlayer->affects(targetElement, CSS PropertyOpacity))
247 || (propertyTransformCancel && attachedPlayer->affects(targetElement , CSSPropertyTransform))
248 || (propertyFilterCancel && attachedPlayer->affects(targetElement, C SSPropertyWebkitFilter)))
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

Powered by Google App Engine
This is Rietveld 408576698