Bug 1062832 - Move frame invalidation from nsSVGFilterReference to nsSVGFilterProperty. r=roc

This commit is contained in:
Markus Stange 2014-09-09 17:14:46 +02:00
parent 5ca816d536
commit b12757247a
2 changed files with 53 additions and 25 deletions

View File

@ -245,39 +245,37 @@ nsSVGFilterReference::GetFilterFrame()
void void
nsSVGFilterReference::DoUpdate() nsSVGFilterReference::DoUpdate()
{ {
nsSVGRenderingObserverProperty::DoUpdate(); nsSVGIDRenderingObserver::DoUpdate();
nsIFrame* frame = mFrameReference.Get(); if (mFilterChainObserver) {
if (!frame) mFilterChainObserver->Invalidate();
return;
// Repaint asynchronously in case the filter frame is being torn down
nsChangeHint changeHint =
nsChangeHint(nsChangeHint_RepaintFrame);
// Don't need to request UpdateOverflow if we're being reflowed.
if (!(frame->GetStateBits() & NS_FRAME_IN_REFLOW)) {
NS_UpdateHint(changeHint, nsChangeHint_UpdateOverflow);
} }
frame->PresContext()->RestyleManager()->PostRestyleEvent(
frame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
} }
NS_IMPL_ISUPPORTS(nsSVGFilterProperty, nsISupports) NS_IMPL_ISUPPORTS(nsSVGFilterProperty, nsISupports)
nsSVGFilterProperty::nsSVGFilterProperty(const nsTArray<nsStyleFilter> &aFilters, nsSVGFilterProperty::nsSVGFilterProperty(const nsTArray<nsStyleFilter> &aFilters,
nsIFrame *aFilteredFrame) nsIFrame *aFilteredFrame)
: mFrameReference(aFilteredFrame)
{ {
nsIContent* filteredElement = aFilteredFrame->GetContent();
for (uint32_t i = 0; i < aFilters.Length(); i++) { for (uint32_t i = 0; i < aFilters.Length(); i++) {
if (aFilters[i].GetType() != NS_STYLE_FILTER_URL) if (aFilters[i].GetType() != NS_STYLE_FILTER_URL)
continue; continue;
nsRefPtr<nsSVGFilterReference> reference = nsRefPtr<nsSVGFilterReference> reference =
new nsSVGFilterReference(aFilters[i].GetURL(), aFilteredFrame); new nsSVGFilterReference(aFilters[i].GetURL(), filteredElement, this);
mReferences.AppendElement(reference); mReferences.AppendElement(reference);
} }
} }
nsSVGFilterProperty::~nsSVGFilterProperty()
{
for (uint32_t i = 0; i < mReferences.Length(); i++) {
mReferences[i]->DetachFromChainObserver();
}
}
bool bool
nsSVGFilterProperty::ReferencesValidResources() nsSVGFilterProperty::ReferencesValidResources()
{ {
@ -299,11 +297,28 @@ nsSVGFilterProperty::IsInObserverLists() const
} }
void void
nsSVGFilterProperty::Invalidate() nsSVGFilterProperty::DoUpdate()
{ {
for (uint32_t i = 0; i < mReferences.Length(); i++) { nsIFrame* frame = mFrameReference.Get();
mReferences[i]->Invalidate(); if (!frame)
return;
if (frame && frame->IsFrameOfType(nsIFrame::eSVG)) {
// Changes should propagate out to things that might be observing
// the referencing frame or its ancestors.
nsSVGEffects::InvalidateRenderingObservers(frame);
} }
// Repaint asynchronously in case the filter frame is being torn down
nsChangeHint changeHint =
nsChangeHint(nsChangeHint_RepaintFrame);
// Don't need to request UpdateOverflow if we're being reflowed.
if (!(frame->GetStateBits() & NS_FRAME_IN_REFLOW)) {
NS_UpdateHint(changeHint, nsChangeHint_UpdateOverflow);
}
frame->PresContext()->RestyleManager()->PostRestyleEvent(
frame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
} }
void void

View File

@ -29,6 +29,7 @@ class nsSVGClipPathFrame;
class nsSVGPaintServerFrame; class nsSVGPaintServerFrame;
class nsSVGFilterFrame; class nsSVGFilterFrame;
class nsSVGMaskFrame; class nsSVGMaskFrame;
class nsSVGFilterProperty;
/* /*
* This interface allows us to be notified when a piece of SVG content is * This interface allows us to be notified when a piece of SVG content is
@ -197,13 +198,20 @@ protected:
* The nsSVGFilterProperty class manages a list of nsSVGFilterReferences. * The nsSVGFilterProperty class manages a list of nsSVGFilterReferences.
*/ */
class nsSVGFilterReference MOZ_FINAL : class nsSVGFilterReference MOZ_FINAL :
public nsSVGRenderingObserverProperty, public nsISVGFilterReference { public nsSVGIDRenderingObserver, public nsISVGFilterReference {
public: public:
nsSVGFilterReference(nsIURI *aURI, nsIFrame *aFilteredFrame) nsSVGFilterReference(nsIURI* aURI,
: nsSVGRenderingObserverProperty(aURI, aFilteredFrame, false) {} nsIContent* aObservingContent,
nsSVGFilterProperty* aFilterChainObserver)
: nsSVGIDRenderingObserver(aURI, aObservingContent, false)
, mFilterChainObserver(aFilterChainObserver)
{
}
bool ReferencesValidResource() { return GetFilterFrame(); } bool ReferencesValidResource() { return GetFilterFrame(); }
void DetachFromChainObserver() { mFilterChainObserver = nullptr; }
/** /**
* @return the filter frame, or null if there is no filter frame * @return the filter frame, or null if there is no filter frame
*/ */
@ -218,9 +226,11 @@ public:
protected: protected:
virtual ~nsSVGFilterReference() {} virtual ~nsSVGFilterReference() {}
private: // nsSVGIDRenderingObserver
// nsSVGRenderingObserverProperty
virtual void DoUpdate() MOZ_OVERRIDE; virtual void DoUpdate() MOZ_OVERRIDE;
private:
nsSVGFilterProperty* mFilterChainObserver;
}; };
/** /**
@ -240,16 +250,19 @@ public:
bool ReferencesValidResources(); bool ReferencesValidResources();
bool IsInObserverLists() const; bool IsInObserverLists() const;
void Invalidate(); void Invalidate() { DoUpdate(); }
// nsISupports // nsISupports
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
protected: protected:
virtual ~nsSVGFilterProperty() {} virtual ~nsSVGFilterProperty();
virtual void DoUpdate();
private: private:
nsTArray<nsRefPtr<nsSVGFilterReference>> mReferences; nsTArray<nsRefPtr<nsSVGFilterReference>> mReferences;
nsSVGFrameReferenceFromProperty mFrameReference;
}; };
class nsSVGMarkerProperty : public nsSVGRenderingObserverProperty { class nsSVGMarkerProperty : public nsSVGRenderingObserverProperty {