bool CompositorAnimations::startAnimationOnCompositor(const Element& element, int group, double startTime, double timeOffset, const Timing& timing, const AnimationPlayer& player, const AnimationEffect& effect, Vector<int>& startedAnimationIds, double playerPlaybackRate) { ASSERT(startedAnimationIds.isEmpty()); ASSERT(isCandidateForAnimationOnCompositor(timing, element, &player, effect, playerPlaybackRate)); ASSERT(canStartAnimationOnCompositor(element)); const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(effect); DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())->layer(); ASSERT(layer); Vector<OwnPtr<WebCompositorAnimation>> animations; CompositorAnimationsImpl::getAnimationOnCompositor(timing, group, startTime, timeOffset, keyframeEffect, animations, playerPlaybackRate); ASSERT(!animations.isEmpty()); for (auto& animation : animations) { int id = animation->id(); if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer(); ASSERT(compositorPlayer); compositorPlayer->addAnimation(animation.leakPtr()); } else if (!layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->addAnimation(animation.release())) { // FIXME: We should know ahead of time whether these animations can be started. for (int startedAnimationId : startedAnimationIds) cancelAnimationOnCompositor(element, player, startedAnimationId); startedAnimationIds.clear(); return false; } startedAnimationIds.append(id); } ASSERT(!startedAnimationIds.isEmpty()); return true; }
bool CompositorAnimations::startAnimationOnCompositor(const Element& element, const Timing& timing, const AnimationEffect& effect, Vector<int>& startedAnimationIds) { ASSERT(startedAnimationIds.isEmpty()); ASSERT(isCandidateForAnimationOnCompositor(timing, effect)); ASSERT(canStartAnimationOnCompositor(element)); const KeyframeEffectModel& keyframeEffect = *toKeyframeEffectModel(&effect); RenderLayer* layer = toRenderBoxModelObject(element.renderer())->layer(); ASSERT(layer); Vector<OwnPtr<blink::WebAnimation> > animations; CompositorAnimationsImpl::getAnimationOnCompositor(timing, keyframeEffect, animations); ASSERT(!animations.isEmpty()); for (size_t i = 0; i < animations.size(); ++i) { int id = animations[i]->id(); if (!layer->compositedLayerMapping()->mainGraphicsLayer()->addAnimation(animations[i].release())) { // FIXME: We should know ahead of time whether these animations can be started. for (size_t j = 0; j < startedAnimationIds.size(); ++j) cancelAnimationOnCompositor(element, startedAnimationIds[j]); startedAnimationIds.clear(); return false; } startedAnimationIds.append(id); } ASSERT(!startedAnimationIds.isEmpty()); return true; }
bool Animation::isCandidateForAnimationOnCompositor() const { if (!canStartAnimationOnCompositor()) return false; return toKeyframeEffect(m_content.get())->isCandidateForAnimationOnCompositor(m_playbackRate); }
void CompositorAnimations::cancelAnimationOnCompositor(const Element& element, int id) { if (!canStartAnimationOnCompositor(element)) { ASSERT_NOT_REACHED(); return; } toRenderBoxModelObject(element.renderer())->layer()->compositedLayerMapping()->mainGraphicsLayer()->removeAnimation(id); }
void CompositorAnimations::pauseAnimationForTestingOnCompositor(const Element& element, int id, double pauseTime) { // FIXME: canStartAnimationOnCompositor queries compositingState, which is not necessarily up to date. DisableCompositingQueryAsserts disabler; if (!canStartAnimationOnCompositor(element)) { ASSERT_NOT_REACHED(); return; } toRenderBoxModelObject(element.renderer())->layer()->compositedLayerMapping()->mainGraphicsLayer()->pauseAnimation(id, pauseTime); }
bool AnimationPlayer::maybeStartAnimationOnCompositor() { if (!canStartAnimationOnCompositor()) return false; double startTime = timeline()->zeroTime() + startTimeInternal(); double timeOffset = 0; if (std::isnan(startTime)) { timeOffset = currentTimeInternal(); } return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(startTime, timeOffset); }
void CompositorAnimations::pauseAnimationForTestingOnCompositor(const Element& element, const AnimationPlayer& player, int id, double pauseTime) { // FIXME: canStartAnimationOnCompositor queries compositingState, which is not necessarily up to date. // https://code.google.com/p/chromium/issues/detail?id=339847 DisableCompositingQueryAsserts disabler; if (!canStartAnimationOnCompositor(element)) { ASSERT_NOT_REACHED(); return; } if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer(); ASSERT(compositorPlayer); compositorPlayer->pauseAnimation(id, pauseTime); } else { toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->pauseAnimation(id, pauseTime); } }
void CompositorAnimations::cancelAnimationOnCompositor(const Element& element, const AnimationPlayer& player, int id) { if (!canStartAnimationOnCompositor(element)) { // When an element is being detached, we cancel any associated // AnimationPlayers for CSS animations. But by the time we get // here the mapping will have been removed. // FIXME: Defer remove/pause operations until after the // compositing update. return; } if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer(); ASSERT(compositorPlayer); compositorPlayer->removeAnimation(id); } else { toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->removeAnimation(id); } }
bool AnimationPlayer::maybeStartAnimationOnCompositor() { if (!canStartAnimationOnCompositor()) return false; bool reversed = m_playbackRate < 0; double startTime = timeline()->zeroTime() + startTimeInternal(); if (reversed) { startTime -= sourceEnd() / fabs(m_playbackRate); } double timeOffset = 0; if (std::isnan(startTime)) { timeOffset = reversed ? sourceEnd() - currentTimeInternal() : currentTimeInternal(); timeOffset = timeOffset / fabs(m_playbackRate); } ASSERT(m_compositorGroup != 0); return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(m_compositorGroup, startTime, timeOffset, m_playbackRate); }