randr: Take panning into account when computing CRTC bounds

Submitted by Rui Matos on June 30, 2011, 10:02 a.m.

Details

Message ID 1309402954-21067-1-git-send-email-tiagomatos@gmail.com
State Deferred, archived
Headers show

Commit Message

Rui Matos June 30, 2011, 10:02 a.m.
Fixes regression introduced in 56c90e29f04727c903bd0f084d23bf44eb1a0a11.

Signed-off-by: Rui Matos <tiagomatos@gmail.com>
---
 hw/xfree86/modes/xf86RandR12.c |    5 +++
 randr/randrstr.h               |    1 +
 randr/rrcrtc.c                 |   56 ++++++++++++++++++++++++++++++++++-----
 3 files changed, 54 insertions(+), 8 deletions(-)

v2: Since crtc_bounds() is called a lot, use a flag on the crtc structure to
check for panning before calling rrGetPanning().

Patch hide | download patch | download mbox

diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index cb20d1c..7eefb19 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -336,7 +336,12 @@  xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
     if (! crtc->enabled						||
 	(crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1	&&
 	 crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1))
+    {
+	crtc->randr_crtc->panning = FALSE;
 	return;
+    }
+
+    crtc->randr_crtc->panning = TRUE;
 
     newX   = crtc->x;
     newY   = crtc->y;
diff --git a/randr/randrstr.h b/randr/randrstr.h
index d8dd37d..84d548e 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -119,6 +119,7 @@  struct _rrCrtc {
     CARD16	    *gammaBlue;
     CARD16	    *gammaGreen;
     void	    *devPrivate;
+    Bool            panning;
     Bool	    transforms;
     RRTransformRec  client_pending_transform;
     RRTransformRec  client_current_transform;
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 0437795..fa5d5ba 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -90,6 +90,7 @@  RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
     crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
     crtc->changed = FALSE;
     crtc->devPrivate = devPrivate;
+    crtc->panning = FALSE;
     RRTransformInit (&crtc->client_pending_transform);
     RRTransformInit (&crtc->client_current_transform);
     pixman_transform_init_identity (&crtc->transform);
@@ -297,21 +298,60 @@  RRCrtcPendingProperties (RRCrtcPtr crtc)
 static void
 crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
 {
-    *left = crtc->x;
-    *top = crtc->y;
+    ScreenPtr pScreen = crtc->pScreen;
+    rrScrPriv (pScreen);
+    BoxRec panned_area;
+    Bool x_pan = FALSE;
+    Bool y_pan = FALSE;
+
+    if (crtc->panning) {
+        pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL);
+        x_pan = panned_area.x2 > panned_area.x1;
+        y_pan = panned_area.y2 > panned_area.y1;
+    }
 
     switch (crtc->rotation) {
     case RR_Rotate_0:
     case RR_Rotate_180:
     default:
-       *right = crtc->x + crtc->mode->mode.width;
-       *bottom = crtc->y + crtc->mode->mode.height;
-       return;
+
+        if (x_pan) {
+            *left = panned_area.x1;
+            *right = panned_area.x2;
+        } else {
+            *left = crtc->x;
+            *right = crtc->x + crtc->mode->mode.width;
+        }
+
+        if (y_pan) {
+            *top = panned_area.y1;
+            *bottom = panned_area.y2;
+        } else {
+            *top = crtc->y;
+            *bottom = crtc->y + crtc->mode->mode.height;
+        }
+
+        return;
     case RR_Rotate_90:
     case RR_Rotate_270:
-       *right = crtc->x + crtc->mode->mode.height;
-       *bottom = crtc->y + crtc->mode->mode.width;
-       return;
+
+        if (x_pan) {
+            *left = panned_area.x1;
+            *right = panned_area.x2;
+        } else {
+            *left = crtc->x;
+            *right = crtc->x + crtc->mode->mode.height;
+        }
+
+        if (y_pan) {
+            *top = panned_area.y1;
+            *bottom = panned_area.y2;
+        } else {
+            *top = crtc->y;
+            *bottom = crtc->y + crtc->mode->mode.width;
+        }
+
+        return;
     }
 }