[PATCH] RandR 1.2 driver screen resize hook

Aaron Plattner aplattner at nvidia.com
Tue Feb 27 11:08:00 PST 2007


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
-------------- next part --------------
From 383a98ba2c21ac909968210e7951a0c68ae8d9be Mon Sep 17 00:00:00 2001
From: Aaron Plattner <aplattner at nvidia.com>
Date: Mon, 26 Feb 2007 17:45:40 -0800
Subject: [PATCH] Return BadMatch if a client tries to clone non-cloneable outputs.

---
 randr/rrcrtc.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index fdd1d42..474c946 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -667,6 +667,27 @@ ProcRRSetCrtcConfig (ClientPtr client)
 	    return BadMatch;
 	}
     }
+    /* validate clones */
+    for (i = 0; i < numOutputs; i++)
+    {
+	for (j = 0; j < numOutputs; j++)
+	{
+	    int k;
+	    if (i == j)
+		continue;
+	    for (k = 0; k < outputs[i]->numClones; k++)
+	    {
+		if (outputs[i]->clones[k] == outputs[j])
+		    break;
+	    }
+	    if (k == outputs[i]->numClones)
+	    {
+		if (outputs)
+		    xfree (outputs);
+		return BadMatch;
+	    }
+	}
+    }
 
     pScreen = crtc->pScreen;
     pScrPriv = rrGetScrPriv(pScreen);
-- 
1.4.4.4

-------------- next part --------------
From 09a60e72fd719e224e8adc30b169ce9cc5e15039 Mon Sep 17 00:00:00 2001
From: Aaron Plattner <aplattner at nvidia.com>
Date: Tue, 27 Feb 2007 10:06:09 -0800
Subject: [PATCH] Driver hook for randr 1.2 drivers to resize the screen.

Adds new DriverFunc ops RR12_GET_SCREEN_SIZE_RANGES and RR12_SET_SCREEN_SIZE.
If a driver returns TRUE to the former, the randr 1.2 DDX code will pass the
returned size ranges to the DIX.  When a client requests that the screen be
resized, the DDX will call DriverFunc with the RR12_SET_SCREEN_SIZE op, passing
in the new desktop size in the xorgRR12Size argument.  The driver is responsible
for updating virtualX and virtualY.
---
 hw/xfree86/common/xf86str.h    |   28 ++++++++++++++++++++-
 hw/xfree86/modes/xf86RandR12.c |   52 ++++++++++++++++++++++++++++++++-------
 2 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 6e62e52..3a95147 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -256,6 +256,8 @@ typedef enum {
     RR_GET_INFO,
     RR_SET_CONFIG,
     RR_GET_MODE_MM,
+    RR12_GET_SCREEN_SIZE_RANGES,
+    RR12_SET_SCREEN_SIZE,
     GET_REQUIRED_HW_INTERFACES = 10
 } xorgDriverFuncOp;
 
@@ -268,7 +270,7 @@ typedef struct {
     int rate;
     int width;
     int height;
-} xorgRRConfig;
+} xorgRRConfig, *xorgRRConfigPtr;
 
 typedef union {
     short RRRotations;
@@ -284,6 +286,30 @@ typedef struct {
     int mmHeight;
 } xorgRRModeMM, *xorgRRModeMMPtr;
 
+/* RR12_GET_SCREEN_SIZE_RANGES */
+/*
+ * Allows a driver to tell the RandR 1.2 DDX layer what range of root window
+ * sizes it supports.  If a driver returns TRUE in response to this request, it
+ * must also support the RR12_SET_SCREEN_SIZE request.
+ */
+typedef struct {
+    int minWidth;
+    int maxWidth;
+    int minHeight;
+    int maxHeight;
+} xorgRR12SizeRanges, *xorgRR12SizeRangesPtr;
+
+/* RR12_SET_SCREEN_SIZE */
+/*
+ * Tells the driver to reallocate the screen to the requested size.  A driver is
+ * responsible for changing the screen's virtualX and virtualY in response to
+ * this request.
+ */
+typedef struct {
+    int width;
+    int height;
+} xorgRR12Size, *xorgRR12SizePtr;
+
 /* GET_REQUIRED_HW_INTERFACES */
 #define HW_IO 1
 #define HW_MMIO 2
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index abdf92e..8e54945 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -55,6 +55,7 @@ typedef struct _xf86RandR12Info {
     int				    maxY;
     Rotation			    rotation; /* current mode */
     Rotation                        supported_rotations; /* driver supported */
+    Bool			    driverSupportsResize; /* driver implements RR12_SET_SCREEN_SIZE */
 } XF86RandRInfoRec, *XF86RandRInfoPtr;
 
 #ifdef RANDR_12_INTERFACE
@@ -336,7 +337,8 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScreen,
     XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
     ScrnInfoPtr		pScrn = XF86SCRNINFO(pScreen);
     WindowPtr		pRoot = WindowTable[pScreen->myNum];
-    Bool 		ret = TRUE;
+    Bool 		ret = FALSE;
+    Bool		changed = FALSE;
 
     if (randrp->virtualX == -1 || randrp->virtualY == -1)
     {
@@ -345,20 +347,38 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScreen,
     }
     if (pRoot)
 	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
-    pScrn->virtualX = width;
-    pScrn->virtualY = height;
 
-    pScreen->width = pScrn->virtualX;
-    pScreen->height = pScrn->virtualY;
+    if (randrp->driverSupportsResize)
+    {
+	xorgRR12Size size;
+
+	size.width = width;
+	size.height = height;
+
+	/* Let the driver change virtualX and virtualY */
+	if (!(*pScrn->DriverFunc)(pScrn, RR12_SET_SCREEN_SIZE, &size))
+	    goto finish;
+    } else {
+	pScrn->virtualX = width;
+	pScrn->virtualY = height;
+    }
+
+    changed = TRUE;
+    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] && changed)
 	RRScreenSizeNotify (pScreen);
 #endif
     return ret;
@@ -482,6 +502,7 @@ xf86RandR12Init (ScreenPtr pScreen)
     randrp->supported_rotations = RR_Rotate_0;
 
     randrp->maxX = randrp->maxY = 0;
+    randrp->driverSupportsResize = FALSE;
 
     pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
 
@@ -906,13 +927,24 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
     XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xorgRR12SizeRanges  ranges;
 
     for (c = 0; c < config->num_crtc; c++)
 	xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-    
-    
-    RRScreenSetSizeRange (pScreen, 320, 240,
-			  randrp->virtualX, randrp->virtualY);
+
+    if (pScrn->DriverFunc &&
+	(*pScrn->DriverFunc)(pScrn, RR12_GET_SCREEN_SIZE_RANGES, &ranges))
+    {
+	randrp->driverSupportsResize = TRUE;
+	RRScreenSetSizeRange (pScreen, ranges.minWidth, ranges.minHeight,
+			      ranges.maxWidth, ranges.maxHeight);
+    }
+    else
+    {
+	randrp->driverSupportsResize = FALSE;
+	RRScreenSetSizeRange (pScreen, 320, 240,
+			      randrp->virtualX, randrp->virtualY);
+    }
     return TRUE;
 }
 
-- 
1.4.4.4

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.x.org/archives/xorg/attachments/20070227/06a53606/attachment.pgp>


More information about the xorg mailing list