Bug 864832 - Get rid of the majority of the remaining nsSVGUtils::InvalidateBounds calls, except for those related to transforms and nsSVGTextFrame2. r=mattwoodrow
--- a/content/svg/content/src/SVGSwitchElement.cpp
+++ b/content/svg/content/src/SVGSwitchElement.cpp
@@ -1,14 +1,16 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/SVGSwitchElement.h"
+
+#include "nsSVGEffects.h"
#include "nsSVGUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/SVGSwitchElementBinding.h"
class nsIFrame;
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Switch)
@@ -59,17 +61,17 @@ SVGSwitchElement::MaybeInvalidate()
nsIContent *newActiveChild = FindActiveChild();
if (newActiveChild == mActiveChild) {
return;
}
nsIFrame *frame = GetPrimaryFrame();
if (frame) {
- nsSVGUtils::InvalidateBounds(frame, false);
+ nsSVGEffects::InvalidateRenderingObservers(frame);
nsSVGUtils::ScheduleReflowSVG(frame);
}
mActiveChild = newActiveChild;
}
//----------------------------------------------------------------------
// nsIDOMNode methods
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -7723,18 +7723,18 @@ DoApplyRenderingChangeToTree(nsIFrame* a
bool needInvalidatingPaint = false;
// if frame has view, will already be invalidated
if (aChange & nsChangeHint_RepaintFrame) {
if (aFrame->IsFrameOfType(nsIFrame::eSVG) &&
!(aFrame->GetStateBits() & NS_STATE_IS_OUTER_SVG)) {
if (aChange & nsChangeHint_UpdateEffects) {
needInvalidatingPaint = true;
- // Invalidate and update our area:
- nsSVGUtils::InvalidateBounds(aFrame, false);
+ nsSVGEffects::InvalidateRenderingObservers(aFrame);
+ // Need to update our overflow rects:
nsSVGUtils::ScheduleReflowSVG(aFrame);
} else {
needInvalidatingPaint = true;
// Just invalidate our area:
nsSVGEffects::InvalidateRenderingObservers(aFrame);
aFrame->InvalidateFrameSubtree();
}
} else {
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -88,30 +88,34 @@ nsSVGForeignObjectFrame::GetType() const
NS_IMETHODIMP
nsSVGForeignObjectFrame::AttributeChanged(int32_t aNameSpaceID,
nsIAtom *aAttribute,
int32_t aModType)
{
if (aNameSpaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::height) {
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
// XXXjwatt: why mark intrinsic widths dirty? can't we just use eResize?
RequestReflow(nsIPresShell::eStyleChange);
} else if (aAttribute == nsGkAtoms::x ||
- aAttribute == nsGkAtoms::y ||
- aAttribute == nsGkAtoms::transform) {
+ aAttribute == nsGkAtoms::y) {
+ // make sure our cached transform matrix gets (lazily) updated
+ mCanvasTM = nullptr;
+ nsSVGEffects::InvalidateRenderingObservers(this);
+ nsSVGUtils::ScheduleReflowSVG(this);
+ } else if (aAttribute == nsGkAtoms::transform) {
// make sure our cached transform matrix gets (lazily) updated
mCanvasTM = nullptr;
nsSVGUtils::InvalidateBounds(this, false);
nsSVGUtils::ScheduleReflowSVG(this);
} else if (aAttribute == nsGkAtoms::viewBox ||
aAttribute == nsGkAtoms::preserveAspectRatio) {
- nsSVGUtils::InvalidateBounds(this);
+ nsSVGEffects::InvalidateRenderingObservers(this);
}
}
return NS_OK;
}
/* virtual */ void
nsSVGForeignObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
@@ -120,17 +124,17 @@ nsSVGForeignObjectFrame::DidSetStyleCont
// No need to invalidate before first reflow - that will happen elsewhere.
// Moreover we haven't been initialised properly yet so we may not have the
// right state bits.
if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
// XXXperf: probably only need a bounds update if 'font-size' changed and
// we have em unit width/height. Or, once we map 'transform' into style,
// if some transform property changed.
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
}
}
NS_IMETHODIMP
nsSVGForeignObjectFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
--- a/layout/svg/nsSVGGlyphFrame.cpp
+++ b/layout/svg/nsSVGGlyphFrame.cpp
@@ -285,17 +285,17 @@ nsSVGGlyphFrame::CharacterDataChanged(Ch
NotifyGlyphMetricsChange();
ClearTextRun();
if (IsTextEmpty()) {
// The one time that NotifyGlyphMetricsChange fails to call
// nsSVGUtils::InvalidateAndScheduleBoundsUpdate properly is when all our
// text is gone, since it skips empty frames. So we have to invalidate
// ourself.
- nsSVGUtils::InvalidateBounds(this);
+ nsSVGEffects::InvalidateRenderingObservers(this);
}
return NS_OK;
}
// Usable font size range in devpixels / user-units
#define CLAMP_MIN_SIZE 8
#define CLAMP_MAX_SIZE 200
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -179,17 +179,17 @@ nsSVGImageFrame::AttributeChanged(int32_
nsIAtom* aAttribute,
int32_t aModType)
{
if (aNameSpaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::x ||
aAttribute == nsGkAtoms::y ||
aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::height) {
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
return NS_OK;
}
else if (aAttribute == nsGkAtoms::preserveAspectRatio) {
nsSVGUtils::InvalidateBounds(this);
return NS_OK;
}
}
@@ -554,29 +554,28 @@ nsSVGImageListener::nsSVGImageListener(n
NS_IMETHODIMP
nsSVGImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
{
if (!mFrame)
return NS_ERROR_FAILURE;
if (aType == imgINotificationObserver::LOAD_COMPLETE) {
- nsSVGUtils::InvalidateBounds(mFrame, false);
+ nsSVGEffects::InvalidateRenderingObservers(mFrame);
nsSVGUtils::ScheduleReflowSVG(mFrame);
}
if (aType == imgINotificationObserver::FRAME_UPDATE) {
// No new dimensions, so we don't need to call
// nsSVGUtils::InvalidateAndScheduleBoundsUpdate.
nsSVGEffects::InvalidateRenderingObservers(mFrame);
- nsSVGUtils::InvalidateBounds(mFrame);
}
if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
// Called once the resource's dimensions have been obtained.
aRequest->GetImage(getter_AddRefs(mFrame->mImageContainer));
- nsSVGUtils::InvalidateBounds(mFrame, false);
+ nsSVGEffects::InvalidateRenderingObservers(mFrame);
nsSVGUtils::ScheduleReflowSVG(mFrame);
}
return NS_OK;
}
--- a/layout/svg/nsSVGInnerSVGFrame.cpp
+++ b/layout/svg/nsSVGInnerSVGFrame.cpp
@@ -7,16 +7,17 @@
#include "nsSVGInnerSVGFrame.h"
// Keep others in (case-insensitive) order:
#include "gfxContext.h"
#include "nsIFrame.h"
#include "nsISVGChildFrame.h"
#include "nsRenderingContext.h"
#include "nsSVGContainerFrame.h"
+#include "nsSVGEffects.h"
#include "nsSVGIntegrationUtils.h"
#include "mozilla/dom/SVGSVGElement.h"
using namespace mozilla;
using namespace mozilla::dom;
nsIFrame*
NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -167,17 +168,17 @@ nsSVGInnerSVGFrame::AttributeChanged(int
{
if (aNameSpaceID == kNameSpaceID_None &&
!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) {
SVGSVGElement* content = static_cast<SVGSVGElement*>(mContent);
if (aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::height) {
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
if (content->HasViewBoxOrSyntheticViewBox()) {
// make sure our cached transform matrix gets (lazily) updated
mCanvasTM = nullptr;
content->ChildrenOnlyTransformChanged();
nsSVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
} else {
@@ -192,26 +193,31 @@ nsSVGInnerSVGFrame::AttributeChanged(int
} else if (aAttribute == nsGkAtoms::transform ||
aAttribute == nsGkAtoms::preserveAspectRatio ||
aAttribute == nsGkAtoms::viewBox ||
aAttribute == nsGkAtoms::x ||
aAttribute == nsGkAtoms::y) {
// make sure our cached transform matrix gets (lazily) updated
mCanvasTM = nullptr;
- nsSVGUtils::InvalidateBounds(this, false);
- nsSVGUtils::ScheduleReflowSVG(this);
-
nsSVGUtils::NotifyChildrenOfSVGChange(
this, aAttribute == nsGkAtoms::viewBox ?
TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED : TRANSFORM_CHANGED);
- if (aAttribute == nsGkAtoms::viewBox ||
- (aAttribute == nsGkAtoms::preserveAspectRatio &&
- content->HasViewBoxOrSyntheticViewBox())) {
+ if (aAttribute == nsGkAtoms::x || aAttribute == nsGkAtoms::y) {
+ nsSVGEffects::InvalidateRenderingObservers(this);
+ nsSVGUtils::ScheduleReflowSVG(this);
+ } else if (aAttribute == nsGkAtoms::transform) {
+ nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGUtils::ScheduleReflowSVG(this);
+ } else if (aAttribute == nsGkAtoms::viewBox ||
+ (aAttribute == nsGkAtoms::preserveAspectRatio &&
+ content->HasViewBoxOrSyntheticViewBox())) {
+ nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGUtils::ScheduleReflowSVG(this);
content->ChildrenOnlyTransformChanged();
}
}
}
return NS_OK;
}
--- a/layout/svg/nsSVGPathGeometryFrame.cpp
+++ b/layout/svg/nsSVGPathGeometryFrame.cpp
@@ -103,18 +103,20 @@ nsDisplaySVGPathGeometry::Paint(nsDispla
NS_IMETHODIMP
nsSVGPathGeometryFrame::AttributeChanged(int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType)
{
if (aNameSpaceID == kNameSpaceID_None &&
(static_cast<nsSVGPathGeometryElement*>
- (mContent)->AttributeDefinesGeometry(aAttribute) ||
- aAttribute == nsGkAtoms::transform)) {
+ (mContent)->AttributeDefinesGeometry(aAttribute))) {
+ nsSVGEffects::InvalidateRenderingObservers(this);
+ nsSVGUtils::ScheduleReflowSVG(this);
+ } else if (aAttribute == nsGkAtoms::transform) {
nsSVGUtils::InvalidateBounds(this, false);
nsSVGUtils::ScheduleReflowSVG(this);
}
return NS_OK;
}
/* virtual */ void
nsSVGPathGeometryFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
@@ -122,17 +124,17 @@ nsSVGPathGeometryFrame::DidSetStyleConte
nsSVGPathGeometryFrameBase::DidSetStyleContext(aOldStyleContext);
// XXX: we'd like to use the style_hint mechanism and the
// ContentStateChanged/AttributeChanged functions for style changes
// to get slightly finer granularity, but unfortunately the
// style_hints don't map very well onto svg. Here seems to be the
// best place to deal with style changes:
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
}
nsIAtom *
nsSVGPathGeometryFrame::GetType() const
{
return nsGkAtoms::svgPathGeometryFrame;
}
--- a/layout/svg/nsSVGTSpanFrame.cpp
+++ b/layout/svg/nsSVGTSpanFrame.cpp
@@ -2,16 +2,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Main header first:
#include "nsSVGTSpanFrame.h"
// Keep others in (case-insensitive) order:
+#include "nsSVGEffects.h"
#include "nsSVGIntegrationUtils.h"
#include "nsSVGUtils.h"
//----------------------------------------------------------------------
// Implementation
nsIFrame*
NS_NewSVGTSpanFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -73,17 +74,17 @@ nsSVGTSpanFrame::AttributeChanged(int32_
int32_t aModType)
{
if (aNameSpaceID == kNameSpaceID_None &&
(aAttribute == nsGkAtoms::x ||
aAttribute == nsGkAtoms::y ||
aAttribute == nsGkAtoms::dx ||
aAttribute == nsGkAtoms::dy ||
aAttribute == nsGkAtoms::rotate)) {
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
NotifyGlyphMetricsChange();
}
return NS_OK;
}
//----------------------------------------------------------------------
--- a/layout/svg/nsSVGTextFrame.cpp
+++ b/layout/svg/nsSVGTextFrame.cpp
@@ -5,16 +5,17 @@
// Main header first:
#include "nsSVGTextFrame.h"
// Keep others in (case-insensitive) order:
#include "nsGkAtoms.h"
#include "mozilla/dom/SVGIRect.h"
#include "nsISVGGlyphFragmentNode.h"
+#include "nsSVGEffects.h"
#include "nsSVGGlyphFrame.h"
#include "nsSVGIntegrationUtils.h"
#include "nsSVGTextPathFrame.h"
#include "nsSVGUtils.h"
#include "SVGGraphicsElement.h"
#include "SVGLengthList.h"
using namespace mozilla;
@@ -57,17 +58,17 @@ nsSVGTextFrame::AttributeChanged(int32_t
nsSVGUtils::InvalidateBounds(this, false);
nsSVGUtils::ScheduleReflowSVG(this);
NotifySVGChanged(TRANSFORM_CHANGED);
} else if (aAttribute == nsGkAtoms::x ||
aAttribute == nsGkAtoms::y ||
aAttribute == nsGkAtoms::dx ||
aAttribute == nsGkAtoms::dy ||
aAttribute == nsGkAtoms::rotate) {
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
NotifyGlyphMetricsChange();
}
return NS_OK;
}
nsIAtom *
@@ -315,17 +316,17 @@ MarkDirtyBitsOnDescendants(nsIFrame *aFr
void
nsSVGTextFrame::NotifyGlyphMetricsChange()
{
// NotifySVGChanged isn't appropriate here, so we just mark our descendants
// as fully dirty to get ReflowSVG() called on them:
MarkDirtyBitsOnDescendants(this);
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
mPositioningDirty = true;
}
void
nsSVGTextFrame::SetWhitespaceHandling(nsSVGGlyphFrame *aFrame)
{
--- a/layout/svg/nsSVGTextPathFrame.cpp
+++ b/layout/svg/nsSVGTextPathFrame.cpp
@@ -153,22 +153,22 @@ nsSVGTextPathFrame::GetOffsetScale()
NS_IMETHODIMP
nsSVGTextPathFrame::AttributeChanged(int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType)
{
if (aNameSpaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::startOffset) {
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
NotifyGlyphMetricsChange();
} else if (aNameSpaceID == kNameSpaceID_XLink &&
aAttribute == nsGkAtoms::href) {
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
// Blow away our reference, if any
Properties().Delete(nsSVGEffects::HrefProperty());
NotifyGlyphMetricsChange();
}
return NS_OK;
}
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -1,15 +1,16 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Keep in (case-insensitive) order:
#include "nsIAnonymousContentCreator.h"
+#include "nsSVGEffects.h"
#include "nsSVGGFrame.h"
#include "mozilla/dom/SVGUseElement.h"
#include "nsContentList.h"
typedef nsSVGGFrame nsSVGUseFrameBase;
using namespace mozilla::dom;
@@ -118,39 +119,39 @@ nsSVGUseFrame::AttributeChanged(int32_t
{
SVGUseElement *useElement = static_cast<SVGUseElement*>(mContent);
if (aNameSpaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::x ||
aAttribute == nsGkAtoms::y) {
// make sure our cached transform matrix gets (lazily) updated
mCanvasTM = nullptr;
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
nsSVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
} else if (aAttribute == nsGkAtoms::width ||
aAttribute == nsGkAtoms::height) {
bool invalidate = false;
if (mHasValidDimensions != useElement->HasValidDimensions()) {
mHasValidDimensions = !mHasValidDimensions;
invalidate = true;
}
if (useElement->OurWidthAndHeightAreUsed()) {
invalidate = true;
useElement->SyncWidthOrHeight(aAttribute);
}
if (invalidate) {
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
}
}
} else if (aNameSpaceID == kNameSpaceID_XLink &&
aAttribute == nsGkAtoms::href) {
// we're changing our nature, clear out the clone information
- nsSVGUtils::InvalidateBounds(this, false);
+ nsSVGEffects::InvalidateRenderingObservers(this);
nsSVGUtils::ScheduleReflowSVG(this);
useElement->mOriginal = nullptr;
useElement->UnlinkSource();
useElement->TriggerReclone();
}
return nsSVGUseFrameBase::AttributeChanged(aNameSpaceID,
aAttribute, aModType);