feImage doesn't invalidate when its target SVG element is animated
authorzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Feb 2012 12:12:31 +0000 (12:12 +0000)
committerzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Feb 2012 12:12:31 +0000 (12:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=73860

Reviewed by Dirk Schulze.

Source/WebCore:

Consider following testcase:
<defs>
    <rect id="rect" fill="red" width="50" height="50"/>
    <filter id="filter">
        <feImage xlink:href="#rect"/>
    </filter>
</defs>
<rect width="50" height="50" filter="url(#filter)"/>

If the <rect id="rect"> gets changed dynamically (attribute/property/style change) the <feImage>
doesn't notice this, as there's no link between the <rect> and the <feImage>, as the <rect> is not
a child of the <feImage/>. To get invalidations working for these situations, we have to track
the referencingElement & referencedElement in SVGDocumentExtensions.

Fixes parts the SVG-Wow twirl testcase and David Daileys SVG waves example.

Tests: svg/filters/feImage-animated-transform-on-target-rect.svg
       svg/filters/feImage-late-indirect-update.svg
       svg/filters/feImage-mutliple-targets-id-change.svg
       svg/filters/feImage-target-attribute-change-with-use-indirection-2.svg
       svg/filters/feImage-target-attribute-change-with-use-indirection.svg
       svg/filters/feImage-target-attribute-change.svg
       svg/filters/feImage-target-inline-style-change.svg
       svg/filters/feImage-target-property-change.svg
       svg/filters/feImage-target-style-change.svg

* rendering/svg/RenderSVGResource.cpp:
(WebCore::removeFromFilterCacheAndInvalidateDependencies): Renamed from removeFromFilterCache, as it has another purpose now.
(WebCore::RenderSVGResource::markForLayoutAndParentResourceInvalidation): s/removeFromFilterCache/removeFromFilterCacheAndInvalidateDependencies/.
* rendering/svg/RenderSVGResource.h: Removed removeFromFilterCache, it got inlined.
* svg/SVGDocumentExtensions.cpp: Add a new HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > > used for dependency tracking.
(WebCore::SVGDocumentExtensions::setOfElementsReferencingTarget): Returns all elements the passed in element depends on.
(WebCore::SVGDocumentExtensions::addElementReferencingTarget): Register element 'a' referencing target 'b'.
(WebCore::SVGDocumentExtensions::removeAllTargetReferencesForElement): Called by element 'a' on destruction or any target change.
(WebCore::SVGDocumentExtensions::removeAllElementReferencesForTarget): Called by element 'b' on destruction.
* svg/SVGDocumentExtensions.h: Expose new methods.
* svg/SVGElement.cpp:
(WebCore::SVGElement::~SVGElement): Call remove removeAllElementReferencesForTarget on destruction.
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::clearResourceReferences):
(WebCore::SVGFEImageElement::buildPendingResource):

LayoutTests:

Add lots of new testcases covering <feImage> invalidation, when the referenced target changes.
Thanks to the repaint harness, it uncovered a bug with feImage-late-indirect-update.svg - there no gray
overlay rects are visible, as the whole screen gets repainted, which is a bug!

* platform/mac/svg/filters/feImage-animated-transform-on-target-rect-expected.png: Added.
* platform/mac/svg/filters/feImage-change-target-id-expected.png: Added.
* platform/mac/svg/filters/feImage-change-target-id-expected.txt: Added.
* platform/mac/svg/filters/feImage-late-indirect-update-expected.png: Added.
* platform/mac/svg/filters/feImage-late-indirect-update-expected.txt: Added.
* platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.png: Added.
* platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.txt: Added.
* platform/mac/svg/filters/feImage-remove-target-expected.png: Added.
* platform/mac/svg/filters/feImage-remove-target-expected.txt: Added.
* platform/mac/svg/filters/feImage-target-add-to-document-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-add-to-document-expected.png.
* platform/mac/svg/filters/feImage-target-add-to-document-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-add-to-document-expected.txt.
* platform/mac/svg/filters/feImage-target-attribute-change-expected.png: Added.
* platform/mac/svg/filters/feImage-target-attribute-change-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
* platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-2-expected.png: Added.
* platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-2-expected.txt: Added.
* platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-expected.png: Added.
* platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-expected.txt: Added.
* platform/mac/svg/filters/feImage-target-changes-id-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-changes-id-expected.png.
* platform/mac/svg/filters/feImage-target-changes-id-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
* platform/mac/svg/filters/feImage-target-id-change-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-id-change-expected.png.
* platform/mac/svg/filters/feImage-target-id-change-expected.txt: Renamed from LayoutTests/svg/filters/feImage-target-id-change-expected.txt.
* platform/mac/svg/filters/feImage-target-inline-style-change-expected.png: Added.
* platform/mac/svg/filters/feImage-target-inline-style-change-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
* platform/mac/svg/filters/feImage-target-property-change-expected.png: Added.
* platform/mac/svg/filters/feImage-target-property-change-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
* platform/mac/svg/filters/feImage-target-reappend-to-document-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.png.
* platform/mac/svg/filters/feImage-target-reappend-to-document-expected.txt: Renamed from LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.txt.
* platform/mac/svg/filters/feImage-target-remove-from-document-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-remove-from-document-expected.png.
* platform/mac/svg/filters/feImage-target-remove-from-document-expected.txt: Renamed from LayoutTests/svg/filters/feImage-target-remove-from-document-expected.txt.
* platform/mac/svg/filters/feImage-target-style-change-expected.png: Added.
* platform/mac/svg/filters/feImage-target-style-change-expected.txt: Renamed from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
* svg/filters/feImage-animated-transform-on-target-rect-expected.txt: Added.
* svg/filters/feImage-animated-transform-on-target-rect.svg: Added.
* svg/filters/feImage-change-target-id.svg: Added.
* svg/filters/feImage-late-indirect-update.svg: Added.
* svg/filters/feImage-multiple-targets-id-change.svg: Added.
* svg/filters/feImage-remove-target.svg: Added.
* svg/filters/feImage-target-attribute-change-with-use-indirection-2.svg: Added.
* svg/filters/feImage-target-attribute-change-with-use-indirection.svg: Added.
* svg/filters/feImage-target-attribute-change.svg: Added.
* svg/filters/feImage-target-inline-style-change.svg: Added.
* svg/filters/feImage-target-property-change.svg: Added.
* svg/filters/feImage-target-style-change.svg: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@107067 268f45cc-cd09-0410-ab3c-d52691b4dbfc

52 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/chromium/test_expectations.txt
LayoutTests/platform/mac/svg/filters/feImage-animated-transform-on-target-rect-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-change-target-id-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-change-target-id-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-late-indirect-update-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-late-indirect-update-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-remove-target-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-remove-target-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-add-to-document-expected.png [moved from LayoutTests/svg/filters/feImage-target-add-to-document-expected.png with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-add-to-document-expected.txt [moved from LayoutTests/svg/filters/feImage-target-add-to-document-expected.txt with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-expected.png [moved from LayoutTests/svg/filters/feImage-target-remove-from-document-expected.png with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-expected.txt [moved from LayoutTests/svg/filters/feImage-target-id-change-expected.txt with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-2-expected.png [moved from LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.png with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-2-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-expected.png [moved from LayoutTests/svg/filters/feImage-target-id-change-expected.png with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-changes-id-expected.png [moved from LayoutTests/svg/filters/feImage-target-changes-id-expected.png with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-changes-id-expected.txt [moved from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-id-change-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-id-change-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-inline-style-change-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-inline-style-change-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-property-change-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-property-change-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-reappend-to-document-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-reappend-to-document-expected.txt [moved from LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.txt with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-remove-from-document-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-remove-from-document-expected.txt [moved from LayoutTests/svg/filters/feImage-target-remove-from-document-expected.txt with 100% similarity]
LayoutTests/platform/mac/svg/filters/feImage-target-style-change-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/svg/filters/feImage-target-style-change-expected.txt [new file with mode: 0644]
LayoutTests/svg/filters/feImage-animated-transform-on-target-rect-expected.txt [new file with mode: 0644]
LayoutTests/svg/filters/feImage-animated-transform-on-target-rect.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-change-target-id.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-late-indirect-update.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-multiple-targets-id-change.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-remove-target.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-attribute-change-with-use-indirection-2.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-attribute-change-with-use-indirection.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-attribute-change.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-inline-style-change.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-property-change.svg [new file with mode: 0644]
LayoutTests/svg/filters/feImage-target-style-change.svg [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/svg/RenderSVGResource.cpp
Source/WebCore/rendering/svg/RenderSVGResource.h
Source/WebCore/svg/SVGDocumentExtensions.cpp
Source/WebCore/svg/SVGDocumentExtensions.h
Source/WebCore/svg/SVGElement.cpp
Source/WebCore/svg/SVGFEImageElement.cpp

index 9acea59..adfef70 100644 (file)
@@ -1,3 +1,58 @@
+2012-02-08  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        feImage doesn't invalidate when its target SVG element is animated
+        https://bugs.webkit.org/show_bug.cgi?id=73860
+
+        Reviewed by Dirk Schulze.
+
+        Add lots of new testcases covering <feImage> invalidation, when the referenced target changes.
+        Thanks to the repaint harness, it uncovered a bug with feImage-late-indirect-update.svg - there no gray
+        overlay rects are visible, as the whole screen gets repainted, which is a bug!
+
+        * platform/mac/svg/filters/feImage-animated-transform-on-target-rect-expected.png: Added.
+        * platform/mac/svg/filters/feImage-change-target-id-expected.png: Added.
+        * platform/mac/svg/filters/feImage-change-target-id-expected.txt: Added.
+        * platform/mac/svg/filters/feImage-late-indirect-update-expected.png: Added.
+        * platform/mac/svg/filters/feImage-late-indirect-update-expected.txt: Added.
+        * platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.png: Added.
+        * platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.txt: Added.
+        * platform/mac/svg/filters/feImage-remove-target-expected.png: Added.
+        * platform/mac/svg/filters/feImage-remove-target-expected.txt: Added.
+        * platform/mac/svg/filters/feImage-target-add-to-document-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-add-to-document-expected.png.
+        * platform/mac/svg/filters/feImage-target-add-to-document-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-add-to-document-expected.txt.
+        * platform/mac/svg/filters/feImage-target-attribute-change-expected.png: Added.
+        * platform/mac/svg/filters/feImage-target-attribute-change-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
+        * platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-2-expected.png: Added.
+        * platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-2-expected.txt: Added.
+        * platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-expected.png: Added.
+        * platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-expected.txt: Added.
+        * platform/mac/svg/filters/feImage-target-changes-id-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-changes-id-expected.png.
+        * platform/mac/svg/filters/feImage-target-changes-id-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
+        * platform/mac/svg/filters/feImage-target-id-change-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-id-change-expected.png.
+        * platform/mac/svg/filters/feImage-target-id-change-expected.txt: Renamed from LayoutTests/svg/filters/feImage-target-id-change-expected.txt.
+        * platform/mac/svg/filters/feImage-target-inline-style-change-expected.png: Added.
+        * platform/mac/svg/filters/feImage-target-inline-style-change-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
+        * platform/mac/svg/filters/feImage-target-property-change-expected.png: Added.
+        * platform/mac/svg/filters/feImage-target-property-change-expected.txt: Copied from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
+        * platform/mac/svg/filters/feImage-target-reappend-to-document-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.png.
+        * platform/mac/svg/filters/feImage-target-reappend-to-document-expected.txt: Renamed from LayoutTests/svg/filters/feImage-target-reappend-to-document-expected.txt.
+        * platform/mac/svg/filters/feImage-target-remove-from-document-expected.png: Renamed from LayoutTests/svg/filters/feImage-target-remove-from-document-expected.png.
+        * platform/mac/svg/filters/feImage-target-remove-from-document-expected.txt: Renamed from LayoutTests/svg/filters/feImage-target-remove-from-document-expected.txt.
+        * platform/mac/svg/filters/feImage-target-style-change-expected.png: Added.
+        * platform/mac/svg/filters/feImage-target-style-change-expected.txt: Renamed from LayoutTests/svg/filters/feImage-target-changes-id-expected.txt.
+        * svg/filters/feImage-animated-transform-on-target-rect-expected.txt: Added.
+        * svg/filters/feImage-animated-transform-on-target-rect.svg: Added.
+        * svg/filters/feImage-change-target-id.svg: Added.
+        * svg/filters/feImage-late-indirect-update.svg: Added.
+        * svg/filters/feImage-multiple-targets-id-change.svg: Added.
+        * svg/filters/feImage-remove-target.svg: Added.
+        * svg/filters/feImage-target-attribute-change-with-use-indirection-2.svg: Added.
+        * svg/filters/feImage-target-attribute-change-with-use-indirection.svg: Added.
+        * svg/filters/feImage-target-attribute-change.svg: Added.
+        * svg/filters/feImage-target-inline-style-change.svg: Added.
+        * svg/filters/feImage-target-property-change.svg: Added.
+        * svg/filters/feImage-target-style-change.svg: Added.
+
 2012-02-08  Csaba Osztrogonác  <ossy@webkit.org>
 
         [Qt] Unreviewed gardening. Unskip now passing tests, skip failing tests and one update.
index c78e25c..1f89e96 100644 (file)
@@ -4050,5 +4050,18 @@ BUGWK78084 : svg/custom/repaint-on-image-bounds-change.svg = IMAGE+TEXT
 BUGWK78084 : svg/custom/text-ctm.svg = IMAGE+TEXT
 BUGWK78084 : svg/custom/text-hit-test.svg = IMAGE+TEXT
 
+// feImage now supports dynamic invalidations if the target changes.
+BUGWK73860 : svg/filters/feImage-animated-transform-on-target-rect.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-change-target-id.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-late-indirect-update.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-multiple-targets-id-change.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-remove-target.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-target-attribute-change-with-use-indirection-2.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-target-attribute-change-with-use-indirection.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-target-attribute-change.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-target-inline-style-change.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-target-property-change.svg = IMAGE+TEXT
+BUGWK73860 : svg/filters/feImage-target-style-change.svg = IMAGE+TEXT
+
 BUGWK78038 DEBUG : compositing/iframes/invisible-nested-iframe-show.html = PASS CRASH
 BUGWK78038 DEBUG : compositing/iframes/layout-on-compositing-change.html = PASS CRASH
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-animated-transform-on-target-rect-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-animated-transform-on-target-rect-expected.png
new file mode 100644 (file)
index 0000000..e91efa8
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-animated-transform-on-target-rect-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-change-target-id-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-change-target-id-expected.png
new file mode 100644 (file)
index 0000000..eb45e94
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-change-target-id-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-change-target-id-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-change-target-id-expected.txt
new file mode 100644 (file)
index 0000000..cffc1e3
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="0x0"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-late-indirect-update-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-late-indirect-update-expected.png
new file mode 100644 (file)
index 0000000..1f3e66d
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-late-indirect-update-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-late-indirect-update-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-late-indirect-update-expected.txt
new file mode 100644 (file)
index 0000000..a519293
--- /dev/null
@@ -0,0 +1,12 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 800x600
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGResourceLinearGradient {linearGradient} [id="gradient"] [gradientUnits=objectBoundingBox] [start=(0,0)] [end=(1,1)]
+        RenderSVGGradientStop {stop} [offset=0.00] [color=#008000]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="400x300"]
+      RenderSVGPath {ellipse} at (200,150) size 400x300 [fill={[type=LINEAR-GRADIENT] [id="gradient"]}] [cx=400.00] [cy=300.00] [rx=200.00] [ry=150.00]
+    RenderSVGRect {rect} at (0,0) size 800x600 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=800.00] [height=600.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-80,-60) size 960x720
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.png
new file mode 100644 (file)
index 0000000..c065d27
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-multiple-targets-id-change-expected.txt
new file mode 100644 (file)
index 0000000..44c1a4c
--- /dev/null
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 105x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="image1"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+      RenderSVGResourceFilter {filter} [id="image2"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 56x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=50.00] [height=100.00]
+      [filter="image1"] RenderSVGResourceFilter {filter} at (-5,-10) size 60x120
+    RenderSVGRect {rect} at (45,0) size 60x111 [fill={[type=SOLID] [color=#000000]}] [x=50.00] [y=0.00] [width=50.00] [height=100.00]
+      [filter="image2"] RenderSVGResourceFilter {filter} at (45,-10) size 60x120
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-remove-target-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-remove-target-expected.png
new file mode 100644 (file)
index 0000000..eb45e94
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-remove-target-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-remove-target-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-remove-target-expected.txt
new file mode 100644 (file)
index 0000000..1c71cd3
--- /dev/null
@@ -0,0 +1,9 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="0x0"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-2-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-2-expected.txt
new file mode 100644 (file)
index 0000000..4d186eb
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 50x100 [fill={[type=SOLID] [color=#008000]}] [x=-50.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGContainer {use} at (0,0) size 100x100
+        RenderSVGContainer {g} at (0,0) size 100x100 [transform={m=((1.00,0.00)(0.00,1.00)) t=(50.00,0.00)}]
+          RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=-50.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-target-attribute-change-with-use-indirection-expected.txt
new file mode 100644 (file)
index 0000000..8a1bdff
--- /dev/null
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGContainer {use} at (0,0) size 100x100
+        RenderSVGContainer {g} at (0,0) size 100x100
+          RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-id-change-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-target-id-change-expected.png
new file mode 100644 (file)
index 0000000..8834406
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-target-id-change-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-id-change-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-target-id-change-expected.txt
new file mode 100644 (file)
index 0000000..96cc36d
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-inline-style-change-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-target-inline-style-change-expected.png
new file mode 100644 (file)
index 0000000..8834406
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-target-inline-style-change-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-inline-style-change-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-target-inline-style-change-expected.txt
new file mode 100644 (file)
index 0000000..96cc36d
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-property-change-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-target-property-change-expected.png
new file mode 100644 (file)
index 0000000..8834406
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-target-property-change-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-property-change-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-target-property-change-expected.txt
new file mode 100644 (file)
index 0000000..96cc36d
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-reappend-to-document-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-target-reappend-to-document-expected.png
new file mode 100644 (file)
index 0000000..8834406
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-target-reappend-to-document-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-remove-from-document-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-target-remove-from-document-expected.png
new file mode 100644 (file)
index 0000000..8834406
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-target-remove-from-document-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-style-change-expected.png b/LayoutTests/platform/mac/svg/filters/feImage-target-style-change-expected.png
new file mode 100644 (file)
index 0000000..8834406
Binary files /dev/null and b/LayoutTests/platform/mac/svg/filters/feImage-target-style-change-expected.png differ
diff --git a/LayoutTests/platform/mac/svg/filters/feImage-target-style-change-expected.txt b/LayoutTests/platform/mac/svg/filters/feImage-target-style-change-expected.txt
new file mode 100644 (file)
index 0000000..96cc36d
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (0,0) size 111x111
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGRect {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
+        [feImage image-size="100x100"]
+    RenderSVGRect {rect} at (0,0) size 111x111 [fill={[type=SOLID] [color=#000000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
+      [filter="filter"] RenderSVGResourceFilter {filter} at (-10,-10) size 120x120
diff --git a/LayoutTests/svg/filters/feImage-animated-transform-on-target-rect-expected.txt b/LayoutTests/svg/filters/feImage-animated-transform-on-target-rect-expected.txt
new file mode 100644 (file)
index 0000000..55488db
--- /dev/null
@@ -0,0 +1,2 @@
+Passes if rect is not rotated
+
diff --git a/LayoutTests/svg/filters/feImage-animated-transform-on-target-rect.svg b/LayoutTests/svg/filters/feImage-animated-transform-on-target-rect.svg
new file mode 100644 (file)
index 0000000..26917b8
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <defs>
+        <rect id="rect" fill="green" width="50" height="50" transform="rotate(45)">
+            <animateTransform id="animation" attributeName="transform" type="rotate" calcMode="discrete" begin="indefinite" from="45" to="0" dur="0.1s" fill="freeze"/>
+        </rect>
+
+        <filter id="filter">
+            <feImage xlink:href="#rect"/>
+        </filter>
+    </defs>
+    <text y="-50">Passes if rect is not rotated</text>
+    <rect fill="red" x="50" y="50" width="50" height="50" filter="url(#filter)"/>
+
+<script><![CDATA[
+    function repaintTest() {
+        if (window.layoutTestController)
+          layoutTestController.waitUntilDone();
+
+        document.getElementById("animation").beginElement();
+        setTimeout(finishTest, 50);
+
+        function finishTest() {    
+          // Wait for the animation to finish
+          if (document.getElementById("rect").transform.animVal.getItem(0).matrix.a != 1) {
+            setTimeout(finishTest, 50);
+            return;
+          }
+
+          if (window.layoutTestController)
+            layoutTestController.notifyDone();
+        }
+    }
+
+    if (window.layoutTestController)
+        layoutTestController.dumpAsText(true);
+]]></script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-change-target-id.svg b/LayoutTests/svg/filters/feImage-change-target-id.svg
new file mode 100644 (file)
index 0000000..0113c80
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <title>Nothing should be rendered</title>
+    <defs>
+        <rect id="rect" width="100" height="100" fill="green"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#rect" />
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function repaintTest() {
+            document.getElementById("rect").setAttribute("id", "away");
+        }
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-late-indirect-update.svg b/LayoutTests/svg/filters/feImage-late-indirect-update.svg
new file mode 100644 (file)
index 0000000..458ca6c
--- /dev/null
@@ -0,0 +1,20 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+<script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+<defs>
+    <linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="1">
+        <stop id="stop" stop-color="red" offset="0"/>
+    </linearGradient>
+
+    <filter id="filter" >
+        <feImage xlink:href="#ellipse"/>
+    </filter>
+    <ellipse id="ellipse" cx="50%" cy="50%" rx="25%" ry="25%" fill="url(#gradient)"/>
+</defs>
+<rect width="100%" height="100%" filter='url(#filter)'/>
+
+<script>
+function repaintTest() {
+    document.getElementById("stop").setAttribute("stop-color", "green");
+}
+</script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-multiple-targets-id-change.svg b/LayoutTests/svg/filters/feImage-multiple-targets-id-change.svg
new file mode 100644 (file)
index 0000000..1e9d0ae
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="rect" width="1" height="100" fill="green"/>
+
+        <filter id="image1">
+            <feImage id="feimage1" xlink:href="#rect" />
+        </filter>
+
+        <filter id="image2">
+            <feImage id="feimage2" xlink:href="#rect" />
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="50" height="100" filter="url(#image1)" />
+    <rect x="50" y="0" width="50" height="100" filter="url(#image2)" />
+    <script>
+    <![CDATA[
+        function repaintTest() {
+            document.getElementById("rect").setAttribute("width", "100");
+        }
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-remove-target.svg b/LayoutTests/svg/filters/feImage-remove-target.svg
new file mode 100644 (file)
index 0000000..9b89c97
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <title>Nothing should be rendered</title>
+    <defs>
+        <rect id="rect" width="100" height="100" fill="green"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#rect" />
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function repaintTest() {
+            var rect = document.getElementById("rect");
+            rect.parentNode.removeChild(rect);
+        }
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-attribute-change-with-use-indirection-2.svg b/LayoutTests/svg/filters/feImage-target-attribute-change-with-use-indirection-2.svg
new file mode 100644 (file)
index 0000000..11205a1
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="rect" x="-50" width="100" height="100" fill="green"/>
+        <use xlink:href="#rect" id="use"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#use"/>
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function repaintTest() {
+            document.getElementById("use").setAttribute("x", "50");
+        }
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-attribute-change-with-use-indirection.svg b/LayoutTests/svg/filters/feImage-target-attribute-change-with-use-indirection.svg
new file mode 100644 (file)
index 0000000..de09755
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="rect" width="1" height="100" fill="green"/>
+        <use xlink:href="#rect" id="use"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#use"/>
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function repaintTest() {
+            document.getElementById("rect").setAttribute("width", "100");
+        }
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-attribute-change.svg b/LayoutTests/svg/filters/feImage-target-attribute-change.svg
new file mode 100644 (file)
index 0000000..3df1d20
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="rect" width="1" height="100" fill="green"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#rect" />
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function repaintTest() {
+            document.getElementById("rect").setAttribute("width", "100");
+        }
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-inline-style-change.svg b/LayoutTests/svg/filters/feImage-target-inline-style-change.svg
new file mode 100644 (file)
index 0000000..5a4f00c
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="rect" width="100" height="100" style="fill: red"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#rect" />
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function repaintTest() {
+            document.getElementById("rect").setAttribute("style", "fill: green");
+        }
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-property-change.svg b/LayoutTests/svg/filters/feImage-target-property-change.svg
new file mode 100644 (file)
index 0000000..bc471f0
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="rect" width="1" height="100" fill="green"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#rect" />
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function repaintTest() {
+            document.getElementById("rect").width.baseVal.value = 100;
+        }
+    ]]>
+    </script>
+</svg>
diff --git a/LayoutTests/svg/filters/feImage-target-style-change.svg b/LayoutTests/svg/filters/feImage-target-style-change.svg
new file mode 100644 (file)
index 0000000..11eb991
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="runRepaintTest()">
+    <script xlink:href="../../fast/repaint/resources/repaint.js"></script>
+    <title>There should be a single green 100x100 square.</title>
+    <defs>
+        <rect id="rect" width="100" height="100" fill="red"/>
+
+        <filter id="filter">
+            <feImage id="feimage" xlink:href="#rect" />
+        </filter>
+    </defs>
+    <rect x="0" y="0" width="100" height="100" filter="url(#filter)" />
+    <script>
+    <![CDATA[
+        function repaintTest() {
+            document.getElementById("rect").style.fill = "green";
+        }
+    ]]>
+    </script>
+</svg>
index 29d9a82..938a7f5 100644 (file)
@@ -1,3 +1,52 @@
+2012-02-08  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        feImage doesn't invalidate when its target SVG element is animated
+        https://bugs.webkit.org/show_bug.cgi?id=73860
+
+        Reviewed by Dirk Schulze.
+
+        Consider following testcase:
+        <defs>
+            <rect id="rect" fill="red" width="50" height="50"/>
+            <filter id="filter">
+                <feImage xlink:href="#rect"/>
+            </filter>
+        </defs>
+        <rect width="50" height="50" filter="url(#filter)"/>
+
+        If the <rect id="rect"> gets changed dynamically (attribute/property/style change) the <feImage>
+        doesn't notice this, as there's no link between the <rect> and the <feImage>, as the <rect> is not
+        a child of the <feImage/>. To get invalidations working for these situations, we have to track
+        the referencingElement & referencedElement in SVGDocumentExtensions.
+
+        Fixes parts the SVG-Wow twirl testcase and David Daileys SVG waves example.
+
+        Tests: svg/filters/feImage-animated-transform-on-target-rect.svg
+               svg/filters/feImage-late-indirect-update.svg
+               svg/filters/feImage-mutliple-targets-id-change.svg
+               svg/filters/feImage-target-attribute-change-with-use-indirection-2.svg
+               svg/filters/feImage-target-attribute-change-with-use-indirection.svg
+               svg/filters/feImage-target-attribute-change.svg
+               svg/filters/feImage-target-inline-style-change.svg
+               svg/filters/feImage-target-property-change.svg
+               svg/filters/feImage-target-style-change.svg
+
+        * rendering/svg/RenderSVGResource.cpp:
+        (WebCore::removeFromFilterCacheAndInvalidateDependencies): Renamed from removeFromFilterCache, as it has another purpose now.
+        (WebCore::RenderSVGResource::markForLayoutAndParentResourceInvalidation): s/removeFromFilterCache/removeFromFilterCacheAndInvalidateDependencies/.
+        * rendering/svg/RenderSVGResource.h: Removed removeFromFilterCache, it got inlined.
+        * svg/SVGDocumentExtensions.cpp: Add a new HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > > used for dependency tracking.
+        (WebCore::SVGDocumentExtensions::setOfElementsReferencingTarget): Returns all elements the passed in element depends on.
+        (WebCore::SVGDocumentExtensions::addElementReferencingTarget): Register element 'a' referencing target 'b'.
+        (WebCore::SVGDocumentExtensions::removeAllTargetReferencesForElement): Called by element 'a' on destruction or any target change.
+        (WebCore::SVGDocumentExtensions::removeAllElementReferencesForTarget): Called by element 'b' on destruction.
+        * svg/SVGDocumentExtensions.h: Expose new methods.
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::~SVGElement): Call remove removeAllElementReferencesForTarget on destruction.
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::SVGFEImageElement::clearResourceReferences):
+        (WebCore::SVGFEImageElement::buildPendingResource):
+
 2012-02-08  Kihong Kwon  <kihong.kwon@samsung.com>
 
         [EFL] Using string method instead of char* operation in the platformLanguage().
index 24adf5b..4fc5e23 100644 (file)
@@ -161,37 +161,42 @@ RenderSVGResourceSolidColor* RenderSVGResource::sharedSolidPaintingResource()
     return s_sharedSolidPaintingResource;
 }
 
-void RenderSVGResource::removeFromFilterCache(RenderObject* object)
+static inline void removeFromFilterCacheAndInvalidateDependencies(RenderObject* object, bool needsLayout)
 {
-#if ENABLE(FILTERS)
     ASSERT(object);
-
-    SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
-    if (!resources)
+#if ENABLE(FILTERS)
+    if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object)) {
+        if (RenderSVGResourceFilter* filter = resources->filter())
+            filter->removeClientFromCache(object);
+    }
+#endif
+    if (!object->node() || !object->node()->isSVGElement())
         return;
-
-    RenderSVGResourceFilter* filter = resources->filter();
-    if (!filter)
+    HashSet<SVGElement*>* dependencies = object->document()->accessSVGExtensions()->setOfElementsReferencingTarget(static_cast<SVGElement*>(object->node()));
+    if (!dependencies)
         return;
-
-    filter->removeClientFromCache(object);
-#else
-    UNUSED_PARAM(object);
-#endif
+    HashSet<SVGElement*>::iterator end = dependencies->end();
+    for (HashSet<SVGElement*>::iterator it = dependencies->begin(); it != end; ++it) {
+        if (RenderObject* renderer = (*it)->renderer())
+            RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, needsLayout);
+    }
 }
 
 void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject* object, bool needsLayout)
 {
     ASSERT(object);
+    ASSERT(object->document());
+    ASSERT(object->node());
+
     if (needsLayout)
         object->setNeedsLayout(true);
 
-    removeFromFilterCache(object);
+    removeFromFilterCacheAndInvalidateDependencies(object, needsLayout);
 
     // Invalidate resources in ancestor chain, if needed.
     RenderObject* current = object->parent();
     while (current) {
-        removeFromFilterCache(current);
+        removeFromFilterCacheAndInvalidateDependencies(current, needsLayout);
 
         if (current->isSVGResourceContainer()) {
             // This will process the rest of the ancestors.
index 8ff552b..e020154 100644 (file)
@@ -82,9 +82,6 @@ public:
     static RenderSVGResourceSolidColor* sharedSolidPaintingResource();
 
     static void markForLayoutAndParentResourceInvalidation(RenderObject*, bool needsLayout = true);
-
-private:
-    static void removeFromFilterCache(RenderObject*);
 };
 
 }
index 7116110..6f19d80 100644 (file)
@@ -37,6 +37,7 @@
 #include "SVGSMILElement.h"
 #include "SVGSVGElement.h"
 #include "ScriptableDocumentParser.h"
+#include "XLinkNames.h"
 #include <wtf/text/AtomicString.h>
 
 namespace WebCore {
@@ -290,8 +291,8 @@ void SVGDocumentExtensions::removeElementFromPendingResources(SVGStyledElement*
     element->clearHasPendingResourcesIfPossible();
 
     // We use the removePendingResource function here because it deals with set lifetime correctly.
-    Vector<AtomicString>::iterator endVector = toBeRemoved.end();
-    for (Vector<AtomicString>::iterator it = toBeRemoved.begin(); it != endVector; ++it)
+    Vector<AtomicString>::iterator vectorEnd = toBeRemoved.end();
+    for (Vector<AtomicString>::iterator it = toBeRemoved.begin(); it != vectorEnd; ++it)
         removePendingResource(*it);
 }
 
@@ -314,6 +315,74 @@ void SVGDocumentExtensions::removePendingResourceForElement(const AtomicString&
     element->clearHasPendingResourcesIfPossible();
 }
 
+HashSet<SVGElement*>* SVGDocumentExtensions::setOfElementsReferencingTarget(SVGElement* referencedElement) const
+{
+    ASSERT(referencedElement);
+    const HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::const_iterator it = m_elementDependencies.find(referencedElement);
+    if (it == m_elementDependencies.end())
+        return 0;
+    return it->second.get();
+}
+
+void SVGDocumentExtensions::addElementReferencingTarget(SVGElement* referencingElement, SVGElement* referencedElement)
+{
+    ASSERT(referencingElement);
+    ASSERT(referencedElement);
+
+    if (HashSet<SVGElement*>* elements = m_elementDependencies.get(referencedElement)) {
+        elements->add(referencingElement);
+        return;
+    }
+
+    OwnPtr<HashSet<SVGElement*> > elements = adoptPtr(new HashSet<SVGElement*>);
+    elements->add(referencingElement);
+    m_elementDependencies.set(referencedElement, elements.release());
+}
+
+void SVGDocumentExtensions::removeAllTargetReferencesForElement(SVGElement* referencingElement)
+{
+    Vector<SVGElement*> toBeRemoved;
+
+    HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::iterator end = m_elementDependencies.end();
+    for (HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::iterator it = m_elementDependencies.begin(); it != end; ++it) {
+        SVGElement* referencedElement = it->first;
+        HashSet<SVGElement*>* referencingElements = it->second.get();
+        HashSet<SVGElement*>::iterator setIt = referencingElements->find(referencingElement);
+        if (setIt == referencingElements->end())
+            continue;
+
+        referencingElements->remove(setIt);
+        if (referencingElements->isEmpty())
+            toBeRemoved.append(referencedElement);
+    }
+
+    Vector<SVGElement*>::iterator vectorEnd = toBeRemoved.end();
+    for (Vector<SVGElement*>::iterator it = toBeRemoved.begin(); it != vectorEnd; ++it)
+        m_elementDependencies.remove(*it);
+}
+
+void SVGDocumentExtensions::removeAllElementReferencesForTarget(SVGElement* referencedElement)
+{
+    ASSERT(referencedElement);
+    HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::iterator it = m_elementDependencies.find(referencedElement);
+    if (it == m_elementDependencies.end())
+        return;
+    ASSERT(it->first == referencedElement);
+    Vector<SVGElement*> toBeNotified;
+
+    HashSet<SVGElement*>* referencingElements = it->second.get();
+    HashSet<SVGElement*>::iterator setEnd = referencingElements->end();
+    for (HashSet<SVGElement*>::iterator setIt = referencingElements->begin(); setIt != setEnd; ++setIt)
+        toBeNotified.append(*setIt);
+
+    m_elementDependencies.remove(it);
+
+    // Force rebuilding the referencingElement so it knows about this change.
+    Vector<SVGElement*>::iterator vectorEnd = toBeNotified.end();
+    for (Vector<SVGElement*>::iterator vectorIt = toBeNotified.begin(); vectorIt != vectorEnd; ++vectorIt)
+        (*vectorIt)->svgAttributeChanged(XLinkNames::hrefAttr);
+}
+
 }
 
 #endif
index db608bd..36664c3 100644 (file)
@@ -68,12 +68,18 @@ public:
 
     SVGResourcesCache* resourcesCache() const { return m_resourcesCache.get(); }
 
+    HashSet<SVGElement*>* setOfElementsReferencingTarget(SVGElement* referencedElement) const;
+    void addElementReferencingTarget(SVGElement* referencingElement, SVGElement* referencedElement);
+    void removeAllTargetReferencesForElement(SVGElement* referencingElement);
+    void removeAllElementReferencesForTarget(SVGElement* referencedElement);
+
 private:
     Document* m_document; // weak reference
     HashSet<SVGSVGElement*> m_timeContainers; // For SVG 1.2 support this will need to be made more general.
     HashMap<SVGElement*, HashSet<SVGSMILElement*>* > m_animatedElements;
     HashMap<AtomicString, RenderSVGResourceContainer*> m_resources;
     HashMap<AtomicString, SVGPendingElements*> m_pendingResources;
+    HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > > m_elementDependencies;
     OwnPtr<SVGResourcesCache> m_resourcesCache;
 
 public:
index a617f91..f3d5874 100644 (file)
@@ -85,6 +85,7 @@ SVGElement::~SVGElement()
         rareDataMap.remove(it);
     }
     document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this);
+    document()->accessSVGExtensions()->removeAllElementReferencesForTarget(this);
 }
 
 SVGElementRareData* SVGElement::rareSVGData() const
@@ -159,6 +160,7 @@ void SVGElement::setXmlbase(const String& value, ExceptionCode&)
 void SVGElement::removedFromDocument()
 {
     document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this);
+    document()->accessSVGExtensions()->removeAllElementReferencesForTarget(this);
     StyledElement::removedFromDocument();
 }
 
@@ -407,8 +409,10 @@ void SVGElement::attributeChanged(Attribute* attr)
     if (isSynchronizingSVGAttributes())
         return;
 
-    if (isIdAttributeName(attr->name()))
+    if (isIdAttributeName(attr->name())) {
         document()->accessSVGExtensions()->removeAllAnimationElementsFromTarget(this);
+        document()->accessSVGExtensions()->removeAllElementReferencesForTarget(this);
+    }
 
     // Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods),
     // so we don't want changes to the style attribute to result in extra work here.
index e1e7000..8d5d197 100644 (file)
@@ -73,6 +73,9 @@ void SVGFEImageElement::clearResourceReferences()
         m_cachedImage->removeClient(this);
         m_cachedImage = 0;
     }
+
+    ASSERT(document());
+    document()->accessSVGExtensions()->removeAllTargetReferencesForElement(this);
 }
 
 void SVGFEImageElement::requestImageResource()
@@ -102,6 +105,10 @@ void SVGFEImageElement::buildPendingResource()
             document()->accessSVGExtensions()->addPendingResource(id, this);
             ASSERT(hasPendingResources());
         }
+    } else if (target->isSVGElement()) {
+        // Register us with the target in the dependencies map. Any change of hrefElement
+        // that leads to relayout/repainting now informs us, so we can react to it.
+        document()->accessSVGExtensions()->addElementReferencingTarget(this, static_cast<SVGElement*>(target));
     }
 
     invalidate();