Bug 1383650 - Invalidate path cache when geometry changed via CSS r=longsonr

We cached the path of an element. Previously we only need to invalidate
the cached path if an geometry attribute is changed. Now we also need
to invalidate if the corresponding CSS is changed.

Differential Revision: https://phabricator.services.mozilla.com/D30472

--HG--
extra : moz-landing-system : lando
This commit is contained in:
violet 2019-05-16 00:50:15 +00:00
Родитель 9264ebe151
Коммит 4e7e1be890
9 изменённых файлов: 84 добавлений и 1 удалений

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

@ -4,6 +4,7 @@
* 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 "ComputedStyle.h"
#include "mozilla/dom/SVGCircleElement.h"
#include "mozilla/gfx/2D.h"
#include "nsGkAtoms.h"
@ -139,5 +140,15 @@ already_AddRefed<Path> SVGCircleElement::BuildPath(PathBuilder* aBuilder) {
return aBuilder->Finish();
}
bool SVGCircleElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
const ComputedStyle& aOldStyle) {
auto *newSVGReset = aNewStyle.StyleSVGReset(),
*oldSVGReset = aOldStyle.StyleSVGReset();
return newSVGReset->mCx != oldSVGReset->mCx ||
newSVGReset->mCy != oldSVGReset->mCy ||
newSVGReset->mR != oldSVGReset->mR;
}
} // namespace dom
} // namespace mozilla

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

@ -14,6 +14,8 @@ nsresult NS_NewSVGCircleElement(
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
namespace mozilla {
class ComputedStyle;
namespace dom {
typedef SVGGeometryElement SVGCircleElementBase;
@ -43,6 +45,9 @@ class SVGCircleElement final : public SVGCircleElementBase {
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
const ComputedStyle& aOldStyle);
// WebIDL
already_AddRefed<DOMSVGAnimatedLength> Cx();
already_AddRefed<DOMSVGAnimatedLength> Cy();

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

@ -4,6 +4,7 @@
* 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 "ComputedStyle.h"
#include "mozilla/dom/SVGEllipseElement.h"
#include "mozilla/dom/SVGEllipseElementBinding.h"
#include "mozilla/dom/SVGLengthBinding.h"
@ -151,5 +152,16 @@ already_AddRefed<Path> SVGEllipseElement::BuildPath(PathBuilder* aBuilder) {
return aBuilder->Finish();
}
bool SVGEllipseElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
const ComputedStyle& aOldStyle) {
auto *newSVGReset = aNewStyle.StyleSVGReset(),
*oldSVGReset = aOldStyle.StyleSVGReset();
return newSVGReset->mCx != oldSVGReset->mCx ||
newSVGReset->mCy != oldSVGReset->mCy ||
newSVGReset->mRx != oldSVGReset->mRx ||
newSVGReset->mRy != oldSVGReset->mRy;
}
} // namespace dom
} // namespace mozilla

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

@ -14,6 +14,8 @@ nsresult NS_NewSVGEllipseElement(
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
namespace mozilla {
class ComputedStyle;
namespace dom {
typedef SVGGeometryElement SVGEllipseElementBase;
@ -43,6 +45,9 @@ class SVGEllipseElement final : public SVGEllipseElementBase {
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
const ComputedStyle& aOldStyle);
// WebIDL
already_AddRefed<DOMSVGAnimatedLength> Cx();
already_AddRefed<DOMSVGAnimatedLength> Cy();

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

@ -10,8 +10,11 @@
#include "gfxPlatform.h"
#include "nsCOMPtr.h"
#include "nsComputedDOMStyle.h"
#include "SVGAnimatedLength.h"
#include "nsSVGUtils.h"
#include "SVGAnimatedLength.h"
#include "SVGCircleElement.h"
#include "SVGEllipseElement.h"
#include "SVGRectElement.h"
#include "mozilla/dom/SVGLengthBinding.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
@ -111,6 +114,22 @@ already_AddRefed<Path> SVGGeometryElement::GetOrBuildPathForMeasuring() {
return GetOrBuildPath(drawTarget, fillRule);
}
bool SVGGeometryElement::IsGeometryChangedViaCSS(
ComputedStyle const& aNewStyle, ComputedStyle const& aOldStyle) const {
if (IsSVGElement(nsGkAtoms::rect)) {
return SVGRectElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
}
if (IsSVGElement(nsGkAtoms::circle)) {
return SVGCircleElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
}
if (IsSVGElement(nsGkAtoms::ellipse)) {
return SVGEllipseElement::IsLengthChangedViaCSS(aNewStyle, aOldStyle);
}
return false;
}
FillRule SVGGeometryElement::GetFillRule() {
FillRule fillRule =
FillRule::FILL_WINDING; // Equivalent to StyleFillRule::Nonzero

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

@ -191,6 +191,13 @@ class SVGGeometryElement : public SVGGeometryElementBase {
*/
virtual already_AddRefed<Path> GetOrBuildPathForMeasuring();
/**
* Return |true| if some geometry properties (|x|, |y|, etc) are changed
* because of CSS change.
*/
bool IsGeometryChangedViaCSS(ComputedStyle const& aNewStyle,
ComputedStyle const& aOldStyle) const;
/**
* Returns the current computed value of the CSS property 'fill-rule' for
* this element.

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

@ -226,5 +226,20 @@ already_AddRefed<Path> SVGRectElement::BuildPath(PathBuilder* aBuilder) {
return aBuilder->Finish();
}
bool SVGRectElement::IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
const ComputedStyle& aOldStyle) {
auto *newSVGReset = aNewStyle.StyleSVGReset(),
*oldSVGReset = aOldStyle.StyleSVGReset();
auto *newPosition = aNewStyle.StylePosition(),
*oldPosition = aOldStyle.StylePosition();
return newSVGReset->mX != oldSVGReset->mX ||
newSVGReset->mY != oldSVGReset->mY ||
newPosition->mWidth != oldPosition->mWidth ||
newPosition->mHeight != oldPosition->mHeight ||
newSVGReset->mRx != oldSVGReset->mRx ||
newSVGReset->mRy != oldSVGReset->mRy;
}
} // namespace dom
} // namespace mozilla

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

@ -14,6 +14,8 @@ nsresult NS_NewSVGRectElement(
nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
namespace mozilla {
class ComputedStyle;
namespace dom {
typedef SVGGeometryElement SVGRectElementBase;
@ -44,6 +46,9 @@ class SVGRectElement final : public SVGRectElementBase {
virtual nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
static bool IsLengthChangedViaCSS(const ComputedStyle& aNewStyle,
const ComputedStyle& aOldStyle);
// WebIDL
already_AddRefed<DOMSVGAnimatedLength> X();
already_AddRefed<DOMSVGAnimatedLength> Y();

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

@ -197,6 +197,10 @@ void SVGGeometryFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
}
}
}
if (element->IsGeometryChangedViaCSS(*Style(), *aOldComputedStyle)) {
element->ClearAnyCachedPath();
}
}
}