[Switch] Use the display's resolution, 1080p when docked - #25
Open
ferrolho wants to merge 1 commit into
Open
Conversation
The window size was hardcoded in four getters, so a docked console rendered 720p and left the system scaler to stretch it to the TV. OS_Switch::get_window_size() was the load-bearing one: SceneTree polls it every iteration and rebuilds the root viewport when it changes, so a constant there meant a resize could never propagate. Size the NWindow from appletGetOperationMode() before creating the EGL surface, report what eglQuerySurface actually returns, and poll the operation mode each frame to rebuild the surface when the console is docked or undocked.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The problem
The Switch outputs 1080p to a TV, but a libnx app only gets a 1080p framebuffer if it asks for one. It has to size its
NWindowand notice when the operating mode changes. This port never did, so it always rendered 720p and let the console's scaler stretch that to the television.Four getters returned hardcoded sizes, one of them marked unfinished:
get_window_size()is the one that matters most.SceneTreecompares it against the previous frame's value every iteration and rebuilds the root viewport when it changes. A constant there means a resize can never propagate, whatever else the port does. It also means the engine side needs no changes: once the port reports the real size, the existing resize path handles the rest.The change
NWindowwithnwindowSetDimensions()before creating the EGL surface, based onappletGetOperationMode(): 1920x1080 docked, 1280x720 handheld.eglQuerySurface) instead of what we asked for.appletGetOperationMode()once per frame inOS_Switch::run(). On a change, rebuild the window surface and updatecurrent_videomode. libnx has no notification for docking, so polling is the only option. The value is cached in the applet service, so it is not an IPC call.get_screen_size(), which previously fell through to the base class.The surface rebuild keeps the EGL context, and falls back to recreating the previous size if the new one fails. A refused resize leaves the engine with a working surface rather than none.
Testing
Tested on a v1 Switch with Atmosphère over several sessions:
Note for project authors
A project that renders 3D into a sub-viewport and blits it gets sharper 2D and UI at no extra 3D cost, because the sub-viewport keeps its own size. A project that renders 3D straight to the root viewport will shade 2.25x the pixels when docked. I can add a project setting to opt out if you would prefer that.