[PATCH] RandR 1.2 driver screen resize hook (heads up)
Aaron Plattner
aplattner at nvidia.com
Fri Mar 2 12:36:01 PST 2007
I just pushed these to master. RandR 1.2 drivers will need to be updated.
-- Aaron
On Wed, Feb 28, 2007 at 08:19:39PM -0800, Aaron Plattner wrote:
> I talked to Keith some more and he pointed out that screen-level driver hooks
> could be attached to the xf86CrtcConfigRec. These changes add that support. If
> there are no objections, I'll check these in later this week or possibly early
> next week.
>
> -- Aaron
>
> On Tue, Feb 27, 2007 at 11:08:00AM -0800, Aaron Plattner wrote:
> > I'm actually going to sneak two patches into this message. The first is a
> > straightforward fix to have ProcRRSetCrtcConfig reject client requests to clone
> > non-cloneable outputs.
> >
> > The second patch is more interesting. It adds a driver hook to report to the
> > DDX the range of desktop sizes it supports, as well as a hook to actually resize
> > the screen in response to a client resize request. Currently, the randr 1.2
> > code is forced to try to set virtualX and virtualY big enough so that the driver
> > will statically allocate enough space during PreInit for the largest modes on
> > each output. This wastes memory and doesn't even work right in the monitor
> > hotplug case. With these hooks, a driver can reallocate its vidmem, allowing
> > the desktop to grow larger than the virtual size configured in PreInit.
> >
> > Keith Packard actually suggested that this interface be mandatory for randr 1.2
> > drivers, which would make this second patch a bit smaller. A naive (read "XAA")
> > driver that can't actually resize the desktop will simply report its configured
> > virtualX and virtualY in response to RR12_GET_SCREEN_SIZE_RANGES and just set
> > virtualX and virtualY (and nothing else) in response to RR12_SET_SCREEN_SIZE. A
> > more advanced driver will want to reallocate its vidmem and change devKind and
> > devPrivate.ptr in the screen pixmap as well. If there are no objections, I'll
> > make it mandatory.
> >
> > Driver developers: Does this interface look like it will work for your drivers?
> > Feedback is welcome.
> >
> > -- Aaron
> From 562b183307e758b9f9db6d2e089d33945184d449 Mon Sep 17 00:00:00 2001
> From: Aaron Plattner <aplattner at nvidia.com>
> Date: Wed, 28 Feb 2007 13:36:58 -0800
> Subject: [PATCH] Add a screen resize hook to xf86CrtcConfigRec.
>
> This hook is called when the DDX needs to resize the screen. The driver is
> responsible for changing virtualX and virtualY, along with any other related
> screen properties (devPrivate.ptr, devKind, displayWidth, etc.).
>
> Use the size range from the crtc config instead of randrp->virtual[XY] when
> reporting the min and max screen sizes to the DDX.
> ---
> hw/xfree86/modes/xf86Crtc.c | 6 +++++-
> hw/xfree86/modes/xf86Crtc.h | 24 +++++++++++++++++++++++-
> hw/xfree86/modes/xf86RandR12.c | 24 +++++++++++++++---------
> 3 files changed, 43 insertions(+), 11 deletions(-)
>
> diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
> index 29042a0..ebc0f8f 100644
> --- a/hw/xfree86/modes/xf86Crtc.c
> +++ b/hw/xfree86/modes/xf86Crtc.c
> @@ -52,13 +52,17 @@
> int xf86CrtcConfigPrivateIndex = -1;
>
> void
> -xf86CrtcConfigInit (ScrnInfoPtr scrn)
> +xf86CrtcConfigInit (ScrnInfoPtr scrn,
> + const xf86CrtcConfigFuncsRec *funcs)
> {
> xf86CrtcConfigPtr config;
>
> if (xf86CrtcConfigPrivateIndex == -1)
> xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
> config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
> +
> + config->funcs = funcs;
> +
> scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
> }
>
> diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
> index 756730e..345332b 100644
> --- a/hw/xfree86/modes/xf86Crtc.h
> +++ b/hw/xfree86/modes/xf86Crtc.h
> @@ -407,6 +407,25 @@ struct _xf86Output {
> #endif
> };
>
> +typedef struct _xf86CrtcConfigFuncs {
> + /**
> + * Requests that the driver resize the screen.
> + *
> + * The driver is responsible for updating scrn->virtualX and scrn->virtualY.
> + * If the requested size cannot be set, the driver should leave those values
> + * alone and return FALSE.
> + *
> + * A naive driver that cannot reallocate the screen may simply change
> + * virtual[XY]. A more advanced driver will want to also change the
> + * devPrivate.ptr and devKind of the screen pixmap, update any offscreen
> + * pixmaps it may have moved, and change pScrn->displayWidth.
> + */
> + Bool
> + (*resize)(ScrnInfoPtr scrn,
> + int width,
> + int height);
> +} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
> +
> typedef struct _xf86CrtcConfig {
> int num_output;
> xf86OutputPtr *output;
> @@ -435,6 +454,8 @@ typedef struct _xf86CrtcConfig {
> int dga_width, dga_height, dga_stride;
> DisplayModePtr dga_save_mode;
>
> + const xf86CrtcConfigFuncsRec *funcs;
> +
> } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
>
> extern int xf86CrtcConfigPrivateIndex;
> @@ -446,7 +467,8 @@ extern int xf86CrtcConfigPrivateIndex;
> */
>
> void
> -xf86CrtcConfigInit (ScrnInfoPtr scrn);
> +xf86CrtcConfigInit (ScrnInfoPtr scrn,
> + const xf86CrtcConfigFuncsRec *funcs);
>
> void
> xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
> diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
> index abdf92e..052d12a 100644
> --- a/hw/xfree86/modes/xf86RandR12.c
> +++ b/hw/xfree86/modes/xf86RandR12.c
> @@ -335,8 +335,9 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
> {
> XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
> ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
> + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
> WindowPtr pRoot = WindowTable[pScreen->myNum];
> - Bool ret = TRUE;
> + Bool ret = FALSE;
>
> if (randrp->virtualX == -1 || randrp->virtualY == -1)
> {
> @@ -345,20 +346,26 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
> }
> if (pRoot)
> (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
> - pScrn->virtualX = width;
> - pScrn->virtualY = height;
>
> - pScreen->width = pScrn->virtualX;
> - pScreen->height = pScrn->virtualY;
> + /* Let the driver update virtualX and virtualY */
> + if (!(*config->funcs->resize)(pScrn, width, height))
> + goto finish;
> +
> + ret = TRUE;
> +
> + pScreen->width = width;
> + pScreen->height = height;
> pScreen->mmWidth = mmWidth;
> pScreen->mmHeight = mmHeight;
>
> xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
> xf86SetViewport (pScreen, 0, 0);
> +
> +finish:
> if (pRoot)
> (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
> #if RANDR_12_INTERFACE
> - if (WindowTable[pScreen->myNum])
> + if (WindowTable[pScreen->myNum] && ret)
> RRScreenSizeNotify (pScreen);
> #endif
> return ret;
> @@ -904,15 +911,14 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
> {
> int c;
> ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
> - XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
> xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
>
> for (c = 0; c < config->num_crtc; c++)
> xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
>
>
> - RRScreenSetSizeRange (pScreen, 320, 240,
> - randrp->virtualX, randrp->virtualY);
> + RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight,
> + config->maxWidth, config->maxHeight);
> return TRUE;
> }
>
> --
> 1.4.4.4
>
> From f87dfcef7d5968dfa6690b2e038cca61d3246909 Mon Sep 17 00:00:00 2001
> From: Aaron Plattner <aplattner at nvidia.com>
> Date: Wed, 28 Feb 2007 14:26:47 -0800
> Subject: [PATCH] Add a canGrow argument to xf86InitialConfiguration.
>
> canGrow indicates to the DDX that the driver can enlarge the desktop via the
> xf86_config->funcs->resize hook. If so, xf86InitialConfiguration will set
> virtual[XY] to match the configuration it chooses and will leave the crtc config
> size ranges alone. If FALSE, it will bloat the screen to fit the largest probed
> mode and also set the crtc config max size to limit the desktop to the initial
> virtual[XY] size.
> ---
> hw/xfree86/modes/xf86Crtc.c | 78 +++++++++++++++++++++++++++++-------------
> hw/xfree86/modes/xf86Crtc.h | 2 +-
> 2 files changed, 55 insertions(+), 25 deletions(-)
>
> diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
> index ebc0f8f..c53d2a8 100644
> --- a/hw/xfree86/modes/xf86Crtc.c
> +++ b/hw/xfree86/modes/xf86Crtc.c
> @@ -734,12 +734,16 @@ xf86PickCrtcs (ScrnInfoPtr scrn,
>
> /*
> * Compute the virtual size necessary to place all of the available
> - * crtcs in the specified configuration and also large enough to
> - * resize any crtc to the largest available mode
> + * crtcs in the specified configuration.
> + *
> + * canGrow indicates that the driver can make the screen larger than its initial
> + * configuration. If FALSE, this function will enlarge the screen to include
> + * the largest available mode.
> */
>
> static void
> -xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp)
> +xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp,
> + Bool canGrow)
> {
> xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
> int width = 0, height = 0;
> @@ -757,26 +761,28 @@ xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp)
> crtc_width = crtc->x + xf86ModeWidth (&crtc->desiredMode, crtc->desiredRotation);
> crtc_height = crtc->y + xf86ModeHeight (&crtc->desiredMode, crtc->desiredRotation);
> }
> - for (o = 0; o < config->num_output; o++)
> - {
> - xf86OutputPtr output = config->output[o];
> + if (!canGrow) {
> + for (o = 0; o < config->num_output; o++)
> + {
> + xf86OutputPtr output = config->output[o];
>
> - for (s = 0; s < config->num_crtc; s++)
> - if (output->possible_crtcs & (1 << s))
> - {
> - DisplayModePtr mode;
> - for (mode = output->probed_modes; mode; mode = mode->next)
> + for (s = 0; s < config->num_crtc; s++)
> + if (output->possible_crtcs & (1 << s))
> {
> - if (mode->HDisplay > crtc_width)
> - crtc_width = mode->HDisplay;
> - if (mode->VDisplay > crtc_width)
> - crtc_width = mode->VDisplay;
> - if (mode->VDisplay > crtc_height)
> - crtc_height = mode->VDisplay;
> - if (mode->HDisplay > crtc_height)
> - crtc_height = mode->HDisplay;
> + DisplayModePtr mode;
> + for (mode = output->probed_modes; mode; mode = mode->next)
> + {
> + if (mode->HDisplay > crtc_width)
> + crtc_width = mode->HDisplay;
> + if (mode->VDisplay > crtc_width)
> + crtc_width = mode->VDisplay;
> + if (mode->VDisplay > crtc_height)
> + crtc_height = mode->VDisplay;
> + if (mode->HDisplay > crtc_height)
> + crtc_height = mode->HDisplay;
> + }
> }
> - }
> + }
> }
> if (crtc_width > width)
> width = crtc_width;
> @@ -1350,10 +1356,17 @@ xf86SetScrnInfoModes (ScrnInfoPtr scrn)
> *
> * Given auto-detected (and, eventually, configured) values,
> * construct a usable configuration for the system
> + *
> + * canGrow indicates that the driver can resize the screen to larger than its
> + * initially configured size via the config->funcs->resize hook. If TRUE, this
> + * function will set virtualX and virtualY to match the initial configuration
> + * and leave config->max{Width,Height} alone. If FALSE, it will bloat
> + * virtual[XY] to include the largest modes and set config->max{Width,Height}
> + * accordingly.
> */
>
> Bool
> -xf86InitialConfiguration (ScrnInfoPtr scrn)
> +xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
> {
> xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
> int o, c;
> @@ -1491,9 +1504,10 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
> if (scrn->display->virtualX == 0)
> {
> /*
> - * Expand virtual size to cover potential mode switches
> + * Expand virtual size to cover the current config and potential mode
> + * switches, if the driver can't enlarge the screen later.
> */
> - xf86DefaultScreenLimits (scrn, &width, &height);
> + xf86DefaultScreenLimits (scrn, &width, &height, canGrow);
>
> scrn->display->virtualX = width;
> scrn->display->virtualY = height;
> @@ -1503,7 +1517,23 @@ xf86InitialConfiguration (ScrnInfoPtr scrn)
> scrn->virtualX = width;
> if (height > scrn->virtualY)
> scrn->virtualY = height;
> -
> +
> + /*
> + * Make sure the configuration isn't too small.
> + */
> + if (width < config->minWidth || height < config->minHeight)
> + return FALSE;
> +
> + /*
> + * Limit the crtc config to virtual[XY] if the driver can't grow the
> + * desktop.
> + */
> + if (!canGrow)
> + {
> + xf86CrtcSetSizeRange (scrn, config->minWidth, config->minHeight,
> + width, height);
> + }
> +
> /* Mirror output modes to scrn mode list */
> xf86SetScrnInfoModes (scrn);
>
> diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
> index 345332b..b04f7f3 100644
> --- a/hw/xfree86/modes/xf86Crtc.h
> +++ b/hw/xfree86/modes/xf86Crtc.h
> @@ -545,7 +545,7 @@ void
> xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
>
> Bool
> -xf86InitialConfiguration (ScrnInfoPtr pScrn);
> +xf86InitialConfiguration (ScrnInfoPtr pScrn, Bool canGrow);
>
> void
> xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
> --
> 1.4.4.4
>
>
> =====================
> This message appears to be from an NVIDIA.COM e-mail address, yet did not originate from an NVIDIA server.
> Please be cautious of any attachments or links in this message.
> Thank you, NVIDIA IT Team.
> =====================
> _______________________________________________
> xorg mailing list
> xorg at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/xorg
More information about the xorg
mailing list