[PATCH 1/2] xfree86/modes: Let the driver handle the transform

Aaron Plattner aplattner at nvidia.com
Thu Aug 25 16:34:17 PDT 2011


If a driver can use hardware to handle the crtc transform, then
there's no need for the server's shadow layer to do it.  Add a crtc
flag that lets the driver indicate that it is handling the transform.
If it's set, consider the transformed size of the screen but don't
actually enable the shadow layer.  Also stop adjusting the cursor
image and position.

Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
---
 hw/xfree86/modes/xf86Crtc.h    |   16 +++++-
 hw/xfree86/modes/xf86Cursors.c |   31 +++++++---
 hw/xfree86/modes/xf86Rotate.c  |  131 +++++++++++++++++++++-------------------
 3 files changed, 107 insertions(+), 71 deletions(-)

diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 68a968c..0d7a6a6 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2006 Keith Packard
+ * Copyright © 2011 Aaron Plattner
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -223,7 +224,7 @@ typedef struct _xf86CrtcFuncs {
 
 } xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
 
-#define XF86_CRTC_VERSION 3
+#define XF86_CRTC_VERSION 4
 
 struct _xf86Crtc {
     /**
@@ -361,6 +362,19 @@ struct _xf86Crtc {
      * Clear the shadow
      */
     Bool	    shadowClear;
+
+    /**
+     * Indicates that the driver is handling the transform, so the shadow
+     * surface should be disabled.  The driver writes this field before calling
+     * xf86CrtcRotate to indicate that it is handling the transform (including
+     * rotation and reflection).
+     *
+     * Setting this flag also causes the server to stop adjusting the cursor
+     * image and position.
+     *
+     * Added in ABI version 4
+     */
+    Bool	    driverIsPerformingTransform;
 };
 
 typedef struct _xf86OutputFuncs {
diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index 0667447..4281ab3 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -1,6 +1,6 @@
 /*
  * Copyright © 2007 Keith Packard
- * Copyright © 2010 Aaron Plattner
+ * Copyright © 2010-2011 Aaron Plattner
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -47,6 +47,18 @@
 #include "inputstr.h"
 
 /*
+ * Returns the rotation being performed by the server.  If the driver indicates
+ * that it's handling the screen transform, then this returns RR_Rotate_0.
+ */
+static Rotation
+xf86_crtc_cursor_rotation (xf86CrtcPtr crtc)
+{
+    if (crtc->driverIsPerformingTransform)
+	return RR_Rotate_0;
+    return crtc->rotation;
+}
+
+/*
  * Given a screen coordinate, rotate back to a cursor source coordinate
  */
 static void
@@ -214,6 +226,7 @@ xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
     int			xin, yin;
     int			flags = cursor_info->Flags;
     CARD32		bits;
+    const Rotation	rotation = xf86_crtc_cursor_rotation(crtc);
 
 #ifdef ARGB_CURSOR
     crtc->cursor_argb = FALSE;
@@ -222,7 +235,7 @@ xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
     for (y = 0; y < cursor_info->MaxHeight; y++)
 	for (x = 0; x < cursor_info->MaxWidth; x++) 
 	{
-	    xf86_crtc_rotate_coord (crtc->rotation,
+	    xf86_crtc_rotate_coord (rotation,
 				    cursor_info->MaxWidth,
 				    cursor_info->MaxHeight,
 				    x, y, &xin, &yin);
@@ -338,7 +351,7 @@ xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
     /*
      * Transform position of cursor on screen
      */
-    if (crtc->transform_in_use)
+    if (crtc->transform_in_use && !crtc->driverIsPerformingTransform)
     {
 	ScreenPtr	screen = scrn->pScreen;
 	xf86CursorScreenPtr ScreenPriv =
@@ -420,12 +433,13 @@ xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
     CARD8		*cursor_image;
+    const Rotation	rotation = xf86_crtc_cursor_rotation(crtc);
 
 #ifdef ARGB_CURSOR
     crtc->cursor_argb = FALSE;
 #endif
 
-    if (crtc->rotation == RR_Rotate_0)
+    if (rotation == RR_Rotate_0)
 	cursor_image = src;
     else
     {
@@ -439,7 +453,7 @@ xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
         for (y = 0; y < cursor_info->MaxHeight; y++)
 	    for (x = 0; x < cursor_info->MaxWidth; x++) 
 	    {
-		xf86_crtc_rotate_coord (crtc->rotation,
+		xf86_crtc_rotate_coord (rotation,
 					cursor_info->MaxWidth,
 					cursor_info->MaxHeight,
 					x, y, &xin, &yin);
@@ -532,12 +546,13 @@ xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor)
     int			source_height = cursor->bits->height;
     int			image_width = cursor_info->MaxWidth;
     int			image_height = cursor_info->MaxHeight;
-    
+    const Rotation	rotation = xf86_crtc_cursor_rotation(crtc);
+
     for (y = 0; y < image_height; y++)
 	for (x = 0; x < image_width; x++)
 	{
-	    xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height,
-				    x, y, &xin, &yin);
+	    xf86_crtc_rotate_coord (rotation, image_width, image_height, x, y,
+				    &xin, &yin);
 	    if (xin < source_width && yin < source_height)
 		bits = cursor_source[yin * source_width + xin];
 	    else
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 57c3499..45aabf0 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2006 Keith Packard
+ * Copyright © 2011 Aaron Plattner
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -84,7 +85,10 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
     int			n = RegionNumRects(region);
     BoxPtr		b = RegionRects(region);
     XID			include_inferiors = IncludeInferiors;
-    
+
+    if (crtc->driverIsPerformingTransform)
+	return;
+
     src = CreatePicture (None,
 			 &root->drawable,
 			 format,
@@ -290,7 +294,7 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
     }
 
     for (c = 0; c < xf86_config->num_crtc; c++)
-	if (xf86_config->crtc[c]->transform_in_use)
+	if (xf86_config->crtc[c]->rotatedData)
 	    return;
 
     /*
@@ -414,52 +418,73 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
     }
     else
     {
-	/*
-	 * these are the size of the shadow pixmap, which
-	 * matches the mode, not the pre-rotated copy in the
-	 * frame buffer
-	 */
-	int	    width = crtc->mode.HDisplay;
-	int	    height = crtc->mode.VDisplay;
-	void	    *shadowData = crtc->rotatedData;
-	PixmapPtr   shadow = crtc->rotatedPixmap;
-	int	    old_width = shadow ? shadow->drawable.width : 0;
-	int	    old_height = shadow ? shadow->drawable.height : 0;
-
-	/* Allocate memory for rotation */
-	if (old_width != width || old_height != height)
-	{
-	    if (shadow || shadowData)
+	if (crtc->driverIsPerformingTransform) {
+	    xf86RotateDestroy(crtc);
+	} else {
+	    /*
+	     * these are the size of the shadow pixmap, which
+	     * matches the mode, not the pre-rotated copy in the
+	     * frame buffer
+	     */
+	    int		width = crtc->mode.HDisplay;
+	    int		height = crtc->mode.VDisplay;
+	    void	*shadowData = crtc->rotatedData;
+	    PixmapPtr	shadow = crtc->rotatedPixmap;
+	    int		old_width = shadow ? shadow->drawable.width : 0;
+	    int		old_height = shadow ? shadow->drawable.height : 0;
+
+	    /* Allocate memory for rotation */
+	    if (old_width != width || old_height != height)
 	    {
-		crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
-		crtc->rotatedPixmap = NULL;
-		crtc->rotatedData = NULL;
+		if (shadow || shadowData)
+		{
+		    crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
+		    crtc->rotatedPixmap = NULL;
+		    crtc->rotatedData = NULL;
+		}
+		shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
+		if (!shadowData)
+		    goto bail1;
+		crtc->rotatedData = shadowData;
+		/* shadow will be damaged in xf86RotatePrepare */
+	    }
+	    else
+	    {
+		/* mark shadowed area as damaged so it will be repainted */
+		damage = TRUE;
 	    }
-	    shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
-	    if (!shadowData)
-		goto bail1;
-	    crtc->rotatedData = shadowData;
-	    /* shadow will be damaged in xf86RotatePrepare */
-	}
-	else
-	{
-	    /* mark shadowed area as damaged so it will be repainted */
-	    damage = TRUE;
-	}
 
-	if (!xf86_config->rotation_damage)
-	{
-	    /* Create damage structure */
-	    xf86_config->rotation_damage = DamageCreate (NULL, NULL,
-						DamageReportNone,
-						TRUE, pScreen, pScreen);
 	    if (!xf86_config->rotation_damage)
-		goto bail2;
-	    
-	    /* Wrap block handler */
-	    if (!xf86_config->BlockHandler) {
-		xf86_config->BlockHandler = pScreen->BlockHandler;
-		pScreen->BlockHandler = xf86RotateBlockHandler;
+	    {
+		/* Create damage structure */
+		xf86_config->rotation_damage = DamageCreate (NULL, NULL,
+						    DamageReportNone,
+						    TRUE, pScreen, pScreen);
+		if (!xf86_config->rotation_damage)
+		    goto bail2;
+
+		/* Wrap block handler */
+		if (!xf86_config->BlockHandler) {
+		    xf86_config->BlockHandler = pScreen->BlockHandler;
+		    pScreen->BlockHandler = xf86RotateBlockHandler;
+		}
+	    }
+
+	    if (0)
+	    {
+	bail2:
+		if (shadow || shadowData)
+		{
+		    crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
+		    crtc->rotatedPixmap = NULL;
+		    crtc->rotatedData = NULL;
+		}
+	bail1:
+		if (old_width && old_height)
+		    crtc->rotatedPixmap =
+			crtc->funcs->shadow_create (crtc, NULL, old_width,
+						    old_height);
+		return FALSE;
 	    }
 	}
 #ifdef RANDR_12_INTERFACE
@@ -482,24 +507,6 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
 	    }
 	}
 #endif
-
-	if (0)
-	{
-    bail2:
-	    if (shadow || shadowData)
-	    {
-		crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
-		crtc->rotatedPixmap = NULL;
-		crtc->rotatedData = NULL;
-	    }
-    bail1:
-	    if (old_width && old_height)
-		crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
-								  NULL,
-								  old_width,
-								  old_height);
-	    return FALSE;
-	}
 	crtc->transform_in_use = TRUE;
     }
     crtc->crtc_to_framebuffer = crtc_to_fb;
-- 
1.7.4.1



More information about the xorg-devel mailing list