Commit e53c590a authored by Fredrik Söderqvist's avatar Fredrik Söderqvist Committed by Commit Bot

Remove most synchronous SVG resource layouts

Since most resources - markers excepted - no longer influence layout, we
can burn down most of SVGLayoutSupport::LayoutResourcesIfNeeded, only
leaving the essential bits (marker layout). Move the remnant of the
function closer to its single user. Move the |is_in_layout_| member
field from LayoutSVGResourceContainer to its LayoutSVGResourceMarker
subclass.

Bug: 1028061, 1028063
Change-Id: I87188dd6673df3b3eba3e5a49deb61669ce9b249
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2517501
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824120}
parent fbd658a9
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h"
#include "base/auto_reset.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources.h" #include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h" #include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.h" #include "third_party/blink/renderer/core/layout/svg/svg_resources_cycle_solver.h"
...@@ -42,7 +41,6 @@ LocalSVGResource* ResourceForContainer( ...@@ -42,7 +41,6 @@ LocalSVGResource* ResourceForContainer(
LayoutSVGResourceContainer::LayoutSVGResourceContainer(SVGElement* node) LayoutSVGResourceContainer::LayoutSVGResourceContainer(SVGElement* node)
: LayoutSVGHiddenContainer(node), : LayoutSVGHiddenContainer(node),
is_in_layout_(false),
completed_invalidations_mask_(0), completed_invalidations_mask_(0),
is_invalidating_(false) {} is_invalidating_(false) {}
...@@ -50,17 +48,10 @@ LayoutSVGResourceContainer::~LayoutSVGResourceContainer() = default; ...@@ -50,17 +48,10 @@ LayoutSVGResourceContainer::~LayoutSVGResourceContainer() = default;
void LayoutSVGResourceContainer::UpdateLayout() { void LayoutSVGResourceContainer::UpdateLayout() {
NOT_DESTROYED(); NOT_DESTROYED();
// FIXME: Investigate a way to detect and break resource layout dependency // TODO(fs): This is only here to clear the invalidation mask, without that
// cycles early. Then we can remove this method altogether, and fall back onto // we wouldn't need to override LayoutSVGHiddenContainer::UpdateLayout().
// LayoutSVGHiddenContainer::layout().
DCHECK(NeedsLayout()); DCHECK(NeedsLayout());
if (is_in_layout_)
return;
base::AutoReset<bool> in_layout_change(&is_in_layout_, true);
LayoutSVGHiddenContainer::UpdateLayout(); LayoutSVGHiddenContainer::UpdateLayout();
ClearInvalidationMask(); ClearInvalidationMask();
} }
......
...@@ -100,8 +100,6 @@ class LayoutSVGResourceContainer : public LayoutSVGHiddenContainer { ...@@ -100,8 +100,6 @@ class LayoutSVGResourceContainer : public LayoutSVGHiddenContainer {
void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override; void StyleDidChange(StyleDifference, const ComputedStyle* old_style) override;
void WillBeDestroyed() override; void WillBeDestroyed() override;
bool is_in_layout_;
private: private:
// Track global (markAllClientsForInvalidation) invalidations to avoid // Track global (markAllClientsForInvalidation) invalidations to avoid
// redundant crawls. // redundant crawls.
......
...@@ -31,7 +31,9 @@ ...@@ -31,7 +31,9 @@
namespace blink { namespace blink {
LayoutSVGResourceMarker::LayoutSVGResourceMarker(SVGMarkerElement* node) LayoutSVGResourceMarker::LayoutSVGResourceMarker(SVGMarkerElement* node)
: LayoutSVGResourceContainer(node), needs_transform_update_(true) {} : LayoutSVGResourceContainer(node),
needs_transform_update_(true),
is_in_layout_(false) {}
LayoutSVGResourceMarker::~LayoutSVGResourceMarker() = default; LayoutSVGResourceMarker::~LayoutSVGResourceMarker() = default;
...@@ -43,9 +45,9 @@ void LayoutSVGResourceMarker::UpdateLayout() { ...@@ -43,9 +45,9 @@ void LayoutSVGResourceMarker::UpdateLayout() {
base::AutoReset<bool> in_layout_change(&is_in_layout_, true); base::AutoReset<bool> in_layout_change(&is_in_layout_, true);
// LayoutSVGHiddenContainer overwrites layout(). We need the // LayoutSVGHiddenContainer overrides UpdateLayout(). We need the
// layouting of LayoutSVGContainer for calculating local // LayoutSVGContainer behavior for calculating local transformations and paint
// transformations and paint invalidation. // invalidation.
LayoutSVGContainer::UpdateLayout(); LayoutSVGContainer::UpdateLayout();
ClearInvalidationMask(); ClearInvalidationMask();
......
...@@ -80,6 +80,7 @@ class LayoutSVGResourceMarker final : public LayoutSVGResourceContainer { ...@@ -80,6 +80,7 @@ class LayoutSVGResourceMarker final : public LayoutSVGResourceContainer {
AffineTransform local_to_parent_transform_; AffineTransform local_to_parent_transform_;
FloatSize viewport_size_; FloatSize viewport_size_;
bool needs_transform_update_; bool needs_transform_update_;
bool is_in_layout_;
}; };
DEFINE_LAYOUT_SVG_RESOURCE_TYPE_CASTS(LayoutSVGResourceMarker, DEFINE_LAYOUT_SVG_RESOURCE_TYPE_CASTS(LayoutSVGResourceMarker,
......
...@@ -233,8 +233,6 @@ void LayoutSVGRoot::UpdateLayout() { ...@@ -233,8 +233,6 @@ void LayoutSVGRoot::UpdateLayout() {
did_screen_scale_factor_change_ = did_screen_scale_factor_change_ =
transform_change == SVGTransformChange::kFull; transform_change == SVGTransformChange::kFull;
SVGLayoutSupport::LayoutResourcesIfNeeded(*this);
// selfNeedsLayout() will cover changes to one (or more) of viewBox, // selfNeedsLayout() will cover changes to one (or more) of viewBox,
// current{Scale,Translate}, decorations and 'overflow'. // current{Scale,Translate}, decorations and 'overflow'.
const bool viewport_may_have_changed = const bool viewport_may_have_changed =
......
...@@ -7,13 +7,28 @@ ...@@ -7,13 +7,28 @@
#include "third_party/blink/renderer/core/layout/svg/layout_svg_container.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_container.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_shape.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_shape.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_text.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_text.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h" #include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
#include "third_party/blink/renderer/core/svg/svg_element.h" #include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources_cache.h"
namespace blink { namespace blink {
static void LayoutMarkerResourcesIfNeeded(LayoutObject& layout_object) {
SVGResources* resources =
SVGResourcesCache::CachedResourcesForLayoutObject(layout_object);
if (!resources)
return;
if (LayoutSVGResourceMarker* marker = resources->MarkerStart())
marker->LayoutIfNeeded();
if (LayoutSVGResourceMarker* marker = resources->MarkerMid())
marker->LayoutIfNeeded();
if (LayoutSVGResourceMarker* marker = resources->MarkerEnd())
marker->LayoutIfNeeded();
}
void SVGContentContainer::Layout(const SVGContainerLayoutInfo& layout_info) { void SVGContentContainer::Layout(const SVGContainerLayoutInfo& layout_info) {
for (LayoutObject* child = children_.FirstChild(); child; for (LayoutObject* child = children_.FirstChild(); child;
child = child->NextSibling()) { child = child->NextSibling()) {
...@@ -54,11 +69,10 @@ void SVGContentContainer::Layout(const SVGContainerLayoutInfo& layout_info) { ...@@ -54,11 +69,10 @@ void SVGContentContainer::Layout(const SVGContainerLayoutInfo& layout_info) {
// SVGSVGElement::svgAttributeChange() or at a higher SubtreeLayoutScope (in // SVGSVGElement::svgAttributeChange() or at a higher SubtreeLayoutScope (in
// LayoutView::layout()). We do not create a SubtreeLayoutScope for // LayoutView::layout()). We do not create a SubtreeLayoutScope for
// resources because their ability to reference each other leads to circular // resources because their ability to reference each other leads to circular
// layout. We protect against that within the layout code for resources, but // layout. We protect against that within the layout code for marker
// it causes assertions if we use a SubTreeLayoutScope for them. // resources, but it causes assertions if we use a SubtreeLayoutScope for
// them.
if (child->IsSVGResourceContainer()) { if (child->IsSVGResourceContainer()) {
// Lay out any referenced resources before the child.
SVGLayoutSupport::LayoutResourcesIfNeeded(*child);
child->LayoutIfNeeded(); child->LayoutIfNeeded();
} else { } else {
SubtreeLayoutScope layout_scope(*child); SubtreeLayoutScope layout_scope(*child);
...@@ -68,7 +82,7 @@ void SVGContentContainer::Layout(const SVGContainerLayoutInfo& layout_info) { ...@@ -68,7 +82,7 @@ void SVGContentContainer::Layout(const SVGContainerLayoutInfo& layout_info) {
} }
// Lay out any referenced resources before the child. // Lay out any referenced resources before the child.
SVGLayoutSupport::LayoutResourcesIfNeeded(*child); LayoutMarkerResourcesIfNeeded(*child);
child->LayoutIfNeeded(); child->LayoutIfNeeded();
} }
} }
......
...@@ -245,13 +245,6 @@ bool SVGLayoutSupport::ScreenScaleFactorChanged(const LayoutObject* ancestor) { ...@@ -245,13 +245,6 @@ bool SVGLayoutSupport::ScreenScaleFactorChanged(const LayoutObject* ancestor) {
return false; return false;
} }
void SVGLayoutSupport::LayoutResourcesIfNeeded(const LayoutObject& object) {
SVGResources* resources =
SVGResourcesCache::CachedResourcesForLayoutObject(object);
if (resources)
resources->LayoutIfNeeded();
}
bool SVGLayoutSupport::IsOverflowHidden(const LayoutObject& object) { bool SVGLayoutSupport::IsOverflowHidden(const LayoutObject& object) {
// LayoutSVGRoot should never query for overflow state - it should always clip // LayoutSVGRoot should never query for overflow state - it should always clip
// itself to the initial viewport size. // itself to the initial viewport size.
......
...@@ -47,9 +47,6 @@ class CORE_EXPORT SVGLayoutSupport { ...@@ -47,9 +47,6 @@ class CORE_EXPORT SVGLayoutSupport {
STATIC_ONLY(SVGLayoutSupport); STATIC_ONLY(SVGLayoutSupport);
public: public:
// Layout resources used by this node.
static void LayoutResourcesIfNeeded(const LayoutObject&);
// Helper function determining whether overflow is hidden. // Helper function determining whether overflow is hidden.
static bool IsOverflowHidden(const LayoutObject&); static bool IsOverflowHidden(const LayoutObject&);
static bool IsOverflowHidden(const ComputedStyle&); static bool IsOverflowHidden(const ComputedStyle&);
......
...@@ -237,37 +237,6 @@ std::unique_ptr<SVGResources> SVGResources::BuildResources( ...@@ -237,37 +237,6 @@ std::unique_ptr<SVGResources> SVGResources::BuildResources(
: std::move(resources); : std::move(resources);
} }
void SVGResources::LayoutIfNeeded() {
if (clipper_filter_masker_data_) {
if (LayoutSVGResourceClipper* clipper =
clipper_filter_masker_data_->clipper)
clipper->LayoutIfNeeded();
if (LayoutSVGResourceMasker* masker = clipper_filter_masker_data_->masker)
masker->LayoutIfNeeded();
if (LayoutSVGResourceFilter* filter = clipper_filter_masker_data_->filter)
filter->LayoutIfNeeded();
}
if (marker_data_) {
if (LayoutSVGResourceMarker* marker = marker_data_->marker_start)
marker->LayoutIfNeeded();
if (LayoutSVGResourceMarker* marker = marker_data_->marker_mid)
marker->LayoutIfNeeded();
if (LayoutSVGResourceMarker* marker = marker_data_->marker_end)
marker->LayoutIfNeeded();
}
if (fill_stroke_data_) {
if (LayoutSVGResourcePaintServer* fill = fill_stroke_data_->fill)
fill->LayoutIfNeeded();
if (LayoutSVGResourcePaintServer* stroke = fill_stroke_data_->stroke)
stroke->LayoutIfNeeded();
}
if (linked_resource_)
linked_resource_->LayoutIfNeeded();
}
void SVGResources::ResourceDestroyed(LayoutSVGResourceContainer* resource) { void SVGResources::ResourceDestroyed(LayoutSVGResourceContainer* resource) {
DCHECK(resource); DCHECK(resource);
if (!HasResourceData()) if (!HasResourceData())
......
...@@ -70,8 +70,6 @@ class SVGResources { ...@@ -70,8 +70,6 @@ class SVGResources {
const ComputedStyle&); const ComputedStyle&);
static void ClearMarkers(SVGElement&, const ComputedStyle*); static void ClearMarkers(SVGElement&, const ComputedStyle*);
void LayoutIfNeeded();
static bool SupportsMarkers(const SVGElement&); static bool SupportsMarkers(const SVGElement&);
// Ordinary resources // Ordinary resources
......
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