Sophie

Sophie

distrib > * > 2008.0 > x86_64 > by-pkgid > e265b08b6bebf8514a189c80db57a2d3 > files > 27

x11-server-1.3.0.0-25.1mdv2008.0.src.rpm

From 28276a8aa71a2276873470cba7f0701009cfbbb1 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp@neko.keithp.com>
Date: Thu, 17 May 2007 20:24:18 -0700
Subject: [PATCH] Use Screen block handler for rotation to draw under DRI lock.

DRI uses a non-screen block/wakeup handler which will be executed after the
screen block handler finishes. To ensure that the rotation block handler is
executed under the DRI lock, dynamically wrap the screen block handler for
rotation.
---
 hw/xfree86/modes/xf86Crtc.h   |   11 ++++++++++
 hw/xfree86/modes/xf86Rotate.c |   44 +++++++++++++++++-----------------------
 2 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index e64ce1e..2d62600 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -555,6 +555,17 @@ typedef struct _xf86CrtcConfig {
     CARD8		*cursor_image;
     Bool		cursor_on;
     CARD32		cursor_fg, cursor_bg;
+
+    /**
+     * Options parsed from the related device section
+     */
+    OptionInfoPtr	options;
+
+    Bool		debug_modes;
+
+    /* wrap screen BlockHandler for rotation */
+    ScreenBlockHandlerProcPtr	BlockHandler;
+
 } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
 
 extern int xf86CrtcConfigPrivateIndex;
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 359501e..1379939 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -264,7 +264,7 @@ xf86RotatePrepare (ScreenPtr pScreen)
     }
 }
 
-static void
+static Bool
 xf86RotateRedisplay(ScreenPtr pScreen)
 {
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
@@ -273,7 +273,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
     RegionPtr		region;
 
     if (!damage)
-	return;
+	return FALSE;
     xf86RotatePrepare (pScreen);
     region = DamageRegion(damage);
     if (REGION_NOTEMPTY(pScreen, region)) 
@@ -317,19 +317,25 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 	pScreen->SourceValidate = SourceValidate;
 	DamageEmpty(damage);
     }
+    return TRUE;
 }
 
 static void
-xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
+xf86RotateBlockHandler(int screenNum, pointer blockData,
+		       pointer pTimeout, pointer pReadmask)
 {
-    ScreenPtr pScreen = (ScreenPtr) data;
-
-    xf86RotateRedisplay(pScreen);
-}
+    ScreenPtr		pScreen = screenInfo.screens[screenNum];
+    ScrnInfoPtr		pScrn = xf86Screens[screenNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 
-static void
-xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask)
-{
+    pScreen->BlockHandler = xf86_config->BlockHandler;
+    (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
+    if (xf86RotateRedisplay(pScreen))
+    {
+	/* Re-wrap if rotation is still happening */
+	xf86_config->BlockHandler = pScreen->BlockHandler;
+	pScreen->BlockHandler = xf86RotateBlockHandler;
+    }
 }
 
 static void
@@ -367,10 +373,6 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
 	}
 	DamageDestroy (xf86_config->rotation_damage);
 	xf86_config->rotation_damage = NULL;
-	/* Free block/wakeup handler */
-	RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
-				      xf86RotateWakeupHandler,
-				      (pointer) pScreen);
     }
 }
 
@@ -440,20 +442,12 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
 	    if (!xf86_config->rotation_damage)
 		goto bail2;
 	    
-	    /* Assign block/wakeup handler */
-	    if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler,
-						 xf86RotateWakeupHandler,
-						 (pointer) pScreen))
-	    {
-		goto bail3;
-	    }
+	    /* Wrap block handler */
+	    xf86_config->BlockHandler = pScreen->BlockHandler;
+	    pScreen->BlockHandler = xf86RotateBlockHandler;
 	}
 	if (0)
 	{
-bail3:
-	    DamageDestroy (xf86_config->rotation_damage);
-	    xf86_config->rotation_damage = NULL;
-	    
 bail2:
 	    if (shadow || shadowData)
 	    {
-- 
1.5.2.4