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