WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 113059
[SVG] Incorrect light source positioning
https://bugs.webkit.org/show_bug.cgi?id=113059
Summary
[SVG] Incorrect light source positioning
Florin Malita
Reported
2013-03-22 07:50:22 PDT
Created
attachment 194543
[details]
Spot light positioned/scaled incorrectly.
https://code.google.com/p/chromium/issues/detail?id=177623
Light sources are not correctly positioned relative to the filter target coordinate system. This is most obvious when scaled/transformed - see attached example.
Attachments
Spot light positioned/scaled incorrectly.
(947 bytes, image/svg+xml)
2013-03-22 07:50 PDT
,
Florin Malita
no flags
Details
Patch
(1.13 MB, patch)
2013-03-26 10:39 PDT
,
Florin Malita
no flags
Details
Formatted Diff
Diff
Patch
(1.13 MB, patch)
2013-03-27 08:03 PDT
,
Florin Malita
bfulgham
: review-
Details
Formatted Diff
Diff
Screenshots of user agents rendering the test case
(277.10 KB, application/zip)
2014-04-09 17:51 PDT
,
Adenilson Cavalcanti Silva
no flags
Details
Patch
(45.08 KB, patch)
2014-04-09 17:58 PDT
,
Adenilson Cavalcanti Silva
krit
: review-
Details
Formatted Diff
Diff
Show Obsolete
(1)
View All
Add attachment
proposed patch, testcase, etc.
Florin Malita
Comment 1
2013-03-26 10:39:48 PDT
Created
attachment 195114
[details]
Patch
WebKit Review Bot
Comment 2
2013-03-26 10:43:23 PDT
Attachment 195114
[details]
did not pass style-queue: Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'LayoutTests/ChangeLog', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-dom-limitingConeAngle-attr-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-dom-pointsAtX-attr-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-dom-pointsAtY-attr-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-dom-pointsAtZ-attr-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-dom-specularExponent-attr-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-dom-x-attr-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-dom-y-attr-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-dom-z-attr-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-svgdom-limitingConeAngle-prop-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-svgdom-pointsAtX-prop-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-svgdom-pointsAtY-prop-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-svgdom-pointsAtZ-prop-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-svgdom-specularExponent-prop-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-svgdom-x-prop-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-svgdom-y-prop-expected.png', u'LayoutTests/platform/chromium-linux/svg/dynamic-updates/SVGFESpotLightElement-svgdom-z-prop-expected.png', u'LayoutTests/platform/chromium-linux/svg/filters/light-source-positioning-expected.png', u'LayoutTests/platform/chromium/TestExpectations', u'LayoutTests/platform/efl/TestExpectations', u'LayoutTests/platform/gtk/TestExpectations', u'LayoutTests/platform/mac/TestExpectations', u'LayoutTests/platform/qt/TestExpectations', u'LayoutTests/svg/dynamic-updates/SVGFESpotLightElement-dom-pointsAtX-attr-expected.txt', u'LayoutTests/svg/dynamic-updates/SVGFESpotLightElement-dom-x-attr-expected.txt', u'LayoutTests/svg/dynamic-updates/SVGFESpotLightElement-svgdom-pointsAtX-prop-expected.txt', u'LayoutTests/svg/dynamic-updates/SVGFESpotLightElement-svgdom-x-prop-expected.txt', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-dom-limitingConeAngle-attr.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-dom-pointsAtX-attr.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-dom-pointsAtY-attr.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-dom-pointsAtZ-attr.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-dom-specularExponent-attr.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-dom-x-attr.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-dom-y-attr.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-dom-z-attr.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-svgdom-limitingConeAngle-prop.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-svgdom-pointsAtX-prop.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-svgdom-pointsAtY-prop.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-svgdom-pointsAtZ-prop.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-svgdom-specularExponent-prop.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-svgdom-x-prop.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-svgdom-y-prop.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFESpotLightElement-svgdom-z-prop.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFilterElement-dom-primitiveUnits-attr.js', u'LayoutTests/svg/dynamic-updates/script-tests/SVGFilterElement-svgdom-primitiveUnits-prop.js', u'LayoutTests/svg/filters/light-source-positioning-expected.txt', u'LayoutTests/svg/filters/light-source-positioning.svg', u'Source/WebCore/ChangeLog', u'Source/WebCore/platform/graphics/cpu/arm/filters/FELightingNEON.h', u'Source/WebCore/platform/graphics/filters/DistantLightSource.cpp', u'Source/WebCore/platform/graphics/filters/DistantLightSource.h', u'Source/WebCore/platform/graphics/filters/FELighting.cpp', u'Source/WebCore/platform/graphics/filters/Filter.h', u'Source/WebCore/platform/graphics/filters/LightSource.h', u'Source/WebCore/platform/graphics/filters/PointLightSource.cpp', u'Source/WebCore/platform/graphics/filters/PointLightSource.h', u'Source/WebCore/platform/graphics/filters/SpotLightSource.cpp', u'Source/WebCore/platform/graphics/filters/SpotLightSource.h', u'Source/WebCore/platform/graphics/filters/skia/FELightingSkia.cpp', u'Source/WebCore/svg/graphics/filters/SVGFilter.cpp', u'Source/WebCore/svg/graphics/filters/SVGFilter.h']" exit_code: 1 Source/WebCore/platform/graphics/filters/LightSource.h:92: enum members should use InterCaps with an initial capital letter. [readability/enum_casing] [4] Source/WebCore/platform/graphics/filters/LightSource.h:93: enum members should use InterCaps with an initial capital letter. [readability/enum_casing] [4] Source/WebCore/platform/graphics/filters/LightSource.h:94: enum members should use InterCaps with an initial capital letter. [readability/enum_casing] [4] Total errors found: 3 in 45 files If any of these errors are false positives, please file a bug against check-webkit-style.
Florin Malita
Comment 3
2013-03-27 08:03:52 PDT
Created
attachment 195324
[details]
Patch check-webkit-style is crimping my style :)
Dirk Schulze
Comment 4
2013-03-28 14:25:38 PDT
Comment on
attachment 195324
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=195324&action=review
> Source/WebCore/platform/graphics/filters/LightSource.h:96 > + FloatPoint3D mapPointToFilter(const FloatPoint3D& point, const Filter* filter) const > + {
I am not sure if I understand the idea correctly. What you want is the point of origin of either the obb or the userspace of the target element transformed to our filter space, right? This is not necessarily identical with the filter region origin.
> Source/WebCore/platform/graphics/filters/PointLightSource.h:44 > + virtual void initPaintingData(PaintingData&, const Filter*);
I wonder why we not just pass the necessary values here instead of passing Filter. It just looks like we should calculate all these values before creating the point source.
> Source/WebCore/platform/graphics/filters/PointLightSource.h:63 > + mutable FloatPoint3D m_filterPosition; > + mutable bool m_filterDataIsDirty : 1;
Especially having this mutable FloatPoint doesn't look really nice and that they are in all light sources instead of the global class.
Florin Malita
Comment 5
2013-03-29 07:57:29 PDT
Thanks Dirk, let me do another pass on this. (In reply to
comment #4
)
> (From update of
attachment 195324
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=195324&action=review
> > > Source/WebCore/platform/graphics/filters/LightSource.h:96 > > + FloatPoint3D mapPointToFilter(const FloatPoint3D& point, const Filter* filter) const > > + { > > I am not sure if I understand the idea correctly. What you want is the point of origin of either the obb or the userspace of the target element transformed to our filter space, right?
Yes, that is the intent but the implementation is somewhat obfuscated by the overridden behavior of apply{Horizontal,Vertical}Scale and filterOffset.
> This is not necessarily identical with the filter region origin.
Good point, applying the scale upfront is probably wrong. I guess the tests only cover the scale == 1.0 case otherwise this should have been obvious... Will need add a fiterRes test too.
> > Source/WebCore/platform/graphics/filters/PointLightSource.h:44 > > + virtual void initPaintingData(PaintingData&, const Filter*); > > I wonder why we not just pass the necessary values here instead of passing Filter. It just looks like we should calculate all these values before creating the point source.
The problem is that the light sources are long lived and their attributes can be updated at a later time via JS wrappers/setters. On that path we do not have immediate access to the corresponding Filter, and even if we did, encapsulating the logic here seems like a good idea (instead of having all setter callers plus platform impls duplicate the same calculations).
> > Source/WebCore/platform/graphics/filters/PointLightSource.h:63 > > + mutable FloatPoint3D m_filterPosition; > > + mutable bool m_filterDataIsDirty : 1; > > Especially having this mutable FloatPoint doesn't look really nice and that they are in all light sources instead of the global class.
I'm not sure I understand this: the filter space "shadowing" fields are tied to their corresponding attributes, so they do need to live in the same class as the actual fields they're based on (PointLightSource::m_position, SpotLightSource::m_position, SpotLightSource::m_direction). The reason I've marked them mutable is that they're not really part of the logical state of the object: they're derived on demand (think cached values) - hence they should not affect method const-ness.
ben
Comment 6
2013-04-05 10:28:16 PDT
A very closely related bug: light source positions and sizes also aren't being scaled relative to the viewBox. Look at this:
http://codepen.io/anon/pen/FEIhL
Stretch the browser viewport wide and narrow, and notice that the position of the spotlight isn't scaling. The "viewbox" 1.1 spec says "If specified, an additional transformation is applied to all descendants of the given element to achieve the specified effect." Since the filter in this CodePen is a descendant of the element to which the viewBox is applied, it's squarely within the viewBox's "scope", and the units should be scaled. I realize this is distinct from the primitiveUnits="objectBoundingBox" use case. I can file this separately if necessary, but I thought it might make sense to bring up here.
Dirk Schulze
Comment 7
2014-03-02 09:14:29 PST
Florin, does it still make sense to review the patch? It might not apply anymore, I am more interested if the fix is still valid.
Florin Malita
Comment 8
2014-03-03 09:17:32 PST
(In reply to
comment #7
)
> Florin, does it still make sense to review the patch? It might not apply anymore, I am more interested if the fix is still valid.
I think so, yes. I may have to review it myself to recall the details, but from a quick glance I think it still makes sense.
Stephen White
Comment 9
2014-03-03 09:55:30 PST
(In reply to
comment #8
)
> (In reply to
comment #7
) > > Florin, does it still make sense to review the patch? It might not apply anymore, I am more interested if the fix is still valid. > > I think so, yes. I may have to review it myself to recall the details, but from a quick glance I think it still makes sense.
sugoi@ is working on a fix for this (in a different way) over in Blink:
https://codereview.chromium.org/181943003/
Dirk Schulze
Comment 10
2014-03-03 11:10:24 PST
(In reply to
comment #9
)
> (In reply to
comment #8
) > > (In reply to
comment #7
) > > > Florin, does it still make sense to review the patch? It might not apply anymore, I am more interested if the fix is still valid. > > > > I think so, yes. I may have to review it myself to recall the details, but from a quick glance I think it still makes sense. > > sugoi@ is working on a fix for this (in a different way) over in Blink:
https://codereview.chromium.org/181943003/
Thanks Stephen and Florin!
Adenilson Cavalcanti Silva
Comment 11
2014-04-09 17:49:54 PDT
I'm taking this one. First I started to check what was the current state of other user agents concerning the bug: all are ok (FF, Chrome Canary, even IE) besides WebKit. Initially I started by trying to backport the patch that landed in Blink (it would be nice to share the same implementation for this case):
https://gist.github.com/Adenilson/10330991
But later on I noticed that it depends on some new properties (absoluteTransform/inverse, etc) on Filter that are not present on WebKit (plus it would require some changes in RenderLayer to backport it). So, as a fallback, decided to give it a try in Florin's original patch: it required basically no significant changes.
Adenilson Cavalcanti Silva
Comment 12
2014-04-09 17:51:33 PDT
Created
attachment 229008
[details]
Screenshots of user agents rendering the test case
Adenilson Cavalcanti Silva
Comment 13
2014-04-09 17:58:45 PDT
Created
attachment 229009
[details]
Patch
WebKit Commit Bot
Comment 14
2014-04-09 18:00:57 PDT
Attachment 229009
[details]
did not pass style-queue: ERROR: Source/WebCore/platform/graphics/filters/SpotLightSource.h:67: Wrong number of spaces before statement. (expected: 12) [whitespace/indent] [4] Total errors found: 1 in 16 files If any of these errors are false positives, please file a bug against check-webkit-style.
Dirk Schulze
Comment 15
2014-04-16 13:02:51 PDT
Comment on
attachment 229009
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=229009&action=review
Please take a look at the style bot output as well.
> Source/WebCore/ChangeLog:20 > + direction for feSpotLight, position for fePointlight.
Could you add more descriptions what exactly you are doing to fix this please?
> Source/WebCore/ChangeLog:31 > + * platform/graphics/cpu/arm/filters/FELightingNEON.h: > + (WebCore::FELighting::platformApplyNeon): > + * platform/graphics/filters/DistantLightSource.cpp: > + (WebCore::DistantLightSource::initPaintingData): > + * platform/graphics/filters/DistantLightSource.h: > + * platform/graphics/filters/FELighting.cpp: > + (WebCore::FELighting::drawLighting): > + * platform/graphics/filters/Filter.h:
Please do more detailed descriptions behind the function names here. It really would help to understand.
> Source/WebCore/platform/graphics/cpu/arm/filters/FELightingNEON.h:120 > + FloatPoint3D position = pointLightSource->position(filter());
I wonder why you pass a filter() here. Need to check.I guess I can imagine why.
> Source/WebCore/platform/graphics/cpu/arm/filters/FELightingNEON.h:124 > + floatArguments.lightX = position.x(); > + floatArguments.lightY = position.y(); > + floatArguments.lightZ = position.z(); > floatArguments.padding2 = 0;
What is float arguments and why doesn't it simply take a FloatPoint3D?
> Source/WebCore/platform/graphics/filters/DistantLightSource.cpp:40 > +void DistantLightSource::initPaintingData(PaintingData& paintingData, const Filter*)
There should always be a Filter. therefore, you should be able to pass a reference. Why do you pass it at all? Can't see an instance of the virtual function that is using it?
> Source/WebCore/platform/graphics/filters/LightSource.h:101 > + FloatPoint3D mapPointToFilter(const FloatPoint3D& point, const Filter* filter) const > + { > + ASSERT(filter); > + float horizontalUnit = filter->applyHorizontalScale(1); > + float verticalUnit = filter->applyVerticalScale(1); > + > + float adjustedX = point.x() * horizontalUnit - filter->filterOffset().width(); > + float adjustedY = point.y() * verticalUnit - filter->filterOffset().height(); > + float adjustedZ = point.z() * sqrtf((horizontalUnit * horizontalUnit + verticalUnit * verticalUnit) / 2); > + > + return FloatPoint3D(adjustedX, adjustedY, adjustedZ); > + }
We usually do scaling operations in Filter itself. Examples are applyHorizontalScale and applyVerticalScale actually. Can't you move this function to Filter as well? Also, don't initialize 3 floats but then create a FloatPoint3D. Create the FloatPoint3D from the beginning: return FloatPoint3D( adjX, adjY, adjZ); Also, can you pass point.x() directly to applyHorizontalScale()? Ditto for point.y()
> Source/WebCore/platform/graphics/filters/PointLightSource.cpp:40 > +void PointLightSource::initPaintingData(PaintingData&, const Filter* filter)
Ok, missed this one.
> Source/WebCore/platform/graphics/filters/PointLightSource.cpp:43 > + if (m_filterDataIsDirty) > + updateFilterData(filter);
Is that some kind of optimization? Can you elaborate more?
> Source/WebCore/platform/graphics/filters/PointLightSource.h:38 > + const FloatPoint3D& position(const Filter*) const;
reference, no pointer.
> Source/WebCore/platform/graphics/filters/PointLightSource.h:56 > + void updateFilterData(const Filter*) const;
Ditto.
> Source/WebCore/platform/graphics/filters/PointLightSource.h:61 > + mutable FloatPoint3D m_filterPosition; > + mutable bool m_filterDataIsDirty : 1;
: 1 doesn't make much sense if it is the only argument you want to put in a word. Why is m_filterPosition a member variable? And why does it need to be mutable?
> Source/WebCore/platform/graphics/filters/SpotLightSource.cpp:200 > + m_filterPosition = mapPointToFilter(m_position, filter); > + m_filterDirection = mapPointToFilter(m_direction, filter); > + m_filterDataIsDirty = false;
Even more new member variables. Why do they need to be mem variables?
> Source/WebCore/platform/graphics/filters/SpotLightSource.cpp:215 > +const FloatPoint3D& SpotLightSource::position(const Filter* filter) const > +{ > + if (m_filterDataIsDirty) > + updateFilterData(filter); > + return m_filterPosition; > +} > + > +const FloatPoint3D& SpotLightSource::direction(const Filter* filter) const > +{ > + if (m_filterDataIsDirty) > + updateFilterData(filter); > + return m_filterDirection; > +}
Is that the optimization why you need to variables? How often do we compute that per run? Is it really that costly?
> Source/WebCore/platform/graphics/filters/SpotLightSource.h:82 > + mutable bool m_filterDataIsDirty : 1;
Ditto. See above.
Adenilson Cavalcanti Silva
Comment 16
2014-04-17 11:40:47 PDT
Dirk Thanks for reviewing, I will be submitting a new patch soon.
Brent Fulgham
Comment 17
2014-10-31 11:41:13 PDT
(In reply to
comment #16
)
> Dirk > > Thanks for reviewing, I will be submitting a new patch soon.
Is this bug still being worked on?
Florin Malita
Comment 18
2014-10-31 11:50:12 PDT
(In reply to
comment #17
)
> (In reply to
comment #16
) > > Dirk > > > > Thanks for reviewing, I will be submitting a new patch soon. > > Is this bug still being worked on?
Nope.
Dirk Schulze
Comment 19
2014-10-31 12:26:19 PDT
(In reply to
comment #18
)
> (In reply to
comment #17
) > > (In reply to
comment #16
) > > > Dirk > > > > > > Thanks for reviewing, I will be submitting a new patch soon. > > > > Is this bug still being worked on? > > Nope.
It is just currently not worked on. Not not at all.
Florin Malita
Comment 20
2014-10-31 12:33:35 PDT
(In reply to
comment #19
)
> (In reply to
comment #18
) > > (In reply to
comment #17
) > > > (In reply to
comment #16
) > > > > Dirk > > > > > > > > Thanks for reviewing, I will be submitting a new patch soon. > > > > > > Is this bug still being worked on? > > > > Nope. > > It is just currently not worked on. Not not at all.
Sorry, didn't mean to imply that: I was the bug assignee and since I'm no longer working on it (or planning to), I unassigned myself. But yes, what I meant is "I am no longer working on this bug, feel free to re-assign" :)
Brent Fulgham
Comment 21
2016-03-14 12:06:55 PDT
Comment on
attachment 195324
[details]
Patch This patch doesn't apply, and seems to be largely abandoned. Marking r- to get it off of the review queue.
Brent Fulgham
Comment 22
2016-03-14 12:07:46 PDT
Said, I just CC'd you on this bug in case you can find some use for Florin's work. The test cases seem like they would be useful to add.
Simon Fraser (smfr)
Comment 23
2018-01-03 16:00:03 PST
Fixed via
bug 181147
and
bug 181197
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