bool KeyframeEffectReadonly::HasAnimationOfProperties( const nsCSSProperty* aProperties, size_t aPropertyCount) const { for (size_t i = 0; i < aPropertyCount; i++) { if (HasAnimationOfProperty(aProperties[i])) { return true; } } return false; }
bool KeyframeEffectReadOnly::CanThrottle() const { // Unthrottle if we are not in effect or current. This will be the case when // our owning animation has finished, is idle, or when we are in the delay // phase (but without a backwards fill). In each case the computed progress // value produced on each tick will be the same so we will skip requesting // unnecessary restyles in NotifyAnimationTimingUpdated. Any calls we *do* get // here will be because of a change in state (e.g. we are newly finished or // newly no longer in effect) in which case we shouldn't throttle the sample. if (!IsInEffect() || !IsCurrent()) { return false; } nsIFrame* frame = GetAnimationFrame(); if (!frame) { // There are two possible cases here. // a) No target element // b) The target element has no frame, e.g. because it is in a display:none // subtree. // In either case we can throttle the animation because there is no // need to update on the main thread. return true; } // We can throttle the animation if the animation is paint only and // the target frame is out of view or the document is in background tabs. if (CanIgnoreIfNotVisible()) { nsIPresShell* presShell = GetPresShell(); if ((presShell && !presShell->IsActive()) || frame->IsScrolledOutOfView()) { return true; } } // First we need to check layer generation and transform overflow // prior to the property.mIsRunningOnCompositor check because we should // occasionally unthrottle these animations even if the animations are // already running on compositor. for (const LayerAnimationInfo::Record& record : LayerAnimationInfo::sRecords) { // Skip properties that are overridden in the cascade. // (GetAnimationOfProperty, as called by HasAnimationOfProperty, // only returns an animation if it currently wins in the cascade.) if (!HasAnimationOfProperty(record.mProperty)) { continue; } EffectSet* effectSet = EffectSet::GetEffectSet(mTarget->mElement, mTarget->mPseudoType); MOZ_ASSERT(effectSet, "CanThrottle should be called on an effect " "associated with a target element"); layers::Layer* layer = FrameLayerBuilder::GetDedicatedLayer(frame, record.mLayerType); // Unthrottle if the layer needs to be brought up to date if (!layer || effectSet->GetAnimationGeneration() != layer->GetAnimationGeneration()) { return false; } // If this is a transform animation that affects the overflow region, // we should unthrottle the animation periodically. if (record.mProperty == eCSSProperty_transform && !CanThrottleTransformChanges(*frame)) { return false; } } for (const AnimationProperty& property : mProperties) { if (!property.mIsRunningOnCompositor) { return false; } } return true; }