[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