Implement new screen extension API.
authorKristian Høgsberg <krh@hinata.boston.redhat.com>
Tue, 15 May 2007 16:31:31 +0000 (12:31 -0400)
committerKristian Høgsberg <krh@redhat.com>
Wed, 10 Oct 2007 22:47:22 +0000 (18:47 -0400)
This new API lets the loader examine DRI level extensions provided by the
driver in a forward compatible manner.

Much of the churn in the DRI interface is adding support for new
extensions or removing old, unused extensions.  This new extension
mechanism lets the loader query the extensions provided by the driver
and implement the extensions it knows about.  Deprecating extensions
is done by not exporting that extension in the list, which doesn't
require keeping old function pointers around to preserve ABI.

include/GL/internal/dri_interface.h
src/glx/x11/glxext.c
src/mesa/drivers/dri/common/dri_util.c

index aa2b1cf8057b9781e2ebdcc681c785793f6a36d9..ee73233771c40e50f07a5c67ccfd8bd1cd7a702a 100644 (file)
@@ -56,9 +56,24 @@ typedef struct __DRIdriverRec                __DRIdriver;
 typedef struct __DRIframebufferRec     __DRIframebuffer;
 typedef struct __DRIversionRec         __DRIversion;
 typedef struct __DRIinterfaceMethodsRec        __DRIinterfaceMethods;
+
+typedef struct __DRIextensionRec       __DRIextension;
 /*@}*/
 
 
+/**
+ * Extension struct.  Drivers 'inherit' from this struct by embedding
+ * it as the first element in the extension struct.  The
+ * __DRIscreen::getExtensions entry point will return a list of these
+ * structs and the loader can use the extensions it knows about by
+ * casting it to a more specific extension and optionally advertising
+ * the GLX extension.  See below for examples.
+ */
+struct __DRIextensionRec {
+    const char *name;
+};
+
+
 /**
  * \name Functions provided by the driver loader.
  */
@@ -274,6 +289,11 @@ struct __DRIscreenRec {
      */
     void (*destroyScreen)(__DRIscreen *screen);
 
+    /**
+     * Method to get screen extensions.
+     */
+    const __DRIextension **(*getExtensions)(__DRIscreen *screen);
+
     /**
      * Method to create the private DRI drawable data and initialize the
      * drawable dependent methods.
index ee8e238bec52c86e67ca9ecb899d7c8991053b63..cb187717f1e15ef2a33027000996f2860e695813 100644 (file)
@@ -1011,6 +1011,18 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
 
     return psp;
 }
+
+static void queryExtensions(__GLXscreenConfigs *psc)
+{
+    const __DRIextension **extensions;
+    int i;
+
+    extensions = psc->driScreen.getExtensions(&psc->driScreen);
+    for (i = 0; extensions[i]; i++) {
+       /* Unknown extension, just ignore... */
+    }
+}
+
 #endif /* GLX_DIRECT_RENDERING */
 
 
@@ -1205,6 +1217,8 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
                    CallCreateNewScreen(dpy, i, psc,
                                        & priv->driDisplay,
                                        priv->driDisplay.createNewScreen[i] );
+               if (psc->driScreen.private != NULL)
+                   queryExtensions(psc);
            }
        }
 #endif
index 84a6d819def48d7622e52c411dd8c28a1f89b582..c8be7b070647e5d3edce4424beb9a5c492c3502a 100644 (file)
@@ -624,6 +624,14 @@ driCreateNewContext(__DRIscreen *screen, const __GLcontextModes *modes,
 }
 /*@}*/
 
+static const __DRIextension **
+driGetExtensions(__DRIscreen *screen)
+{
+    __DRIscreenPrivate *psp = screen->private;
+    static const __DRIextension *extensions[1];
+
+    return extensions;
+}
 
 /*****************************************************************/
 /** \name Screen handling functions                              */
@@ -750,6 +758,7 @@ void * __DRI_CREATE_NEW_SCREEN( int scrn, __DRIscreen *psc,
     psp->dummyContextPriv.driScreenPriv = NULL;
 
     psc->destroyScreen     = driDestroyScreen;
+    psc->getExtensions     = driGetExtensions;
     psc->createNewDrawable = driCreateNewDrawable;
     psc->getMSC            = driGetMSC;
     psc->createNewContext  = driCreateNewContext;