зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1900958 - Create a SVGObserverUtils::SelfOrAncestorHasRenderingObservers method that we can use in animations r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D212774
This commit is contained in:
Родитель
c13a783267
Коммит
535e996010
|
@ -24,6 +24,7 @@
|
|||
#include "mozilla/ServoStyleSet.h"
|
||||
#include "mozilla/StaticPrefs_layers.h"
|
||||
#include "mozilla/StyleAnimationValue.h"
|
||||
#include "mozilla/SVGObserverUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCSSPropertyIDSet.h"
|
||||
#include "nsCSSProps.h"
|
||||
|
@ -77,17 +78,9 @@ bool EffectCompositor::AllowCompositorAnimationsOnFrame(
|
|||
// Disable async animations if we have a rendering observer that
|
||||
// depends on our content (svg masking, -moz-element etc) so that
|
||||
// it gets updated correctly.
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
while (content) {
|
||||
if (content->HasRenderingObservers()) {
|
||||
aWarning = AnimationPerformanceWarning::Type::HasRenderingObserver;
|
||||
return false;
|
||||
}
|
||||
const auto* frame = content->GetPrimaryFrame();
|
||||
if (frame && frame->IsRenderingObserverContainer()) {
|
||||
break;
|
||||
}
|
||||
content = content->GetParent();
|
||||
if (SVGObserverUtils::SelfOrAncestorHasRenderingObservers(aFrame)) {
|
||||
aWarning = AnimationPerformanceWarning::Type::HasRenderingObserver;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -1867,8 +1867,9 @@ class nsINode : public mozilla::dom::EventTarget {
|
|||
*/
|
||||
private:
|
||||
enum BooleanFlag {
|
||||
// Set if we're being used from -moz-element
|
||||
NodeHasRenderingObservers,
|
||||
// Set if we're being used from -moz-element or observed via a mask,
|
||||
// clipPath, filter or use element.
|
||||
NodeHasDirectRenderingObservers,
|
||||
// Set if our parent chain (including this node itself) terminates
|
||||
// in a document
|
||||
IsInDocument,
|
||||
|
@ -1971,11 +1972,11 @@ class nsINode : public mozilla::dom::EventTarget {
|
|||
}
|
||||
|
||||
public:
|
||||
bool HasRenderingObservers() const {
|
||||
return GetBoolFlag(NodeHasRenderingObservers);
|
||||
bool HasDirectRenderingObservers() const {
|
||||
return GetBoolFlag(NodeHasDirectRenderingObservers);
|
||||
}
|
||||
void SetHasRenderingObservers(bool aValue) {
|
||||
SetBoolFlag(NodeHasRenderingObservers, aValue);
|
||||
void SetHasDirectRenderingObservers(bool aValue) {
|
||||
SetBoolFlag(NodeHasDirectRenderingObservers, aValue);
|
||||
}
|
||||
bool IsContent() const { return GetBoolFlag(NodeIsContent); }
|
||||
bool HasID() const { return GetBoolFlag(ElementHasID); }
|
||||
|
|
|
@ -1769,6 +1769,22 @@ void SVGObserverUtils::UpdateEffects(nsIFrame* aFrame) {
|
|||
}
|
||||
}
|
||||
|
||||
bool SVGObserverUtils::SelfOrAncestorHasRenderingObservers(
|
||||
const nsIFrame* aFrame) {
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
while (content) {
|
||||
if (content->HasDirectRenderingObservers()) {
|
||||
return true;
|
||||
}
|
||||
const auto* frame = content->GetPrimaryFrame();
|
||||
if (frame && frame->IsRenderingObserverContainer()) {
|
||||
break;
|
||||
}
|
||||
content = content->GetFlattenedTreeParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SVGObserverUtils::AddRenderingObserver(Element* aElement,
|
||||
SVGRenderingObserver* aObserver) {
|
||||
SVGRenderingObserverSet* observers = GetObserverSet(aElement);
|
||||
|
@ -1782,7 +1798,7 @@ void SVGObserverUtils::AddRenderingObserver(Element* aElement,
|
|||
nsINode::DeleteProperty<SVGRenderingObserverSet>,
|
||||
/* aTransfer = */ true);
|
||||
}
|
||||
aElement->SetHasRenderingObservers(true);
|
||||
aElement->SetHasDirectRenderingObservers(true);
|
||||
observers->Add(aObserver);
|
||||
}
|
||||
|
||||
|
@ -1795,7 +1811,7 @@ void SVGObserverUtils::RemoveRenderingObserver(
|
|||
observers->Remove(aObserver);
|
||||
if (observers->IsEmpty()) {
|
||||
aElement->RemoveProperty(nsGkAtoms::renderingobserverset);
|
||||
aElement->SetHasRenderingObservers(false);
|
||||
aElement->SetHasDirectRenderingObservers(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1805,7 +1821,7 @@ void SVGObserverUtils::RemoveAllRenderingObservers(Element* aElement) {
|
|||
if (observers) {
|
||||
observers->RemoveAll();
|
||||
aElement->RemoveProperty(nsGkAtoms::renderingobserverset);
|
||||
aElement->SetHasRenderingObservers(false);
|
||||
aElement->SetHasDirectRenderingObservers(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1853,7 +1869,7 @@ void SVGObserverUtils::InvalidateDirectRenderingObservers(
|
|||
frame->RemoveProperty(SVGUtils::ObjectBoundingBoxProperty());
|
||||
}
|
||||
|
||||
if (aElement->HasRenderingObservers()) {
|
||||
if (aElement->HasDirectRenderingObservers()) {
|
||||
SVGRenderingObserverSet* observers = GetObserverSet(aElement);
|
||||
if (observers) {
|
||||
if (aFlags & INVALIDATE_REFLOW) {
|
||||
|
|
|
@ -200,6 +200,11 @@ class SVGObserverUtils {
|
|||
*/
|
||||
static void UpdateEffects(nsIFrame* aFrame);
|
||||
|
||||
/*
|
||||
* Returns true if the frame or any of its ancestors have rendering observers.
|
||||
*/
|
||||
static bool SelfOrAncestorHasRenderingObservers(const nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* @param aFrame must be a first-continuation.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче