From: Francisco J. <cur...@ri...> - 2010-01-16 22:00:37
|
Bumps the supported DRI2 protocol version to 1.3. Signed-off-by: Francisco Jerez <cur...@ri...> --- hw/xfree86/dri2/dri2.c | 82 +++++++++++++++++++++++++++++++++++++++++++ hw/xfree86/dri2/dri2.h | 4 ++ hw/xfree86/dri2/dri2ext.c | 22 +++++++++++ include/protocol-versions.h | 2 +- 4 files changed, 109 insertions(+), 1 deletions(-) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 65433e9..783c98f 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -65,6 +65,12 @@ typedef struct _DRI2Drawable { CARD64 target_sbc; /* -1 means no SBC wait outstanding */ CARD64 last_swap_target; /* most recently queued swap target */ int swap_limit; /* for N-buffering */ + + /* Array of clients that want to be notified + * when the drawable dimensions change. */ + ClientPtr *track_clients; + int track_count; + } DRI2DrawableRec, *DRI2DrawablePtr; typedef struct _DRI2Screen *DRI2ScreenPtr; @@ -83,6 +89,8 @@ typedef struct _DRI2Screen { DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC; HandleExposuresProcPtr HandleExposures; + + PreConfigureWindowProcPtr PreConfigureWindow; } DRI2ScreenRec; static DRI2ScreenPtr @@ -142,6 +150,8 @@ DRI2CreateDrawable(DrawablePtr pDraw) pPriv->swap_interval = 1; pPriv->last_swap_target = -1; pPriv->swap_limit = 1; /* default to double buffering */ + pPriv->track_clients = NULL; + pPriv->track_count = 0; if (pDraw->type == DRAWABLE_WINDOW) { @@ -380,6 +390,54 @@ DRI2BlockClient(ClientPtr client, DrawablePtr pDraw) } int +DRI2TrackClient(ClientPtr client, DrawablePtr pDraw) +{ + DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); + ClientPtr *clients; + int i; + + if (pPriv == NULL) + return BadDrawable; + + /* Check if the client is already in. */ + for (i = 0; i < pPriv->track_count; i++) { + if (pPriv->track_clients[i] == client) + return Success; + } + + /* Grow the track_clients array. */ + clients = xrealloc(pPriv->track_clients, + (pPriv->track_count + 1) * sizeof(*clients)); + if (clients == NULL) + return BadAlloc; + + pPriv->track_clients = clients; + pPriv->track_clients[pPriv->track_count++] = client; + + return Success; +} + +void +DRI2InvalidateDrawable(DrawablePtr pDraw) +{ + DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw); + int i; + + if (pPriv == NULL) + return; + + for (i = 0; i < pPriv->track_count; i++) + DRI2InvalidateBuffersEvent(pPriv->track_clients[i], pDraw); + + pPriv->track_count = 0; + + if (pPriv->track_clients) { + xfree(pPriv->track_clients); + pPriv->track_clients = NULL; + } +} + +int DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, unsigned int dest, unsigned int src) { @@ -760,6 +818,9 @@ DRI2DestroyDrawable(DrawablePtr pDraw) if (!pPriv->swapsPending) xfree(pPriv); + if (pPriv->track_clients) + xfree(pPriv->track_clients); + if (pDraw->type == DRAWABLE_WINDOW) { pWin = (WindowPtr) pDraw; @@ -802,6 +863,24 @@ DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic) return TRUE; } +static void +DRI2PreConfigureWindow(WindowPtr pWin, int x, int y, int w, int h, int bw, + WindowPtr pSib) +{ + DrawablePtr pDraw = (DrawablePtr)pWin; + ScreenPtr pScreen = pDraw->pScreen; + DRI2ScreenPtr ds = DRI2GetScreen(pScreen); + DRI2DrawablePtr dd = DRI2GetDrawable(pDraw); + + if (ds->PreConfigureWindow) + (*ds->PreConfigureWindow)(pWin, x, y, w, h, bw, pSib); + + if (!dd || (dd->width == w && dd->height == h)) + return; + + DRI2InvalidateDrawable(pDraw); +} + Bool DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) { @@ -836,6 +915,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds); + ds->PreConfigureWindow = pScreen->PreConfigureWindow; + pScreen->PreConfigureWindow = DRI2PreConfigureWindow; + xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n"); return TRUE; diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index c0f82ee..b448e51 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -259,4 +259,8 @@ extern _X_EXPORT void DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame, unsigned int tv_sec, unsigned int tv_usec); +extern _X_EXPORT int DRI2TrackClient(ClientPtr client, DrawablePtr pDraw); +extern _X_EXPORT void DRI2InvalidateBuffersEvent(ClientPtr client, DrawablePtr draw); +extern _X_EXPORT void DRI2InvalidateDrawable(DrawablePtr pDraw); + #endif diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index a4ed2ad..a41376b 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -266,6 +266,9 @@ ProcDRI2GetBuffers(ClientPtr client) buffers = DRI2GetBuffers(pDrawable, &width, &height, attachments, stuff->count, &count); + status = DRI2TrackClient(client, pDrawable); + if (status) + return status; send_buffers_reply(client, pDrawable, buffers, count, width, height); @@ -293,6 +296,10 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client) buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height, attachments, stuff->count, &count); + status = DRI2TrackClient(client, pDrawable); + if (status) + return status; + send_buffers_reply(client, pDrawable, buffers, count, width, height); return client->noClientException; @@ -367,6 +374,18 @@ DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc, WriteEventsToClient(client, 1, (xEvent *)&event); } +void +DRI2InvalidateBuffersEvent(ClientPtr client, DrawablePtr draw) +{ + xDRI2InvalidateBuffers event; + + event.type = DRI2EventBase + DRI2_InvalidateBuffers; + event.sequenceNumber = client->sequence; + event.drawable = draw->id; + + WriteEventsToClient(client, 1, (xEvent *)&event); +} + static int ProcDRI2SwapBuffers(ClientPtr client) { @@ -391,6 +410,9 @@ ProcDRI2SwapBuffers(ClientPtr client) if (status != Success) return BadDrawable; + if (type != DRI2_SWAP_BLIT) + DRI2InvalidateDrawable(pDrawable); + rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; diff --git a/include/protocol-versions.h b/include/protocol-versions.h index c74b7fa..c425eef 100644 --- a/include/protocol-versions.h +++ b/include/protocol-versions.h @@ -53,7 +53,7 @@ /* DRI2 */ #define SERVER_DRI2_MAJOR_VERSION 1 -#define SERVER_DRI2_MINOR_VERSION 2 +#define SERVER_DRI2_MINOR_VERSION 3 /* Generic event extension */ #define SERVER_GE_MAJOR_VERSION 1 -- 1.6.4.4 |