bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing, double timeOffset, CompositorTiming& out, double playerPlaybackRate) { timing.assertValid(); // FIXME: Compositor does not know anything about endDelay. if (timing.endDelay != 0) return false; if (std::isnan(timing.iterationDuration) || !timing.iterationCount || !timing.iterationDuration) return false; if (!std::isfinite(timing.iterationCount)) { out.adjustedIterationCount = -1; } else { out.adjustedIterationCount = timing.iterationCount; } out.scaledDuration = timing.iterationDuration; out.direction = timing.direction; // Compositor's time offset is positive for seeking into the animation. out.scaledTimeOffset = -timing.startDelay / playerPlaybackRate + timeOffset; out.playbackRate = timing.playbackRate * playerPlaybackRate; out.fillMode = timing.fillMode == Timing::FillModeAuto ? Timing::FillModeNone : timing.fillMode; out.iterationStart = timing.iterationStart; out.assertValid(); return true; }
Timing CSSTimingData::convertToTiming(size_t index) const { Timing timing; timing.startDelay = getRepeated(m_delayList, index); timing.iterationDuration = getRepeated(m_durationList, index); timing.timingFunction = getRepeated(m_timingFunctionList, index); timing.assertValid(); return timing; }
Timing TimingInput::convert(const Dictionary& timingInputDictionary) { Timing result; // FIXME: This method needs to be refactored to handle invalid // null, NaN, Infinity values better. // See: http://www.w3.org/TR/WebIDL/#es-double double startDelay = Timing::defaults().startDelay; timingInputDictionary.get("delay", startDelay); setStartDelay(result, startDelay); double endDelay = Timing::defaults().endDelay; timingInputDictionary.get("endDelay", endDelay); setEndDelay(result, endDelay); String fillMode; timingInputDictionary.get("fill", fillMode); setFillMode(result, fillMode); double iterationStart = Timing::defaults().iterationStart; timingInputDictionary.get("iterationStart", iterationStart); setIterationStart(result, iterationStart); double iterationCount = Timing::defaults().iterationCount; timingInputDictionary.get("iterations", iterationCount); setIterationCount(result, iterationCount); double iterationDuration = 0; if (timingInputDictionary.get("duration", iterationDuration)) { setIterationDuration(result, iterationDuration); } double playbackRate = Timing::defaults().playbackRate; timingInputDictionary.get("playbackRate", playbackRate); setPlaybackRate(result, playbackRate); String direction; timingInputDictionary.get("direction", direction); setPlaybackDirection(result, direction); String timingFunctionString; timingInputDictionary.get("easing", timingFunctionString); setTimingFunction(result, timingFunctionString); result.assertValid(); return result; }
bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing, CompositorTiming& out) { timing.assertValid(); // All fill modes are supported (the calling code handles them). // FIXME: Support non-zero iteration start. if (timing.iterationStart) return false; // FIXME: Compositor only supports positive, integer iteration counts. // Zero iterations could be converted, but silly. if ((std::floor(timing.iterationCount) != timing.iterationCount) || timing.iterationCount <= 0) return false; if (std::isnan(timing.iterationDuration) || !timing.iterationDuration) return false; // FIXME: Support other playback rates if (timing.playbackRate != 1) return false; // All directions are supported. // Now attempt an actual conversion out.scaledDuration = timing.iterationDuration; ASSERT(out.scaledDuration > 0); double scaledStartDelay = timing.startDelay; if (scaledStartDelay > 0 && scaledStartDelay > out.scaledDuration * timing.iterationCount) return false; out.reverse = (timing.direction == Timing::PlaybackDirectionReverse || timing.direction == Timing::PlaybackDirectionAlternateReverse); out.alternate = (timing.direction == Timing::PlaybackDirectionAlternate || timing.direction == Timing::PlaybackDirectionAlternateReverse); if (!std::isfinite(timing.iterationCount)) { out.adjustedIterationCount = -1; } else { out.adjustedIterationCount = std::floor(timing.iterationCount); ASSERT(out.adjustedIterationCount > 0); } // Compositor's time offset is positive for seeking into the animation. out.scaledTimeOffset = -scaledStartDelay; return true; }
// Returns the default timing function. const PassRefPtr<TimingFunction> timingFromAnimationData(const CSSAnimationData* animationData, Timing& timing, bool& isPaused) { if (animationData->isDelaySet()) timing.startDelay = animationData->delay(); if (animationData->isDurationSet()) { timing.iterationDuration = animationData->duration(); timing.hasIterationDuration = true; } if (animationData->isIterationCountSet()) { if (animationData->iterationCount() == CSSAnimationData::IterationCountInfinite) timing.iterationCount = std::numeric_limits<double>::infinity(); else timing.iterationCount = animationData->iterationCount(); } if (animationData->isFillModeSet()) { switch (animationData->fillMode()) { case AnimationFillModeForwards: timing.fillMode = Timing::FillModeForwards; break; case AnimationFillModeBackwards: timing.fillMode = Timing::FillModeBackwards; break; case AnimationFillModeBoth: timing.fillMode = Timing::FillModeBoth; break; case AnimationFillModeNone: timing.fillMode = Timing::FillModeNone; break; default: ASSERT_NOT_REACHED(); } } else { timing.fillMode = Timing::FillModeNone; } if (animationData->isDirectionSet()) { switch (animationData->direction()) { case CSSAnimationData::AnimationDirectionNormal: timing.direction = Timing::PlaybackDirectionNormal; break; case CSSAnimationData::AnimationDirectionAlternate: timing.direction = Timing::PlaybackDirectionAlternate; break; case CSSAnimationData::AnimationDirectionReverse: timing.direction = Timing::PlaybackDirectionReverse; break; case CSSAnimationData::AnimationDirectionAlternateReverse: timing.direction = Timing::PlaybackDirectionAlternateReverse; break; default: ASSERT_NOT_REACHED(); } } // For CSS, the constraints on the timing properties are tighter than in // the general case of the Web Animations model. timing.assertValid(); ASSERT(!timing.iterationStart); ASSERT(timing.playbackRate == 1); ASSERT(timing.iterationDuration >= 0 && std::isfinite(timing.iterationDuration)); isPaused = animationData->isPlayStateSet() && animationData->playState() == AnimPlayStatePaused; return animationData->isTimingFunctionSet() ? animationData->timingFunction() : CSSAnimationData::initialAnimationTimingFunction(); }