From 0904421f57a6e3c1889cda145ec318c7071a3ee0 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Mon, 4 Apr 2022 14:22:20 +0200 Subject: [PATCH 1/2] randr: Add "RANDR Emulation" property When RANDR is emulated as with Xwayland, the actual output configuration does not change as RANDR is emulated using viewports. As a result, changes to the CRTC may be skipped, resulting in the configuration being (wrongly) assumed to be unchanged. Add a new output property "RANDR Emulation" that the DDX can set to force RRCrtcSet() to reconfigure the CRTC regardless of the change. Signed-off-by: Olivier Fourdan Reviewed-by: Hans de Goede --- randr/rrcrtc.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index cf66f8ef9..cf149768f 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -709,6 +709,25 @@ rrCheckPixmapBounding(ScreenPtr pScreen, return TRUE; } +#define XRANDR_EMULATION_PROP "RANDR Emulation" +static Bool +rrCheckEmulated(RROutputPtr output) +{ + const char *emulStr = XRANDR_EMULATION_PROP; + Atom emulProp; + RRPropertyValuePtr val; + + emulProp = MakeAtom(emulStr, strlen(emulStr), FALSE); + if (emulProp == None) + return FALSE; + + val = RRGetOutputProperty(output, emulProp, TRUE); + if (val && val->data) + return !!val->data; + + return FALSE; +} + /* * Request that the Crtc be reconfigured */ @@ -728,9 +747,11 @@ RRCrtcSet(RRCrtcPtr crtc, crtcChanged = FALSE; for (o = 0; o < numOutputs; o++) { - if (outputs[o] && outputs[o]->crtc != crtc) { - crtcChanged = TRUE; - break; + if (outputs[o]) { + if (rrCheckEmulated(outputs[o]) || (outputs[o]->crtc != crtc)) { + crtcChanged = TRUE; + break; + } } } -- GitLab From 7b7170ecd636ae1110622e2430549f79598750ca Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Mon, 4 Apr 2022 14:28:15 +0200 Subject: [PATCH 2/2] xwayland/output: Set the "RANDR Emulation" property Xwayland does not change the actual XRANDR setup for real, it just emulates the resolution changes using viewports in Wayland. With a single output, if an X11 applications tries to change the CRTC back to the native mode, RRCrtcSet() will simply ignore the request as no actual change is induced by this. Set the property "RANDR Emulation" on all Xwayland outputs to make sure the optimizations in RRCrtcSet() get skipped and Xwayland can receive and act upon the client request. Also make sure we do not allow that property to be changed by X11 clients. v2: Prevent X11 clients from changing the property value (Pekka Paalanen ) Signed-off-by: Olivier Fourdan Reviewed-by: Hans de Goede Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1305 --- hw/xwayland/xwayland-output.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index d2fa4e0bb..3ad8adc8b 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -720,6 +720,27 @@ static const struct zxdg_output_v1_listener xdg_output_listener = { xdg_output_handle_description, }; +#define XRANDR_EMULATION_PROP "RANDR Emulation" +static Atom +get_rand_emulation_property(void) +{ + const char *emulStr = XRANDR_EMULATION_PROP; + + return MakeAtom(emulStr, strlen(emulStr), TRUE); +} + +static void +xwl_output_set_emulated(struct xwl_output *xwl_output) +{ + int32_t val = TRUE; + + RRChangeOutputProperty(xwl_output->randr_output, + get_rand_emulation_property(), + XA_INTEGER, + 32, PropModeReplace, 1, + &val, FALSE, FALSE); +} + struct xwl_output * xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id) { @@ -758,6 +779,7 @@ xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id) ErrorF("Failed creating RandR Output\n"); goto err; } + xwl_output_set_emulated(xwl_output); RRCrtcGammaSetSize(xwl_output->randr_crtc, 256); RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1); @@ -896,6 +918,10 @@ xwl_randr_output_set_property(ScreenPtr pScreen, Atom property, RRPropertyValuePtr value) { + /* RANDR Emulation property is read-only. */ + if (get_rand_emulation_property() == property) + return FALSE; + return TRUE; } -- GitLab