Title: [132809] branches/chromium/1271

Diff

Copied: branches/chromium/1271/LayoutTests/svg/filters/feImage-self-referencing-expected.html (from rev 131488, trunk/LayoutTests/svg/filters/feImage-self-referencing-expected.html) (0 => 132809)


--- branches/chromium/1271/LayoutTests/svg/filters/feImage-self-referencing-expected.html	                        (rev 0)
+++ branches/chromium/1271/LayoutTests/svg/filters/feImage-self-referencing-expected.html	2012-10-29 16:56:11 UTC (rev 132809)
@@ -0,0 +1,6 @@
+<html>
+  <body>
+    <p>PASS if no crash</p>
+  </body>
+</html>
+

Copied: branches/chromium/1271/LayoutTests/svg/filters/feImage-self-referencing.html (from rev 131488, trunk/LayoutTests/svg/filters/feImage-self-referencing.html) (0 => 132809)


--- branches/chromium/1271/LayoutTests/svg/filters/feImage-self-referencing.html	                        (rev 0)
+++ branches/chromium/1271/LayoutTests/svg/filters/feImage-self-referencing.html	2012-10-29 16:56:11 UTC (rev 132809)
@@ -0,0 +1,23 @@
+<html>
+  <head>
+    <script>
+      _onload_ = function() {
+        document.getElementById("feImage").setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#svgRoot')
+      }
+    </script>
+  </head>
+  <body>
+    <p>PASS if no crash</p>
+    <svg width="10" height="10" id="svgRoot" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+      <g>
+        <defs>
+          <filter id="imageFilter">
+            <feImage id="feImage" />
+            <feOffset dx="50" dy="50" />
+          </filter>
+        </defs>
+        <rect filter="url(#imageFilter)" x="0" y="0" width="50" height="50" fill="green" />
+      </g>
+    </svg>
+  </body>
+</html>

Modified: branches/chromium/1271/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (132808 => 132809)


--- branches/chromium/1271/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2012-10-29 16:50:06 UTC (rev 132808)
+++ branches/chromium/1271/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2012-10-29 16:56:11 UTC (rev 132809)
@@ -57,6 +57,25 @@
 
 namespace WebCore {
 
+class ApplyingFilterEffectGuard {
+public:
+    ApplyingFilterEffectGuard(FilterData* data)
+        : m_filterData(data)
+    {
+        // The guard must be constructed when the filter is not applying.
+        ASSERT(!m_filterData->isApplying);
+        m_filterData->isApplying = true;
+    }
+
+    ~ApplyingFilterEffectGuard()
+    {
+        ASSERT(m_filterData->isApplying);
+        m_filterData->isApplying = false;
+    }
+
+    FilterData* m_filterData;
+};
+
 RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceType;
 
 RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node)
@@ -153,7 +172,7 @@
     // draw the stored filter output, not the unfiltered object as well.
     if (m_filter.contains(object)) {
         FilterData* filterData = m_filter.get(object);
-        if (filterData->builded)
+        if (filterData->isBuilt || filterData->isApplying)
             return false;
 
         delete m_filter.take(object); // Oops, have to rebuild, go through normal code path
@@ -278,7 +297,12 @@
         return;
     }
 
-    if (!filterData->builded) {
+    // We have a cycle if we are already applying the data.
+    // This can occur due to FeImage referencing a source that makes use of the FEImage itself.
+    if (filterData->isApplying)
+        return;
+
+    if (!filterData->isBuilt) {
         if (!filterData->savedContext) {
             removeClientFromCache(object);
             return;
@@ -288,16 +312,18 @@
         filterData->savedContext = 0;
     }
 
+    ApplyingFilterEffectGuard isApplyingGuard(filterData);
+
     FilterEffect* lastEffect = filterData->builder->lastEffect();
 
     if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPrimitiveSubregion().isEmpty()) {
         // This is the real filtering of the object. It just needs to be called on the
         // initial filtering process. We just take the stored filter result on a
         // second drawing.
-        if (!filterData->builded)
+        if (!filterData->isBuilt)
             filterData->filter->setSourceImage(filterData->sourceGraphicBuffer.release());
 
-        // Always true if filterData is just built (filterData->builded is false).
+        // Always true if filterData is just built (filterData->isBuilt is false).
         if (!lastEffect->hasResult()) {
             lastEffect->apply();
             lastEffect->correctFilterResultIfNeeded();
@@ -307,7 +333,7 @@
                 resultImage->transformColorSpace(lastEffect->colorSpace(), ColorSpaceDeviceRGB);
 #endif
         }
-        filterData->builded = true;
+        filterData->isBuilt = true;
 
         ImageBuffer* resultImage = lastEffect->asImageBuffer();
         if (resultImage) {
@@ -339,7 +365,7 @@
 
     for (; it != end; ++it) {
         FilterData* filterData = it->second;
-        if (!filterData->builded)
+        if (!filterData->isBuilt)
             continue;
 
         SVGFilterBuilder* builder = filterData->builder.get();

Modified: branches/chromium/1271/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h (132808 => 132809)


--- branches/chromium/1271/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h	2012-10-29 16:50:06 UTC (rev 132808)
+++ branches/chromium/1271/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h	2012-10-29 16:56:11 UTC (rev 132809)
@@ -44,7 +44,8 @@
 public:
     FilterData()
         : savedContext(0)
-        , builded(false)
+        , isBuilt(false)
+        , isApplying(false)
         , markedForRemoval(false)
     {
     }
@@ -56,7 +57,8 @@
     AffineTransform shearFreeAbsoluteTransform;
     FloatRect boundaries;
     FloatSize scale;
-    bool builded : 1;
+    bool isBuilt : 1;
+    bool isApplying : 1;
     bool markedForRemoval : 1;
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to