Bumps the supported DRI2 protocol version to 1.3.

Signed-off-by: Francisco Jerez <curroje...@riseup.net>
---
 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


------------------------------------------------------------------------------
Throughout its 18-year history, RSA Conference consistently attracts the
world's best and brightest in the field, creating opportunities for Conference
attendees to learn about information security's most important issues through
interactions with peers, luminaries and emerging and established companies.
http://p.sf.net/sfu/rsaconf-dev2dev
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to