mirror of https://github.com/encounter/SDL.git
SetDisplayMode: Call XRRSetScreenSize before setting CRTC config
X11_SetDisplayMode currently calls X11_XRRSetCrtcConfig alone. This results in the monitor's viewport getting changed, but the underlying screen dimensions stay the same. The spec indicates that RRSetCrtcConfig only changes the crtc mode and has no effect on the screen dimensions, only mentioning that the new crtc must fit entirely within the screen size. For the size to change, RRSetScreenSize also needs to be called. This affects Metro Exodus on Linux, when changing the resolution in the in-game settings Metro gets stuck in a loop waiting for the size of its vulkan surface to change. Because XRRSetScreenSize is not called the screen size is never changed, the vulkan surface dimensions do not change, and Metro hangs forever watching for a surface size update that will never come. This change disables the CRTC, calls XRRSetScreenSize, and then updates the CRTC configuration. This fixes changing the resolution from the Metro settings. Tested with: Metro Exodus, Portal 2
This commit is contained in:
parent
118480e563
commit
16e3bfe807
|
@ -1002,6 +1002,7 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode
|
||||||
Display *display = viddata->display;
|
Display *display = viddata->display;
|
||||||
SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
|
SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
|
||||||
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
|
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
|
||||||
|
int mm_width, mm_height;
|
||||||
|
|
||||||
viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2);
|
viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2);
|
||||||
|
|
||||||
|
@ -1030,10 +1031,23 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode
|
||||||
return SDL_SetError("Couldn't get XRandR crtc info");
|
return SDL_SetError("Couldn't get XRandR crtc info");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X11_XGrabServer(display);
|
||||||
|
status = X11_XRRSetCrtcConfig(display, res, output_info->crtc, CurrentTime,
|
||||||
|
0, 0, None, crtc->rotation, NULL, 0);
|
||||||
|
if (status != Success) {
|
||||||
|
goto setCrtcError;
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_width = mode->w * DisplayWidthMM(display, data->screen) / DisplayWidth(display, data->screen);
|
||||||
|
mm_height = mode->h * DisplayHeightMM(display, data->screen) / DisplayHeight(display, data->screen);
|
||||||
|
X11_XRRSetScreenSize(display, RootWindow(display, data->screen), mode->w, mode->h, mm_width, mm_height);
|
||||||
|
|
||||||
status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
|
status = X11_XRRSetCrtcConfig (display, res, output_info->crtc, CurrentTime,
|
||||||
crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
|
crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
|
||||||
&data->xrandr_output, 1);
|
&data->xrandr_output, 1);
|
||||||
|
|
||||||
|
setCrtcError:
|
||||||
|
X11_XUngrabServer(display);
|
||||||
X11_XRRFreeCrtcInfo(crtc);
|
X11_XRRFreeCrtcInfo(crtc);
|
||||||
X11_XRRFreeOutputInfo(output_info);
|
X11_XRRFreeOutputInfo(output_info);
|
||||||
X11_XRRFreeScreenResources(res);
|
X11_XRRFreeScreenResources(res);
|
||||||
|
|
Loading…
Reference in New Issue