Initial server side implementation of fence sync
objects.  Allows creation and management of
binary state objects.  Currently they are not
useful as there is no way to wait for them or
query their state.

The basic trigger operation added here triggers
relative to a given X screen's rendering operations.
To perform this operation, fence sync objects must
be tied to a screen.  As Aaron Plattner pointed out,
screens are identified but a drawable in X protocol,
so a drawable argument is included in
XSyncCreateFence().  The screen also could have been
specified as part of the trigger operation.  However,
it is also desireable to associate a screen with
fence sync objects at creation time so that the
associated screen's driver can allocate any HW-
specific resources needed by the fence object up
front.

Signed-off-by: James Jones <jajo...@nvidia.com>
Reviewed-by: Aaron Plattner <aplatt...@nvidia.com>
Reviewed-by: Robert Morell <rmor...@nvidia.com>
Reviewed-by: Adam Jackson <a...@redhat.com>
---
 Xext/sync.c    |  173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Xext/syncsrv.h |    6 ++
 2 files changed, 179 insertions(+), 0 deletions(-)

diff --git a/Xext/sync.c b/Xext/sync.c
index f23df6c..147eab8 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -63,6 +63,7 @@ PERFORMANCE OF THIS SOFTWARE.
 #include "os.h"
 #include "extnsionst.h"
 #include "dixstruct.h"
+#include "pixmapstr.h"
 #include "resource.h"
 #include "opaque.h"
 #include <X11/extensions/syncproto.h>
@@ -84,6 +85,7 @@ static RESTYPE  RTCounter = 0;
 static RESTYPE  RTAwait;
 static RESTYPE  RTAlarm;
 static RESTYPE  RTAlarmClient;
+static RESTYPE  RTFence;
 static int SyncNumSystemCounters = 0;
 static SyncCounter **SysCounterList = NULL;
 
@@ -1732,6 +1734,108 @@ ProcSyncDestroyAlarm(ClientPtr client)
     return Success;
 }
 
+static int
+ProcSyncCreateFence(ClientPtr client)
+{
+    REQUEST(xSyncCreateFenceReq);
+    DrawablePtr pDraw;
+    SyncFence *pFence;
+    int rc;
+
+    REQUEST_SIZE_MATCH(xSyncCreateFenceReq);
+
+    rc = dixLookupDrawable(&pDraw, stuff->d, client, M_ANY, DixGetAttrAccess);
+    if (rc != Success)
+       return rc;
+
+    LEGAL_NEW_RESOURCE(stuff->fid, client);
+
+    if (!(pFence = malloc(sizeof(SyncFence))))
+       return BadAlloc;
+
+    if (!AddResource(stuff->fid, RTFence, (pointer) pFence))
+    {
+       free(pFence);
+       return BadAlloc;
+    }
+
+    pFence->pScreen = pDraw->pScreen;
+    pFence->client = client;
+    pFence->id = stuff->fid;
+    pFence->triggered = stuff->initially_triggered;
+
+    return client->noClientException;
+}
+
+static int
+FreeFence(void *obj, XID id)
+{
+    SyncFence *pFence = (SyncFence *) obj;
+
+    free(pFence);
+
+    return Success;
+}
+
+static int
+ProcSyncTriggerFence(ClientPtr client)
+{
+    REQUEST(xSyncTriggerFenceReq);
+    SyncFence *pFence;
+    int rc;
+
+    REQUEST_SIZE_MATCH(xSyncTriggerFenceReq);
+
+    rc = dixLookupResourceByType((pointer *)&pFence, stuff->fid, RTFence,
+                                client, DixWriteAccess);
+    if (rc != Success)
+       return rc;
+
+    pFence->triggered = TRUE;
+
+    return client->noClientException;
+}
+
+static int
+ProcSyncResetFence(ClientPtr client)
+{
+    REQUEST(xSyncResetFenceReq);
+    SyncFence *pFence;
+    int rc;
+
+    REQUEST_SIZE_MATCH(xSyncResetFenceReq);
+
+    rc = dixLookupResourceByType((pointer *)&pFence, stuff->fid, RTFence,
+                                client, DixWriteAccess);
+    if (rc != Success)
+       return rc;
+
+    if (pFence->triggered != TRUE)
+       return BadMatch;
+
+    pFence->triggered = FALSE;
+
+    return client->noClientException;
+}
+
+static int
+ProcSyncDestroyFence(ClientPtr client)
+{
+    REQUEST(xSyncDestroyFenceReq);
+    SyncFence *pFence;
+    int rc;
+
+    REQUEST_SIZE_MATCH(xSyncDestroyFenceReq);
+
+    rc = dixLookupResourceByType((pointer *)&pFence, stuff->fid, RTFence,
+                                client, DixDestroyAccess);
+    if (rc != Success)
+       return rc;
+
+    FreeResource(stuff->fid, RT_NONE);
+    return client->noClientException;
+}
+
 /*
  * ** Given an extension request, call the appropriate request procedure
  */
@@ -1770,6 +1874,14 @@ ProcSyncDispatch(ClientPtr client)
        return ProcSyncSetPriority(client);
       case X_SyncGetPriority:
        return ProcSyncGetPriority(client);
+      case X_SyncCreateFence:
+       return ProcSyncCreateFence(client);
+      case X_SyncTriggerFence:
+       return ProcSyncTriggerFence(client);
+      case X_SyncResetFence:
+       return ProcSyncResetFence(client);
+      case X_SyncDestroyFence:
+       return ProcSyncDestroyFence(client);
       default:
        return BadRequest;
     }
@@ -1969,6 +2081,57 @@ SProcSyncGetPriority(ClientPtr client)
     return ProcSyncGetPriority(client);
 }
 
+static int
+SProcSyncCreateFence(ClientPtr client)
+{
+    REQUEST(xSyncCreateFenceReq);
+    char n;
+
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH (xSyncCreateFenceReq);
+    swapl(&stuff->fid, n);
+
+    return ProcSyncCreateFence(client);
+}
+
+static int
+SProcSyncTriggerFence(ClientPtr client)
+{
+    REQUEST(xSyncTriggerFenceReq);
+    char n;
+
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH (xSyncTriggerFenceReq);
+    swapl(&stuff->fid, n);
+
+    return ProcSyncTriggerFence(client);
+}
+
+static int
+SProcSyncResetFence(ClientPtr client)
+{
+    REQUEST(xSyncResetFenceReq);
+    char n;
+
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH (xSyncResetFenceReq);
+    swapl(&stuff->fid, n);
+
+    return ProcSyncResetFence(client);
+}
+
+static int
+SProcSyncDestroyFence(ClientPtr client)
+{
+    REQUEST(xSyncDestroyFenceReq);
+    char n;
+
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH (xSyncDestroyFenceReq);
+    swapl(&stuff->fid, n);
+
+    return ProcSyncDestroyFence(client);
+}
 
 static int
 SProcSyncDispatch(ClientPtr client)
@@ -2005,6 +2168,14 @@ SProcSyncDispatch(ClientPtr client)
        return SProcSyncSetPriority(client);
       case X_SyncGetPriority:
        return SProcSyncGetPriority(client);
+      case X_SyncCreateFence:
+       return SProcSyncCreateFence(client);
+      case X_SyncTriggerFence:
+       return SProcSyncTriggerFence(client);
+      case X_SyncResetFence:
+       return SProcSyncResetFence(client);
+      case X_SyncDestroyFence:
+       return SProcSyncDestroyFence(client);
       default:
        return BadRequest;
     }
@@ -2073,6 +2244,7 @@ SyncExtensionInit(void)
     }
     RTAlarm = CreateNewResourceType(FreeAlarm, "SyncAlarm");
     RTAwait = CreateNewResourceType(FreeAwait, "SyncAwait");
+    RTFence = CreateNewResourceType(FreeFence, "SyncFence");
     if (RTAwait)
        RTAwait |= RC_NEVERRETAIN;
     RTAlarmClient = CreateNewResourceType(FreeAlarmClient, "SyncAlarmClient");
@@ -2099,6 +2271,7 @@ SyncExtensionInit(void)
 
     SetResourceTypeErrorValue(RTCounter, SyncErrorBase + XSyncBadCounter);
     SetResourceTypeErrorValue(RTAlarm, SyncErrorBase + XSyncBadAlarm);
+    SetResourceTypeErrorValue(RTFence, SyncErrorBase + XSyncBadFence);
 
     /*
      * Although SERVERTIME is implemented by the OS layer, we initialise it
diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
index 6d0e3d6..a805f28 100644
--- a/Xext/syncsrv.h
+++ b/Xext/syncsrv.h
@@ -148,6 +148,12 @@ typedef union {
     SyncAwait      await;
 } SyncAwaitUnion;
 
+typedef struct _SyncFence {
+    ClientPtr          client;         /* Owning client. */
+    XSyncFence         id;             /* resource ID */
+    ScreenPtr           pScreen;       /* Screen of this fence object */
+    Bool               triggered;      /* fence state */
+} SyncFence;
 
 extern pointer SyncCreateSystemCounter(
     char *     /* name */,
-- 
1.7.1

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to