Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / drivers / dri / common / dri_util.c
index 3649c296662d66b9462144545adaf8690d675155..a5b71bd40adb51c683b65a1fefa9e6acfd99c17f 100644 (file)
 #include "dri_util.h"
 #include "drm_sarea.h"
 #include "utils.h"
+#include "xmlpool.h"
+#include "../glsl/glsl_parser_extras.h"
+
+PUBLIC const char __dri2ConfigOptions[] =
+   DRI_CONF_BEGIN
+      DRI_CONF_SECTION_PERFORMANCE
+         DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
+      DRI_CONF_SECTION_END
+   DRI_CONF_END;
+
+static const uint __dri2NConfigOptions = 1;
 
 #ifndef GLX_OML_sync_control
 typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
@@ -47,28 +58,6 @@ const __DRIextension driReadDrawableExtension = {
     __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
 };
 
-/**
- * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
- * is set. 
- * 
- * Is called from the drivers.
- * 
- * \param f \c printf like format string.
- */
-void
-__driUtilMessage(const char *f, ...)
-{
-    va_list args;
-
-    if (getenv("LIBGL_DEBUG")) {
-        fprintf(stderr, "libGL: ");
-        va_start(args, f);
-        vfprintf(stderr, f, args);
-        va_end(args);
-        fprintf(stderr, "\n");
-    }
-}
-
 GLint
 driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
 {
@@ -127,6 +116,7 @@ static int driUnbindContext(__DRIcontext *pcp)
     /* Let driver unbind drawable from context */
     (*psp->DriverAPI.UnbindContext)(pcp);
 
+    assert(pdp);
     if (pdp->refcount == 0) {
        /* ERROR!!! */
        return GL_FALSE;
@@ -150,11 +140,6 @@ static int driUnbindContext(__DRIcontext *pcp)
      */
     pcp->driDrawablePriv = pcp->driReadablePriv = NULL;
 
-#if 0
-    /* Unbind the drawable */
-    pdp->driContextPriv = &psp->dummyContextPriv;
-#endif
-
     return GL_TRUE;
 }
 
@@ -169,19 +154,24 @@ static int driBindContext(__DRIcontext *pcp,
 {
     __DRIscreen *psp = NULL;
 
-    /* Bind the drawable to the context */
+    /*
+    ** Assume error checking is done properly in glXMakeCurrent before
+    ** calling driUnbindContext.
+    */
 
-    if (pcp) {
-       psp = pcp->driScreenPriv;
-       pcp->driDrawablePriv = pdp;
-       pcp->driReadablePriv = prp;
-       if (pdp) {
-           pdp->driContextPriv = pcp;
-           dri_get_drawable(pdp);
-       }
-       if ( prp && pdp != prp ) {
-           dri_get_drawable(prp);
-       }
+    if (!pcp)
+       return GL_FALSE;
+
+    /* Bind the drawable to the context */
+    psp = pcp->driScreenPriv;
+    pcp->driDrawablePriv = pdp;
+    pcp->driReadablePriv = prp;
+    if (pdp) {
+       pdp->driContextPriv = pcp;
+       dri_get_drawable(pdp);
+    }
+    if (prp && pdp != prp) {
+       dri_get_drawable(prp);
     }
 
     /*
@@ -203,7 +193,6 @@ static int driBindContext(__DRIcontext *pcp,
     }
 
     /* Call device-specific MakeCurrent */
-
     return (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp);
 }
 
@@ -242,12 +231,12 @@ __driUtilUpdateDrawableInfo(__DRIdrawable *pdp)
     }
 
     if (pdp->pClipRects) {
-       _mesa_free(pdp->pClipRects); 
+       free(pdp->pClipRects); 
        pdp->pClipRects = NULL;
     }
 
     if (pdp->pBackClipRects) {
-       _mesa_free(pdp->pBackClipRects); 
+       free(pdp->pBackClipRects); 
        pdp->pBackClipRects = NULL;
     }
 
@@ -324,7 +313,7 @@ static void driSwapBuffers(__DRIdrawable *dPriv)
     if (!dPriv->numClipRects)
         return;
 
-    rects = _mesa_malloc(sizeof(*rects) * dPriv->numClipRects);
+    rects = malloc(sizeof(*rects) * dPriv->numClipRects);
 
     if (!rects)
         return;
@@ -337,7 +326,7 @@ static void driSwapBuffers(__DRIdrawable *dPriv)
     }
 
     driReportDamage(dPriv, rects, dPriv->numClipRects);
-    _mesa_free(rects);
+    free(rects);
 }
 
 static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
@@ -430,11 +419,12 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
      */
     (void) attrs;
 
-    pdp = _mesa_malloc(sizeof *pdp);
+    pdp = malloc(sizeof *pdp);
     if (!pdp) {
        return NULL;
     }
 
+    pdp->driContextPriv = NULL;
     pdp->loaderPrivate = data;
     pdp->hHWDrawable = hwDrawable;
     pdp->refcount = 1;
@@ -453,12 +443,9 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
     pdp->vblFlags = 0;
 
     pdp->driScreenPriv = psp;
-    pdp->driContextPriv = &psp->dummyContextPriv;
-    pdp->validBuffers = GL_FALSE;
 
-    if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
-                                       renderType == GLX_PIXMAP_BIT)) {
-       _mesa_free(pdp);
+    if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, 0)) {
+       free(pdp);
        return NULL;
     }
 
@@ -485,12 +472,50 @@ dri2CreateNewDrawable(__DRIscreen *screen,
     if (!pdraw)
        return NULL;
 
-    pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
-    pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
+    pdraw->pClipRects = &pdraw->dri2.clipRect;
+    pdraw->pBackClipRects = &pdraw->dri2.clipRect;
+
+    pdraw->pStamp = &pdraw->dri2.stamp;
+    *pdraw->pStamp = pdraw->lastStamp + 1;
 
     return pdraw;
 }
 
+static int
+dri2ConfigQueryb(__DRIscreen *screen, const char *var, GLboolean *val)
+{
+   if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
+      return -1;
+
+   *val = driQueryOptionb(&screen->optionCache, var);
+
+   return 0;
+}
+
+static int
+dri2ConfigQueryi(__DRIscreen *screen, const char *var, GLint *val)
+{
+   if (!driCheckOption(&screen->optionCache, var, DRI_INT) &&
+       !driCheckOption(&screen->optionCache, var, DRI_ENUM))
+      return -1;
+
+    *val = driQueryOptioni(&screen->optionCache, var);
+
+    return 0;
+}
+
+static int
+dri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val)
+{
+   if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT))
+      return -1;
+
+    *val = driQueryOptionf(&screen->optionCache, var);
+
+    return 0;
+}
+
+
 static void dri_get_drawable(__DRIdrawable *pdp)
 {
     pdp->refcount++;
@@ -507,15 +532,15 @@ static void dri_put_drawable(__DRIdrawable *pdp)
 
        psp = pdp->driScreenPriv;
         (*psp->DriverAPI.DestroyBuffer)(pdp);
-       if (pdp->pClipRects) {
-           _mesa_free(pdp->pClipRects);
+       if (pdp->pClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
+           free(pdp->pClipRects);
            pdp->pClipRects = NULL;
        }
-       if (pdp->pBackClipRects) {
-           _mesa_free(pdp->pBackClipRects);
+       if (pdp->pBackClipRects && pdp->pClipRects != &pdp->dri2.clipRect) {
+           free(pdp->pBackClipRects);
            pdp->pBackClipRects = NULL;
        }
-       _mesa_free(pdp);
+       free(pdp);
     }
 }
 
@@ -545,7 +570,7 @@ driDestroyContext(__DRIcontext *pcp)
 {
     if (pcp) {
        (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
-       _mesa_free(pcp);
+       free(pcp);
     }
 }
 
@@ -575,33 +600,76 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
     __DRIcontext *pcp;
     void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
 
-    pcp = _mesa_malloc(sizeof *pcp);
+    pcp = malloc(sizeof *pcp);
     if (!pcp)
        return NULL;
 
     pcp->driScreenPriv = psp;
     pcp->driDrawablePriv = NULL;
+    pcp->loaderPrivate = data;
+    
+    pcp->dri2.draw_stamp = 0;
+    pcp->dri2.read_stamp = 0;
 
-    /* When the first context is created for a screen, initialize a "dummy"
-     * context.
-     */
+    pcp->hHWContext = hwContext;
 
-    if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) {
-        psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context;
-        psp->dummyContextPriv.driScreenPriv = psp;
-        psp->dummyContextPriv.driDrawablePriv = NULL;
-        psp->dummyContextPriv.driverPrivate = NULL;
-       /* No other fields should be used! */
+    if ( !(*psp->DriverAPI.CreateContext)(API_OPENGL,
+                                         &config->modes, pcp, shareCtx) ) {
+        free(pcp);
+        return NULL;
     }
 
-    pcp->hHWContext = hwContext;
+    return pcp;
+}
 
-    if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) {
-        _mesa_free(pcp);
+static unsigned int
+dri2GetAPIMask(__DRIscreen *screen)
+{
+    return screen->api_mask;
+}
+
+static __DRIcontext *
+dri2CreateNewContextForAPI(__DRIscreen *screen, int api,
+                          const __DRIconfig *config,
+                          __DRIcontext *shared, void *data)
+{
+    __DRIcontext *context;
+    const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
+    void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
+    gl_api mesa_api;
+
+    if (!(screen->api_mask & (1 << api)))
+       return NULL;
+
+    switch (api) {
+    case __DRI_API_OPENGL:
+           mesa_api = API_OPENGL;
+           break;
+    case __DRI_API_GLES:
+           mesa_api = API_OPENGLES;
+           break;
+    case __DRI_API_GLES2:
+           mesa_api = API_OPENGLES2;
+           break;
+    default:
+           return NULL;
+    }
+
+    context = malloc(sizeof *context);
+    if (!context)
+       return NULL;
+
+    context->driScreenPriv = screen;
+    context->driDrawablePriv = NULL;
+    context->loaderPrivate = data;
+    
+    if (!(*screen->DriverAPI.CreateContext)(mesa_api, modes,
+                                           context, shareCtx) ) {
+        free(context);
         return NULL;
     }
 
-    return pcp;
+    return context;
 }
 
 
@@ -609,10 +677,10 @@ static __DRIcontext *
 dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
                      __DRIcontext *shared, void *data)
 {
-    return driCreateNewContext(screen, config, 0, shared, 0, data);
+   return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL,
+                                    config, shared, data);
 }
 
-
 static int
 driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
 {
@@ -642,6 +710,8 @@ static void driDestroyScreen(__DRIscreen *psp)
         * stream open to the X-server anymore.
         */
 
+       _mesa_destroy_shader_compiler();
+
        if (psp->DriverAPI.DestroyScreen)
            (*psp->DriverAPI.DestroyScreen)(psp);
 
@@ -649,9 +719,12 @@ static void driDestroyScreen(__DRIscreen *psp)
           (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
           (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
           (void)drmCloseOnce(psp->fd);
+       } else {
+          driDestroyOptionCache(&psp->optionCache);
+          driDestroyOptionInfo(&psp->optionInfo);
        }
 
-       _mesa_free(psp);
+       free(psp);
     }
 }
 
@@ -670,6 +743,10 @@ setupLoaderExtensions(__DRIscreen *psp,
            psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
        if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
            psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
+       if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0)
+           psp->dri2.image = (__DRIimageLookupExtension *) extensions[i];
+       if (strcmp(extensions[i]->name, __DRI_USE_INVALIDATE) == 0)
+           psp->dri2.useInvalidate = (__DRIuseInvalidateExtension *) extensions[i];
     }
 }
 
@@ -677,7 +754,7 @@ setupLoaderExtensions(__DRIscreen *psp,
  * This is the bootstrap function for the driver.  libGL supplies all of the
  * requisite information about the system, and the driver initializes itself.
  * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
+ * with the \c struct gl_config that the driver can support for windows or
  * pbuffers.
  *
  * For legacy DRI.
@@ -689,7 +766,7 @@ setupLoaderExtensions(__DRIscreen *psp,
  * \param drm_version Version of the kernel DRM.
  * \param frame_buffer Data describing the location and layout of the
  *                     framebuffer.
- * \param pSAREA       Pointer the the SAREA.
+ * \param pSAREA       Pointer to the SAREA.
  * \param fd           Device handle for the DRM.
  * \param extensions   ??
  * \param driver_modes  Returns modes suppoted by the driver
@@ -713,7 +790,7 @@ driCreateNewScreen(int scrn,
     static const __DRIextension *emptyExtensionList[] = { NULL };
     __DRIscreen *psp;
 
-    psp = _mesa_calloc(sizeof *psp);
+    psp = calloc(1, sizeof *psp);
     if (!psp)
        return NULL;
 
@@ -747,18 +824,12 @@ driCreateNewScreen(int scrn,
     psp->myNum = scrn;
     psp->dri2.enabled = GL_FALSE;
 
-    /*
-    ** Do not init dummy context here; actual initialization will be
-    ** done when the first DRI context is created.  Init screen priv ptr
-    ** to NULL to let CreateContext routine that it needs to be inited.
-    */
-    psp->dummyContextPriv.driScreenPriv = NULL;
-
     psp->DriverAPI = driDriverAPI;
+    psp->api_mask = (1 << __DRI_API_OPENGL);
 
     *driver_modes = driDriverAPI.InitScreen(psp);
     if (*driver_modes == NULL) {
-       _mesa_free(psp);
+       free(psp);
        return NULL;
     }
 
@@ -780,7 +851,7 @@ dri2CreateNewScreen(int scrn, int fd,
     if (driDriverAPI.InitScreen2 == NULL)
         return NULL;
 
-    psp = _mesa_calloc(sizeof(*psp));
+    psp = calloc(1, sizeof(*psp));
     if (!psp)
        return NULL;
 
@@ -800,13 +871,20 @@ dri2CreateNewScreen(int scrn, int fd,
     psp->dri2.enabled = GL_TRUE;
 
     psp->DriverAPI = driDriverAPI;
+    psp->api_mask = (1 << __DRI_API_OPENGL);
     *driver_configs = driDriverAPI.InitScreen2(psp);
     if (*driver_configs == NULL) {
-       _mesa_free(psp);
+       free(psp);
        return NULL;
     }
 
     psp->DriverAPI = driDriverAPI;
+    psp->loaderPrivate = data;
+
+    driParseOptionInfo(&psp->optionInfo, __dri2ConfigOptions,
+                      __dri2NConfigOptions);
+    driParseConfigFiles(&psp->optionCache, &psp->optionInfo, psp->myNum,
+                       "dri2");
 
     return psp;
 }
@@ -848,41 +926,15 @@ const __DRIdri2Extension driDRI2Extension = {
     dri2CreateNewScreen,
     dri2CreateNewDrawable,
     dri2CreateNewContext,
+    dri2GetAPIMask,
+    dri2CreateNewContextForAPI
 };
 
-static int
-driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
-{
-    return GLX_BAD_CONTEXT;
-}
-
-static int
-driQueryFrameTracking(__DRIdrawable *dpriv,
-                     int64_t * sbc, int64_t * missedFrames,
-                     float * lastMissedUsage, float * usage)
-{
-   __DRIswapInfo   sInfo;
-   int             status;
-   int64_t         ust;
-   __DRIscreen *psp = dpriv->driScreenPriv;
-
-   status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
-   if ( status == 0 ) {
-      *sbc = sInfo.swap_count;
-      *missedFrames = sInfo.swap_missed_count;
-      *lastMissedUsage = sInfo.swap_missed_usage;
-
-      (*psp->systemTime->getUST)( & ust );
-      *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
-   }
-
-   return status;
-}
-
-const __DRIframeTrackingExtension driFrameTrackingExtension = {
-    { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
-    driFrameTracking,
-    driQueryFrameTracking    
+const __DRI2configQueryExtension dri2ConfigQueryExtension = {
+   { __DRI2_CONFIG_QUERY, __DRI2_CONFIG_QUERY_VERSION },
+   dri2ConfigQueryb,
+   dri2ConfigQueryi,
+   dri2ConfigQueryf,
 };
 
 /**
@@ -948,4 +1000,10 @@ driCalculateSwapUsage( __DRIdrawable *dPriv, int64_t last_swap_ust,
    return usage;
 }
 
+void
+dri2InvalidateDrawable(__DRIdrawable *drawable)
+{
+    drawable->dri2.stamp++;
+}
+
 /*@}*/