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:
longsonr 2024-06-07 09:28:41 +00:00
Родитель c13a783267
Коммит 535e996010
4 изменённых файлов: 36 добавлений и 21 удалений

Просмотреть файл

@ -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.
*/