Commit a229e828 authored by fs's avatar fs Committed by Commit bot

Strength-reduce the "scale-factor changed" condition in LayoutSVGRoot

Spend some cycles examining the difference between the old and new
local-to-border-box transforms, and only signal scale-factor changes
if that part of the transform changed.
This also means that we now detect changes scale that we previously
didn't (like [1].)

[1] paint/invalidation/svg/absolute-sized-content-with-resources.xhtml

BUG=603956,664961

Review-Url: https://codereview.chromium.org/2559123003
Cr-Commit-Position: refs/heads/master@{#437767}
parent d1693364
......@@ -19,7 +19,7 @@
{
"object": "LayoutSVGRect rect",
"rect": [42, 117, 334, 268],
"reason": "bounds change"
"reason": "SVG resource change"
},
{
"object": "LayoutSVGRoot svg",
......@@ -54,7 +54,7 @@
{
"object": "LayoutSVGRect rect",
"rect": [17, 217, 84, 68],
"reason": "bounds change"
"reason": "SVG resource change"
},
{
"object": "LayoutSVGRoot svg",
......@@ -109,7 +109,7 @@
},
{
"object": "LayoutSVGRect rect",
"reason": "bounds change"
"reason": "SVG resource change"
}
]
}
......
......@@ -19,7 +19,7 @@
{
"object": "LayoutSVGRect rect",
"rect": [42, 119, 334, 268],
"reason": "bounds change"
"reason": "SVG resource change"
},
{
"object": "LayoutSVGRoot svg",
......@@ -54,7 +54,7 @@
{
"object": "LayoutSVGRect rect",
"rect": [17, 219, 84, 68],
"reason": "bounds change"
"reason": "SVG resource change"
},
{
"object": "LayoutSVGRoot svg",
......@@ -109,7 +109,7 @@
},
{
"object": "LayoutSVGRect rect",
"reason": "bounds change"
"reason": "SVG resource change"
}
]
}
......
......@@ -145,23 +145,34 @@ void LayoutSVGRoot::layout() {
updateLogicalWidth();
updateLogicalHeight();
buildLocalToBorderBoxTransform();
// TODO(fs): Temporarily, needing a layout implies that the local transform
// has changed. This should be updated to be more precise and factor in the
// actual (relevant) changes to the computed user-space transform.
m_didScreenScaleFactorChange = selfNeedsLayout();
// The local-to-border-box transform is a function with the following as
// input:
//
// * effective zoom
// * contentWidth/Height
// * viewBox
// * border + padding
// * currentTranslate
// * currentScale
//
// Which means that |transformChange| will notice a change to the scale from
// any of these.
SVGTransformChange transformChange = buildLocalToBorderBoxTransform();
// The scale factor from the local-to-border-box transform is all that our
// scale-dependent descendants care about.
m_didScreenScaleFactorChange = transformChange == SVGTransformChange::Full;
SVGLayoutSupport::layoutResourcesIfNeeded(this);
// selfNeedsLayout() will cover changes to one (or more) of viewBox,
// current{Scale,Translate} and decorations.
// current{Scale,Translate}, decorations and 'overflow'.
const bool viewportMayHaveChanged = selfNeedsLayout() || oldSize != size();
// The scale of one or more of the SVG elements may have changed, or new
// content may have been exposed, so mark the entire subtree as needing paint
// invalidation checking. (It is only somewhat by coincidence that this
// condition happens to be the same as the one for viewport changes.)
if (viewportMayHaveChanged) {
// The scale of one or more of the SVG elements may have changed, content
// (the entire SVG) could have moved or new content may have been exposed, so
// mark the entire subtree as needing paint invalidation checking.
if (transformChange != SVGTransformChange::None || viewportMayHaveChanged) {
setMayNeedPaintInvalidationSubtree();
if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled())
setNeedsPaintPropertyUpdate();
......@@ -333,21 +344,23 @@ PositionWithAffinity LayoutSVGRoot::positionForPoint(const LayoutPoint& point) {
// LayoutBox methods will expect coordinates w/o any transforms in coordinates
// relative to our borderBox origin. This method gives us exactly that.
void LayoutSVGRoot::buildLocalToBorderBoxTransform() {
SVGTransformChange LayoutSVGRoot::buildLocalToBorderBoxTransform() {
SVGTransformChangeDetector changeDetector(m_localToBorderBoxTransform);
SVGSVGElement* svg = toSVGSVGElement(node());
ASSERT(svg);
float scale = style()->effectiveZoom();
FloatPoint translate = svg->currentTranslate();
LayoutSize borderAndPadding(borderLeft() + paddingLeft(),
borderTop() + paddingTop());
m_localToBorderBoxTransform = svg->viewBoxToViewTransform(
contentWidth() / scale, contentHeight() / scale);
FloatPoint translate = svg->currentTranslate();
LayoutSize borderAndPadding(borderLeft() + paddingLeft(),
borderTop() + paddingTop());
AffineTransform viewToBorderBoxTransform(
scale, 0, 0, scale, borderAndPadding.width() + translate.x(),
borderAndPadding.height() + translate.y());
viewToBorderBoxTransform.scale(svg->currentScale());
m_localToBorderBoxTransform.preMultiply(viewToBorderBoxTransform);
return changeDetector.computeChange(m_localToBorderBoxTransform);
}
AffineTransform LayoutSVGRoot::localToSVGParentTransform() const {
......
......@@ -28,6 +28,7 @@
namespace blink {
class SVGElement;
enum class SVGTransformChange;
class CORE_EXPORT LayoutSVGRoot final : public LayoutReplaced {
public:
......@@ -156,7 +157,7 @@ class CORE_EXPORT LayoutSVGRoot final : public LayoutReplaced {
void descendantIsolationRequirementsChanged(DescendantIsolationState) final;
void updateCachedBoundaries();
void buildLocalToBorderBoxTransform();
SVGTransformChange buildLocalToBorderBoxTransform();
PositionWithAffinity positionForPoint(const LayoutPoint&) final;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment