xf86-video-intel: Branch 'modesetting-rotation' - 2 commits - src/i830_xf86Rotate.c

Keith Packard keithp at kemper.freedesktop.org
Sat Jan 27 10:11:33 EET 2007


 src/i830_xf86Rotate.c |   88 ++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 74 insertions(+), 14 deletions(-)

New commits:
diff-tree 7a5f17087bda2833e84fa7e7ff0cb168943b89b6 (from 2d95cb6f041653f7e530b1f32cf007929c23ef3b)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Sat Jan 27 00:11:21 2007 -0800

    Mark crtc region as damaged when rotation is set.
    
    When shadow frame buffer is allocated for rotation, it needs to be
    initialized by copying from the frame buffer. Do this by simply marking the
    entire screen as damaged which will force an update.

diff --git a/src/i830_xf86Rotate.c b/src/i830_xf86Rotate.c
index abfaec6..7d056e5 100644
--- a/src/i830_xf86Rotate.c
+++ b/src/i830_xf86Rotate.c
@@ -328,6 +328,8 @@ xf86CrtcRotate (xf86CrtcPtr crtc, Displa
 	PixmapPtr   shadow = crtc->rotatedPixmap;
 	int	    old_width = shadow ? shadow->drawable.width : 0;
 	int	    old_height = shadow ? shadow->drawable.height : 0;
+	BoxRec	    damage_box;
+	RegionRec   damage_region;
 	
 	/* Allocate memory for rotation */
 	if (old_width != width || old_height != height)
@@ -363,6 +365,14 @@ xf86CrtcRotate (xf86CrtcPtr crtc, Displa
 	    {
 		goto bail3;
 	    }
+	    damage_box.x1 = 0;
+	    damage_box.y1 = 0;
+	    damage_box.x2 = mode_width (mode, rotation);
+	    damage_box.y2 = mode_height (mode, rotation);
+	    REGION_INIT (pScreen, &damage_region, &damage_box, 1);
+	    DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+				&damage_region);
+	    REGION_UNINIT (pScreen, &damage_region);
 	}
 	if (0)
 	{
diff-tree 2d95cb6f041653f7e530b1f32cf007929c23ef3b (from 5c1e27cdd243dc24dd2bfdeb46d757bbef6ba6af)
Author: Keith Packard <keithp at guitar.keithp.com>
Date:   Sat Jan 27 00:04:13 2007 -0800

    Make rotated pixmap size of mode, not rotated mode. Update only damage.
    
    Rotated pixmap should match size of displayed mode, not the rotated version
    of that size.
    
    Take damaged region, rotate each box and display them instead of displaying
    the whole screen after each damage update. This exposes a bug where the
    screen is not correctly damaged after rotation.

diff --git a/src/i830_xf86Rotate.c b/src/i830_xf86Rotate.c
index 8da79b6..abfaec6 100644
--- a/src/i830_xf86Rotate.c
+++ b/src/i830_xf86Rotate.c
@@ -94,6 +94,46 @@ compWindowFormat (WindowPtr pWin)
 }
 
 static void
+xf86RotateBox (BoxPtr dst, BoxPtr src, Rotation rotation,
+	       int dest_width, int dest_height)
+{
+    switch (rotation & 0xf) {
+    default:
+    case RR_Rotate_0:
+	*dst = *src;
+	break;
+    case RR_Rotate_90:
+	dst->x1 = src->y1;
+	dst->y1 = dest_height - src->x2;
+	dst->x2 = src->y2;
+	dst->y2 = dest_height - src->x1;
+	break;
+    case RR_Rotate_180:
+	dst->x1 = dest_width - src->x2;
+	dst->y1 = dest_height - src->y2;
+	dst->x2 = dest_width - src->x1;
+	dst->y2 = dest_height - src->y1;
+	break;
+    case RR_Rotate_270:
+	dst->x1 = dest_width - src->y2;
+	dst->y1 = src->x1;
+	dst->y2 = src->x2;
+	dst->x2 = dest_width - src->y1;
+	break;
+    }
+    if (rotation & RR_Reflect_X) {
+	int x1 = dst->x1;
+	dst->x1 = dest_width - dst->x2;
+	dst->x2 = dest_width - x1;
+    }
+    if (rotation & RR_Reflect_Y) {
+	int y1 = dst->y1;
+	dst->y1 = dest_height - dst->y2;
+	dst->y2 = dest_height - y1;
+    }
+}
+
+static void
 xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
 {
     ScrnInfoPtr		scrn = crtc->scrn;
@@ -104,6 +144,8 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crt
     int			error;
     PicturePtr		src, dst;
     PictTransform	transform;
+    int			n = REGION_NUM_RECTS(region);
+    BoxPtr		b = REGION_RECTS(region);
     
     src = CreatePicture (None,
 			 &src_pixmap->drawable,
@@ -127,18 +169,13 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crt
 	ErrorF("couldn't create src pict\n");
 	return;
     }
-    /* Unfortunately, we don't do clipping on transformed source pictures.
-     * So we can't use this.  Instead, we'll just repaint the whole screen
-     * for now, and do transform of the source region into a dest region
-     * later.
-     */
-    /* SetPictureClipRegion (src, 0, 0, region); */
 
     memset (&transform, '\0', sizeof (transform));
     transform.matrix[2][2] = IntToxFixed(1);
     transform.matrix[0][2] = IntToxFixed(crtc->x);
     transform.matrix[1][2] = IntToxFixed(crtc->y);
     switch (crtc->rotation & 0xf) {
+    default:
     case RR_Rotate_0:
 	transform.matrix[0][0] = IntToxFixed(1);
 	transform.matrix[1][1] = IntToxFixed(1);
@@ -177,11 +214,19 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crt
 	return;
     }
 
-    CompositePicture (PictOpSrc,
-		      src, NULL, dst,
-		      0, 0, 0, 0, 0, 0,
-		      dst_pixmap->drawable.width,
-		      dst_pixmap->drawable.height);
+    while (n--)
+    {
+	BoxRec	dst_box;
+
+	xf86RotateBox (&dst_box, b, crtc->rotation,
+		       crtc->mode.HDisplay, crtc->mode.VDisplay);
+	CompositePicture (PictOpSrc,
+			  src, NULL, dst,
+			  dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
+			  dst_box.x2 - dst_box.x1,
+			  dst_box.y2 - dst_box.y1);
+	b++;
+    }
     FreePicture (src, None);
     FreePicture (dst, None);
 }
@@ -220,7 +265,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 		
 		/* update damaged region */
 		if (REGION_NOTEMPTY(pScreen, &crtc_damage))
-		    xf86RotateCrtcRedisplay (crtc, &crtc_damage);
+    		    xf86RotateCrtcRedisplay (crtc, &crtc_damage);
 		
 		REGION_UNINIT (pScreen, &crtc_damage);
 	    }
@@ -273,8 +318,13 @@ xf86CrtcRotate (xf86CrtcPtr crtc, Displa
     }
     else
     {
-	int	    width = mode_width (mode, rotation);
-	int	    height = mode_height (mode, rotation);
+	/* 
+	 * these are the size of the shadow pixmap, which
+	 * matches the mode, not the pre-rotated copy in the
+	 * frame buffer
+	 */
+	int	    width = mode->HDisplay;
+	int	    height = mode->VDisplay;
 	PixmapPtr   shadow = crtc->rotatedPixmap;
 	int	    old_width = shadow ? shadow->drawable.width : 0;
 	int	    old_height = shadow ? shadow->drawable.height : 0;



More information about the xorg-commit mailing list