WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
41396
Pattern is rasterized
https://bugs.webkit.org/show_bug.cgi?id=41396
Summary
Pattern is rasterized
Dusan Maliarik
Reported
2010-06-30 02:08:52 PDT
After scaling an element with a pattern fill, the pattern is pixelized. This effectively cripples any usage of patterns. It becomes even bigger issue when one wants to use different coordinate space. Let's say our SVG is 500px for 500px, and we use meter units, which means the whole graphic is scaled up, with viewBox around 0 0 50 50. Sample SVG demonstrating this issue is attached, please compare with other SVG implementations (mozilla's)
Attachments
pattern scale test case
(436 bytes, image/svg+xml)
2010-06-30 02:09 PDT
,
Dusan Maliarik
no flags
Details
Patch
(
deleted
)
2010-08-19 04:59 PDT
,
Nikolas Zimmermann
krit
: review+
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
Dusan Maliarik
Comment 1
2010-06-30 02:09:59 PDT
Created
attachment 60101
[details]
pattern scale test case
Eric Seidel (no email)
Comment 2
2010-06-30 02:31:20 PDT
I'm not sure if this is expected behavior or not.
Dusan Maliarik
Comment 3
2010-06-30 02:49:35 PDT
There is no mention of rasterization in SVG spec. so I believe this is some premature optimization (evil) that kicks in, and destroys developer's day ;) Otherwise it works like a charm, much faster than mozilla's impl.
Dirk Schulze
Comment 4
2010-06-30 02:53:06 PDT
The Pattern and Gradient resources need to invalidate, on scaling or resizing the window. This doesn't happen at the moment, that's why you see the rasterization. We have some more bug reports about this. And this is also a duplication of another bug report (don't know the bug number atm).
Dusan Maliarik
Comment 5
2010-06-30 02:56:11 PDT
I searched for similar bug reports but couldn't find any. Anyway, is there any workaround we can use until it's fixed?
Nikolas Zimmermann
Comment 6
2010-07-09 23:24:47 PDT
(In reply to
comment #4
)
> The Pattern and Gradient resources need to invalidate, on scaling or resizing the window. This doesn't happen at the moment, that's why you see the rasterization. We have some more bug reports about this. And this is also a duplication of another bug report (don't know the bug number atm).
No, this has nothing to do with invalidation. A pattern of a specific size is created and applied to an object, which gets scaled - this alone creates the artifacts.
Nikolas Zimmermann
Comment 7
2010-08-19 04:55:43 PDT
***
Bug 38704
has been marked as a duplicate of this bug. ***
Nikolas Zimmermann
Comment 8
2010-08-19 04:55:50 PDT
***
Bug 41603
has been marked as a duplicate of this bug. ***
Nikolas Zimmermann
Comment 9
2010-08-19 04:59:26 PDT
Created
attachment 64828
[details]
Patch Patch is large, as it contains several new tests and pixel results.
Nikolas Zimmermann
Comment 10
2010-08-19 05:33:21 PDT
Forgot to mention: integrated the testcase from Dusan, and the ones from the other bug reports, that I marked as duplicate in the patch.
Dirk Schulze
Comment 11
2010-08-19 05:36:13 PDT
Comment on
attachment 64828
[details]
Patch r=me With some changes discussed on IRC
Nikolas Zimmermann
Comment 12
2010-08-19 06:01:41 PDT
Landed in
r65665
.
WebKit Review Bot
Comment 13
2010-08-19 06:22:57 PDT
http://trac.webkit.org/changeset/65665
might have broken SnowLeopard Intel Release (Tests)
Dirk Schulze
Comment 14
2010-08-19 06:52:02 PDT
(In reply to
comment #13
)
>
http://trac.webkit.org/changeset/65665
might have broken SnowLeopard Intel Release (Tests)
Not caused by this patch.
Eric Seidel (no email)
Comment 15
2010-08-19 07:36:01 PDT
Comment on
attachment 64828
[details]
Patch WebCore/rendering/RenderSVGResourcePattern.cpp:191 + return FloatRect(attributes.x().valueAsPercentage() * objectBoundingBox.width() + objectBoundingBox.x(), Why this change? WebCore/rendering/RenderSVGResourcePattern.cpp:202 + AffineTransform RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer, I've been told to avoid returning AffineTransforms as they're very expensive to copy. return PassOwnPtr<ImageBuffer>();: Can't you just reuturn 0 here? // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer. I'm not sure I understand what you're doing here? WebCore/rendering/RenderSVGResourcePattern.cpp:263 + if (!tileImageTransform.isIdentity()) Does concatCTM assert it's not identity? I'm surprised we have to check outisde concatCTM. WebCore/rendering/SVGImageBufferTools.cpp:32 + AffineTransform SVGImageBufferTools::screenCoordinateSystemForRenderer(const RenderObject* renderer) Yeah, these should probably be changed to return the AffineTransform as a reference variable. At least according to smfr last time I talked with him about it. WebCore/rendering/SVGImageBufferTools.cpp:37 + ASSERT(current); This assert is redundant. No need to even put renderer in a local variable, the argument is already a local variable, I would just use it as the loop variable. WebCore/rendering/SVGImageBufferTools.cpp:81 + return IntSize(static_cast<int>(lroundf(size.width())), static_cast<int>(lroundf(size.height()))); Really? We don't already have a method like this on IntSize? Why wouldn't this go on IntSize? WebCore/rendering/SVGRenderSupport.h:83 + static const RenderObject* findTextRootObject(const RenderObject* start); We should just remove the RenderObject* one. I don't think I really fully understand the patch, but in general it looked fine. I'm surprised krit had 0 comments. :p I guess he made them all over IRC. Thanks for doing this.
Eric Seidel (no email)
Comment 16
2010-08-19 07:37:15 PDT
Just an FYI CC to other folks affected by SVG rendering tree changes.
Dirk Schulze
Comment 17
2010-08-19 07:52:20 PDT
(In reply to
comment #15
)
> (From update of
attachment 64828
[details]
) > WebCore/rendering/RenderSVGResourcePattern.cpp:191 > + return FloatRect(attributes.x().valueAsPercentage() * objectBoundingBox.width() + objectBoundingBox.x(), > Why this change?
Because it was wrong not to do it.
> > WebCore/rendering/RenderSVGResourcePattern.cpp:202 > + AffineTransform RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer, > I've been told to avoid returning AffineTransforms as they're very expensive to copy.
Not AffineTransform, maybe TransformationMatrix with it's 16 floats.
> > return PassOwnPtr<ImageBuffer>();: > Can't you just reuturn 0 here? > > // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer. > I'm not sure I understand what you're doing here?
Because we may have a width or height with decimal places, but don't want artefacts on the tile.
> > WebCore/rendering/RenderSVGResourcePattern.cpp:263 > + if (!tileImageTransform.isIdentity()) > Does concatCTM assert it's not identity? I'm surprised we have to check outisde concatCTM.
tileImageTransform is the AffineTransform for the tile. Why shouldn't we check if it is identity? If it is, we don't need to transform the ctm.
> > WebCore/rendering/SVGImageBufferTools.cpp:81 > + return IntSize(static_cast<int>(lroundf(size.width())), static_cast<int>(lroundf(size.height()))); > Really? We don't already have a method like this on IntSize? Why wouldn't this go on IntSize?
Just IntRect has it.
> > WebCore/rendering/SVGRenderSupport.h:83 > + static const RenderObject* findTextRootObject(const RenderObject* start); > We should just remove the RenderObject* one.
No, the first is searching for the text root, the second one for the outermost svg renderer.
> > I don't think I really fully understand the patch, but in general it looked fine. I'm surprised krit had 0 comments. :p I guess he made them all over IRC. Thanks for doing this.
Like I wrote on my r=me comment, I gave comments on IRC. But thanks for rechecking the patch. Four eyes are better than two.
Nikolas Zimmermann
Comment 18
2010-08-22 03:35:28 PDT
(In reply to
comment #15
)
> (From update of
attachment 64828
[details]
) > WebCore/rendering/RenderSVGResourcePattern.cpp:191 > + return FloatRect(attributes.x().valueAsPercentage() * objectBoundingBox.width() + objectBoundingBox.x(), > Why this change?
Because it was not correct before, we hacked around it with an additional transformation before. I just fixed it.
> WebCore/rendering/RenderSVGResourcePattern.cpp:202 > + AffineTransform RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer, > I've been told to avoid returning AffineTransforms as they're very expensive to copy.
Going to fix this in my next patch.
> > return PassOwnPtr<ImageBuffer>();: > Can't you just reuturn 0 here?
#ifdef LOOSE_PASS_OWN_PTR PassOwnPtr(PtrType ptr) : m_ptr(ptr) { } PassOwnPtr& operator=(PtrType); ... // Remove this once we make all WebKit code compatible with stricter rules about PassOwnPtr. #define LOOSE_PASS_OWN_PTR My understanding is that the implicit 0 -> PassOwnPtr conversion is deprecated.
> > // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer. > I'm not sure I understand what you're doing here?
I'm fixing scaling artefacts. ImageBuffers are using integer based sizes, and the content may use floating-point numbers, so we scale so it fits inside the integer based box.
> > WebCore/rendering/RenderSVGResourcePattern.cpp:263 > + if (!tileImageTransform.isIdentity()) > Does concatCTM assert it's not identity? I'm surprised we have to check outisde concatCTM.
It doesn't :( We should fix this ASAP, and remove lots of these checks from SVG code.
> WebCore/rendering/SVGImageBufferTools.cpp:32 > + AffineTransform SVGImageBufferTools::screenCoordinateSystemForRenderer(const RenderObject* renderer) > Yeah, these should probably be changed to return the AffineTransform as a reference variable. At least according to smfr last time I talked with him about it.
Fixing in my next patch, thanks for the hint.
> > WebCore/rendering/SVGImageBufferTools.cpp:37 > + ASSERT(current); > This assert is redundant. No need to even put renderer in a local variable, the argument is already a local variable, I would just use it as the loop variable.
Yes, fixing in my next patch.
> > WebCore/rendering/SVGImageBufferTools.cpp:81 > + return IntSize(static_cast<int>(lroundf(size.width())), static_cast<int>(lroundf(size.height()))); > Really? We don't already have a method like this on IntSize? Why wouldn't this go on IntSize?
Because I specifically need lroundf here, no ceil or floor solution.
> > WebCore/rendering/SVGRenderSupport.h:83 > + static const RenderObject* findTextRootObject(const RenderObject* start); > We should just remove the RenderObject* one.
As Dirk already said, there's findTextRootObject and findTreeRootObject, yes looks confusing, that's why there's a FIXME above, that it should be moved away :-)
> > I don't think I really fully understand the patch, but in general it looked fine. I'm surprised krit had 0 comments. :p I guess he made them all over IRC. Thanks for doing this.
Yeah, we generally talk a lot on IRC before I submit the acutal patch, and after submitting. Usually Dirk has comments :-)
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