xserver: Branch 'mpx' - 3 commits

Peter Hutterer whot at kemper.freedesktop.org
Tue May 6 05:35:12 PDT 2008


 hw/xfree86/ramdac/xf86Cursor.c |  139 ++++++++++++++++++++++++++++++++++-------
 hw/xfree86/ramdac/xf86HWCurs.c |    4 -
 2 files changed, 118 insertions(+), 25 deletions(-)

New commits:
commit 9e0d73fd8a43647b648ec5b2f0bcaae30c03259c
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue May 6 17:52:15 2008 +0930

    xfree86: call SetCursor for the VCP when switching between SW/HW rendering.
    
    We need a manual call to SetCursor when we switch from SW to HW rendering and
    the other way round. This way we display the new cursor after removing the old
    one.
    In addition, we only update the internal state for the VCP's sprite. This way,
    when we switch back to HW rendering the state is up-to-date and wasn't
    overwritten with the other sprite's state.
    
    The second part is a hack. It would be better to keep a state for each sprite,
    but then again we don't have hardware that can render multiple cursors so we
    might as well do with the hack.

diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 4ecb03e..010575b 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -302,10 +302,16 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
     miPointerScreenPtr PointPriv;
 
-    ScreenPriv->CurrentCursor = pCurs;
-    ScreenPriv->x = x;
-    ScreenPriv->y = y;
-    ScreenPriv->CursorToRestore = NULL;
+    /* only update for VCP, otherwise we get cursor jumps when removing a
+       sprite. The second cursor is never HW rendered anyway. */
+    if (pDev == inputInfo.pointer ||
+	    (!pDev->isMaster && pDev->u.master == inputInfo.pointer))
+    {
+	ScreenPriv->CurrentCursor = pCurs;
+	ScreenPriv->x = x;
+	ScreenPriv->y = y;
+	ScreenPriv->CursorToRestore = NULL;
+    }
 
     if (!infoPtr->pScrn->vtSema)
 	 ScreenPriv->SavedCursor = pCurs;
@@ -322,8 +328,12 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
 	return;
     }
 
-    ScreenPriv->HotX = pCurs->bits->xhot;
-    ScreenPriv->HotY = pCurs->bits->yhot;
+    if (pDev == inputInfo.pointer ||
+	    (!pDev->isMaster && pDev->u.master == inputInfo.pointer))
+    {
+	ScreenPriv->HotX = pCurs->bits->xhot;
+	ScreenPriv->HotY = pCurs->bits->yhot;
+    }
 
     PointPriv = (miPointerScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						     miPointerScreenKey);
@@ -379,12 +389,17 @@ xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
 	&pScreen->devPrivates, xf86CursorScreenKey);
 
-    ScreenPriv->x = x;
-    ScreenPriv->y = y;
+    /* only update coordinate state for first sprite, otherwise we get jumps
+       when removing a sprite. The second sprite is never HW rendered anyway */
+    if (pDev == inputInfo.pointer ||
+            (!pDev->isMaster && pDev->u.master == inputInfo.pointer))
+    {
+	ScreenPriv->x = x;
+	ScreenPriv->y = y;
+    }
 
     if (ScreenPriv->CursorToRestore)
-	xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore,
-			    ScreenPriv->x, ScreenPriv->y);
+	xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore, x, y);
     else if (ScreenPriv->SWCursor)
 	(*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
     else if (ScreenPriv->isUp)
@@ -441,14 +456,24 @@ xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
 static Bool
 xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
 {
+    int ret;
     xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
             &pScreen->devPrivates, xf86CursorScreenKey);
 
+    /* Init SW cursor */
+    ret = (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen);
+
     if (pDev != inputInfo.pointer)
+    {
+	if (!ScreenPriv->SWCursor)
+	{
+	    ScreenPriv->spriteFuncs->SetCursor(inputInfo.pointer, pScreen,
+		    ScreenPriv->CurrentCursor, ScreenPriv->x, ScreenPriv->y);
+	}
         ScreenPriv->SWCursor = TRUE | XF86_FORCE_SW_CURSOR;
+    }
 
-    /* Init SW cursor */
-    return (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen);
+    return ret;
 }
 
 /**
@@ -469,7 +494,11 @@ xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
     }
 
     if (!it) /* no other sprites except VCP. restore HW rendering */
-        ScreenPriv->SWCursor = TRUE;
+    {
+	ScreenPriv->SWCursor = TRUE;
+	xf86CursorSetCursor(inputInfo.pointer, pScreen,
+		ScreenPriv->CurrentCursor, ScreenPriv->x, ScreenPriv->y);
+    }
 
     /* Clean up SW cursor */
     (*ScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
commit b9c1a57e7a98dea63cd362f714411547e728a85a
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue May 6 14:51:23 2008 +0930

    xfree86: switch between to SW cursors if more than 1 sprite is available.
    
    Switches back to HW cursors when sprites other than the VCP are removed.
    The current state requires the cursor to change shape once before it updates
    to SW / HW rendering (whatever is appropriate), e.g. by moving into a
    different window. Until this is done, the cursor is invisible.

diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 61fb0ed..4ecb03e 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -20,6 +20,8 @@ extern InputInfo inputInfo;
 
 DevPrivateKey xf86CursorScreenKey = &xf86CursorScreenKey;
 
+#define XF86_FORCE_SW_CURSOR (1 << 7)
+
 /* sprite functions */
 
 static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
@@ -325,25 +327,29 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
 
     PointPriv = (miPointerScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
 						     miPointerScreenKey);
-    if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
+    if (!(ScreenPriv->SWCursor & XF86_FORCE_SW_CURSOR))
+    {
+	if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
 #ifdef ARGB_CURSOR
-	pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
-	 (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
-	pCurs->bits->argb == 0 &&
+			    pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
+			    (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
+			    pCurs->bits->argb == 0 &&
 #endif
-	(pCurs->bits->height <= infoPtr->MaxHeight) &&
-	(pCurs->bits->width <= infoPtr->MaxWidth) &&
-	(!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))))))
-    {
+			    (pCurs->bits->height <= infoPtr->MaxHeight) &&
+			    (pCurs->bits->width <= infoPtr->MaxWidth) &&
+			    (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))))))
+	{
 
 	if (ScreenPriv->SWCursor)	/* remove the SW cursor */
-	      (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
+	  (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
 
 	xf86SetCursor(pScreen, pCurs, x, y);
 	ScreenPriv->SWCursor = FALSE;
 	ScreenPriv->isUp = TRUE;
 	PointPriv->waitForUpdate = !infoPtr->pScrn->silkenMouse;
 	return;
+  }
+
     }
 
     PointPriv->waitForUpdate = TRUE;
@@ -358,10 +364,12 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
 	}
     }
 
-    ScreenPriv->SWCursor = TRUE;
+    if (!ScreenPriv->SWCursor)
+        ScreenPriv->SWCursor = TRUE;
 
     if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
 	pCurs = NullCursor;
+
     (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, pCurs, x, y);
 }
 
@@ -436,6 +444,9 @@ xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
     xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
             &pScreen->devPrivates, xf86CursorScreenKey);
 
+    if (pDev != inputInfo.pointer)
+        ScreenPriv->SWCursor = TRUE | XF86_FORCE_SW_CURSOR;
+
     /* Init SW cursor */
     return (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen);
 }
@@ -446,9 +457,20 @@ xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
 static void
 xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
 {
+    DeviceIntPtr it;
     xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
             &pScreen->devPrivates, xf86CursorScreenKey);
 
+    for (it = inputInfo.devices; it; it = it->next)
+    {
+        if (it->isMaster && it != inputInfo.pointer && it !=
+                inputInfo.keyboard)
+            break;
+    }
+
+    if (!it) /* no other sprites except VCP. restore HW rendering */
+        ScreenPriv->SWCursor = TRUE;
+
     /* Clean up SW cursor */
     (*ScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
 }
commit 3df88c17e315b5ae580096e4bc88920d1f452e83
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue May 6 11:50:20 2008 +0930

    xfree86: re-enable hardware cursor (for a single cursor)
    
    This commit enables HW rendering for cursors again, but only for a single
    cursor. Other cursors can be created, however they will not be visible.

diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 5c909c7..61fb0ed 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -26,12 +26,18 @@ static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
 static Bool xf86CursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
 static void xf86CursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int);
 static void xf86CursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int);
+static Bool xf86DeviceCursorInitialize(DeviceIntPtr, ScreenPtr);
+static void xf86DeviceCursorCleanup(DeviceIntPtr, ScreenPtr);
+static void xf86DeviceCursorUndisplay(DeviceIntPtr, ScreenPtr);
 
 static miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
    xf86CursorRealizeCursor,
    xf86CursorUnrealizeCursor,
    xf86CursorSetCursor,
-   xf86CursorMoveCursor
+   xf86CursorMoveCursor,
+   xf86DeviceCursorInitialize,
+   xf86DeviceCursorCleanup,
+   xf86DeviceCursorUndisplay
 };
 
 /* Screen functions */
@@ -420,3 +426,43 @@ xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
 {
     xfree(infoPtr);
 }
+
+/**
+ * New cursor has been created. Do your initalizations here.
+ */
+static Bool
+xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+            &pScreen->devPrivates, xf86CursorScreenKey);
+
+    /* Init SW cursor */
+    return (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen);
+}
+
+/**
+ * Cursor has been removed. Clean up after yourself.
+ */
+static void
+xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+            &pScreen->devPrivates, xf86CursorScreenKey);
+
+    /* Clean up SW cursor */
+    (*ScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
+}
+
+/**
+ * Called on server shutdown to remove all cursors from the screen before
+ * bringing the server down.
+ */
+static void
+xf86DeviceCursorUndisplay(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+            &pScreen->devPrivates, xf86CursorScreenKey);
+
+    /* Undisplay SW cursor */
+    (*ScreenPriv->spriteFuncs->UndisplayCursor)(pDev, pScreen);
+}
diff --git a/hw/xfree86/ramdac/xf86HWCurs.c b/hw/xfree86/ramdac/xf86HWCurs.c
index 4c5ef40..d10e283 100644
--- a/hw/xfree86/ramdac/xf86HWCurs.c
+++ b/hw/xfree86/ramdac/xf86HWCurs.c
@@ -73,10 +73,6 @@ static unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
 Bool
 xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
 {
-    /* Graphics cards cannot render multiple cursors in hardware. We have to
-       software render them. */
-    return FALSE;
-
     if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
 	return FALSE;
 


More information about the xorg-commit mailing list