From a41a6b8350b7133de61caa0f3af30280db4734d8 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 28 Jun 2010 15:58:20 -0700 Subject: [PATCH 2/2] DRI2: keep clients suspended across VT switch 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 --- 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