Changeset 226363 in webkit
- Timestamp:
- Jan 3, 2018 9:58:05 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r226361 r226363 1 2018-01-03 Simon Fraser <simon.fraser@apple.com> 2 3 SVG lighting filter lights are in the wrong coordinate system 4 https://bugs.webkit.org/show_bug.cgi?id=181147 5 6 Reviewed by Zalan Bujtas. 7 8 * svg/filters/fePointLight-coordinates-expected.svg: Added. 9 * svg/filters/fePointLight-coordinates.svg: Added. 10 * svg/filters/feSpotLight-coordinates-expected.svg: Added. 11 * svg/filters/feSpotLight-coordinates.svg: Added. 12 * svg/filters/hidpi/fePointLight-coordinates-expected.svg: Added. 13 * svg/filters/hidpi/fePointLight-coordinates.svg: Added. 14 * svg/filters/hidpi/feSpotLight-coordinates-expected.svg: Added. 15 * svg/filters/hidpi/feSpotLight-coordinates.svg: Added. 16 1 17 2018-01-03 Youenn Fablet <youenn@apple.com> 2 18 -
trunk/Source/WebCore/ChangeLog
r226361 r226363 1 2018-01-03 Simon Fraser <simon.fraser@apple.com> 2 3 SVG lighting filter lights are in the wrong coordinate system 4 https://bugs.webkit.org/show_bug.cgi?id=181147 5 6 Reviewed by Zalan Bujtas. 7 8 Point and spot light coordinates weren't being converted into buffer-relative 9 coordinates before being fed into the lighting math, resulting in incorrect light 10 rendering on Retina devices, and when the filter primitive region was clipped. 11 12 Fix by storing absoluteUnclippedSubregion on FilterEffect, which allows us to map 13 lighting points from user space coordinates into the coordinates of the buffer being 14 used for rendering. Also scale the light z coordinate by doing a dummy point mapping in x. 15 16 Rename members of PointLightSource and SpotLightSource to make it clear which coordinate 17 system they are in. 18 19 Tests include HiDPI tests. 20 21 Tests: svg/filters/fePointLight-coordinates-expected.svg 22 svg/filters/fePointLight-coordinates.svg 23 svg/filters/feSpotLight-coordinates-expected.svg 24 svg/filters/feSpotLight-coordinates.svg 25 svg/filters/hidpi/fePointLight-coordinates-expected.svg 26 svg/filters/hidpi/fePointLight-coordinates.svg 27 svg/filters/hidpi/feSpotLight-coordinates-expected.svg 28 svg/filters/hidpi/feSpotLight-coordinates.svg 29 30 * platform/graphics/FloatPoint3D.h: Make it easy to get and set the X and Y coords as a FloatPoint. 31 (WebCore::FloatPoint3D::xy const): 32 (WebCore::FloatPoint3D::setXY): 33 * platform/graphics/GeometryUtilities.cpp: 34 (WebCore::mapPoint): 35 (WebCore::mapRect): 36 * platform/graphics/GeometryUtilities.h: Helper to make a point between rects. 37 * platform/graphics/filters/DistantLightSource.cpp: 38 (WebCore::DistantLightSource::initPaintingData): 39 * platform/graphics/filters/DistantLightSource.h: 40 * platform/graphics/filters/FELighting.cpp: 41 (WebCore::FELighting::drawLighting): 42 * platform/graphics/filters/FilterEffect.cpp: 43 (WebCore::FilterEffect::mapPointFromUserSpaceToBuffer const): 44 * platform/graphics/filters/FilterEffect.h: 45 (WebCore::FilterEffect::setUnclippedAbsoluteSubregion): 46 * platform/graphics/filters/LightSource.h: 47 * platform/graphics/filters/PointLightSource.cpp: 48 (WebCore::PointLightSource::initPaintingData): 49 (WebCore::PointLightSource::computePixelLightingData const): 50 (WebCore::PointLightSource::setX): 51 (WebCore::PointLightSource::setY): 52 (WebCore::PointLightSource::setZ): 53 * platform/graphics/filters/PointLightSource.h: 54 (WebCore::PointLightSource::position const): 55 (WebCore::PointLightSource::PointLightSource): 56 * platform/graphics/filters/SpotLightSource.cpp: 57 (WebCore::SpotLightSource::initPaintingData): 58 (WebCore::SpotLightSource::computePixelLightingData const): 59 (WebCore::SpotLightSource::setX): 60 (WebCore::SpotLightSource::setY): 61 (WebCore::SpotLightSource::setZ): 62 (WebCore::SpotLightSource::setPointsAtX): 63 (WebCore::SpotLightSource::setPointsAtY): 64 (WebCore::SpotLightSource::setPointsAtZ): 65 * platform/graphics/filters/SpotLightSource.h: 66 (WebCore::SpotLightSource::position const): 67 (WebCore::SpotLightSource::direction const): 68 (WebCore::SpotLightSource::SpotLightSource): 69 * rendering/svg/RenderSVGResourceFilter.cpp: 70 (WebCore::RenderSVGResourceFilter::buildPrimitives const): 71 * rendering/svg/RenderSVGResourceFilterPrimitive.cpp: 72 (WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion): 73 1 74 2018-01-03 Youenn Fablet <youenn@apple.com> 2 75 -
trunk/Source/WebCore/platform/graphics/FloatPoint3D.h
r220503 r226363 63 63 float y() const { return m_y; } 64 64 void setY(float y) { m_y = y; } 65 66 FloatPoint xy() const { return { m_x, m_y }; } 67 void setXY(FloatPoint p) 68 { 69 m_x = p.x(); 70 m_y = p.y(); 71 } 65 72 66 73 float z() const { return m_z; } -
trunk/Source/WebCore/platform/graphics/GeometryUtilities.cpp
r222245 r226363 97 97 } 98 98 99 FloatPoint mapPoint(FloatPoint p, const FloatRect& srcRect, const FloatRect& destRect) 100 { 101 if (!srcRect.width() || !srcRect.height()) 102 return p; 103 104 float widthScale = destRect.width() / srcRect.width(); 105 float heightScale = destRect.height() / srcRect.height(); 106 107 return { 108 destRect.x() + (p.x() - srcRect.x()) * widthScale, 109 destRect.y() + (p.y() - srcRect.y()) * heightScale 110 }; 111 } 112 99 113 FloatRect mapRect(const FloatRect& r, const FloatRect& srcRect, const FloatRect& destRect) 100 114 { … … 104 118 float widthScale = destRect.width() / srcRect.width(); 105 119 float heightScale = destRect.height() / srcRect.height(); 106 return FloatRect(destRect.x() + (r.x() - srcRect.x()) * widthScale, 120 return { 121 destRect.x() + (r.x() - srcRect.x()) * widthScale, 107 122 destRect.y() + (r.y() - srcRect.y()) * heightScale, 108 r.width() * widthScale, r.height() * heightScale); 123 r.width() * widthScale, 124 r.height() * heightScale 125 }; 109 126 } 110 127 -
trunk/Source/WebCore/platform/graphics/GeometryUtilities.h
r222113 r226363 42 42 WEBCORE_EXPORT FloatRect unionRect(const Vector<FloatRect>&); 43 43 44 // Map rect r from srcRect to an equivalent rect in destRect. 44 // Map point from srcRect to an equivalent point in destRect. 45 FloatPoint mapPoint(FloatPoint, const FloatRect& srcRect, const FloatRect& destRect); 46 47 // Map rect from srcRect to an equivalent rect in destRect. 45 48 FloatRect mapRect(const FloatRect&, const FloatRect& srcRect, const FloatRect& destRect); 46 49 -
trunk/Source/WebCore/platform/graphics/filters/DistantLightSource.cpp
r226317 r226363 36 36 namespace WebCore { 37 37 38 void DistantLightSource::initPaintingData( PaintingData& paintingData)38 void DistantLightSource::initPaintingData(const FilterEffect&, PaintingData& paintingData) 39 39 { 40 40 float azimuth = deg2rad(m_azimuth); -
trunk/Source/WebCore/platform/graphics/filters/DistantLightSource.h
r225122 r226363 42 42 bool setElevation(float) override; 43 43 44 void initPaintingData( PaintingData&) override;44 void initPaintingData(const FilterEffect&, PaintingData&) override; 45 45 ComputedLightingData computePixelLightingData(const PaintingData&, int x, int y, float z) const final; 46 46 -
trunk/Source/WebCore/platform/graphics/filters/FELighting.cpp
r226317 r226363 402 402 Color lightColor = (operatingColorSpace() == ColorSpaceLinearRGB) ? sRGBToLinearColor(m_lightingColor) : m_lightingColor; 403 403 paintingData.initialLightingData.colorVector = FloatPoint3D(lightColor.red(), lightColor.green(), lightColor.blue()); 404 m_lightSource->initPaintingData( paintingData);404 m_lightSource->initPaintingData(*this, paintingData); 405 405 406 406 // Top left. -
trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp
r225453 r226363 26 26 27 27 #include "Filter.h" 28 #include "GeometryUtilities.h" 28 29 #include "ImageBuffer.h" 29 30 #include "Logging.h" … … 65 66 else 66 67 m_absolutePaintRect.unite(enclosingIntRect(m_maxEffectRect)); 68 } 69 70 FloatPoint FilterEffect::mapPointFromUserSpaceToBuffer(FloatPoint userSpacePoint) const 71 { 72 FloatPoint absolutePoint = mapPoint(userSpacePoint, m_filterPrimitiveSubregion, m_absoluteUnclippedSubregion); 73 absolutePoint.moveBy(-m_absolutePaintRect.location()); 74 return absolutePoint; 67 75 } 68 76 -
trunk/Source/WebCore/platform/graphics/filters/FilterEffect.h
r225366 r226363 137 137 FloatRect effectBoundaries() const { return m_effectBoundaries; } 138 138 void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; } 139 140 void setUnclippedAbsoluteSubregion(const FloatRect& r) { m_absoluteUnclippedSubregion = r; } 141 142 FloatPoint mapPointFromUserSpaceToBuffer(FloatPoint) const; 139 143 140 144 Filter& filter() { return m_filter; } … … 209 213 // filter primitive on a later step. 210 214 FloatRect m_effectBoundaries; 215 216 // filterPrimitiveSubregion mapped to absolute coordinates before clipping. 217 FloatRect m_absoluteUnclippedSubregion; 211 218 212 219 bool m_alphaImage { false }; -
trunk/Source/WebCore/platform/graphics/filters/LightSource.h
r226317 r226363 39 39 }; 40 40 41 class FilterEffect; 42 41 43 class LightSource : public RefCounted<LightSource> { 42 44 public: … … 64 66 virtual WTF::TextStream& externalRepresentation(WTF::TextStream&) const = 0; 65 67 66 virtual void initPaintingData( PaintingData&) = 0;68 virtual void initPaintingData(const FilterEffect&, PaintingData&) = 0; 67 69 // z is a float number, since it is the alpha value scaled by a user 68 // specified "surfaceScale" constant, which type is <number> in the SVG standard 70 // specified "surfaceScale" constant, which type is <number> in the SVG standard. 71 // x and y are in the coordinates of the FilterEffect's buffer. 69 72 virtual ComputedLightingData computePixelLightingData(const PaintingData&, int x, int y, float z) const = 0; 70 73 71 74 virtual bool setAzimuth(float) { return false; } 72 75 virtual bool setElevation(float) { return false; } 76 77 // These are in user space coordinates. 73 78 virtual bool setX(float) { return false; } 74 79 virtual bool setY(float) { return false; } … … 77 82 virtual bool setPointsAtY(float) { return false; } 78 83 virtual bool setPointsAtZ(float) { return false; } 84 79 85 virtual bool setSpecularExponent(float) { return false; } 80 86 virtual bool setLimitingConeAngle(float) { return false; } -
trunk/Source/WebCore/platform/graphics/filters/PointLightSource.cpp
r226317 r226363 36 36 namespace WebCore { 37 37 38 void PointLightSource::initPaintingData( PaintingData&)38 void PointLightSource::initPaintingData(const FilterEffect& filterEffect, PaintingData&) 39 39 { 40 m_bufferPosition.setXY(filterEffect.mapPointFromUserSpaceToBuffer(m_userSpacePosition.xy())); 41 // To scale Z, map a point offset from m_userSpacePosition in the x direction by z. 42 FloatPoint mappedZ = filterEffect.mapPointFromUserSpaceToBuffer({ m_userSpacePosition.x() + m_userSpacePosition.z(), m_userSpacePosition.y() }); 43 m_bufferPosition.setZ(mappedZ.x() - m_bufferPosition.x()); 40 44 } 41 45 … … 43 47 { 44 48 FloatPoint3D lightVector = { 45 m_ position.x() - x,46 m_ position.y() - y,47 m_ position.z() - z49 m_bufferPosition.x() - x, 50 m_bufferPosition.y() - y, 51 m_bufferPosition.z() - z 48 52 }; 49 53 … … 53 57 bool PointLightSource::setX(float x) 54 58 { 55 if (m_ position.x() == x)59 if (m_userSpacePosition.x() == x) 56 60 return false; 57 m_ position.setX(x);61 m_userSpacePosition.setX(x); 58 62 return true; 59 63 } … … 61 65 bool PointLightSource::setY(float y) 62 66 { 63 if (m_ position.y() == y)67 if (m_userSpacePosition.y() == y) 64 68 return false; 65 m_ position.setY(y);69 m_userSpacePosition.setY(y); 66 70 return true; 67 71 } … … 69 73 bool PointLightSource::setZ(float z) 70 74 { 71 if (m_ position.z() == z)75 if (m_userSpacePosition.z() == z) 72 76 return false; 73 m_ position.setZ(z);77 m_userSpacePosition.setZ(z); 74 78 return true; 75 79 } -
trunk/Source/WebCore/platform/graphics/filters/PointLightSource.h
r225122 r226363 35 35 } 36 36 37 const FloatPoint3D& position() const { return m_ position; }37 const FloatPoint3D& position() const { return m_userSpacePosition; } 38 38 bool setX(float) override; 39 39 bool setY(float) override; 40 40 bool setZ(float) override; 41 41 42 void initPaintingData( PaintingData&) override;42 void initPaintingData(const FilterEffect&, PaintingData&) override; 43 43 ComputedLightingData computePixelLightingData(const PaintingData&, int x, int y, float z) const final; 44 44 … … 48 48 PointLightSource(const FloatPoint3D& position) 49 49 : LightSource(LS_POINT) 50 , m_ position(position)50 , m_userSpacePosition(position) 51 51 { 52 52 } 53 53 54 FloatPoint3D m_position; 54 FloatPoint3D m_userSpacePosition; 55 FloatPoint3D m_bufferPosition; 55 56 }; 56 57 -
trunk/Source/WebCore/platform/graphics/filters/SpotLightSource.cpp
r226317 r226363 41 41 static const float antiAliasTreshold = 0.016f; 42 42 43 void SpotLightSource::initPaintingData( PaintingData& paintingData)43 void SpotLightSource::initPaintingData(const FilterEffect& filterEffect, PaintingData& paintingData) 44 44 { 45 paintingData.directionVector = m_direction - m_position; 45 m_bufferPosition.setXY(filterEffect.mapPointFromUserSpaceToBuffer(m_userSpacePosition.xy())); 46 // To scale Z, map a point offset from m_userSpacePosition in the x direction by z. 47 FloatPoint mappedZ = filterEffect.mapPointFromUserSpaceToBuffer({ m_userSpacePosition.x() + m_userSpacePosition.z(), m_userSpacePosition.y() }); 48 m_bufferPosition.setZ(mappedZ.x() - m_bufferPosition.x()); 49 50 paintingData.directionVector = m_userSpacePointsAt - m_userSpacePosition; 46 51 paintingData.directionVector.normalize(); 47 52 … … 71 76 { 72 77 FloatPoint3D lightVector = { 73 m_ position.x() - x,74 m_ position.y() - y,75 m_ position.z() - z78 m_bufferPosition.x() - x, 79 m_bufferPosition.y() - y, 80 m_bufferPosition.z() - z 76 81 }; 77 82 float lightVectorLength = lightVector.length(); … … 112 117 bool SpotLightSource::setX(float x) 113 118 { 114 if (m_ position.x() == x)119 if (m_userSpacePosition.x() == x) 115 120 return false; 116 m_ position.setX(x);121 m_userSpacePosition.setX(x); 117 122 return true; 118 123 } … … 120 125 bool SpotLightSource::setY(float y) 121 126 { 122 if (m_ position.y() == y)127 if (m_userSpacePosition.y() == y) 123 128 return false; 124 m_ position.setY(y);129 m_userSpacePosition.setY(y); 125 130 return true; 126 131 } … … 128 133 bool SpotLightSource::setZ(float z) 129 134 { 130 if (m_ position.z() == z)135 if (m_userSpacePosition.z() == z) 131 136 return false; 132 m_ position.setZ(z);137 m_userSpacePosition.setZ(z); 133 138 return true; 134 139 } … … 136 141 bool SpotLightSource::setPointsAtX(float pointsAtX) 137 142 { 138 if (m_ direction.x() == pointsAtX)143 if (m_userSpacePointsAt.x() == pointsAtX) 139 144 return false; 140 m_ direction.setX(pointsAtX);145 m_userSpacePointsAt.setX(pointsAtX); 141 146 return true; 142 147 } … … 144 149 bool SpotLightSource::setPointsAtY(float pointsAtY) 145 150 { 146 if (m_ direction.y() == pointsAtY)151 if (m_userSpacePointsAt.y() == pointsAtY) 147 152 return false; 148 m_ direction.setY(pointsAtY);153 m_userSpacePointsAt.setY(pointsAtY); 149 154 return true; 150 155 } … … 152 157 bool SpotLightSource::setPointsAtZ(float pointsAtZ) 153 158 { 154 if (m_ direction.z() == pointsAtZ)159 if (m_userSpacePointsAt.z() == pointsAtZ) 155 160 return false; 156 m_ direction.setZ(pointsAtZ);161 m_userSpacePointsAt.setZ(pointsAtZ); 157 162 return true; 158 163 } -
trunk/Source/WebCore/platform/graphics/filters/SpotLightSource.h
r225122 r226363 36 36 } 37 37 38 const FloatPoint3D& position() const { return m_ position; }39 const FloatPoint3D& direction() const { return m_ direction; }38 const FloatPoint3D& position() const { return m_userSpacePosition; } 39 const FloatPoint3D& direction() const { return m_userSpacePointsAt; } 40 40 float specularExponent() const { return m_specularExponent; } 41 41 float limitingConeAngle() const { return m_limitingConeAngle; } … … 51 51 bool setLimitingConeAngle(float) override; 52 52 53 void initPaintingData( PaintingData&) override;53 void initPaintingData(const FilterEffect&, PaintingData&) override; 54 54 ComputedLightingData computePixelLightingData(const PaintingData&, int x, int y, float z) const final; 55 55 … … 57 57 58 58 private: 59 SpotLightSource(const FloatPoint3D& position, const FloatPoint3D& direction, 60 float specularExponent, float limitingConeAngle) 59 SpotLightSource(const FloatPoint3D& position, const FloatPoint3D& direction, float specularExponent, float limitingConeAngle) 61 60 : LightSource(LS_SPOT) 62 , m_ position(position)63 , m_ direction(direction)61 , m_userSpacePosition(position) 62 , m_userSpacePointsAt(direction) 64 63 , m_specularExponent(specularExponent) 65 64 , m_limitingConeAngle(limitingConeAngle) … … 67 66 } 68 67 69 FloatPoint3D m_position; 70 FloatPoint3D m_direction; 68 FloatPoint3D m_userSpacePosition; 69 FloatPoint3D m_userSpacePointsAt; 70 71 FloatPoint3D m_bufferPosition; 71 72 72 73 float m_specularExponent; -
trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
r224537 r226363 105 105 FloatRect absoluteSubregion = filter.absoluteTransform().mapRect(subregion); 106 106 FloatSize filterResolution = filter.filterResolution(); 107 absoluteSubregion.scale(filterResolution.width(), filterResolution.height()); 107 absoluteSubregion.scale(filterResolution); 108 // Save this before clipping so we can use it to map lighting points from user space to buffer coordinates. 109 effect.setUnclippedAbsoluteSubregion(absoluteSubregion); 108 110 109 111 // Clip every filter effect to the filter region. 110 112 FloatRect absoluteScaledFilterRegion = filter.filterRegion(); 111 absoluteScaledFilterRegion.scale(filterResolution .width(), filterResolution.height());113 absoluteScaledFilterRegion.scale(filterResolution); 112 114 absoluteSubregion.intersect(absoluteScaledFilterRegion); 113 115
Note: See TracChangeset
for help on using the changeset viewer.