[patch] only destroy rotate in block handler

Hong Liu hong.liu at intel.com
Tue Mar 25 20:43:35 PDT 2008


This is an update of the previous patch (xf86Modes: restore block
handler when destroying rotate) I sent before (it's wrong because it may
corrupt the block handler call chain).

Fix bug #15157
This bug only happens in the following situation:
two crtcs, only the 2nd crtc is rotated. Thus when entering VT and
setting mode on the 1st crtc, X server will destroy rotate because no
crtcs are rotated (the shadow buffer on the 2nd crtc was freed when
Leaving VT). But we don't have a chance to run the BlockHandler to
unwrap the rotate block handler. Thus when we try to setup rotation on
the 2nd crtc and wrap rotation block handler, this will make both
pScreen->BlockHandler and xf86_config->BlockHandler be set to the same
function.

diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index e2d6295..d0b2fb6 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -423,24 +423,6 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 }
 
 static void
-xf86RotateBlockHandler(int screenNum, pointer blockData,
-		       pointer pTimeout, pointer pReadmask)
-{
-    ScreenPtr		pScreen = screenInfo.screens[screenNum];
-    ScrnInfoPtr		pScrn = xf86Screens[screenNum];
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-    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
 xf86RotateDestroy (xf86CrtcPtr crtc)
 {
     ScrnInfoPtr		pScrn = crtc->scrn;
@@ -478,6 +460,31 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
     }
 }
 
+static void
+xf86RotateBlockHandler(int screenNum, pointer blockData,
+		       pointer pTimeout, pointer pReadmask)
+{
+    ScreenPtr		pScreen = screenInfo.screens[screenNum];
+    ScrnInfoPtr		pScrn = xf86Screens[screenNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			c;
+
+    pScreen->BlockHandler = xf86_config->BlockHandler;
+    (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
+
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	if (!xf86_config->crtc[c]->transform_in_use)
+	    xf86RotateDestroy(xf86_config->crtc[c]);
+    }
+
+    if (xf86RotateRedisplay(pScreen))
+    {
+	/* Re-wrap if rotation is still happening */
+	xf86_config->BlockHandler = pScreen->BlockHandler;
+	pScreen->BlockHandler = xf86RotateBlockHandler;
+    }
+}
+
 _X_EXPORT void
 xf86RotateCloseScreen (ScreenPtr screen)
 {
@@ -576,7 +583,6 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
 				       F (-crtc->x), F (-crtc->y));
 	PictureTransformInitTranslate (&crtc->framebuffer_to_crtc,
 				       F ( crtc->x), F ( crtc->y));
-	xf86RotateDestroy (crtc);
     }
     else
     {








More information about the xorg mailing list