WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
26380
SVG Filters and big sized filterRegions
https://bugs.webkit.org/show_bug.cgi?id=26380
Summary
SVG Filters and big sized filterRegions
Dirk Schulze
Reported
2009-06-13 22:35:36 PDT
We need to take care about very big filterRegions and itemSizes of filters. CI has problems with very big image size. We could clip the filterRegion after a defined maximum size and don't support bigger filters. Perhaps we can try to scale down the GraphicsContext and limit the size of all ImageBuffers for source input / filter effects. We could transform the filterRegion and itemsize too. But we will see every pixel. The size of every pixel gets bigger on bigger sized filters. Or we give the CTM of the scaling to every filter effect and transform the context of every filter effect. But many filter effects need pixel manipulation. Don't know if that is a possible way. Another way is maybe to just draw the visible area. But I don't have experience with that. And what to do on zooming out of the SVG?
Attachments
big svg filter
(5.32 KB, patch)
2009-06-14 11:46 PDT
,
Dirk Schulze
oliver
: review-
Details
Formatted Diff
Diff
big svg filter
(5.53 KB, patch)
2009-08-04 12:49 PDT
,
Dirk Schulze
no flags
Details
Formatted Diff
Diff
clip filter to viewport
(4.69 KB, patch)
2009-11-10 10:37 PST
,
Dirk Schulze
simon.fraser
: review-
Details
Formatted Diff
Diff
Testcase with svg inside 3d transform
(952 bytes, application/xhtml+xml)
2009-11-10 14:12 PST
,
Simon Fraser (smfr)
no flags
Details
Better testcase
(958 bytes, application/xhtml+xml)
2009-11-10 14:20 PST
,
Simon Fraser (smfr)
no flags
Details
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Dirk Schulze
Comment 1
2009-06-14 11:46:11 PDT
Created
attachment 31267
[details]
big svg filter This patch uses one of the solutions above. We scale the context down to a predefined maximum size and transform all necessary rects too. Apply the effects and scale back. It seems, that opera and firefox use simular solutions. I haven't tested it on a mac. We might use a smaller size than 3000x3000. I'll set the review flag when i'am sure.
Dirk Schulze
Comment 2
2009-06-14 13:10:43 PDT
Comment on
attachment 31267
[details]
big svg filter works on mac
Oliver Hunt
Comment 3
2009-06-18 01:52:51 PDT
Comment on
attachment 31267
[details]
big svg filter Where does the 3000.0f maxSize come from? It looks like it's actually a constant so i believe you actually probably want a static const float kMaxFilterSize = 3000.0f; in the file, rather than scoped to the function.
Dirk Schulze
Comment 4
2009-08-04 12:49:02 PDT
Created
attachment 34081
[details]
big svg filter constant for maximum filter size. At ~3000x3000 px a difference at calculating is sensible.
Eric Seidel (no email)
Comment 5
2009-08-07 12:29:21 PDT
Comment on
attachment 34081
[details]
big svg filter Seems like this is an aspect ratio scaling problem which we've already solved in other parts of the code. I wonder if we could just re-use the scaling code instead of writing it again here.
Dirk Schulze
Comment 6
2009-08-07 13:00:32 PDT
(In reply to
comment #5
)
> (From update of
attachment 34081
[details]
) > Seems like this is an aspect ratio scaling problem which we've already solved > in other parts of the code. I wonder if we could just re-use the scaling code > instead of writing it again here.
where did we solve this problem?
Eric Seidel (no email)
Comment 7
2009-08-07 13:02:41 PDT
Certainly SVGPerserveAspectRatio solves this.
Eric Seidel (no email)
Comment 8
2009-08-07 13:02:59 PDT
There are probably less-complicated solutions in the Image code too.
Eric Seidel (no email)
Comment 9
2009-08-08 09:08:37 PDT
There was also a recent TransformationMatrix::rectToRect call added, but that won't handle aspect ratios for you.
Eric Seidel (no email)
Comment 10
2009-09-03 00:53:37 PDT
Comment on
attachment 34081
[details]
big svg filter So this is just about limiting the size of the intermediate buffers? Doesn't SVG have some sort of attribute to control this kind of thing anyway?
Dirk Schulze
Comment 11
2009-09-03 05:52:26 PDT
(In reply to
comment #10
)
> (From update of
attachment 34081
[details]
) > So this is just about limiting the size of the intermediate buffers? Doesn't > SVG have some sort of attribute to control this kind of thing anyway?
The size of a filter can be as big as you wish. And it is neccessary to limit the size of a buffer, especially if you have many filters. But as far as I know, we don't have attributes or parameters to limit intermediate buffers with context scaling for big filters. Another point to add limitations here is filterRes. This code can be used to add different resolutions for filters later.
> Certainly SVGPerserveAspectRatio solves this.
I looked at SVGPerserveAspectRatio during some experiments with feImage. It seems to be a bit to complex for this simple scaling of context and image with. I haven't looked at Image yet.
Simon Fraser (smfr)
Comment 12
2009-09-21 14:14:55 PDT
Won't scaling the graphics context down cause image aliasing artifacts etc?
Dirk Schulze
Comment 13
2009-09-21 23:03:58 PDT
(In reply to
comment #12
)
> Won't scaling the graphics context down cause image aliasing artifacts etc?
Images will loose quality, yes. But a filter size can be as big as you want. And scaling down the context on a pre defined size, makes it possible to calculate filter effects with pixel manipulation in an acceptable time. It makes it possible to draw the effect at all, if the size is bigger than some platform ImageBuffers are able to render.
Nikolas Zimmermann
Comment 14
2009-10-14 16:25:57 PDT
So what about this patch? I think we should settle on a solution. I think we should introduce a maximum limit right now, given the fact you can easily blow up a target PC using a dozen masks at a large size :-) When filterRes & friends is taken into account, we need to think about a more clever solution, but I'd vote for an initial "sanitization value", scaling larger filters down, yes with loosing quality. After that I think we can enable SVG Filters as default, so finally pass SVG 1.0, and advertize ourselves as SVG 1.0 fully compilant, see the 'requiredFeatures' feature of SVG viewers. Anyone with me?
Jeff Schiller
Comment 15
2009-10-14 16:59:23 PDT
> Anyone with me?
From an outsider's perspective: um, yes please! :)
Dirk Schulze
Comment 16
2009-11-09 23:52:56 PST
Comment on
attachment 34081
[details]
big svg filter Clearing review flag. This would just limit the size of the filter surface but not of the effect surfaces.
Dirk Schulze
Comment 17
2009-11-10 10:37:23 PST
Created
attachment 42876
[details]
clip filter to viewport This patch clips the filter and all it's effects to the current viewport. This will limit the filter size to the current viewable window content. I'll upload the test results as soon as I have access to a Mac.
Simon Fraser (smfr)
Comment 18
2009-11-10 10:58:49 PST
Comment on
attachment 42876
[details]
clip filter to viewport
> Index: WebCore/svg/SVGFilterElement.cpp > ===================================================================
> @@ -125,6 +127,7 @@ void SVGFilterElement::buildFilter(const > filterRect.width() * targetRect.width(), > filterRect.height() * targetRect.height()); > > + m_filter->setViewPort(document()->view()->visibleContentRect());
But is this rect in the same coordinate system as the rest of the filter rects? What if the filter is on a child of a transformed element?
> Index: WebCore/svg/graphics/SVGResourceFilter.cpp > =================================================================== > --- WebCore/svg/graphics/SVGResourceFilter.cpp (revision 50732) > +++ WebCore/svg/graphics/SVGResourceFilter.cpp (working copy) > @@ -63,6 +63,9 @@ void SVGResourceFilter::prepareFilter(Gr > FloatRect targetRect = object->objectBoundingBox(); > m_ownerElement->buildFilter(targetRect); > > + // clip filterRect to viewPort > + m_filterBBox.intersect(m_viewPort);
This isn't going to do the right thing for filtered SVG inside a HTML with CSS 3D transforms; element content that is outside the viewport can be made visible with a rotateY(), for example. And, yes the visible filtered content may be arbitrarily large in that case.
> Index: WebCore/svg/graphics/SVGResourceFilter.h > =================================================================== > --- WebCore/svg/graphics/SVGResourceFilter.h (revision 50732) > +++ WebCore/svg/graphics/SVGResourceFilter.h (working copy) > @@ -65,6 +65,9 @@ public: > FloatRect filterBoundingBox() { return m_filterBBox; } > void setFilterBoundingBox(const FloatRect& rect) { m_filterBBox = rect; } > > + IntRect viewPort() { return m_viewPort; } > + void setViewPort(const IntRect& rect) { m_viewPort = rect; }
I question the need for these methods, but if you do have them, then viewPort() should be const.
Dirk Schulze
Comment 19
2009-11-10 11:11:59 PST
(In reply to
comment #18
)
> (From update of
attachment 42876
[details]
) > But is this rect in the same coordinate system as the rest of the filter rects? > What if the filter is on a child of a transformed element?
Yes, it's the same coordinate space. I tested it on the W3C test suite, where SVG is embeded to html. We already use this on pattern and others via clampImageBufferSizeToViewport.
> This isn't going to do the right thing for filtered SVG inside a HTML with CSS > 3D transforms; element content that is outside the viewport can be made visible > with a rotateY(), for example. And, yes the visible filtered content may be > arbitrarily large in that case.
I don't like the idea of activating css transforms for SVG. What happens if we transform an SVG element with <animation>, JS and CSS transform (2D or 3D)?
> I question the need for these methods, but if you do have them, then viewPort() > should be const.
Ok, viewPort() is not needed atm. setViewPort is needed to get the viewPort in SVGResourceFilter from SVGFilterElement.
Simon Fraser (smfr)
Comment 20
2009-11-10 11:20:40 PST
(In reply to
comment #19
)
> > This isn't going to do the right thing for filtered SVG inside a HTML with CSS > > 3D transforms; element content that is outside the viewport can be made visible > > with a rotateY(), for example. And, yes the visible filtered content may be > > arbitrarily large in that case. > I don't like the idea of activating css transforms for SVG. What happens if we > transform an SVG element with <animation>, JS and CSS transform (2D or 3D)?
I'm not talking about CSS transforms on SVG. I'm concerned about SVG inside HTML, where the HTML has 3d transforms.
Dirk Schulze
Comment 21
2009-11-10 11:47:42 PST
(In reply to
comment #20
)
> (In reply to
comment #19
) > > > > This isn't going to do the right thing for filtered SVG inside a HTML with CSS > > > 3D transforms; element content that is outside the viewport can be made visible > > > with a rotateY(), for example. And, yes the visible filtered content may be > > > arbitrarily large in that case. > > I don't like the idea of activating css transforms for SVG. What happens if we > > transform an SVG element with <animation>, JS and CSS transform (2D or 3D)? > > I'm not talking about CSS transforms on SVG. I'm concerned about SVG inside > HTML, where the HTML has 3d transforms.
hm. I'm not familiar with 3d transform on CSS, but I made more tests after you comment. The viewPort size of the SVG, will depend on the <object> when you embed a SVG into a HTML. It will get the currently visible size when SVG is the root element (pure SVG).
Dirk Schulze
Comment 22
2009-11-10 11:49:25 PST
(In reply to
comment #21
)
> The viewPort size of the SVG, will depend on the <object> when you > embed a SVG into a HTML.
This means, that the viewPort size is the size of the HTML-element <object>.
Simon Fraser (smfr)
Comment 23
2009-11-10 12:01:30 PST
(In reply to
comment #22
)
> (In reply to
comment #21
) > > The viewPort size of the SVG, will depend on the <object> when you > > embed a SVG into a HTML. > This means, that the viewPort size is the size of the HTML-element <object>.
document()->view()->visibleContentRect() will return the content rect of the HTML document in the case of HTML with nested SVG.
Dirk Schulze
Comment 24
2009-11-10 12:12:54 PST
(In reply to
comment #23
)
> (In reply to
comment #22
) > > (In reply to
comment #21
) > > > The viewPort size of the SVG, will depend on the <object> when you > > > embed a SVG into a HTML. > > This means, that the viewPort size is the size of the HTML-element <object>. > > document()->view()->visibleContentRect() will return the content rect of the > HTML document in the case of HTML with nested SVG.
Well, this example: <html> <div style="margin: 20px;"> <object data="filter.svg" type="image/svg+xml" width="5000"> </div> </body></html> gives me 0,0,5000,150 as contentRect, is it that what you mean?
Simon Fraser (smfr)
Comment 25
2009-11-10 12:21:52 PST
Try xhtml with mixed SVG and HTML. <object> is different.
Dirk Schulze
Comment 26
2009-11-10 12:32:01 PST
(In reply to
comment #25
)
> Try xhtml with mixed SVG and HTML. <object> is different.
Don't we just support embeding svg into html with either <object>, <img> or <embed>?
Dirk Schulze
Comment 27
2009-11-10 12:42:02 PST
(In reply to
comment #26
)
> (In reply to
comment #25
) > > Try xhtml with mixed SVG and HTML. <object> is different. > > Don't we just support embeding svg into html with either <object>, <img> or > <embed>?
Sorry. I noticed, that there is a difference, if I name the file with .xml or .html :-P Here the exmaple: <html xmlns="
http://www.w3.org/1999/xhtml
"> <head> </head> <body id="body"> <svg xmlns="
http://www.w3.org/2000/svg
" xmlns:xlink="
http://www.w3.org/1999/xlink
"> <defs> <linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="1"> <stop offset="0" stop-color="green" /> <stop offset="0.01" stop-color="red" /> </linearGradient> <filter id="filter"> <feOffset/> </filter> </defs> <g> <rect x="0" y="0" width="5000" height="5000" style="fill:url(#gradient);filter:url(#filter);"/> </g> </svg> </body> </html> The viewport is now the visible area of the window and changes with resizing the window.
Dirk Schulze
Comment 28
2009-11-10 12:56:03 PST
(In reply to
comment #25
)
> Try xhtml with mixed SVG and HTML. <object> is different.
When I look at the exmaple above, I still think that the behavior is right, since the HML itself limits the size of the SVG. So clipping here is ok. And even with 3D transform, the SVG shouldn't get more content.
Simon Fraser (smfr)
Comment 29
2009-11-10 14:12:38 PST
Created
attachment 42894
[details]
Testcase with svg inside 3d transform
Simon Fraser (smfr)
Comment 30
2009-11-10 14:20:52 PST
Created
attachment 42897
[details]
Better testcase
Dirk Schulze
Comment 31
2009-11-10 14:33:38 PST
(In reply to
comment #30
)
> Created an attachment (id=42897) [details] > Better testcase
Don't know if this is a bug on Cairo, but this example event don't work without filters. I added <div style="background-color:green; width:5000px;height:50px"></div> and the green box is longer than the green to red rect of the SVG (css transformation disabled). But this reflects a general problem with big sized SVG. We do clampImageBufferSizeToViewport on other parts of SVG and every time this could break CSS transformations :-/. Who decided to combine this techniques ;-)
Dirk Schulze
Comment 32
2009-11-10 23:57:11 PST
I still believe that it is better to clip the filter to viewport for the moment. Even if it causes problems with big filters on CSS transforms. We should figure out a general solution for SVG to aboid this problem, since we clip the size on other parts of SVG too. Or does someone have a better idea how to limit the calculation complexity?
Dirk Schulze
Comment 33
2009-11-23 09:30:28 PST
Fixed in
bug 6021
.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug