New Smart integer scaling implementation to address #18154 #18296
+62
−38
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This pull request proposes a different approach to smart scaling. It chooses overscaling for 240p and 480p content when it would result in at least 192 or 384 lines being shown (i.e. the title safe area); other content (mainly handhelds) is allowed up to 6 cropped lines to accommodate a few resolutions which almost match the overscaled content. Otherwise, underscaling is chosen, as long as it doesn't result in a margin larger than 12% (a threshold I chose by testing various content/display combinations.) If neither condition is satisfied, non-integer scaling is used. In other words, it only opts for integer scaling when it's "close enough."
I've tried to follow the Coding Standards as best I could, but this is my first contribution to RetroArch and I don't typically code in C, so I apologize in advance for any missteps.
Related Issues
"Smart" integer scaling is bugged #18154
In short, this change is trying to address the fact that the current Smart scaling implementation 1) doesn't behave consistently with regards to choosing underscaling or overscaling, and 2) sometimes allows excessive amounts of cropping or letterboxing. My guiding principle was to choose heuristics that would be simple for the end user to understand and unlikely to annoy.
Examples
224p scaled to 1280x720
Underscaled with 6.67% margin.

224p scaled to 1280x800 (Steam Deck)
Overscaled with 16.67% cropping

224p scaled to 1920x1080
Overscaled with 10% cropping.

480p scaled to 1280x720
Stretched to fit. Overscaling would crop 25%, underscaling would waste 1/3 of the screen's height.

480p scaled to 1920x1080
Underscaled with 11.11% margin.

GBA (160p) scaled to 1280x720
Underscaled with 11.11% margin.

GBA (160p) scaled to 1920x1080
Overscaled with 3 lines cropped from the top and bottom each.

PSP (272p) scaled to 1280x720
Stretched to fit. Overscaling would crop 16 lines from the top and bottom each, underscaling would waste 24.4% of the screen height.

PSP (272p) scaled to 1280x800 (Steam Deck)
Also stretched to fit, but this example demonstrates that the scaling works correctly when the screen aspect ratio is taller than the content.

PSP (272p) scaled to 1920x1080
Overscaled with

2 lines1 line cropped from the top and bottom each.Future work
Ideally the cutoff for choosing between underscaling and stretching would be configurable, but I have no experience implementing new config settings.
Reviewers
@sonninnos According to Git blame, they wrote the initial Smart scaling implementation.