-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Corrupt radial gradient on Apple Silicon #2014
Comments
@mgrudzinska Thanks for looking into this. Changing from fy="-600" to fy="-597" doesn't change anything. Perhaps a hint; those are the contents before and after executing the instructions at line 198 //This condition fulfills the SVG 1.1 std:
//the focal point, if outside the end circle, is moved to be on the end circle
//See: the SVG 2 std requirements: https://www.w3.org/TR/SVG2/pservers.html#RadialGradientNotes
if (fill->radial.a < 0) {
|
So it turns out in this case It seems clang is doing some instruction reordering / FMA which is causing loss of precision. I found that storing intermediary results in temporary variables as shown below fixes the problem: // Prevent loss of precision on Apple Silicon when dr=dy and dx=0
// https://github.com/thorvg/thorvg/issues/2014
const float dr2 = fill->radial.dr * fill->radial.dr;
const float dx2 = fill->radial.dx * fill->radial.dx;
const float dy2 = fill->radial.dy * fill->radial.dy;
fill->radial.a = dr2 - dx2 - dy2; @mgrudzinska Do you want me to submit a PR ? |
@lmdsp ThorVG welcomes contributors! If you have solutions or improvements, please don't hesitate to submit patches. Thank you for your support! |
…ARM/Apple Silicon sw_engine: radial gradient [issues 2014: radial gradient](thorvg#2014) Radial gradient results in a corrupted image when the focal point is outside the circle on Apple Silicon. This happens because some compilers use FMA to optimize the a = dr² - dx² - dy² calculation, which cause loss of precision. We use compiler specific float contraction control pragmas to avoid this when they exist, and revert to manual de-optimization in other cases.
…ARM/Apple Silicon sw_engine: radial gradient [issues 2014: radial gradient](thorvg#2014) Radial gradient results in a corrupted image when the focal point is outside the circle on Apple Silicon. This happens because some compilers use FMA to optimize the a = dr² - dx² - dy² calculation, which cause loss of precision. We rely on temporary variables to prevent FMA. We could also use compiler specific float contraction control pragmas to avoid this if this doesn't work in the future
…ARM/Apple Silicon sw_engine: radial gradient [issues 2014: radial gradient](thorvg#2014) Radial gradient results in a corrupted image when the focal point is outside the circle on Apple Silicon. This happens because some compilers use FMA to optimize the a = dr² - dx² - dy² calculation, which cause loss of precision. We rely on temporary variables to prevent FMA. We could also use compiler specific float contraction control pragmas to avoid this if this doesn't work in the future
…ARM/Apple Silicon sw_engine: radial gradient [issues 2014: radial gradient](#2014) Radial gradient results in a corrupted image when the focal point is outside the circle on Apple Silicon. This happens because some compilers use FMA to optimize the a = dr² - dx² - dy² calculation, which cause loss of precision. We rely on temporary variables to prevent FMA. We could also use compiler specific float contraction control pragmas to avoid this if this doesn't work in the future
@lmdsp Your fix will be applied in 0.12.7. Thanks for your contribution |
…ARM/Apple Silicon sw_engine: radial gradient [issues 2014: radial gradient](#2014) Radial gradient results in a corrupted image when the focal point is outside the circle on Apple Silicon. This happens because some compilers use FMA to optimize the a = dr² - dx² - dy² calculation, which cause loss of precision. We rely on temporary variables to prevent FMA. We could also use compiler specific float contraction control pragmas to avoid this if this doesn't work in the future
…ARM/Apple Silicon sw_engine: radial gradient [issues 2014: radial gradient](#2014) Radial gradient results in a corrupted image when the focal point is outside the circle on Apple Silicon. This happens because some compilers use FMA to optimize the a = dr² - dx² - dy² calculation, which cause loss of precision. We rely on temporary variables to prevent FMA. We could also use compiler specific float contraction control pragmas to avoid this if this doesn't work in the future
…ARM/Apple Silicon sw_engine: radial gradient [issues 2014: radial gradient](#2014) Radial gradient results in a corrupted image when the focal point is outside the circle on Apple Silicon. This happens because some compilers use FMA to optimize the a = dr² - dx² - dy² calculation, which cause loss of precision. We rely on temporary variables to prevent FMA. We could also use compiler specific float contraction control pragmas to avoid this if this doesn't work in the future
I've encountered a strange bug when rendering an svg with certain focal point values.
Strangely enough, the rendering is correct on Intel x64 (mac/PC) and the online ThorVG viewer,
but Apple Silicon / ARM show weird horizontal lines instead of the expected gradient.
Note that if
fx
is changed to 600, then there are no artefacts anymore.This is using latest ThorVG 0.12.6, XCode 15.2 and macos Sonoma 14.3.1.
ThorVG viewer:
Test application | x64:
Test application | Apple Silicon:
The text was updated successfully, but these errors were encountered: