Skip to content

Commit

Permalink
[LBSE] Add RenderSVGResourceContainer
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=261880

Reviewed by Nikolas Zimmermann.

Add RenderSVGResourceContainer for LBSE which knows how to handle RenderLayer
and will act for future LBSE specific SVG resources.
Start keeping track of RenderSVGResourceContainer in ShadowRoot and adjust
RenderObject to be able to distinguish between LBSE and legacy SVG resources.

* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/dom/TreeScope.cpp:
(WebCore::TreeScope::addSVGResource):
(WebCore::TreeScope::removeSVGResource):
(WebCore::TreeScope::svgResourceById const):
* Source/WebCore/dom/TreeScope.h:
* Source/WebCore/rendering/RenderObject.h:
(WebCore::RenderObject::isLegacySVGResourceContainer const):
* Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp:
(WebCore::RenderSVGHiddenContainer::RenderSVGHiddenContainer):
* Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h:
(WebCore::RenderObject::isLegacySVGResourceContainer const):
* Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h:
* Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp: Added.
(WebCore::RenderSVGResourceContainer::RenderSVGResourceContainer):
(WebCore::RenderSVGResourceContainer::willBeDestroyed):
(WebCore::RenderSVGResourceContainer::styleDidChange):
(WebCore::RenderSVGResourceContainer::idChanged):
(WebCore::RenderSVGResourceContainer::registerResource):
* Source/WebCore/rendering/svg/RenderSVGResourceContainer.h: Added.
* Source/WebCore/rendering/svg/SVGResourcesCycleSolver.cpp:
(WebCore::SVGResourcesCycleSolver::resourceContainsCycles):
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResourceContainer.h:
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGPath.cpp:
* Source/WebCore/svg/SVGDefsElement.cpp:
(WebCore::SVGDefsElement::createElementRenderer):
* Source/WebCore/svg/SVGGElement.cpp:
(WebCore::SVGGElement::createElementRenderer):
* Source/WebCore/svg/SVGSymbolElement.cpp:
(WebCore::SVGSymbolElement::createElementRenderer):

Canonical link: https://commits.webkit.org/269522@main
  • Loading branch information
rwlbuis committed Oct 19, 2023
1 parent 660a1c4 commit a9d6d01
Show file tree
Hide file tree
Showing 15 changed files with 182 additions and 15 deletions.
1 change: 1 addition & 0 deletions Source/WebCore/Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2769,6 +2769,7 @@ rendering/svg/RenderSVGModelObject.cpp
rendering/svg/RenderSVGPath.cpp
rendering/svg/RenderSVGRect.cpp
rendering/svg/RenderSVGResource.cpp
rendering/svg/RenderSVGResourceContainer.cpp
rendering/svg/RenderSVGResourceFilter.cpp
rendering/svg/RenderSVGResourceFilterPrimitive.cpp
rendering/svg/RenderSVGResourceGradient.cpp
Expand Down
6 changes: 6 additions & 0 deletions Source/WebCore/WebCore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,7 @@
44E349F9246F4E190068479C /* LibWebRTCEnumTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 44E349F7246F4DC70068479C /* LibWebRTCEnumTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
44E8AB4F2AB6014E00F443A8 /* SVGSubpathData.h in Headers */ = {isa = PBXBuildFile; fileRef = 44E8AB4E2AB6014D00F443A8 /* SVGSubpathData.h */; };
44EEA100274757F100594A83 /* ImageControlsMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 44EEA0FA274727F200594A83 /* ImageControlsMac.h */; };
44F48A682ABC7B6F0044526B /* RenderSVGResourceContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 44F48A662ABC7B6F0044526B /* RenderSVGResourceContainer.h */; };
4512502315DCE37D002F84E2 /* SpinButtonElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4512502115DCE37D002F84E2 /* SpinButtonElement.h */; };
453EB637159C570400001BB7 /* DateTimeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 453EB635159C570400001BB7 /* DateTimeFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
45830D4E1679B4F800ACF8C3 /* AutoscrollController.h in Headers */ = {isa = PBXBuildFile; fileRef = 45830D4C1679B4F800ACF8C3 /* AutoscrollController.h */; settings = {ATTRIBUTES = (Private, ); }; };
Expand Down Expand Up @@ -10415,6 +10416,8 @@
44EEA0F627449C0000594A83 /* imageControlsMac.css */ = {isa = PBXFileReference; lastKnownFileType = text.css; path = imageControlsMac.css; sourceTree = "<group>"; };
44EEA0FA274727F200594A83 /* ImageControlsMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageControlsMac.h; sourceTree = "<group>"; };
44EEA0FC274727F400594A83 /* ImageControlsMac.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ImageControlsMac.cpp; sourceTree = "<group>"; };
44F48A652ABC7B6E0044526B /* RenderSVGResourceContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGResourceContainer.cpp; sourceTree = "<group>"; };
44F48A662ABC7B6F0044526B /* RenderSVGResourceContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGResourceContainer.h; sourceTree = "<group>"; };
4512502015DCE37D002F84E2 /* SpinButtonElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpinButtonElement.cpp; sourceTree = "<group>"; };
4512502115DCE37D002F84E2 /* SpinButtonElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpinButtonElement.h; sourceTree = "<group>"; };
45160A892A09FA22009E39A2 /* JSMediaSessionCustom.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSMediaSessionCustom.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -21181,6 +21184,8 @@
A10BB5831484E3A700B3AB6D /* RenderSVGRect.h */,
4367088D12D9CA4A00044234 /* RenderSVGResource.cpp */,
4367088E12D9CA4A00044234 /* RenderSVGResource.h */,
44F48A652ABC7B6E0044526B /* RenderSVGResourceContainer.cpp */,
44F48A662ABC7B6F0044526B /* RenderSVGResourceContainer.h */,
4367089312D9CA4A00044234 /* RenderSVGResourceFilter.cpp */,
4367089412D9CA4A00044234 /* RenderSVGResourceFilter.h */,
CDF747EC270F6ED1008FEEEC /* RenderSVGResourceFilterInlines.h */,
Expand Down Expand Up @@ -41021,6 +41026,7 @@
ADDF1AD71257CC1A1133B644 /* RenderSVGPath.h in Headers */,
A10BB5851484E3A700B3AB6D /* RenderSVGRect.h in Headers */,
436708CD12D9CA4B00044234 /* RenderSVGResource.h in Headers */,
44F48A682ABC7B6F0044526B /* RenderSVGResourceContainer.h in Headers */,
436708D312D9CA4B00044234 /* RenderSVGResourceFilter.h in Headers */,
CDF747ED270F6ED1008FEEEC /* RenderSVGResourceFilterInlines.h in Headers */,
436708D512D9CA4B00044234 /* RenderSVGResourceFilterPrimitive.h in Headers */,
Expand Down
18 changes: 14 additions & 4 deletions Source/WebCore/dom/TreeScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,8 @@ struct SVGResourcesMap {

MemoryCompactRobinHoodHashMap<AtomString, WeakHashSet<SVGElement, WeakPtrImplWithEventTargetData>> pendingResources;
MemoryCompactRobinHoodHashMap<AtomString, WeakHashSet<SVGElement, WeakPtrImplWithEventTargetData>> pendingResourcesForRemoval;
MemoryCompactRobinHoodHashMap<AtomString, LegacyRenderSVGResourceContainer*> resources;
MemoryCompactRobinHoodHashMap<AtomString, RenderSVGResourceContainer*> resources;
MemoryCompactRobinHoodHashMap<AtomString, LegacyRenderSVGResourceContainer*> legacyResources;
};

SVGResourcesMap& TreeScope::svgResourcesMap() const
Expand All @@ -595,7 +596,7 @@ SVGResourcesMap& TreeScope::svgResourcesMap() const
return *m_svgResourcesMap;
}

void TreeScope::addSVGResource(const AtomString& id, LegacyRenderSVGResourceContainer& resource)
void TreeScope::addSVGResource(const AtomString& id, RenderSVGResourceContainer& resource)
{
if (id.isEmpty())
return;
Expand All @@ -604,20 +605,29 @@ void TreeScope::addSVGResource(const AtomString& id, LegacyRenderSVGResourceCont
svgResourcesMap().resources.set(id, &resource);
}

void TreeScope::addSVGResource(const AtomString& id, LegacyRenderSVGResourceContainer& resource)
{
if (id.isEmpty())
return;

// Replaces resource if already present, to handle potential id changes
svgResourcesMap().legacyResources.set(id, &resource);
}

void TreeScope::removeSVGResource(const AtomString& id)
{
if (id.isEmpty())
return;

svgResourcesMap().resources.remove(id);
svgResourcesMap().legacyResources.remove(id);
}

LegacyRenderSVGResourceContainer* TreeScope::svgResourceById(const AtomString& id) const
{
if (id.isEmpty())
return nullptr;

return svgResourcesMap().resources.get(id);
return svgResourcesMap().legacyResources.get(id);
}

void TreeScope::addPendingSVGResource(const AtomString& id, SVGElement& element)
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/dom/TreeScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class LegacyRenderSVGResourceContainer;
class IdTargetObserverRegistry;
class Node;
class RadioButtonGroups;
class RenderSVGResourceContainer;
class SVGElement;
class ShadowRoot;
class TreeScopeOrderedMap;
Expand Down Expand Up @@ -131,6 +132,7 @@ class TreeScope {
std::span<const RefPtr<CSSStyleSheet>> adoptedStyleSheets() const;
ExceptionOr<void> setAdoptedStyleSheets(Vector<RefPtr<CSSStyleSheet>>&&);

void addSVGResource(const AtomString& id, RenderSVGResourceContainer&);
void addSVGResource(const AtomString& id, LegacyRenderSVGResourceContainer&);
void removeSVGResource(const AtomString& id);
LegacyRenderSVGResourceContainer* svgResourceById(const AtomString& id) const;
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/rendering/RenderObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ class RenderObject : public CachedImageClient, public CanMakeCheckedPtr {
bool isLegacySVGForeignObject() const { return type() == Type::LegacySVGForeignObject; }
bool isSVGForeignObject() const { return type() == Type::SVGForeignObject; }
virtual bool isSVGResourceContainer() const { return false; }
virtual bool isLegacySVGResourceContainer() const { return false; }
bool isSVGResourceFilter() const { return type() == Type::SVGResourceFilter; }
bool isSVGResourceClipper() const { return type() == Type::LegacySVGResourceClipper; }
bool isSVGResourceFilterPrimitive() const { return type() == Type::SVGResourceFilterPrimitive; }
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(RenderSVGHiddenContainer);

RenderSVGHiddenContainer::RenderSVGHiddenContainer(SVGElement& element, RenderStyle&& style)
: RenderSVGContainer(Type::SVGHiddenContainer, element, WTFMove(style))
RenderSVGHiddenContainer::RenderSVGHiddenContainer(Type type, SVGElement& element, RenderStyle&& style)
: RenderSVGContainer(type, element, WTFMove(style))
{
}

Expand Down
7 changes: 4 additions & 3 deletions Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@ class SVGElement;

// This class is for containers which are never drawn, but do need to support style
// <defs>, <linearGradient>, <radialGradient> are all good examples
class RenderSVGHiddenContainer final : public RenderSVGContainer {
class RenderSVGHiddenContainer : public RenderSVGContainer {
WTF_MAKE_ISO_ALLOCATED(RenderSVGHiddenContainer);
public:
RenderSVGHiddenContainer(SVGElement&, RenderStyle&&);
RenderSVGHiddenContainer(Type, SVGElement&, RenderStyle&&);

protected:
void layout() override;

void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;

private:
ASCIILiteral renderName() const override { return "RenderSVGHiddenContainer"_s; }

Expand All @@ -53,7 +55,6 @@ class RenderSVGHiddenContainer final : public RenderSVGContainer {
void applyTransform(TransformationMatrix&, const RenderStyle&, const FloatRect&, OptionSet<RenderStyle::TransformOperationOption>) const final { }
void updateFromStyle() final { }
bool needsHasSVGTransformFlags() const final { return false; }
void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
};

} // namespace WebCore
Expand Down
86 changes: 86 additions & 0 deletions Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
* Copyright (c) 2023 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "RenderSVGResourceContainer.h"

#include "RenderLayer.h"
#include "RenderSVGRoot.h"
#include "SVGElementTypeHelpers.h"
#include "SVGResourcesCache.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/SetForScope.h>
#include <wtf/StackStats.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(RenderSVGResourceContainer);

RenderSVGResourceContainer::RenderSVGResourceContainer(Type type, SVGElement& element, RenderStyle&& style)
: RenderSVGHiddenContainer(type, element, WTFMove(style))
, m_id(element.getIdAttribute())
{
}

RenderSVGResourceContainer::~RenderSVGResourceContainer() = default;

void RenderSVGResourceContainer::willBeDestroyed()
{
if (m_registered) {
treeScopeForSVGReferences().removeSVGResource(m_id);
m_registered = false;
}

RenderSVGHiddenContainer::willBeDestroyed();
}

void RenderSVGResourceContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderSVGHiddenContainer::styleDidChange(diff, oldStyle);

if (!m_registered) {
m_registered = true;
registerResource();
}
}

void RenderSVGResourceContainer::idChanged()
{
// Remove old id, that is guaranteed to be present in cache.
treeScopeForSVGReferences().removeSVGResource(m_id);
m_id = element().getIdAttribute();

registerResource();
}

void RenderSVGResourceContainer::registerResource()
{
auto& treeScope = this->treeScopeForSVGReferences();
if (!treeScope.isIdOfPendingSVGResource(m_id)) {
treeScope.addSVGResource(m_id, *this);
return;
}

auto elements = copyToVectorOf<Ref<SVGElement>>(treeScope.removePendingSVGResource(m_id));

treeScope.addSVGResource(m_id, *this);
}

}
58 changes: 58 additions & 0 deletions Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
* Copyright (c) 2023 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#pragma once

#include "RenderSVGHiddenContainer.h"
#include "RenderSVGResource.h"

namespace WebCore {

class RenderLayer;

class RenderSVGResourceContainer : public RenderSVGHiddenContainer, public RenderSVGResource {
WTF_MAKE_ISO_ALLOCATED(RenderSVGResourceContainer);
public:
virtual ~RenderSVGResourceContainer();

void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;

bool isSVGResourceContainer() const final { return true; }

void idChanged();

protected:
RenderSVGResourceContainer(Type, SVGElement&, RenderStyle&&);

private:
friend class SVGResourcesCache;
void addClient(RenderElement&);
void removeClient(RenderElement&);

void willBeDestroyed() final;
void registerResource();

AtomString m_id;
bool m_registered { false };
};

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGResourceContainer, isSVGResourceContainer())
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/svg/SVGResourcesCycleSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ bool SVGResourcesCycleSolver::resourceContainsCycles(LegacyRenderSVGResourceCont

RenderObject* node = &resource;
while (node) {
if (node != &resource && node->isSVGResourceContainer()) {
if (node != &resource && node->isLegacySVGResourceContainer()) {
node = node->nextInPreOrderAfterChildren(&resource);
continue;
}
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/rendering/svg/legacy/LegacyRenderSVGPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "RenderStyleInlines.h"
#include "SVGPathElement.h"
#include "SVGRenderStyle.h"
#include "SVGResources.h"
#include "SVGResourcesCache.h"
#include "SVGSubpathData.h"
#include <wtf/IsoMallocInlines.h>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class LegacyRenderSVGResourceContainer : public LegacyRenderSVGHiddenContainer,
void layout() override;
void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;

bool isSVGResourceContainer() const final { return true; }
bool isLegacySVGResourceContainer() const final { return true; }

static float computeTextPaintingScale(const RenderElement&);
static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform);
Expand Down Expand Up @@ -105,4 +105,4 @@ Renderer* getRenderSVGResourceById(TreeScope& treeScope, const AtomString& id)

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(LegacyRenderSVGResourceContainer, isSVGResourceContainer())
SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(LegacyRenderSVGResourceContainer, isLegacySVGResourceContainer())
2 changes: 1 addition & 1 deletion Source/WebCore/svg/SVGDefsElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ RenderPtr<RenderElement> SVGDefsElement::createElementRenderer(RenderStyle&& sty
{
#if ENABLE(LAYER_BASED_SVG_ENGINE)
if (document().settings().layerBasedSVGEngineEnabled())
return createRenderer<RenderSVGHiddenContainer>(*this, WTFMove(style));
return createRenderer<RenderSVGHiddenContainer>(RenderObject::Type::SVGHiddenContainer, *this, WTFMove(style));
#endif
return createRenderer<LegacyRenderSVGHiddenContainer>(RenderObject::Type::LegacySVGHiddenContainer, *this, WTFMove(style));
}
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/svg/SVGGElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ RenderPtr<RenderElement> SVGGElement::createElementRenderer(RenderStyle&& style,
// FIXME: [LBSE] Support hidden containers
if (document().settings().layerBasedSVGEngineEnabled()) {
if (style.display() == DisplayType::None)
return createRenderer<RenderSVGHiddenContainer>(*this, WTFMove(style));
return createRenderer<RenderSVGHiddenContainer>(RenderObject::Type::SVGHiddenContainer, *this, WTFMove(style));
return createRenderer<RenderSVGTransformableContainer>(*this, WTFMove(style));
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/svg/SVGSymbolElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ RenderPtr<RenderElement> SVGSymbolElement::createElementRenderer(RenderStyle&& s
{
#if ENABLE(LAYER_BASED_SVG_ENGINE)
if (document().settings().layerBasedSVGEngineEnabled())
return createRenderer<RenderSVGHiddenContainer>(*this, WTFMove(style));
return createRenderer<RenderSVGHiddenContainer>(RenderObject::Type::SVGHiddenContainer, *this, WTFMove(style));
#endif
return createRenderer<LegacyRenderSVGHiddenContainer>(RenderObject::Type::LegacySVGHiddenContainer, *this, WTFMove(style));
}
Expand Down

0 comments on commit a9d6d01

Please sign in to comment.