[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

zimmermann at webkit.org zimmermann at webkit.org
Wed Dec 22 11:35:58 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 1c4cfe69713fc1f33cc7c00a8ed4172abc2c6810
Author: zimmermann at webkit.org <zimmermann at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Jul 30 11:02:46 2010 +0000

    2010-07-30  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Dirk Schulze.
    
            Optimize SVGResources memory usage
            https://bugs.webkit.org/show_bug.cgi?id=43236
    
            Instead of storing pointers to all possible resources that could be applied to an element, group them in three categories:
            clipper/filter/masker, marker-start/marker-mid/marker-end, and fill/stroke.
    
            Only build the cached resources data for elements where the properties can be applied to. Maintain a static list of tagnames
            for each of the three categories, to avoid doing unncessary work.
    
            Doesn't affect any tests.
    
            * rendering/SVGResources.cpp:
            (WebCore::SVGResources::SVGResources):
            (WebCore::clipperFilterMaskerTags):
            (WebCore::markerTags):
            (WebCore::fillAndStrokeTags):
            (WebCore::SVGResources::buildCachedResources):
            (WebCore::SVGResources::invalidateClient):
            (WebCore::SVGResources::resourceDestroyed):
            (WebCore::SVGResources::buildSetOfResources):
            (WebCore::SVGResources::setClipper):
            (WebCore::SVGResources::resetClipper):
            (WebCore::SVGResources::setFilter):
            (WebCore::SVGResources::resetFilter):
            (WebCore::SVGResources::setMarkerStart):
            (WebCore::SVGResources::resetMarkerStart):
            (WebCore::SVGResources::setMarkerMid):
            (WebCore::SVGResources::resetMarkerMid):
            (WebCore::SVGResources::setMarkerEnd):
            (WebCore::SVGResources::resetMarkerEnd):
            (WebCore::SVGResources::setMasker):
            (WebCore::SVGResources::resetMasker):
            (WebCore::SVGResources::setFill):
            (WebCore::SVGResources::resetFill):
            (WebCore::SVGResources::setStroke):
            (WebCore::SVGResources::resetStroke):
            (WebCore::SVGResources::dump):
            * rendering/SVGResources.h:
            (WebCore::SVGResources::clipper):
            (WebCore::SVGResources::filter):
            (WebCore::SVGResources::markerStart):
            (WebCore::SVGResources::markerMid):
            (WebCore::SVGResources::markerEnd):
            (WebCore::SVGResources::masker):
            (WebCore::SVGResources::fill):
            (WebCore::SVGResources::stroke):
            (WebCore::SVGResources::ClipperFilterMaskerData::ClipperFilterMaskerData):
            (WebCore::SVGResources::ClipperFilterMaskerData::create):
            (WebCore::SVGResources::MarkerData::MarkerData):
            (WebCore::SVGResources::MarkerData::create):
            (WebCore::SVGResources::FillStrokeData::FillStrokeData):
            (WebCore::SVGResources::FillStrokeData::create):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64345 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e7e067f..8313409 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,60 @@
+2010-07-30  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Optimize SVGResources memory usage
+        https://bugs.webkit.org/show_bug.cgi?id=43236
+
+        Instead of storing pointers to all possible resources that could be applied to an element, group them in three categories:
+        clipper/filter/masker, marker-start/marker-mid/marker-end, and fill/stroke.
+
+        Only build the cached resources data for elements where the properties can be applied to. Maintain a static list of tagnames
+        for each of the three categories, to avoid doing unncessary work.
+
+        Doesn't affect any tests.
+
+        * rendering/SVGResources.cpp:
+        (WebCore::SVGResources::SVGResources):
+        (WebCore::clipperFilterMaskerTags):
+        (WebCore::markerTags):
+        (WebCore::fillAndStrokeTags):
+        (WebCore::SVGResources::buildCachedResources):
+        (WebCore::SVGResources::invalidateClient):
+        (WebCore::SVGResources::resourceDestroyed):
+        (WebCore::SVGResources::buildSetOfResources):
+        (WebCore::SVGResources::setClipper):
+        (WebCore::SVGResources::resetClipper):
+        (WebCore::SVGResources::setFilter):
+        (WebCore::SVGResources::resetFilter):
+        (WebCore::SVGResources::setMarkerStart):
+        (WebCore::SVGResources::resetMarkerStart):
+        (WebCore::SVGResources::setMarkerMid):
+        (WebCore::SVGResources::resetMarkerMid):
+        (WebCore::SVGResources::setMarkerEnd):
+        (WebCore::SVGResources::resetMarkerEnd):
+        (WebCore::SVGResources::setMasker):
+        (WebCore::SVGResources::resetMasker):
+        (WebCore::SVGResources::setFill):
+        (WebCore::SVGResources::resetFill):
+        (WebCore::SVGResources::setStroke):
+        (WebCore::SVGResources::resetStroke):
+        (WebCore::SVGResources::dump):
+        * rendering/SVGResources.h:
+        (WebCore::SVGResources::clipper):
+        (WebCore::SVGResources::filter):
+        (WebCore::SVGResources::markerStart):
+        (WebCore::SVGResources::markerMid):
+        (WebCore::SVGResources::markerEnd):
+        (WebCore::SVGResources::masker):
+        (WebCore::SVGResources::fill):
+        (WebCore::SVGResources::stroke):
+        (WebCore::SVGResources::ClipperFilterMaskerData::ClipperFilterMaskerData):
+        (WebCore::SVGResources::ClipperFilterMaskerData::create):
+        (WebCore::SVGResources::MarkerData::MarkerData):
+        (WebCore::SVGResources::MarkerData::create):
+        (WebCore::SVGResources::FillStrokeData::FillStrokeData):
+        (WebCore::SVGResources::FillStrokeData::create):
+
 2010-07-26  Andrei Popescu  <andreip at google.com>
 
         Reviewed by Jeremy Orlow.
diff --git a/WebCore/rendering/SVGResources.cpp b/WebCore/rendering/SVGResources.cpp
index de23ce1..b6ec75a 100644
--- a/WebCore/rendering/SVGResources.cpp
+++ b/WebCore/rendering/SVGResources.cpp
@@ -32,17 +32,89 @@
 namespace WebCore {
 
 SVGResources::SVGResources()
-    : m_clipper(0)
-#if ENABLE(FILTERS)
-    , m_filter(0)
-#endif
-    , m_markerStart(0)
-    , m_markerMid(0)
-    , m_markerEnd(0)
-    , m_masker(0)
-    , m_fill(0)
-    , m_stroke(0)
+    : m_clipperFilterMaskerData(0)
+    , m_markerData(0)
+    , m_fillStrokeData(0)
+{
+}
+
+static HashSet<AtomicStringImpl*>& clipperFilterMaskerTags()
+{
+    DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+    if (s_tagList.isEmpty()) {
+        // "container elements": http://www.w3.org/TR/SVG11/intro.html#TermContainerElement
+        // "graphics elements" : http://www.w3.org/TR/SVG11/intro.html#TermGraphicsElement
+        s_tagList.add(SVGNames::aTag.localName().impl());
+        s_tagList.add(SVGNames::circleTag.localName().impl());
+        s_tagList.add(SVGNames::ellipseTag.localName().impl());
+        s_tagList.add(SVGNames::glyphTag.localName().impl());
+        s_tagList.add(SVGNames::gTag.localName().impl());
+        s_tagList.add(SVGNames::imageTag.localName().impl());
+        s_tagList.add(SVGNames::lineTag.localName().impl());
+        s_tagList.add(SVGNames::markerTag.localName().impl());
+        s_tagList.add(SVGNames::maskTag.localName().impl());
+        s_tagList.add(SVGNames::missing_glyphTag.localName().impl());
+        s_tagList.add(SVGNames::pathTag.localName().impl());
+        s_tagList.add(SVGNames::polygonTag.localName().impl());
+        s_tagList.add(SVGNames::polylineTag.localName().impl());
+        s_tagList.add(SVGNames::rectTag.localName().impl());
+        s_tagList.add(SVGNames::svgTag.localName().impl());
+        s_tagList.add(SVGNames::textTag.localName().impl());
+        s_tagList.add(SVGNames::useTag.localName().impl());
+
+        // Not listed in the definitions is the clipPath element, the SVG spec says though:
+        // The "clipPath" element or any of its children can specify property "clip-path".
+        // So we have to add clipPathTag here, otherwhise clip-path on clipPath will fail.
+        // (Already mailed SVG WG, waiting for a solution)
+        s_tagList.add(SVGNames::clipPathTag.localName().impl());
+
+        // Not listed in the definitions are the text content elements, though filter/clipper/masker on tspan/text/.. is allowed.
+        // (Already mailed SVG WG, waiting for a solution)
+        s_tagList.add(SVGNames::altGlyphTag.localName().impl());
+        s_tagList.add(SVGNames::textPathTag.localName().impl());
+        s_tagList.add(SVGNames::trefTag.localName().impl());
+        s_tagList.add(SVGNames::tspanTag.localName().impl());
+
+        // Elements that we ignore, as it doesn't make any sense.
+        // defs, pattern, switch (FIXME: Mail SVG WG about these)
+        // symbol (is converted to a svg element, when referenced by use, we can safely ignore it.)
+    }
+
+    return s_tagList;
+}
+
+static HashSet<AtomicStringImpl*>& markerTags()
+{
+    DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+    if (s_tagList.isEmpty()) {
+        s_tagList.add(SVGNames::lineTag.localName().impl());
+        s_tagList.add(SVGNames::pathTag.localName().impl());
+        s_tagList.add(SVGNames::polygonTag.localName().impl());
+        s_tagList.add(SVGNames::polylineTag.localName().impl());
+    }
+
+    return s_tagList;
+}
+
+static HashSet<AtomicStringImpl*>& fillAndStrokeTags()
 {
+    DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+    if (s_tagList.isEmpty()) {
+        s_tagList.add(SVGNames::altGlyphTag.localName().impl());
+        s_tagList.add(SVGNames::circleTag.localName().impl());
+        s_tagList.add(SVGNames::ellipseTag.localName().impl());
+        s_tagList.add(SVGNames::lineTag.localName().impl());
+        s_tagList.add(SVGNames::pathTag.localName().impl());
+        s_tagList.add(SVGNames::polygonTag.localName().impl());
+        s_tagList.add(SVGNames::polylineTag.localName().impl());
+        s_tagList.add(SVGNames::rectTag.localName().impl());
+        s_tagList.add(SVGNames::textTag.localName().impl());
+        s_tagList.add(SVGNames::textPathTag.localName().impl());
+        s_tagList.add(SVGNames::trefTag.localName().impl());
+        s_tagList.add(SVGNames::tspanTag.localName().impl());
+    }
+
+    return s_tagList;
 }
 
 static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, SVGPaint* paint, AtomicString& id, bool& hasPendingResource)
@@ -81,6 +153,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
 
     Node* node = object->node();
     ASSERT(node);
+    ASSERT(node->isElementNode());
 
     Document* document = object->document();
     ASSERT(document);
@@ -88,77 +161,77 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
     SVGDocumentExtensions* extensions = document->accessSVGExtensions();
     ASSERT(extensions);
 
-    bool foundResources = false;
-    if (style->hasClipper()) {
-        AtomicString id(style->clipperResource());
-        m_clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, id);
-        if (m_clipper)
-            foundResources = true;
-        else
-            registerPendingResource(extensions, id, node);
-    }
+    AtomicStringImpl* tagNameImpl = static_cast<Element*>(node)->tagQName().localName().impl();
+    if (!tagNameImpl)
+        return false;
 
-    if (style->hasMasker()) {
-        AtomicString id(style->maskerResource());
-        m_masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, id);
-        if (m_masker)
-            foundResources = true;
-        else
-            registerPendingResource(extensions, id, node);
-    }
+    bool foundResources = false;
+    if (clipperFilterMaskerTags().contains(tagNameImpl)) {
+        if (style->hasClipper()) {
+            AtomicString id(style->clipperResource());
+            if (setClipper(getRenderSVGResourceById<RenderSVGResourceClipper>(document, id)))
+                foundResources = true;
+            else
+                registerPendingResource(extensions, id, node);
+        }
 
 #if ENABLE(FILTERS)
-    if (style->hasFilter()) {
-        AtomicString id(style->filterResource());
-        m_filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, id);
-        if (m_filter)
-            foundResources = true;
-        else
-            registerPendingResource(extensions, id, node);
-    }
+        if (style->hasFilter()) {
+            AtomicString id(style->filterResource());
+            if (setFilter(getRenderSVGResourceById<RenderSVGResourceFilter>(document, id)))
+                foundResources = true;
+            else
+                registerPendingResource(extensions, id, node);
+        }
 #endif
 
-    if (style->hasMarkers()) {
+        if (style->hasMasker()) {
+            AtomicString id(style->maskerResource());
+            if (setMasker(getRenderSVGResourceById<RenderSVGResourceMasker>(document, id)))
+                foundResources = true;
+            else
+                registerPendingResource(extensions, id, node);
+        }
+    }
+
+    if (markerTags().contains(tagNameImpl) && style->hasMarkers()) {
         AtomicString markerStartId(style->markerStartResource());
-        m_markerStart = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerStartId);
-        if (m_markerStart)
+        if (setMarkerStart(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerStartId)))
             foundResources = true;
         else
             registerPendingResource(extensions, markerStartId, node);
 
         AtomicString markerMidId(style->markerMidResource());
-        m_markerMid = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerMidId);
-        if (m_markerMid)
+        if (setMarkerMid(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerMidId)))
             foundResources = true;
         else
             registerPendingResource(extensions, markerMidId, node);
 
         AtomicString markerEndId(style->markerEndResource());
-        m_markerEnd = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerEndId);
-        if (m_markerEnd)
+        if (setMarkerEnd(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerEndId)))
             foundResources = true;
         else
             registerPendingResource(extensions, markerEndId, node);
     }
 
-    if (style->hasFill()) {
-        bool hasPendingResource = false;
-        AtomicString id;
-        m_fill = paintingResourceFromSVGPaint(document, style->fillPaint(), id, hasPendingResource);
-        if (m_fill)
-            foundResources = true;
-        else if (hasPendingResource)
-            registerPendingResource(extensions, id, node);
-    }
+    if (fillAndStrokeTags().contains(tagNameImpl)) {
+        if (style->hasFill()) {
+            bool hasPendingResource = false;
+            AtomicString id;
+            if (setFill(paintingResourceFromSVGPaint(document, style->fillPaint(), id, hasPendingResource)))
+                foundResources = true;
+            else if (hasPendingResource)
+                registerPendingResource(extensions, id, node);
+        }
 
-    if (style->hasStroke()) {
-        bool hasPendingResource = false;
-        AtomicString id;
-        m_stroke = paintingResourceFromSVGPaint(document, style->strokePaint(), id, hasPendingResource);
-        if (m_stroke)
-            foundResources = true;
-        else if (hasPendingResource)
-            registerPendingResource(extensions, id, node);
+        if (style->hasStroke()) {
+            bool hasPendingResource = false;
+            AtomicString id;
+            if (setStroke(paintingResourceFromSVGPaint(document, style->strokePaint(), id, hasPendingResource)))
+                foundResources = true;
+            else if (hasPendingResource)
+                registerPendingResource(extensions, id, node);
+        }
     }
 
     return foundResources;
@@ -166,81 +239,98 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
 
 void SVGResources::invalidateClient(RenderObject* object) const
 {
-    // Ordinary resources
-    if (m_clipper)
-        m_clipper->invalidateClient(object);
+    if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData)
+        return;
+
+    if (m_clipperFilterMaskerData) {
+        if (m_clipperFilterMaskerData->clipper)
+            m_clipperFilterMaskerData->clipper->invalidateClient(object);
 #if ENABLE(FILTERS)
-    if (m_filter)
-        m_filter->invalidateClient(object);
+        if (m_clipperFilterMaskerData->filter)
+            m_clipperFilterMaskerData->filter->invalidateClient(object);
 #endif
-    if (m_masker)
-        m_masker->invalidateClient(object);
-    if (m_markerStart)
-        m_markerStart->invalidateClient(object);
-    if (m_markerMid)
-        m_markerMid->invalidateClient(object);
-    if (m_markerEnd)
-        m_markerEnd->invalidateClient(object);
-
-    // Paint servers
-    if (m_fill)
-        m_fill->invalidateClient(object);
-    if (m_stroke)
-        m_stroke->invalidateClient(object);
+        if (m_clipperFilterMaskerData->masker)
+            m_clipperFilterMaskerData->masker->invalidateClient(object);
+    }
+
+    if (m_markerData) {
+        if (m_markerData->markerStart)
+            m_markerData->markerStart->invalidateClient(object);
+        if (m_markerData->markerMid)
+            m_markerData->markerMid->invalidateClient(object);
+        if (m_markerData->markerEnd)
+            m_markerData->markerEnd->invalidateClient(object);
+    }
+
+    if (m_fillStrokeData) {
+        if (m_fillStrokeData->fill)
+            m_fillStrokeData->fill->invalidateClient(object);
+        if (m_fillStrokeData->stroke)
+            m_fillStrokeData->stroke->invalidateClient(object);
+    }
 }
 
 void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
 {
     ASSERT(resource);
+    if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData)
+        return;
 
     switch (resource->resourceType()) {
     case MaskerResourceType:
-        if (m_masker == resource) {
-            m_masker->invalidateClients();
-            m_masker = 0;
+        if (!m_clipperFilterMaskerData)
+            break;
+        if (m_clipperFilterMaskerData->masker == resource) {
+            m_clipperFilterMaskerData->masker->invalidateClients();
+            m_clipperFilterMaskerData->masker = 0;
         }
         break;
     case MarkerResourceType:
-        if (m_markerStart == resource) {
-            m_markerStart->invalidateClients();
-            m_markerStart = 0;
+        if (!m_markerData)
+            break;
+        if (m_markerData->markerStart == resource) {
+            m_markerData->markerStart->invalidateClients();
+            m_markerData->markerStart = 0;
         }
-
-        if (m_markerMid == resource) {
-            m_markerMid->invalidateClients();
-            m_markerMid = 0;
+        if (m_markerData->markerMid == resource) {
+            m_markerData->markerMid->invalidateClients();
+            m_markerData->markerMid = 0;
         }
-
-        if (m_markerEnd == resource) {
-            m_markerEnd->invalidateClients();
-            m_markerEnd = 0;
+        if (m_markerData->markerEnd == resource) {
+            m_markerData->markerEnd->invalidateClients();
+            m_markerData->markerEnd = 0;
         }
         break;
     case PatternResourceType:
     case LinearGradientResourceType:
     case RadialGradientResourceType:
-        if (m_fill == resource) {
-            m_fill->invalidateClients();
-            m_fill = 0;
+        if (!m_fillStrokeData)
+            break;
+        if (m_fillStrokeData->fill == resource) {
+            m_fillStrokeData->fill->invalidateClients();
+            m_fillStrokeData->fill = 0;
         }
-
-        if (m_stroke == resource) {
-            m_stroke->invalidateClients();
-            m_stroke = 0;
+        if (m_fillStrokeData->stroke == resource) {
+            m_fillStrokeData->stroke->invalidateClients();
+            m_fillStrokeData->stroke = 0;
         }
         break;
 #if ENABLE(FILTERS)
     case FilterResourceType:
-        if (m_filter == resource) {
-            m_filter->invalidateClients();
-            m_filter = 0;
+        if (!m_clipperFilterMaskerData)
+            break;
+        if (m_clipperFilterMaskerData->filter == resource) {
+            m_clipperFilterMaskerData->filter->invalidateClients();
+            m_clipperFilterMaskerData->filter = 0;
         }
         break;
 #endif
     case ClipperResourceType:
-        if (m_clipper == resource) {
-            m_clipper->invalidateClients();
-            m_clipper = 0;
+        if (!m_clipperFilterMaskerData)
+            break; 
+        if (m_clipperFilterMaskerData->clipper == resource) {
+            m_clipperFilterMaskerData->clipper->invalidateClients();
+            m_clipperFilterMaskerData->clipper = 0;
         }
         break;
     case SolidColorResourceType:
@@ -250,77 +340,189 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
 
 void SVGResources::buildSetOfResources(HashSet<RenderSVGResourceContainer*>& set)
 {
-    // Ordinary resources
-    if (m_clipper)
-        set.add(m_clipper);
+    if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData)
+        return;
+
+    if (m_clipperFilterMaskerData) {
+        if (m_clipperFilterMaskerData->clipper)
+            set.add(m_clipperFilterMaskerData->clipper);
 #if ENABLE(FILTERS)
-    if (m_filter)
-        set.add(m_filter);
+        if (m_clipperFilterMaskerData->filter)
+            set.add(m_clipperFilterMaskerData->filter);
 #endif
-    if (m_markerStart)
-        set.add(m_markerStart);
-    if (m_markerMid)
-        set.add(m_markerMid);
-    if (m_markerEnd)
-        set.add(m_markerEnd);
-    if (m_masker)
-        set.add(m_masker);
-
-    // Paint servers 
-    if (m_fill)
-        set.add(m_fill);
-    if (m_stroke)
-        set.add(m_stroke);
+        if (m_clipperFilterMaskerData->masker)
+            set.add(m_clipperFilterMaskerData->masker);
+    }
+
+    if (m_markerData) {
+        if (m_markerData->markerStart)
+            set.add(m_markerData->markerStart);
+        if (m_markerData->markerMid)
+            set.add(m_markerData->markerMid);
+        if (m_markerData->markerEnd)
+            set.add(m_markerData->markerEnd);
+    }
+
+    if (m_fillStrokeData) {
+        if (m_fillStrokeData->fill)
+            set.add(m_fillStrokeData->fill);
+        if (m_fillStrokeData->stroke)
+            set.add(m_fillStrokeData->stroke);
+    }
+}
+
+bool SVGResources::setClipper(RenderSVGResourceClipper* clipper)
+{
+    if (!clipper)
+        return false;
+
+    if (!m_clipperFilterMaskerData)
+        m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
+
+    m_clipperFilterMaskerData->clipper = clipper;
+    return true;
 }
 
 void SVGResources::resetClipper()
 {
-    ASSERT(m_clipper);
-    m_clipper = 0;
+    ASSERT(m_clipperFilterMaskerData);
+    ASSERT(m_clipperFilterMaskerData->clipper);
+    m_clipperFilterMaskerData->clipper = 0;
 }
 
 #if ENABLE(FILTERS)
+bool SVGResources::setFilter(RenderSVGResourceFilter* filter)
+{
+    if (!filter)
+        return false;
+
+    if (!m_clipperFilterMaskerData)
+        m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
+
+    m_clipperFilterMaskerData->filter = filter;
+    return true;
+}
+
 void SVGResources::resetFilter()
 {
-    ASSERT(m_filter);
-    m_filter = 0;
+    ASSERT(m_clipperFilterMaskerData);
+    ASSERT(m_clipperFilterMaskerData->filter);
+    m_clipperFilterMaskerData->filter = 0;
 }
 #endif
 
+bool SVGResources::setMarkerStart(RenderSVGResourceMarker* markerStart)
+{
+    if (!markerStart)
+        return false;
+
+    if (!m_markerData)
+        m_markerData = MarkerData::create();
+
+    m_markerData->markerStart = markerStart;
+    return true;
+}
+
 void SVGResources::resetMarkerStart()
 {
-    ASSERT(m_markerStart);
-    m_markerStart = 0;
+    ASSERT(m_markerData);
+    ASSERT(m_markerData->markerStart);
+    m_markerData->markerStart = 0;
+}
+
+bool SVGResources::setMarkerMid(RenderSVGResourceMarker* markerMid)
+{
+    if (!markerMid)
+        return false;
+
+    if (!m_markerData)
+        m_markerData = MarkerData::create();
+
+    m_markerData->markerMid = markerMid;
+    return true;
 }
 
 void SVGResources::resetMarkerMid()
 {
-    ASSERT(m_markerMid);
-    m_markerMid = 0;
+    ASSERT(m_markerData);
+    ASSERT(m_markerData->markerMid);
+    m_markerData->markerMid = 0;
+}
+
+bool SVGResources::setMarkerEnd(RenderSVGResourceMarker* markerEnd)
+{
+    if (!markerEnd)
+        return false;
+
+    if (!m_markerData)
+        m_markerData = MarkerData::create();
+
+    m_markerData->markerEnd = markerEnd;
+    return true;
 }
 
 void SVGResources::resetMarkerEnd()
 {
-    ASSERT(m_markerEnd);
-    m_markerEnd = 0;
+    ASSERT(m_markerData);
+    ASSERT(m_markerData->markerEnd);
+    m_markerData->markerEnd = 0;
+}
+
+bool SVGResources::setMasker(RenderSVGResourceMasker* masker)
+{
+    if (!masker)
+        return false;
+
+    if (!m_clipperFilterMaskerData)
+        m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
+
+    m_clipperFilterMaskerData->masker = masker;
+    return true;
 }
 
 void SVGResources::resetMasker()
 {
-    ASSERT(m_masker);
-    m_masker = 0;
+    ASSERT(m_clipperFilterMaskerData);
+    ASSERT(m_clipperFilterMaskerData->masker);
+    m_clipperFilterMaskerData->masker = 0;
+}
+
+bool SVGResources::setFill(RenderSVGResourceContainer* fill)
+{
+    if (!fill)
+        return false;
+
+    if (!m_fillStrokeData)
+        m_fillStrokeData = FillStrokeData::create();
+
+    m_fillStrokeData->fill = fill;
+    return true;
 }
 
 void SVGResources::resetFill()
 {
-    ASSERT(m_fill);
-    m_fill = 0;
+    ASSERT(m_fillStrokeData);
+    ASSERT(m_fillStrokeData->fill);
+    m_fillStrokeData->fill = 0;
+}
+
+bool SVGResources::setStroke(RenderSVGResourceContainer* stroke)
+{
+    if (!stroke)
+        return false;
+
+    if (!m_fillStrokeData)
+        m_fillStrokeData = FillStrokeData::create();
+
+    m_fillStrokeData->stroke = stroke;
+    return true;
 }
 
 void SVGResources::resetStroke()
 {
-    ASSERT(m_stroke);
-    m_stroke = 0;
+    ASSERT(m_fillStrokeData);
+    ASSERT(m_fillStrokeData->stroke);
+    m_fillStrokeData->stroke = 0;
 }
 
 #ifndef NDEBUG
@@ -334,24 +536,32 @@ void SVGResources::dump(const RenderObject* object)
     object->node()->showTreeForThis();
 
     fprintf(stderr, "\n | List of resources:\n");
-    if (m_clipper)
-        fprintf(stderr, " |-> Clipper    : %p (node=%p)\n", m_clipper, m_clipper->node());
+    if (m_clipperFilterMaskerData) {
+        if (RenderSVGResourceClipper* clipper = m_clipperFilterMaskerData->clipper)
+            fprintf(stderr, " |-> Clipper    : %p (node=%p)\n", clipper, clipper->node());
 #if ENABLE(FILTERS)
-    if (m_filter)
-        fprintf(stderr, " |-> Filter     : %p (node=%p)\n", m_filter, m_filter->node());
+        if (RenderSVGResourceFilter* filter = m_clipperFilterMaskerData->filter)
+            fprintf(stderr, " |-> Filter     : %p (node=%p)\n", filter, filter->node());
 #endif
-    if (m_markerStart)
-        fprintf(stderr, " |-> MarkerStart: %p (node=%p)\n", m_markerStart, m_markerStart->node());
-    if (m_markerMid)
-        fprintf(stderr, " |-> MarkerMid  : %p (node=%p)\n", m_markerMid, m_markerMid->node());
-    if (m_markerEnd)
-        fprintf(stderr, " |-> MarkerEnd  : %p (node=%p)\n", m_markerEnd, m_markerEnd->node());
-    if (m_masker)
-        fprintf(stderr, " |-> Masker     : %p (node=%p)\n", m_masker, m_masker->node());
-    if (m_fill)
-        fprintf(stderr, " |-> Fill       : %p (node=%p)\n", m_fill, m_fill->node());
-    if (m_stroke)
-        fprintf(stderr, " |-> Stroke     : %p (node=%p)\n", m_stroke, m_stroke->node());
+        if (RenderSVGResourceMasker* masker = m_clipperFilterMaskerData->masker)
+            fprintf(stderr, " |-> Masker     : %p (node=%p)\n", masker, masker->node());
+    }
+
+    if (m_markerData) {
+        if (RenderSVGResourceMarker* markerStart = m_markerData->markerStart)
+            fprintf(stderr, " |-> MarkerStart: %p (node=%p)\n", markerStart, markerStart->node());
+        if (RenderSVGResourceMarker* markerMid = m_markerData->markerMid)
+            fprintf(stderr, " |-> MarkerMid  : %p (node=%p)\n", markerMid, markerMid->node());
+        if (RenderSVGResourceMarker* markerEnd = m_markerData->markerEnd)
+            fprintf(stderr, " |-> MarkerEnd  : %p (node=%p)\n", markerEnd, markerEnd->node());
+    }
+
+    if (m_fillStrokeData) {
+        if (RenderSVGResourceContainer* fill = m_fillStrokeData->fill)
+            fprintf(stderr, " |-> Fill       : %p (node=%p)\n", fill, fill->node());
+        if (RenderSVGResourceContainer* stroke = m_fillStrokeData->stroke)
+            fprintf(stderr, " |-> Stroke     : %p (node=%p)\n", stroke, stroke->node());
+    }
 }
 #endif
 
diff --git a/WebCore/rendering/SVGResources.h b/WebCore/rendering/SVGResources.h
index 57a4140..0486758 100644
--- a/WebCore/rendering/SVGResources.h
+++ b/WebCore/rendering/SVGResources.h
@@ -23,6 +23,8 @@
 #if ENABLE(SVG)
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
 
 namespace WebCore {
 
@@ -43,18 +45,18 @@ public:
     bool buildCachedResources(const RenderObject*, const SVGRenderStyle*);
 
     // Ordinary resources
-    RenderSVGResourceClipper* clipper() const { return m_clipper; }
+    RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : 0; }
 #if ENABLE(FILTERS)
-    RenderSVGResourceFilter* filter() const { return m_filter; }
+    RenderSVGResourceFilter* filter() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->filter : 0; }
 #endif
-    RenderSVGResourceMarker* markerStart() const { return m_markerStart; }
-    RenderSVGResourceMarker* markerMid() const { return m_markerMid; }
-    RenderSVGResourceMarker* markerEnd() const { return m_markerEnd; }
-    RenderSVGResourceMasker* masker() const { return m_masker; }
+    RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : 0; }
+    RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : 0; }
+    RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : 0; }
+    RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : 0; }
 
     // Paint servers
-    RenderSVGResourceContainer* fill() const { return m_fill; }
-    RenderSVGResourceContainer* stroke() const { return m_stroke; }
+    RenderSVGResourceContainer* fill() const { return m_fillStrokeData ? m_fillStrokeData->fill : 0; }
+    RenderSVGResourceContainer* stroke() const { return m_fillStrokeData ? m_fillStrokeData->stroke : 0; }
 
     void buildSetOfResources(HashSet<RenderSVGResourceContainer*>&);
 
@@ -82,19 +84,87 @@ private:
     void resetStroke();
 
 private:
-    // Ordinary resources
-    RenderSVGResourceClipper* m_clipper;
+    bool setClipper(RenderSVGResourceClipper*);
+#if ENABLE(FILTERS)
+    bool setFilter(RenderSVGResourceFilter*);
+#endif
+    bool setMarkerStart(RenderSVGResourceMarker*);
+    bool setMarkerMid(RenderSVGResourceMarker*);
+    bool setMarkerEnd(RenderSVGResourceMarker*);
+    bool setMasker(RenderSVGResourceMasker*);
+    bool setFill(RenderSVGResourceContainer*);
+    bool setStroke(RenderSVGResourceContainer*);
+
+    // From SVG 1.1 2nd Edition
+    // clipper: 'container elements' and 'graphics elements'
+    // filter:  'container elements' and 'graphics elements'
+    // masker:  'container elements' and 'graphics elements'
+    // -> a, circle, defs, ellipse, glyph, g, image, line, marker, mask, missing-glyph, path, pattern, polygon, polyline, rect, svg, switch, symbol, text, use
+    struct ClipperFilterMaskerData {
+        ClipperFilterMaskerData()
+            : clipper(0)
 #if ENABLE(FILTERS)
-    RenderSVGResourceFilter* m_filter;
+            , filter(0)
 #endif
-    RenderSVGResourceMarker* m_markerStart;
-    RenderSVGResourceMarker* m_markerMid;
-    RenderSVGResourceMarker* m_markerEnd;
-    RenderSVGResourceMasker* m_masker;
+            , masker(0)
+        {
+        }
 
-    // Paint servers
-    RenderSVGResourceContainer* m_fill;
-    RenderSVGResourceContainer* m_stroke;
+        static PassOwnPtr<ClipperFilterMaskerData> create()
+        {
+            return new ClipperFilterMaskerData;
+        }
+
+        RenderSVGResourceClipper* clipper;
+#if ENABLE(FILTERS)
+        RenderSVGResourceFilter* filter;
+#endif
+        RenderSVGResourceMasker* masker;
+    };
+
+    // From SVG 1.1 2nd Edition
+    // marker: line, path, polygon, polyline
+    struct MarkerData {
+        MarkerData()
+            : markerStart(0)
+            , markerMid(0)
+            , markerEnd(0)
+        {
+        }
+
+        static PassOwnPtr<MarkerData> create()
+        {
+            return new MarkerData;
+        }
+
+        RenderSVGResourceMarker* markerStart;
+        RenderSVGResourceMarker* markerMid;
+        RenderSVGResourceMarker* markerEnd;
+    };
+
+    // From SVG 1.1 2nd Edition
+    // fill:       'shapes' and 'text content elements'
+    // stroke:     'shapes' and 'text content elements'
+    // -> altGlyph, circle, ellipse, line, path, polygon, polyline, rect, text, textPath, tref, tspan
+    struct FillStrokeData {
+        FillStrokeData()
+            : fill(0)
+            , stroke(0)
+        {
+        }
+
+        static PassOwnPtr<FillStrokeData> create()
+        {
+            return new FillStrokeData;
+        }
+
+        RenderSVGResourceContainer* fill;
+        RenderSVGResourceContainer* stroke;
+    };
+
+    OwnPtr<ClipperFilterMaskerData> m_clipperFilterMaskerData;
+    OwnPtr<MarkerData> m_markerData;
+    OwnPtr<FillStrokeData> m_fillStrokeData;
 };
 
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list