[Xorg] X.org driver support for RandR rotation

Egbert Eich eich at pdx.freedesktop.org
Tue Jul 27 02:17:52 PDT 2004


Aaron Plattner writes:
 > Hello,
 > 
 > Currently, there is no way for a driver to be notified of RandR events.  This
 > patch adds ScrnInfoRec functions which a driver can hook into to register which
 > rotations are supported and be notified when RandR events happen.  This is
 > necessary mainly for hardware rotation support.
 > 
 > There are a few bugs that occur when the screen is rotated 90 or 270 degrees.  A
 > few functions compare pScreen->{width,height} to mode sizes, which is incorrect
 > when the dimensions of the root window are swapped.  This patch changes these
 > functions to use virtualX and virtualY, which are not swapped in rotated modes.
 > This bug also affects drivers such as nv and fbdev that support the "Rotate"
 > option in the config file.  (To reproduce, use nv with 'Option "Rotate" "CW"'
 > and then try using Ctrl-Alt-+ and -).
 > 
 > -- Aaron Plattner
 > 

Aaron, 

Thank you for your patch! I would like to make a few comments:

1. Only drivers that support rotation entirely in HW would benefit from this
extension. About a year ago I have tried implementing a software solution 
taking advantage of the layer code. I failed as the layer code is not 
able to deal with the private structures to the drawables that each function
in the rendering layer can allocate in a graceful way:
When layers are switched a different chain of functions is called. This
may leave some privates unallocated which will be used in a different layer
(from a different rotation).
I did not investigate further on this issue as the plan is to handle screen
rotation when doing the screen composition in the long run.
We should explore how your proposed changes can fit into this picture.

2. There is no sample implementation in any of the X.Org drivers yet.
However to include a new functionality like this into the DDX I feel we 
should have at least one sample implementation for an open source driver.
Maybe you can provide an implementation for the nv driver.

3. Also - and I admit this is a question of personal taste - should we use up
two function slots in the ScrnInfoRec structure for this or can we get by
with just one that is used both for query and setup?

Cheers,
	Egbert.
 


 > Index: hw/xfree86/common/xf86Cursor.c
 > ===================================================================
 > RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86Cursor.c,v
 > retrieving revision 1.1.1.2
 > diff -u -r1.1.1.2 xf86Cursor.c
 > --- hw/xfree86/common/xf86Cursor.c	25 Nov 2003 19:28:32 -0000	1.1.1.2
 > +++ hw/xfree86/common/xf86Cursor.c	23 Jul 2004 22:29:21 -0000
 > @@ -222,7 +222,7 @@
 >    if (mode == pScr->currentMode)
 >      return TRUE;
 >  
 > -  if (mode->HDisplay > pScreen->width || mode->VDisplay > pScreen->height)
 > +  if (mode->HDisplay > pScr->virtualX || mode->VDisplay > pScr->virtualY)
 >      return FALSE;
 >  
 >    pCursorScreen = miPointerCurrentScreen();
 > Index: hw/xfree86/common/xf86Init.c
 > ===================================================================
 > RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86Init.c,v
 > retrieving revision 1.2
 > diff -u -r1.2 xf86Init.c
 > --- hw/xfree86/common/xf86Init.c	23 Apr 2004 19:20:32 -0000	1.2
 > +++ hw/xfree86/common/xf86Init.c	23 Jul 2004 22:29:21 -0000
 > @@ -897,6 +897,8 @@
 >  	xf86Screens[i]->DPMSSet = NULL;
 >  	xf86Screens[i]->LoadPalette = NULL; 
 >  	xf86Screens[i]->SetOverscan = NULL;
 > +	xf86Screens[i]->RRGetInfo = NULL;
 > +	xf86Screens[i]->RRSetConfig = NULL;
 >  	scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
 >        if (scr_index == i) {
 >  	/*
 > Index: hw/xfree86/common/xf86RandR.c
 > ===================================================================
 > RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86RandR.c,v
 > retrieving revision 1.2
 > diff -u -r1.2 xf86RandR.c
 > --- hw/xfree86/common/xf86RandR.c	23 Apr 2004 19:20:32 -0000	1.2
 > +++ hw/xfree86/common/xf86RandR.c	23 Jul 2004 22:29:21 -0000
 > @@ -38,6 +38,7 @@
 >      CloseScreenProcPtr		    CloseScreen;
 >      int				    virtualX;
 >      int				    virtualY;
 > +    Rotation			    rotation;
 >  } XF86RandRInfoRec, *XF86RandRInfoPtr;
 >      
 >  static int	    xf86RandRIndex;
 > @@ -77,8 +78,8 @@
 >  	    return FALSE;
 >  	RRRegisterRate (pScreen, pSize, refresh);
 >  	if (mode == scrp->currentMode &&
 > -	    mode->HDisplay == pScreen->width && mode->VDisplay == pScreen->height)
 > -	    RRSetCurrentConfig (pScreen, RR_Rotate_0, refresh, pSize);
 > +	    mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
 > +	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
 >  	if (mode->next == scrp->modes)
 >  	    break;
 >      }
 > @@ -93,12 +94,17 @@
 >  	if (!pSize)
 >  	    return FALSE;
 >  	RRRegisterRate (pScreen, pSize, refresh0);
 > -	if (pScreen->width == randrp->virtualX && 
 > -	    pScreen->height == randrp->virtualY)
 > +	if (scrp->virtualX == randrp->virtualX && 
 > +	    scrp->virtualY == randrp->virtualY)
 >  	{
 > -	    RRSetCurrentConfig (pScreen, RR_Rotate_0, refresh0, pSize);
 > +	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
 >  	}
 >      }
 > +
 > +    /* If there is driver support for randr, let it set our supported rotations */
 > +    if(scrp->RRGetInfo)
 > +	return (*scrp->RRGetInfo)(scrp, rotations);
 > +
 >      return TRUE;
 >  }
 >  
 > @@ -125,8 +131,17 @@
 >  	scrp->virtualX = mode->HDisplay;
 >  	scrp->virtualY = mode->VDisplay;
 >      }
 > -    pScreen->width = scrp->virtualX;
 > -    pScreen->height = scrp->virtualY;
 > +    if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
 > +    {
 > +	/* If the screen is rotated 90 or 270 degrees, swap the sizes. */
 > +	pScreen->width = scrp->virtualY;
 > +	pScreen->height = scrp->virtualX;
 > +    }
 > +    else
 > +    {
 > +	pScreen->width = scrp->virtualX;
 > +	pScreen->height = scrp->virtualY;
 > +    }
 >      if (!xf86SwitchMode (pScreen, mode))
 >      {
 >  	scrp->virtualX = pScreen->width = oldWidth;
 > @@ -160,6 +175,8 @@
 >      int			    px, py;
 >      Bool		    useVirtual = FALSE;
 >  
 > +    randrp->rotation = rotation;
 > +
 >      miPointerPosition (&px, &py);
 >      for (mode = scrp->modes; ; mode = mode->next)
 >      {
 > @@ -179,6 +196,12 @@
 >  	    return FALSE;
 >  	}
 >      }
 > +
 > +    /* Have the driver do its thing. */
 > +    if (scrp->RRSetConfig &&
 > +        !(*scrp->RRSetConfig)(scrp, rotation, rate, pSize->width, pSize->height))
 > +	return FALSE;
 > +
 >      if (!xf86RandRSetMode (pScreen, mode, useVirtual))
 >  	return FALSE;
 >      /*
 > @@ -189,6 +212,7 @@
 >  	if (px < pSize->width && py < pSize->height)
 >  	    (*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
 >      }
 > +
 >      return TRUE;
 >  }
 >  
 > @@ -277,6 +301,8 @@
 >      randrp->CloseScreen = pScreen->CloseScreen;
 >      pScreen->CloseScreen = xf86RandRCloseScreen;
 >  
 > +    randrp->rotation = RR_Rotate_0;
 > +
 >      pScreen->devPrivates[xf86RandRIndex].ptr = randrp;
 >      return TRUE;
 >  }
 > Index: hw/xfree86/common/xf86str.h
 > ===================================================================
 > RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/common/xf86str.h,v
 > retrieving revision 1.1.1.2
 > diff -u -r1.1.1.2 xf86str.h
 > --- hw/xfree86/common/xf86str.h	25 Nov 2003 19:28:33 -0000	1.1.1.2
 > +++ hw/xfree86/common/xf86str.h	23 Jul 2004 22:29:22 -0000
 > @@ -476,7 +476,7 @@
 >  /* These values should be adjusted when new fields are added to ScrnInfoRec */
 >  #define NUM_RESERVED_INTS		16
 >  #define NUM_RESERVED_POINTERS		15
 > -#define NUM_RESERVED_FUNCS		12
 > +#define NUM_RESERVED_FUNCS		10
 >  
 >  typedef pointer (*funcPointer)(void);
 >  
 > @@ -767,6 +767,8 @@
 >  typedef void xf86DPMSSetProc		  (ScrnInfoPtr, int, int);
 >  typedef void xf86LoadPaletteProc   (ScrnInfoPtr, int, int *, LOCO *, VisualPtr);
 >  typedef void xf86SetOverscanProc          (ScrnInfoPtr, int);
 > +typedef Bool xf86RRGetInfoProc            (ScrnInfoPtr, unsigned short *);
 > +typedef Bool xf86RRSetConfigProc          (ScrnInfoPtr, int, int, int, int);
 >  
 >  /*
 >   * ScrnInfoRec
 > @@ -921,6 +923,8 @@
 >      xf86DPMSSetProc			*DPMSSet;
 >      xf86LoadPaletteProc			*LoadPalette;
 >      xf86SetOverscanProc			*SetOverscan;
 > +    xf86RRGetInfoProc			*RRGetInfo;
 > +    xf86RRSetConfigProc			*RRSetConfig;
 >      
 >      /*
 >       * This can be used when the minor ABI version is incremented.
 > _______________________________________________
 > xorg mailing list
 > xorg at freedesktop.org
 > http://freedesktop.org/mailman/listinfo/xorg



More information about the xorg mailing list