[PATCH 2/2] DRI2: keep clients suspended across VT switch

Jesse Barnes jbarnes at virtuousgeek.org
Mon Jun 28 15:59:04 PDT 2010


DRI2 overrides the GLX suspend/resume client code, potentially waking
clients while the server is VT switched away.

Fix this up by making sure we don't AttendClient after GLX has suspended
our clients.

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
---
 glx/glxdri2.c          |    4 ++-
 hw/xfree86/dri2/dri2.c |   52 ++++++++++++++++++++++++++++++++---------------
 hw/xfree86/dri2/dri2.h |    2 +
 3 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index a580df3..37ac963 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -591,7 +591,8 @@ glxDRIEnterVT (int index, int flags)
 
     if (!(*screen->enterVT) (index, flags))
 	return FALSE;
-    
+
+    DRI2EnterVT(index, flags);
     glxResumeClients();
 
     return TRUE;
@@ -606,6 +607,7 @@ glxDRILeaveVT (int index, int flags)
     LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
 
     glxSuspendClients();
+    DRI2LeaveVT(index, flags);
 
     return (*screen->leaveVT) (index, flags);
 }
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index eef822c..8fcc215 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -456,6 +456,37 @@ DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
 			  out_count, TRUE);
 }
 
+static Bool clientsBlocked;
+
+void
+DRI2EnterVT(int index, int flags)
+{
+    clientsBlocked = FALSE;
+}
+
+void
+DRI2LeaveVT(int index, int flags)
+{
+    clientsBlocked = TRUE;
+}
+
+static void
+__DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
+{
+    if (pPriv->blockedClient == NULL) {
+	IgnoreClient(client);
+	pPriv->blockedClient = client;
+    }
+}
+
+static void
+DRI2AttendClient(DRI2DrawablePtr pPriv)
+{
+    if (!clientsBlocked)
+	AttendClient(pPriv->blockedClient);
+    pPriv->blockedClient = NULL;
+}
+
 /*
  * In the direct rendered case, we throttle the clients that have more
  * than their share of outstanding swaps (and thus busy buffers) when a
@@ -477,23 +508,13 @@ DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
 	!pPriv->blockedClient) {
 	ResetCurrentRequest(client);
 	client->sequence--;
-	IgnoreClient(client);
-	pPriv->blockedClient = client;
+	__DRI2BlockClient(client, pPriv);
 	return TRUE;
     }
 
     return FALSE;
 }
 
-static void
-__DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
-{
-    if (pPriv->blockedClient == NULL) {
-	IgnoreClient(client);
-	pPriv->blockedClient = client;
-    }
-}
-
 void
 DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
 {
@@ -582,9 +603,8 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 			 frame, pPriv->swap_count);
 
     if (pPriv->blockedClient)
-	AttendClient(pPriv->blockedClient);
+	DRI2AttendClient(pPriv);
 
-    pPriv->blockedClient = NULL;
     pPriv->blockedOnMsc = FALSE;
 
 }
@@ -617,12 +637,10 @@ DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
 			     frame, pPriv->swap_count);
 	pPriv->target_sbc = -1;
 
-	AttendClient(pPriv->blockedClient);
-	pPriv->blockedClient = NULL;
+	DRI2AttendClient(pPriv);
     } else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
 	if (pPriv->blockedClient) {
-	    AttendClient(pPriv->blockedClient);
-	    pPriv->blockedClient = NULL;
+	    DRI2AttendClient(pPriv);
 	}
     }
 }
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index b50cb07..fa60a47 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -270,5 +270,7 @@ extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw,
 extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw,
 					  int frame, unsigned int tv_sec,
 					  unsigned int tv_usec);
+extern _X_EXPORT void DRI2EnterVT(int index, int flags);
+extern _X_EXPORT void DRI2LeaveVT(int index, int flags);
 
 #endif
-- 
1.6.6.1



More information about the xorg-devel mailing list