-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Fix svg rendering on macOS retina #12364
Conversation
On Windows 11 it still looks fine. I didn't notice a change by this PR. |
a53a2eb
to
40c159e
Compare
This is a workaround, isn't it? We should file a bug report with them. Does the issue persist in Qt6 builds? |
Qt5 seems to be different here than Qt6: https://doc.qt.io/qt-5/highdpi.html Did you had a look at Line 145 in 2c2e706
Maybe these settings can influence the behavior. |
Yes.
I still need to try this. |
IMO these flags are all set as they should and changing them didn't help. |
this may be a workaround for a QT bug but I think it's a fine workaround and worth merging in to fix the issue |
looks good in linux |
The rendering is done here: This means we have no real benefit from the scaling of a svg. It is treated like png, just with the extra penalty of rendering from svg. Your current solution looks good for 2x but not for other scaling and comes with a performance penalty for smaller (non 2x) screens. I am not sure how the situation is with the "BackPath" skin property. Did you check that?
Will it work? What do you think? |
To be clear: I would much prefer a solution at the c++ level, but I really don't know what else to try, also after looking at the Qt code.
We definitely do have benefit from rendering svgs, and they do scale properly! If you look at the screenshot @JoergAtGithub posted in reply to my bug report, you'll see that with 400% scaling the icons are rendered perfectly. As far as I can see, this issue occurs because the device pixel ratio (2 on macOS retina) is not taken into account. But normal scaling works fine. BTW, I tried setting the iconSize of the style option to 2x but that didn't make any difference. But note that I am not very confident with the styling code, so maybe I got that wrong.
Why do you say that? Do you have examples of that? Other devs report no visual change.
That might be true. (Proposed solution below)
But this would require changing a lot of skin code, wouldn't it? I don't want to go there. Proposed alternative solution: Since this only is a problem on macOS, and on mac retina displays are common enough that a potential performance penalty is not relevant, and seeing that I know which files need to be adjusted (btn_* expect btn__embedded*), instead of modifying the original files, I could add a step that modifies the files when the are copied to the resource, only on macOS. That way we don't "polute" the original svgs, and the workaround is restricted to macOS. |
First of all, I have no strong demands which solution we go. I just want to make sure we have taken a decision with all informations on the table. @m0dB would you mind to test with one knob, if the unscaled svg is blurry removing it from the style and adding it to the skin? mixxx/res/skins/LateNight/style_classic.qss Line 1732 in 2c2e706
The issue is that they are rendered and scaled with their native size to a QPixmap in QIcon, then they are sacaled from that to the final size. This is the reason we see blurriness whenever an upscaling or an odd number scaling happens. I think with "BackPath", we render directly to the final size. So we safe CPU and memory for one rendering.
Yes, that is the issue. I can imagine that all the scaling done here was already tedious. |
This means we'd have to drop the convenient qss solution and set all icons in xml, including potential scheme suffix :| The drawback of setting BackPath is obviously that it doesn't center the icon and allows no additional position correction like in qss.
if that is feasible it very much appreciated and I'd definitely prefer that over the skin changes, either SVG or xml. |
The issue is clearly sourced from the Qt. It has the same code in Qt 5 and 6. So all targets should be affected. This means we need a solution for all. Can we apply the scaling hack at runtime? We could patch Qt ... Or just go with the proposed solution here .. |
Since this is a release blocker, trying to patch QT would be much too slow (and would still have a problem on older versions). We should report a bug upstream to be sure, but a workaround is more appropriate for now. |
Hmm? @m0dB is it looking good in Mixxx 2.3? |
By release-blocker, I mean that we should not release 2.4 with the GUI looking wrong in macOS on HiDPI, do you agree? |
ah, I misunderstood from another screenshot, this is a cosmetic issue but doesn't cause misplaced / missized svgs. So this is not a blocker, just a refinement. (Still seems ok to include in 2.4 imho) |
Right. So my plan is this: (only if APPLE)
I think that should work just fine. I will try to do this later this week. In the mean time, it might be good to merge this so it gets some exposure and we detect it if it causes any graphical artifacts (I didn't see any though), and revert it once I have my dynamic solution in place. |
Don't we need the dynamic solution on the users machine? We don't know which scale factor the user has. |
Is adding both with a @2x prefix an option? |
Can we test this with the basic 2x blowup and a 150% scale on a mac? I suspect it will look fine but it's worth checking. I would prefer not to pre-render every possible scaling setting. |
I tested on 400% and it looked good. Can you confirm this? |
Here it's looking good at 200% and 400% (though Qt icons in the preferences look blurry, checkboxes, radio buttons, up/down arrows etc.) So we have
|
Yes #12364 (comment) All screenshots in #12364 (comment) are with this PR. I am in doubt that the Qt version and the OS makes a big difference, because the related QT code has not been touched. The difference is that unlike Windows, macOS has only integer scale factors by default. But we can use any scaling from the Mixxx preferences. So form this perspective only a direct rendering of the svg into the target size pixmap will be a full solution. |
I assume @daschuer refers to this, but that is never called (or is it called by Qt?). Even though I vaguely remember discussing this high-res image solution I never tested it IIRC. Is it only for Mixxx widgets? Maybe it's broken and no one noticed.. mixxx/src/widget/paintable.cpp Line 278 in 8e41e53
On the Qt side there is https://doc.qt.io/qt-6/scalability.html mentioning @2x, though IIUC it refers to images in the qrc file. |
Ok, I think we have now discussed most aspects. So we have the choice to merge this and accept the remaining edge cases and the extra CPU on start up or replace it with the "BackPath" + center solution where possible. A macOS only upscaling on our build server seems to be not required. What do you think? |
I got a bit lost with all the observations. So there is no visual degradation on non-retina setups? In any case, I do see a simple solution to modify the path to the svgs on the fly: On the long run, moving the svgs out of the style seems to be best solution, but I find it hard to say how much work that would be on a qss/xml level, and if everything now done in the styles could be done with the xml tags, and if not, what would need to be added. |
All targets share the same problem:
This gives the best visual result and performance. |
👍
I think we mixed up native app scaling (macOS retina, Windows 125% @daschuer mentioned) and Mixxx' internal scaling (which I tested, and @JoergAtGithub as well?)
It is not possible to set all icons in xml, for example AFAIK scrollbars, the treeview decoration and the buttons in the library panes (AutoDJ, Recording, Analyze, Missing, Hidden) and menu checkboxes. I'm reluctant to invest that much work into a skin system we plan to replace anyway. |
(Deleted, I got it) |
40c159e
to
9c9ca05
Compare
I have put all 2x scaled svgs in a subdirectory Does this work? Should this be macOS only or no need? |
Thank you. I don't see any impact on startup time caused by the scaling SVG -> pixmap with my i7, still floating around 6s. Would be good to know how this affects low-spec machines. @daschuer could you test with your eeePC? If there's a noticeably increased startup time it should be conditional. Some small issues: icons set on QWidgets need the size fixed in qss to be scaled correctly. fixed size, one dimension is sufficient, aspect ratio is maintained, smaller dimension is dominant appearantly Still loking good: spinboxes in decks and library, all menus (main menu, decks, library), AutoDJ controls, tracks table in-line editors, effect selectors. |
They're also too big, don't know why that looked okay earlier. |
I've set the scaling to 200% in Mixxx and that also draws oversized AutoDJ icons. Probably doesn't mean anything because I didn't see the initial bug with Qt 5.12.8 🤷 @m0dB Are the AutoDJ control icons rendered correctly in 2.4 for you? If no, hmmm.. |
Thanks for dedicating some time to this, @ronso0 . I will merge your commit that fixes the size. As for the AutoDJ icons: I see what you see: on 2.4 they are rendered without non-retina resolution, with the 2x scaled svgs they are rendered too big. |
What is strange though: on the autodj buttons the icons are too big, but they are rendered using the retina dpi. |
I cannot measure a significant difference in start-up time and memory usage. Maybe the original rendering is only a temporary. So we may pick a size, that is a common denominator of all common scalings. 4x would work, need to check. We "just" need to make sure that the final rendering is exactly 1/4 of the source. Otherwise we will se blurry again at different scaling. This is unfortunately not yet the case everywhere. |
Okay, I am finding something very interesting: these images have both width and height and viewBox. I am experimenting with (Edit: viewBox, not viewport, duh) |
Right! For example btn__broadcast_off.svg renders fine with:
and no need to insert the originally:
This might work everywhere! I can't look into this right now, but this might also make the fixed sizes you added to the qss unnecessary. |
replaced by #12407 |
This fixes #12361 by upscaling the btn__ svgs with a factor 2, by multiplying to document size of each btn__ svgs by two and inserting a 2x scale transform, for LateNight palemoon and classic. (This way this could be automated, rather than opening and resizing each svg manually)
It is surprising that this is necessary, but apparently Qt renders these svgs, when rendering with stylesheets, at the document size in pixels and only scales down, never up. I have been looking for a code-based solution but to no avail.
Apparently this is not necessary on windows / linux, so it looks like the HDPI handling is different then on macOS. I expect that this upscaled svgs have no negative effect on windows / linux, but please confirm.
Latenight palemoon:
Before:
With upscaled svgs:
Latenight classic:
Before
After