xserver: Branch 'server-1.20-branch' - 5 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Aug 19 16:23:33 UTC 2019


 Xext/sync.c            |   50 ++++++++++++++++++++++++++---------------------
 Xext/syncsdk.h         |    3 ++
 glx/vndcmds.c          |   13 ++++++++++--
 glx/vndext.c           |   16 ++++++++++++---
 glx/vndserver.h        |   13 ++++++++++++
 glx/vndservermapping.c |   52 +++++++++++++++++++++++++++++++++++++++++--------
 include/glxvndabi.h    |   13 +++++++++++-
 miext/sync/misync.c    |   27 +++++++++++++++----------
 miext/sync/misync.h    |    1 
 miext/sync/misyncstr.h |    5 ++--
 10 files changed, 144 insertions(+), 49 deletions(-)

New commits:
commit 39b3005c329bc63676df72c43529d641bf305bcd
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Tue May 21 10:50:42 2019 -0700

    GLX: Set GlxServerExports::{major,minor}Version
    
    Commit 56c0a71fdd94a008e5d746261f70a713c4767f93 incremented the
    GLXSERVER_VENDOR_ABI_MINOR_VERSION define, but this define was not actually
    being used to set glxServer.minorVersion.
    
    Update the initializer for glxServer to use the correct version numbers.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    (cherry picked from commit b4231d69028adc8123801a7552b40a15ea928d1b)

diff --git a/glx/vndext.c b/glx/vndext.c
index 582e60b6e..0513733b6 100644
--- a/glx/vndext.c
+++ b/glx/vndext.c
@@ -304,8 +304,8 @@ GlxFreeServerImports(GlxServerImports *imports)
 }
 
 _X_EXPORT const GlxServerExports glxServer = {
-    .majorVersion = 0,
-    .minorVersion = 0,
+    .majorVersion = GLXSERVER_VENDOR_ABI_MAJOR_VERSION,
+    .minorVersion = GLXSERVER_VENDOR_ABI_MINOR_VERSION,
 
     .extensionInitCallback = &vndInitCallbackListPtr,
 
commit d3034ef2f5121d85ae766a73fda4e523399043a9
Author: Kyle Brenneman <kbrenneman at nvidia.com>
Date:   Thu May 2 07:17:21 2019 -0600

    GLX: Add a function to change a clients vendor list.
    
    Add a new function, GlxServerExports::setClientScreenVendor, which will change
    the vendor that handles GLX requests for a screen, but only for requests from
    a specific client.
    
    v2: Increment the GLXVND minor version number.
    v3: Note the GLXVND version requirement for setClientScreenVendor.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit 56c0a71fdd94a008e5d746261f70a713c4767f93)

diff --git a/glx/vndext.c b/glx/vndext.c
index 20c0648cc..582e60b6e 100644
--- a/glx/vndext.c
+++ b/glx/vndext.c
@@ -324,6 +324,7 @@ _X_EXPORT const GlxServerExports glxServer = {
     .getContextTagPrivate = GlxGetContextTagPrivate,
     .getVendorForScreen = GlxGetVendorForScreen,
     .forwardRequest =  GlxForwardRequest,
+    .setClientScreenVendor = GlxSetClientScreenVendor,
 };
 
 const GlxServerExports *
diff --git a/glx/vndserver.h b/glx/vndserver.h
index 613fef0fe..772b458a1 100644
--- a/glx/vndserver.h
+++ b/glx/vndserver.h
@@ -107,6 +107,7 @@ GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag);
 void GlxFreeContextTag(GlxContextTagInfo *tagInfo);
 
 Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor);
+Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor);
 GlxScreenPriv *GlxGetScreen(ScreenPtr pScreen);
 GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen);
 
diff --git a/glx/vndservermapping.c b/glx/vndservermapping.c
index 4efab8b81..04788ffbd 100644
--- a/glx/vndservermapping.c
+++ b/glx/vndservermapping.c
@@ -189,6 +189,27 @@ Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor)
     return TRUE;
 }
 
+Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor)
+{
+    GlxClientPriv *cl;
+
+    if (screen == NULL || screen->isGPU) {
+        return FALSE;
+    }
+
+    cl = GlxGetClientData(client);
+    if (cl == NULL) {
+        return FALSE;
+    }
+
+    if (vendor != NULL) {
+        cl->vendors[screen->myNum] = vendor;
+    } else {
+        cl->vendors[screen->myNum] = GlxGetVendorForScreen(NULL, screen);
+    }
+    return TRUE;
+}
+
 GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen)
 {
     // Note that the client won't be sending GPU screen numbers, so we don't
diff --git a/include/glxvndabi.h b/include/glxvndabi.h
index b78306d23..71f36e722 100644
--- a/include/glxvndabi.h
+++ b/include/glxvndabi.h
@@ -75,7 +75,7 @@
  * will still work.
  */
 #define GLXSERVER_VENDOR_ABI_MAJOR_VERSION 0
-#define GLXSERVER_VENDOR_ABI_MINOR_VERSION 0
+#define GLXSERVER_VENDOR_ABI_MINOR_VERSION 1
 
 #if defined(__cplusplus)
 extern "C" {
@@ -236,6 +236,17 @@ typedef struct GlxServerExportsRec {
      * \param client The client.
      */
     int (* forwardRequest) (GlxServerVendor *vendor, ClientPtr client);
+
+    /**
+     * Sets the vendor library to use for a screen for a specific client.
+     *
+     * This function changes which vendor should handle GLX requests for a
+     * screen. Unlike \c setScreenVendor, this function can be called at any
+     * time, and only applies to requests from a single client.
+     *
+     * This function is available in GLXVND version 0.1 or later.
+     */
+    Bool (* setClientScreenVendor) (ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor);
 } GlxServerExports;
 
 extern _X_EXPORT const GlxServerExports glxServer;
commit abeae4a6d356653d50026707ecc2afceac83631e
Author: Kyle Brenneman <kbrenneman at nvidia.com>
Date:   Wed May 8 08:44:54 2019 -0600

    GLX: Use the sending client for looking up XID's
    
    When GlxGetXIDMap looks up an unknown XID, it will now look up a vendor based
    on the screen number for the XID and the client that sent the current request.
    
    In GlxGetXIDMap, if the XID is for a regular X window, then it won't be in the
    (XID -> vendor) mapping, so we have to look up a vendor by screen number.
    
    With this change, GlxGetXIDMap will use the (screen -> vendor) map for
    whichever client sent the current request, instead of using the global
    (screen -> vendor) map.
    
    Since GlxGetXIDMap doesn't take a ClientPtr argument, GlxDispatchRequest will
    store the client for the current request in a global variable. That way, the
    ABI for GLXVND doesn't need to change.
    
    v2: Fix an error check in GlxDispatchRequest.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit 8b67ec7cc6fda243480a5a8ca118b66242f3eb2c)

diff --git a/glx/vndcmds.c b/glx/vndcmds.c
index f0779d14a..21c6fef9e 100644
--- a/glx/vndcmds.c
+++ b/glx/vndcmds.c
@@ -468,15 +468,24 @@ void GlxDispatchReset(void)
 int GlxDispatchRequest(ClientPtr client)
 {
     REQUEST(xReq);
+    int result;
+
     if (GlxExtensionEntry->base == 0)
         return BadRequest;
+
+    GlxSetRequestClient(client);
+
     if (stuff->data < OPCODE_ARRAY_LEN) {
         if (dispatchFuncs[stuff->data] == NULL) {
             // Try to find a dispatch stub.
             dispatchFuncs[stuff->data] = GetVendorDispatchFunc(stuff->data, 0);
         }
-        return dispatchFuncs[stuff->data](client);
+        result = dispatchFuncs[stuff->data](client);
     } else {
-        return dispatch_GLXSingle(client);
+        result = dispatch_GLXSingle(client);
     }
+
+    GlxSetRequestClient(NULL);
+
+    return result;
 }
diff --git a/glx/vndserver.h b/glx/vndserver.h
index 78246d212..613fef0fe 100644
--- a/glx/vndserver.h
+++ b/glx/vndserver.h
@@ -95,6 +95,13 @@ Bool GlxAddXIDMap(XID id, GlxServerVendor *vendor);
 GlxServerVendor * GlxGetXIDMap(XID id);
 void GlxRemoveXIDMap(XID id);
 
+/**
+ * Records the client that sent the current request. This is needed in
+ * GlxGetXIDMap to know which client's (screen -> vendor) mapping to use for a
+ * regular X window.
+ */
+void GlxSetRequestClient(ClientPtr client);
+
 GlxContextTagInfo *GlxAllocContextTag(ClientPtr client, GlxServerVendor *vendor);
 GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag);
 void GlxFreeContextTag(GlxContextTagInfo *tagInfo);
diff --git a/glx/vndservermapping.c b/glx/vndservermapping.c
index 778656bb6..4efab8b81 100644
--- a/glx/vndservermapping.c
+++ b/glx/vndservermapping.c
@@ -33,6 +33,13 @@
 
 #include "vndservervendor.h"
 
+static ClientPtr requestClient = NULL;
+
+void GlxSetRequestClient(ClientPtr client)
+{
+    requestClient = client;
+}
+
 static GlxServerVendor *LookupXIDMapResource(XID id)
 {
     void *ptr = NULL;
@@ -59,10 +66,7 @@ GlxServerVendor *GlxGetXIDMap(XID id)
                                          DixGetAttrAccess);
         if (rv == Success && ptr != NULL) {
             DrawablePtr draw = (DrawablePtr) ptr;
-            GlxScreenPriv *screenPriv = GlxGetScreen(draw->pScreen);
-            if (screenPriv != NULL) {
-                vendor = screenPriv->vendor;
-            }
+            vendor = GlxGetVendorForScreen(requestClient, draw->pScreen);
         }
     }
     return vendor;
commit 1fdb7cbce538f0b37304a3cfc9fae4ff2fe9ece9
Author: Kyle Brenneman <kbrenneman at nvidia.com>
Date:   Thu Oct 19 15:14:51 2017 -0600

    GLX: Add a per-client vendor mapping.
    
    Each client now has its own (screen, vendor) mapping.
    
    Currently, it's just a copy of the global mapping, but later changes will allow
    it to change.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit 37a36a6b5b887d5c5a17a6931ceba8ad5d1bb6d5)

diff --git a/glx/vndext.c b/glx/vndext.c
index d7936467b..20c0648cc 100644
--- a/glx/vndext.c
+++ b/glx/vndext.c
@@ -139,8 +139,17 @@ GlxGetClientData(ClientPtr client)
 {
     GlxClientPriv *cl = xglvGetClientPrivate(client);
     if (cl == NULL) {
-        cl = calloc(1, sizeof(GlxClientPriv));
+        cl = calloc(1, sizeof(GlxClientPriv)
+                + screenInfo.numScreens * sizeof(GlxServerVendor *));
         if (cl != NULL) {
+            int i;
+
+            cl->vendors = (GlxServerVendor **) (cl + 1);
+            for (i=0; i<screenInfo.numScreens; i++)
+            {
+                cl->vendors[i] = GlxGetVendorForScreen(NULL, screenInfo.screens[i]);
+            }
+
             xglvSetClientPrivate(client, cl);
         }
     }
diff --git a/glx/vndserver.h b/glx/vndserver.h
index a175656ae..78246d212 100644
--- a/glx/vndserver.h
+++ b/glx/vndserver.h
@@ -57,6 +57,11 @@ typedef struct GlxContextTagInfoRec {
 typedef struct GlxClientPrivRec {
     GlxContextTagInfo *contextTags;
     unsigned int contextTagCount;
+
+    /**
+     * The vendor handles for each screen.
+     */
+    GlxServerVendor **vendors;
 } GlxClientPriv;
 
 extern int GlxErrorBase;
diff --git a/glx/vndservermapping.c b/glx/vndservermapping.c
index fd3be92d9..778656bb6 100644
--- a/glx/vndservermapping.c
+++ b/glx/vndservermapping.c
@@ -187,10 +187,21 @@ Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor)
 
 GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen)
 {
-    GlxScreenPriv *priv = GlxGetScreen(screen);
-    if (priv != NULL) {
-        return priv->vendor;
+    // Note that the client won't be sending GPU screen numbers, so we don't
+    // need per-client mappings for them.
+    if (client != NULL && !screen->isGPU) {
+        GlxClientPriv *cl = GlxGetClientData(client);
+        if (cl != NULL) {
+            return cl->vendors[screen->myNum];
+        } else {
+            return NULL;
+        }
     } else {
-        return NULL;
+        GlxScreenPriv *priv = GlxGetScreen(screen);
+        if (priv != NULL) {
+            return priv->vendor;
+        } else {
+            return NULL;
+        }
     }
 }
commit 82f01ad7869e3f2be51e41a8246dab5982bbc36a
Author: Alex Goins <agoins at nvidia.com>
Date:   Wed Apr 10 13:48:02 2019 -0500

    xsync: Add resource inside of SyncCreate, export SyncCreate
    
    As shown by DRI3 adding the SyncCreateFenceFromFD() function, extensions may
    want to create a fence, then initialize it in their own way. This currently
    can't be done without adding a function directly to Xext/sync.c due to the fact
    that the RTFence resource type is private and there is no external interface to
    add to it.
    
    To facilitate other X extensions creating fences and initializing them, this
    change exports SyncCreate() and adds the resource directly within it. Callers no
    longer need to call AddResource() after SyncCreate(), they only need to
    initialize the SyncObject.
    
    To prevent FreeFence() and FreeCounter() from segfaulting if the call to
    AddResource() fails before the sync object is initialized, this adds a new
    'initialized' parameter to SyncObject that, when FALSE, causes FreeFence() and
    FreeCounter() to skip de-initialization and simply free the object.
    Initialization after adding the resource shouldn't otherwise be a problem due to
    the single-threaded nature of X.
    
    Signed-off-by: Alex Goins <agoins at nvidia.com>
    Reviewed-by: James Jones <jajones at nvidia.com>
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    (cherry picked from commit 7f962c70b6d9c346477f23f6c15211e749110078)

diff --git a/Xext/sync.c b/Xext/sync.c
index 8f22a865b..fd2ceb042 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -881,18 +881,21 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm * pAlarm, Mask mask,
     return Success;
 }
 
-static SyncObject *
+SyncObject *
 SyncCreate(ClientPtr client, XID id, unsigned char type)
 {
     SyncObject *pSync;
+    RESTYPE resType;
 
     switch (type) {
     case SYNC_COUNTER:
         pSync = malloc(sizeof(SyncCounter));
+        resType = RTCounter;
         break;
     case SYNC_FENCE:
         pSync = (SyncObject *) dixAllocateObjectWithPrivates(SyncFence,
                                                              PRIVATE_SYNC_FENCE);
+        resType = RTFence;
         break;
     default:
         return NULL;
@@ -901,6 +904,11 @@ SyncCreate(ClientPtr client, XID id, unsigned char type)
     if (!pSync)
         return NULL;
 
+    pSync->initialized = FALSE;
+
+    if (!AddResource(id, resType, (void *) pSync))
+        return NULL;
+
     pSync->client = client;
     pSync->id = id;
     pSync->pTriglist = NULL;
@@ -923,13 +931,10 @@ SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL
 
     status = miSyncInitFenceFromFD(pDraw, pFence, fd, initially_triggered);
     if (status != Success) {
-        dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE);
+        FreeResource(pFence->sync.id, RT_NONE);
         return status;
     }
 
-    if (!AddResource(id, RTFence, (void *) pFence))
-        return BadAlloc;
-
     return Success;
 #else
     return BadImplementation;
@@ -957,8 +962,7 @@ SyncCreateCounter(ClientPtr client, XSyncCounter id, int64_t initialvalue)
     pCounter->value = initialvalue;
     pCounter->pSysCounterInfo = NULL;
 
-    if (!AddResource(id, RTCounter, (void *) pCounter))
-        return NULL;
+    pCounter->sync.initialized = TRUE;
 
     return pCounter;
 }
@@ -1137,21 +1141,26 @@ static int
 FreeCounter(void *env, XID id)
 {
     SyncCounter *pCounter = (SyncCounter *) env;
-    SyncTriggerList *ptl, *pnext;
 
     pCounter->sync.beingDestroyed = TRUE;
-    /* tell all the counter's triggers that the counter has been destroyed */
-    for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {
-        (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);
-        pnext = ptl->next;
-        free(ptl);              /* destroy the trigger list as we go */
-    }
-    if (IsSystemCounter(pCounter)) {
-        xorg_list_del(&pCounter->pSysCounterInfo->entry);
-        free(pCounter->pSysCounterInfo->name);
-        free(pCounter->pSysCounterInfo->private);
-        free(pCounter->pSysCounterInfo);
+
+    if (pCounter->sync.initialized) {
+        SyncTriggerList *ptl, *pnext;
+
+        /* tell all the counter's triggers that counter has been destroyed */
+        for (ptl = pCounter->sync.pTriglist; ptl; ptl = pnext) {
+            (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);
+            pnext = ptl->next;
+            free(ptl); /* destroy the trigger list as we go */
+        }
+        if (IsSystemCounter(pCounter)) {
+            xorg_list_del(&pCounter->pSysCounterInfo->entry);
+            free(pCounter->pSysCounterInfo->name);
+            free(pCounter->pSysCounterInfo->private);
+            free(pCounter->pSysCounterInfo);
+        }
     }
+
     free(pCounter);
     return Success;
 }
@@ -1889,9 +1898,6 @@ ProcSyncCreateFence(ClientPtr client)
 
     miSyncInitFence(pDraw->pScreen, pFence, stuff->initially_triggered);
 
-    if (!AddResource(stuff->fid, RTFence, (void *) pFence))
-        return BadAlloc;
-
     return Success;
 }
 
diff --git a/Xext/syncsdk.h b/Xext/syncsdk.h
index f1b99d010..c88285cb1 100644
--- a/Xext/syncsdk.h
+++ b/Xext/syncsdk.h
@@ -29,6 +29,9 @@
 extern _X_EXPORT int
  SyncVerifyFence(SyncFence ** ppFence, XID fid, ClientPtr client, Mask mode);
 
+extern _X_EXPORT SyncObject*
+ SyncCreate(ClientPtr client, XID id, unsigned char type);
+
 #define VERIFY_SYNC_FENCE(pFence, fid, client, mode)			\
     do {								\
 	int rc;								\
diff --git a/miext/sync/misync.c b/miext/sync/misync.c
index 490fa0b17..0931803f6 100644
--- a/miext/sync/misync.c
+++ b/miext/sync/misync.c
@@ -101,24 +101,29 @@ miSyncInitFence(ScreenPtr pScreen, SyncFence * pFence, Bool initially_triggered)
     pFence->funcs = miSyncFenceFuncs;
 
     pScreenPriv->funcs.CreateFence(pScreen, pFence, initially_triggered);
+
+    pFence->sync.initialized = TRUE;
 }
 
 void
 miSyncDestroyFence(SyncFence * pFence)
 {
-    ScreenPtr pScreen = pFence->pScreen;
-    SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
-    SyncTriggerList *ptl, *pNext;
-
     pFence->sync.beingDestroyed = TRUE;
-    /* tell all the fence's triggers that the counter has been destroyed */
-    for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) {
-        (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);
-        pNext = ptl->next;
-        free(ptl);              /* destroy the trigger list as we go */
-    }
 
-    pScreenPriv->funcs.DestroyFence(pScreen, pFence);
+    if (pFence->sync.initialized) {
+        ScreenPtr pScreen = pFence->pScreen;
+        SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen);
+        SyncTriggerList *ptl, *pNext;
+
+        /* tell all the fence's triggers that the counter has been destroyed */
+        for (ptl = pFence->sync.pTriglist; ptl; ptl = pNext) {
+            (*ptl->pTrigger->CounterDestroyed) (ptl->pTrigger);
+            pNext = ptl->next;
+            free(ptl); /* destroy the trigger list as we go */
+        }
+
+        pScreenPriv->funcs.DestroyFence(pScreen, pFence);
+    }
 
     dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE);
 }
diff --git a/miext/sync/misync.h b/miext/sync/misync.h
index dc78c5fdb..f7082d5ea 100644
--- a/miext/sync/misync.h
+++ b/miext/sync/misync.h
@@ -28,6 +28,7 @@
 #ifndef _MISYNC_H_
 #define _MISYNC_H_
 
+typedef struct _SyncObject SyncObject;
 typedef struct _SyncFence SyncFence;
 typedef struct _SyncTrigger SyncTrigger;
 
diff --git a/miext/sync/misyncstr.h b/miext/sync/misyncstr.h
index 2eab2aa57..2a6e84a96 100644
--- a/miext/sync/misyncstr.h
+++ b/miext/sync/misyncstr.h
@@ -38,13 +38,14 @@
 #define SYNC_COUNTER		0
 #define SYNC_FENCE		1
 
-typedef struct _SyncObject {
+struct _SyncObject {
     ClientPtr client;           /* Owning client. 0 for system counters */
     struct _SyncTriggerList *pTriglist; /* list of triggers */
     XID id;                     /* resource ID */
     unsigned char type;         /* SYNC_* */
+    Bool initialized;           /* FALSE if created but not initialized */
     Bool beingDestroyed;        /* in process of going away */
-} SyncObject;
+};
 
 typedef struct _SyncCounter {
     SyncObject sync;            /* Common sync object data */


More information about the xorg-commit mailing list