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;
}
Exemple #2
0
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;
}
Exemple #5
0
// 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();
}