OLD | NEW |
---|---|
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 25 matching lines...) Expand all Loading... | |
36 #include "core/animation/AnimatableValue.h" | 36 #include "core/animation/AnimatableValue.h" |
37 #include "core/animation/CompositorAnimationsImpl.h" | 37 #include "core/animation/CompositorAnimationsImpl.h" |
38 #include "core/platform/animation/AnimationTranslationUtil.h" | 38 #include "core/platform/animation/AnimationTranslationUtil.h" |
39 #include "core/rendering/CompositedLayerMapping.h" | 39 #include "core/rendering/CompositedLayerMapping.h" |
40 #include "core/rendering/RenderBoxModelObject.h" | 40 #include "core/rendering/RenderBoxModelObject.h" |
41 #include "core/rendering/RenderLayer.h" | 41 #include "core/rendering/RenderLayer.h" |
42 #include "core/rendering/RenderObject.h" | 42 #include "core/rendering/RenderObject.h" |
43 #include "public/platform/Platform.h" | 43 #include "public/platform/Platform.h" |
44 #include "public/platform/WebAnimation.h" | 44 #include "public/platform/WebAnimation.h" |
45 #include "public/platform/WebCompositorSupport.h" | 45 #include "public/platform/WebCompositorSupport.h" |
46 #include "public/platform/WebFilterAnimationCurve.h" | |
47 #include "public/platform/WebFloatAnimationCurve.h" | 46 #include "public/platform/WebFloatAnimationCurve.h" |
48 #include "public/platform/WebFloatKeyframe.h" | 47 #include "public/platform/WebFloatKeyframe.h" |
49 #include "public/platform/WebTransformAnimationCurve.h" | |
50 #include "public/platform/WebTransformKeyframe.h" | |
51 #include "public/platform/WebTransformOperations.h" | |
52 | 48 |
53 #include <algorithm> | 49 #include <algorithm> |
54 #include <cmath> | 50 #include <cmath> |
55 | 51 |
56 | |
57 namespace WebCore { | 52 namespace WebCore { |
58 | 53 |
59 // ----------------------------------------------------------------------- | 54 // ----------------------------------------------------------------------- |
60 // TimingFunctionReverser methods | 55 // TimingFunctionReverser methods |
61 // ----------------------------------------------------------------------- | 56 // ----------------------------------------------------------------------- |
62 | 57 |
63 PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c onst LinearTimingFunction* timefunc) | 58 PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c onst LinearTimingFunction* timefunc) |
64 { | 59 { |
65 return const_cast<LinearTimingFunction*>(timefunc); | 60 return const_cast<LinearTimingFunction*>(timefunc); |
66 } | 61 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 PassOwnPtr<Vector<CSSPropertyID> > CompositorAnimationsKeyframeEffectHelper::get Properties( | 162 PassOwnPtr<Vector<CSSPropertyID> > CompositorAnimationsKeyframeEffectHelper::get Properties( |
168 const KeyframeAnimationEffect* effect) | 163 const KeyframeAnimationEffect* effect) |
169 { | 164 { |
170 const_cast<KeyframeAnimationEffect*>(effect)->ensureKeyframeGroups(); | 165 const_cast<KeyframeAnimationEffect*>(effect)->ensureKeyframeGroups(); |
171 OwnPtr<Vector<CSSPropertyID> > propertyIds = adoptPtr(new Vector<CSSProperty ID>(effect->m_keyframeGroups->size())); | 166 OwnPtr<Vector<CSSPropertyID> > propertyIds = adoptPtr(new Vector<CSSProperty ID>(effect->m_keyframeGroups->size())); |
172 copyKeysToVector(*(effect->m_keyframeGroups.get()), *propertyIds.get()); | 167 copyKeysToVector(*(effect->m_keyframeGroups.get()), *propertyIds.get()); |
173 return propertyIds.release(); | 168 return propertyIds.release(); |
174 } | 169 } |
175 | 170 |
176 PassOwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> CompositorA nimationsKeyframeEffectHelper::getKeyframeValuesForProperty( | 171 PassOwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> CompositorA nimationsKeyframeEffectHelper::getKeyframeValuesForProperty( |
177 const KeyframeAnimationEffect* effect, CSSPropertyID id, double zero, double scale, bool reverse) | 172 const KeyframeAnimationEffect* effect, CSSPropertyID id, double scale, bool reverse) |
178 { | 173 { |
179 const_cast<KeyframeAnimationEffect*>(effect)->ensureKeyframeGroups(); | 174 const_cast<KeyframeAnimationEffect*>(effect)->ensureKeyframeGroups(); |
180 return getKeyframeValuesForProperty(effect->m_keyframeGroups->get(id), zero, scale, reverse); | 175 return getKeyframeValuesForProperty(effect->m_keyframeGroups->get(id), scale , reverse); |
181 } | 176 } |
182 | 177 |
183 PassOwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> CompositorA nimationsKeyframeEffectHelper::getKeyframeValuesForProperty( | 178 PassOwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> CompositorA nimationsKeyframeEffectHelper::getKeyframeValuesForProperty( |
184 const KeyframeAnimationEffect::PropertySpecificKeyframeGroup* group, double zero, double scale, bool reverse) | 179 const KeyframeAnimationEffect::PropertySpecificKeyframeGroup* group, double scale, bool reverse) |
185 { | 180 { |
186 OwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> values = ad optPtr( | 181 OwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> values = ad optPtr( |
187 new CompositorAnimationsKeyframeEffectHelper::KeyframeValues()); | 182 new CompositorAnimationsKeyframeEffectHelper::KeyframeValues()); |
188 | 183 |
189 for (size_t i = 0; i < group->m_keyframes.size(); i++) { | 184 for (size_t i = 0; i < group->m_keyframes.size(); i++) { |
190 KeyframeAnimationEffect::PropertySpecificKeyframe* frame = group->m_keyf rames[i].get(); | 185 KeyframeAnimationEffect::PropertySpecificKeyframe* frame = group->m_keyf rames[i].get(); |
191 | 186 |
192 double offset = zero + frame->offset() * scale; | 187 double offset = (reverse ? (1 - frame->offset()) : frame->offset()) * sc ale; |
193 if (reverse) | |
194 offset = zero + (1 - frame->offset()) * scale; | |
195 | |
196 values->append(std::make_pair(offset, frame->value())); | 188 values->append(std::make_pair(offset, frame->value())); |
197 } | 189 } |
198 if (reverse) | 190 if (reverse) |
199 values->reverse(); | 191 values->reverse(); |
200 | 192 |
201 return values.release(); | 193 return values.release(); |
202 } | 194 } |
203 | 195 |
204 // ----------------------------------------------------------------------- | 196 // ----------------------------------------------------------------------- |
205 // CompositorAnimationsImpl | 197 // CompositorAnimationsImpl |
206 // ----------------------------------------------------------------------- | 198 // ----------------------------------------------------------------------- |
207 | 199 |
208 bool CompositorAnimationsImpl::isCandidateForCompositor(const Keyframe& keyframe ) | 200 bool CompositorAnimationsImpl::isCandidateForCompositor(const Keyframe& keyframe ) |
209 { | 201 { |
210 // Only replace mode can be accelerated | 202 // Only replace mode can be accelerated |
211 if (keyframe.composite() != AnimationEffect::CompositeReplace) | 203 if (keyframe.composite() != AnimationEffect::CompositeReplace) |
212 return false; | 204 return false; |
213 | 205 |
214 // Check all the properties can be accelerated | 206 // Check all the properties can be accelerated |
215 const PropertySet properties = keyframe.properties(); // FIXME: properties c reates a whole new PropertySet! | 207 const PropertySet properties = keyframe.properties(); // FIXME: properties c reates a whole new PropertySet! |
216 for (PropertySet::const_iterator it = properties.begin(); it != properties.e nd(); ++it) { | 208 for (PropertySet::const_iterator it = properties.begin(); it != properties.e nd(); ++it) { |
217 switch (*it) { | 209 switch (*it) { |
218 case CSSPropertyOpacity: | 210 case CSSPropertyOpacity: |
219 case CSSPropertyWebkitFilter: // FIXME: What about CSSPropertyFilter? | 211 case CSSPropertyWebkitFilter: // FIXME: What about CSSPropertyFilter? |
220 case CSSPropertyWebkitTransform: | 212 case CSSPropertyWebkitTransform: |
221 return true; | 213 continue; |
222 default: | 214 default: |
223 return false; | 215 return false; |
224 } | 216 } |
225 } | 217 } |
226 return true; | 218 return true; |
227 } | 219 } |
228 | 220 |
229 bool CompositorAnimationsImpl::isCandidateForCompositor(const KeyframeAnimationE ffect& effect) | 221 bool CompositorAnimationsImpl::isCandidateForCompositor(const KeyframeAnimationE ffect& effect) |
230 { | 222 { |
231 const KeyframeAnimationEffect::KeyframeVector frames = effect.getFrames(); | 223 const KeyframeAnimationEffect::KeyframeVector frames = effect.getFrames(); |
232 for (size_t i = 0; i < frames.size(); ++i) { | 224 for (size_t i = 0; i < frames.size(); ++i) { |
233 if (!isCandidateForCompositor(*frames[i].get())) | 225 if (!isCandidateForCompositor(*frames[i].get())) |
234 return false; | 226 return false; |
235 } | 227 } |
236 return true; | 228 return true; |
237 } | 229 } |
238 | 230 |
239 bool CompositorAnimationsImpl::isCandidateForCompositor(const Timing& timing, co nst KeyframeAnimationEffect::KeyframeVector& frames) | 231 bool CompositorAnimationsImpl::isCandidateForCompositor(const Timing& timing, co nst KeyframeAnimationEffect::KeyframeVector& frames) |
240 { | 232 { |
241 // FIXME: Support more then FillModeNone. | |
242 if (timing.fillMode != Timing::FillModeNone) | |
243 return false; | |
244 | 233 |
245 if (!timing.hasIterationDuration) | 234 CompositorTiming out; |
246 return false; | 235 if (!convertTimingForCompositor(timing, out)) |
247 | |
248 // FIXME: Support non-zero iteration start. | |
249 if (timing.iterationStart != 0.0) | |
250 return false; | |
251 | |
252 // FIXME: Compositor only supports integer iteration counts. | |
253 if (!std::isfinite(timing.iterationCount) || (timing.iterationCount < 0) || (std::floor(timing.iterationCount) != timing.iterationCount)) | |
254 return false; | |
255 | |
256 // FIXME: Support positive startDelay and iterations. | |
257 if (timing.iterationCount != 1 && timing.startDelay > 0.0) | |
258 return false; | 236 return false; |
259 | 237 |
260 return isCandidateForCompositor(*timing.timingFunction.get(), frames); | 238 return isCandidateForCompositor(*timing.timingFunction.get(), frames); |
261 } | 239 } |
262 | 240 |
263 bool CompositorAnimationsImpl::isCandidateForCompositor(const TimingFunction& ti mingFunction, const KeyframeAnimationEffect::KeyframeVector& frames, double fram eOffset) | 241 bool CompositorAnimationsImpl::isCandidateForCompositor(const TimingFunction& ti mingFunction, const KeyframeAnimationEffect::KeyframeVector& frames, bool isNest edCall) |
264 { | 242 { |
265 switch (timingFunction.type()) { | 243 switch (timingFunction.type()) { |
266 case TimingFunction::LinearFunction: | 244 case TimingFunction::LinearFunction: |
267 return true; | 245 return true; |
268 | 246 |
269 case TimingFunction::CubicBezierFunction: | 247 case TimingFunction::CubicBezierFunction: |
270 // Can have a cubic if we don't have to split it (IE only have two frame s). | 248 // Can have a cubic if we don't have to split it (IE only have two frame s). |
271 if (frames.size() != 2) | 249 if (!isNestedCall && (frames.size() != 2)) |
272 return false; | 250 return false; |
273 | 251 |
274 if (frames[0]->offset() - frameOffset) | 252 ASSERT(!frames.size() || (frames[0]->offset() == 0.0 && frames[1]->offse t() == 1.0)); |
275 return false; | |
276 | 253 |
277 return true; | 254 return true; |
278 | 255 |
279 case TimingFunction::StepsFunction: | 256 case TimingFunction::StepsFunction: |
280 return false; | 257 return false; |
281 | 258 |
282 case TimingFunction::ChainedFunction: { | 259 case TimingFunction::ChainedFunction: { |
283 // Currently we only support chained segments in the form the CSS code | 260 // Currently we only support chained segments in the form the CSS code |
284 // generates. These chained segments are only one level deep and have | 261 // generates. These chained segments are only one level deep and have |
285 // one timing function per frame. | 262 // one timing function per frame. |
286 const ChainedTimingFunction* chained = static_cast<const ChainedTimingFu nction*>(&timingFunction); | 263 const ChainedTimingFunction* chained = static_cast<const ChainedTimingFu nction*>(&timingFunction); |
287 if (frameOffset) | 264 if (isNestedCall) |
288 return false; | 265 return false; |
289 | 266 |
290 if (!chained->m_segments.size()) | 267 if (!chained->m_segments.size()) |
291 return false; | 268 return false; |
292 | 269 |
293 if (frames.size() != chained->m_segments.size() + 1) | 270 if (frames.size() != chained->m_segments.size() + 1) |
294 return false; | 271 return false; |
295 | 272 |
296 for (size_t timeIndex = 0; timeIndex < chained->m_segments.size(); timeI ndex++) { | 273 for (size_t timeIndex = 0; timeIndex < chained->m_segments.size(); timeI ndex++) { |
297 const ChainedTimingFunction::Segment& segment = chained->m_segments[ timeIndex]; | 274 const ChainedTimingFunction::Segment& segment = chained->m_segments[ timeIndex]; |
298 | 275 |
299 if (frames[timeIndex]->offset() != segment.m_min || frames[timeIndex + 1]->offset() != segment.m_max) | 276 if (frames[timeIndex]->offset() != segment.m_min || frames[timeIndex + 1]->offset() != segment.m_max) |
300 return false; | 277 return false; |
301 | 278 |
302 KeyframeAnimationEffect::KeyframeVector timingFrames; | 279 KeyframeAnimationEffect::KeyframeVector timingFrames; |
Steve Block
2013/11/13 23:17:01
Yes, I think we should convert this function to ta
mithro-old
2013/11/14 02:11:46
Done.
| |
303 timingFrames.append(frames[timeIndex]); | 280 if (!isCandidateForCompositor(*segment.m_timingFunction.get(), timin gFrames, true)) |
304 timingFrames.append(frames[timeIndex + 1]); | |
305 | |
306 if (!isCandidateForCompositor(*(segment.m_timingFunction.get()), tim ingFrames, segment.m_min)) | |
307 return false; | 281 return false; |
308 } | 282 } |
309 return true; | 283 return true; |
310 } | 284 } |
311 default: | 285 default: |
312 ASSERT_NOT_REACHED(); | 286 ASSERT_NOT_REACHED(); |
313 }; | 287 }; |
314 return false; | 288 return false; |
315 } | 289 } |
316 | 290 |
291 bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing, CompositorTiming& out) | |
292 { | |
293 timing.assertValid(); | |
294 // FIXME: Shouldn't this be asserted in timing.assertValid? | |
Steve Block
2013/11/13 23:17:01
Good question. It should always be true right now,
mithro-old
2013/11/14 02:11:46
Done.
| |
295 ASSERT(timing.timingFunction); | |
296 | |
297 // FIXME: Support positive startDelay | |
298 if (timing.startDelay > 0.0) | |
299 return false; | |
300 | |
301 // All fill modes are supported (the calling code handles them). | |
302 | |
303 // FIXME: Support non-zero iteration start. | |
304 if (timing.iterationStart != 0.0) | |
Steve Block
2013/11/13 23:17:01
if (timing.iterationStart)
Ugly I know, but that'
mithro-old
2013/11/14 02:11:46
Done.
Normally the style checker picks this up, w
| |
305 return false; | |
306 | |
307 // FIXME: Compositor only supports finite, integer iteration counts. | |
308 if (!std::isfinite(timing.iterationCount) || (std::floor(timing.iterationCou nt) != timing.iterationCount)) | |
309 return false; | |
310 | |
311 if (!timing.iterationDuration) | |
312 return false; | |
313 | |
314 if (timing.playbackRate <= 0) | |
Steve Block
2013/11/13 23:17:01
Why doesn't this one get a FIXME?
mithro-old
2013/11/14 02:11:46
Does now! Changed to == 1.0 as Doug requested.
| |
315 return false; | |
316 | |
317 // All directions are supported. | |
318 out.reverse = (timing.direction == Timing::PlaybackDirectionReverse | |
319 || timing.direction == Timing::PlaybackDirectionAlternateReverse); | |
320 out.alternate = (timing.direction == Timing::PlaybackDirectionAlternate | |
321 || timing.direction == Timing::PlaybackDirectionAlternateReverse); | |
Steve Block
2013/11/13 23:17:01
Move these down to line 334 where they're used, to
mithro-old
2013/11/14 02:11:46
Done.
| |
322 | |
323 out.scaledDuration = timing.iterationDuration / timing.playbackRate; | |
dstockwell
2013/11/13 11:54:04
I think we should just bail out if playbackRate is
mithro-old
2013/11/13 12:01:43
Trivial to implement, but can remove it you want.
dstockwell
2013/11/13 23:29:31
Remove it.
mithro-old
2013/11/14 02:11:46
Done.
| |
324 ASSERT(out.scaledDuration > 0); | |
325 | |
326 double scaledStartDelay = timing.startDelay / timing.playbackRate; | |
327 ASSERT(scaledStartDelay <= 0); | |
328 | |
329 int pastIterations = std::floor(std::abs(scaledStartDelay) / out.scaledDurat ion); | |
dstockwell
2013/11/13 11:54:04
It's not really clear to me what's going on here.
mithro-old
2013/11/13 12:01:43
When start delay greater than iteration duration m
dstockwell
2013/11/13 23:29:31
OK. Then I think something like skippedIterations
mithro-old
2013/11/14 02:11:46
Done.
| |
330 ASSERT(pastIterations >= 0); | |
331 if (pastIterations >= timing.iterationCount) | |
332 return false; | |
333 | |
334 if (out.alternate && (pastIterations % 2)) | |
335 out.reverse = !out.reverse; | |
336 | |
337 out.adjustedIterationCount = std::floor(timing.iterationCount) - pastIterati ons; | |
338 ASSERT(out.adjustedIterationCount > 0); | |
Steve Block
2013/11/13 23:17:01
What if timing.iterationCount is zero?
For exampl
dstockwell
2013/11/13 23:29:31
Right, bail out if iteration count is 0.
mithro-old
2013/11/14 02:11:46
Actually we'd bail at line 331, in the zero case s
Steve Block
2013/11/14 02:28:08
Sounds good. This will be required once we allow p
| |
339 | |
340 out.scaledTimeOffset = scaledStartDelay + pastIterations * out.scaledDuratio n; | |
341 ASSERT(out.scaledTimeOffset <= 0); | |
342 return true; | |
343 } | |
317 | 344 |
318 namespace { | 345 namespace { |
319 | 346 |
320 template<typename PlatformAnimationKeyframeType> | 347 template<typename PlatformAnimationKeyframeType> |
321 static PassOwnPtr<PlatformAnimationKeyframeType> createPlatformKeyframe(double o ffset, const AnimatableValue&) | 348 static PassOwnPtr<PlatformAnimationKeyframeType> createPlatformKeyframe(double o ffset, const AnimatableValue&) |
322 { | 349 { |
323 // Only the specialized versions of this templated function (found in | 350 // Only the specialized versions of this templated function (found in |
324 // the cpp file) should ever be called. | 351 // the cpp file) should ever be called. |
325 // FIXME: COMPILE_ASSERT(false, CompositorAnimationsNonSpecializedCreateKeyf rameShouldNeverBeUsed); | 352 // FIXME: COMPILE_ASSERT(false, CompositorAnimationsNonSpecializedCreateKeyf rameShouldNeverBeUsed); |
326 ASSERT_NOT_REACHED(); | 353 ASSERT_NOT_REACHED(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 switch (timingFunction.type()) { | 427 switch (timingFunction.type()) { |
401 case TimingFunction::LinearFunction: | 428 case TimingFunction::LinearFunction: |
402 case TimingFunction::CubicBezierFunction: | 429 case TimingFunction::CubicBezierFunction: |
403 keyframeTimingFunction = &timingFunction; | 430 keyframeTimingFunction = &timingFunction; |
404 break; | 431 break; |
405 | 432 |
406 case TimingFunction::ChainedFunction: { | 433 case TimingFunction::ChainedFunction: { |
407 const ChainedTimingFunction* chained = static_cast<const Chained TimingFunction*>(&timingFunction); | 434 const ChainedTimingFunction* chained = static_cast<const Chained TimingFunction*>(&timingFunction); |
408 // ChainedTimingFunction criteria was checked in isCandidate, | 435 // ChainedTimingFunction criteria was checked in isCandidate, |
409 // assert it is valid. | 436 // assert it is valid. |
410 ASSERT(values.size() == chained->m_segments.size()+1); | 437 ASSERT(values.size() == chained->m_segments.size() + 1); |
411 ASSERT(values[i].first == chained->m_segments[i].m_min); | 438 ASSERT(values[i].first == chained->m_segments[i].m_min); |
412 | 439 |
413 keyframeTimingFunction = chained->m_segments[i].m_timingFunction .get(); | 440 keyframeTimingFunction = chained->m_segments[i].m_timingFunction .get(); |
414 break; | 441 break; |
415 } | 442 } |
416 case TimingFunction::StepsFunction: | 443 case TimingFunction::StepsFunction: |
417 default: | 444 default: |
418 ASSERT_NOT_REACHED(); | 445 ASSERT_NOT_REACHED(); |
419 } | 446 } |
420 } | 447 } |
421 | 448 |
422 ASSERT(!values[i].second->dependsOnUnderlyingValue()); | 449 ASSERT(!values[i].second->dependsOnUnderlyingValue()); |
423 RefPtr<AnimatableValue> value = values[i].second->compositeOnto(0); | 450 RefPtr<AnimatableValue> value = values[i].second->compositeOnto(0); |
424 OwnPtr<PlatformAnimationKeyframeType> keyframe = createPlatformKeyframe< PlatformAnimationKeyframeType>(values[i].first, *value.get()); | 451 OwnPtr<PlatformAnimationKeyframeType> keyframe = createPlatformKeyframe< PlatformAnimationKeyframeType>(values[i].first, *value.get()); |
425 addKeyframeWithTimingFunction(curve, *keyframe.get(), keyframeTimingFunc tion); | 452 addKeyframeWithTimingFunction(curve, *keyframe.get(), keyframeTimingFunc tion); |
426 } | 453 } |
427 } | 454 } |
428 | 455 |
429 void CompositorAnimationsImpl::getCompositorAnimations( | 456 void CompositorAnimationsImpl::getCompositorAnimations( |
430 const Timing& timing, const KeyframeAnimationEffect& effect, Vector<OwnPtr<b link::WebAnimation> >& animations) | 457 const Timing& timing, const KeyframeAnimationEffect& effect, Vector<OwnPtr<b link::WebAnimation> >& animations) |
431 { | 458 { |
432 | 459 CompositorTiming compositorTiming; |
433 bool reverse = (timing.direction == Timing::PlaybackDirectionReverse | 460 bool timingValid = convertTimingForCompositor(timing, compositorTiming); |
434 || timing.direction == Timing::PlaybackDirectionAlternateReverse); | 461 ASSERT(timingValid); |
Steve Block
2013/11/13 23:17:01
I think this will need to be an ASSERT_UNUSED for
mithro-old
2013/11/14 02:11:46
Done.
| |
435 | 462 |
436 RefPtr<TimingFunction> timingFunction = timing.timingFunction; | 463 RefPtr<TimingFunction> timingFunction = timing.timingFunction; |
437 if (reverse) { | 464 if (compositorTiming.reverse) |
438 timingFunction = CompositorAnimationsTimingFunctionReverser::reverse(tim ingFunction.get()); | 465 timingFunction = CompositorAnimationsTimingFunctionReverser::reverse(tim ingFunction.get()); |
dstockwell
2013/11/13 23:29:31
Hmm, why do we need to reverse the timing function
dstockwell
2013/11/13 23:41:05
Probably because reverse isn't passed through. Som
Steve Block
2013/11/13 23:56:23
That's my understanding too. The compositor interf
mithro-old
2013/11/14 02:11:46
Correct. If we could just pass reverse, life would
mithro-old
2013/11/14 02:11:46
Correct.
mithro-old
2013/11/14 02:11:46
Because it's not passed to the compositor.
To sim
| |
439 } | |
440 | 466 |
441 OwnPtr<Vector<CSSPropertyID> > properties = CompositorAnimationsKeyframeEffe ctHelper::getProperties(&effect); | 467 OwnPtr<Vector<CSSPropertyID> > properties = CompositorAnimationsKeyframeEffe ctHelper::getProperties(&effect); |
442 for (size_t i = 0; i < properties->size(); i++) { | 468 for (size_t i = 0; i < properties->size(); i++) { |
443 double iterationDuration = timing.iterationDuration / timing.playbackRat e; | |
444 | |
445 double zero = timing.startDelay / timing.playbackRate; | |
446 double keyframeZero = std::max(0.0, zero); | |
447 | 469 |
448 OwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> values = CompositorAnimationsKeyframeEffectHelper::getKeyframeValuesForProperty( | 470 OwnPtr<CompositorAnimationsKeyframeEffectHelper::KeyframeValues> values = CompositorAnimationsKeyframeEffectHelper::getKeyframeValuesForProperty( |
449 &effect, properties->at(i), keyframeZero, iterationDuration, reverse ); | 471 &effect, properties->at(i), compositorTiming.scaledDuration, composi torTiming.reverse); |
450 | 472 |
451 blink::WebAnimation::TargetProperty targetProperty; | 473 blink::WebAnimation::TargetProperty targetProperty; |
452 OwnPtr<blink::WebAnimationCurve> curve; | 474 OwnPtr<blink::WebAnimationCurve> curve; |
453 switch (properties->at(i)) { | 475 switch (properties->at(i)) { |
454 case CSSPropertyOpacity: { | 476 case CSSPropertyOpacity: { |
455 targetProperty = blink::WebAnimation::TargetPropertyOpacity; | 477 targetProperty = blink::WebAnimation::TargetPropertyOpacity; |
456 | 478 |
457 OwnPtr<blink::WebFloatAnimationCurve> floatCurve = adoptPtr(blink::P latform::current()->compositorSupport()->createFloatAnimationCurve()); | 479 OwnPtr<blink::WebFloatAnimationCurve> floatCurve = adoptPtr(blink::P latform::current()->compositorSupport()->createFloatAnimationCurve()); |
458 addKeyframesToCurve<blink::WebFloatAnimationCurve, blink::WebFloatKe yframe>(*floatCurve.get(), *values.get(), *timingFunction.get()); | 480 addKeyframesToCurve<blink::WebFloatAnimationCurve, blink::WebFloatKe yframe>(*floatCurve.get(), *values.get(), *timingFunction.get()); |
459 curve = floatCurve.release(); | 481 curve = floatCurve.release(); |
(...skipping 12 matching lines...) Expand all Loading... | |
472 } | 494 } |
473 default: | 495 default: |
474 ASSERT_NOT_REACHED(); | 496 ASSERT_NOT_REACHED(); |
475 continue; | 497 continue; |
476 } | 498 } |
477 ASSERT(curve.get()); | 499 ASSERT(curve.get()); |
478 | 500 |
479 OwnPtr<blink::WebAnimation> animation = adoptPtr( | 501 OwnPtr<blink::WebAnimation> animation = adoptPtr( |
480 blink::Platform::current()->compositorSupport()->createAnimation(*cu rve, targetProperty)); | 502 blink::Platform::current()->compositorSupport()->createAnimation(*cu rve, targetProperty)); |
481 | 503 |
482 ASSERT(std::floor(timing.iterationCount) == timing.iterationCount); | 504 animation->setIterations(compositorTiming.adjustedIterationCount); |
483 ASSERT(std::isfinite(timing.iterationCount)); | 505 animation->setTimeOffset(compositorTiming.scaledTimeOffset); |
484 double iterationCount = std::floor(timing.iterationCount); | 506 animation->setAlternatesDirection(compositorTiming.alternate); |
485 if (zero < 0) { | |
486 int pastIterations = std::floor(std::abs(zero) / iterationDuration); | |
487 | |
488 iterationCount = iterationCount - pastIterations; | |
489 animation->setTimeOffset(zero + pastIterations * iterationDuration); | |
490 } | |
491 animation->setIterations(iterationCount); | |
492 | |
493 // PlaybackDirection direction | |
494 animation->setAlternatesDirection( | |
495 timing.direction == Timing::PlaybackDirectionAlternate || timing.dir ection == Timing::PlaybackDirectionAlternateReverse); | |
496 | 507 |
497 animations.append(animation.release()); | 508 animations.append(animation.release()); |
498 } | 509 } |
499 } | 510 } |
500 | 511 |
501 } // namespace WebCore | 512 } // namespace WebCore |
OLD | NEW |