Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / glx / x11 / glxext.c
index f47caae43df20d476815f68a91ab672afdfa01db..6403cbd56df9680b3be48e73a46f6efb0d749360 100644 (file)
@@ -1,4 +1,3 @@
-/* $XFree86: xc/lib/GL/glx/glxext.c,v 1.22 2003/12/08 17:35:28 dawes Exp $ */
 
 /*
 ** License Applicability. Except to the extent portions of this file are
@@ -48,6 +47,8 @@
 #include <stdio.h>
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/Xdamage.h>
 #include <assert.h>
 #include "indirect_init.h"
 #include "glapi.h"
@@ -394,6 +395,10 @@ static int __glXFreeDisplayPrivate(XExtData *extension)
        (*priv->driDisplay.destroyDisplay)(priv->dpy,
                                           priv->driDisplay.private);
     priv->driDisplay.private = NULL;
+    if (priv->driDisplay.createNewScreen) {
+        Xfree(priv->driDisplay.createNewScreen); /* free array of ptrs */
+        priv->driDisplay.createNewScreen = NULL;
+    }
 #endif
 
     Xfree((char*) priv);
@@ -666,8 +671,10 @@ filter_modes( __GLcontextModes ** server_modes,
        if ( do_delete && (m->visualID != 0) ) {
            do_delete = GL_FALSE;
 
-           fprintf(stderr, "libGL warning: 3D driver claims to not support "
-                   "visual 0x%02x\n", m->visualID);
+            if (getenv("LIBGL_DEBUG")) {
+               fprintf(stderr, "libGL warning: 3D driver claims to not support "
+                       "visual 0x%02x\n", m->visualID);
+            }
        }
 
        if ( do_delete ) {
@@ -698,6 +705,69 @@ static __DRIfuncPtr get_proc_address( const char * proc_name )
     return NULL;
 }
 
+#ifdef XDAMAGE_1_1_INTERFACE
+static GLboolean has_damage_post(__DRInativeDisplay *dpy)
+{
+    static GLboolean inited = GL_FALSE;
+    static GLboolean has_damage;
+
+    if (!inited) {
+       int major, minor;
+
+       if (XDamageQueryVersion(dpy, &major, &minor) &&
+           major == 1 && minor >= 1)
+       {
+           has_damage = GL_TRUE;
+       } else {
+           has_damage = GL_FALSE;
+       }
+       inited = GL_TRUE;
+    }
+
+    return has_damage;
+}
+#endif /* XDAMAGE_1_1_INTERFACE */
+
+static void __glXReportDamage(__DRInativeDisplay *dpy, int screen,
+                             __DRIid drawable,
+                             int x, int y,
+                             drm_clip_rect_t *rects, int num_rects,
+                             GLboolean front_buffer)
+{
+#ifdef XDAMAGE_1_1_INTERFACE
+    XRectangle *xrects;
+    XserverRegion region;
+    int i;
+    int x_off, y_off;
+
+    if (!has_damage_post(dpy))
+       return;
+
+    if (front_buffer) {
+       x_off = x;
+       y_off = y;
+       drawable = RootWindow(dpy, screen);
+    } else{
+       x_off = 0;
+       y_off = 0;
+    }
+
+    xrects = malloc(sizeof(XRectangle) * num_rects);
+    if (xrects == NULL)
+       return;
+
+    for (i = 0; i < num_rects; i++) {
+       xrects[i].x = rects[i].x1 + x_off;
+       xrects[i].y = rects[i].y1 + y_off;
+       xrects[i].width = rects[i].x2 - rects[i].x1;
+       xrects[i].height = rects[i].y2 - rects[i].y1;
+    }
+    region = XFixesCreateRegion(dpy, xrects, num_rects);
+    free(xrects);
+    XDamageAdd(dpy, drawable, region);
+    XFixesDestroyRegion(dpy, region);
+#endif
+}
 
 /**
  * Table of functions exported by the loader to the driver.
@@ -720,9 +790,12 @@ static const __DRIinterfaceMethods interface_methods = {
 
     __glXGetUST,
     __glXGetMscRateOML,
+
+    __glXReportDamage,
 };
 
 
+
 /**
  * Perform the required libGL-side initialization and call the client-side
  * driver's \c __driCreateNewScreen function.
@@ -773,7 +846,8 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
     framebuffer.dev_priv = NULL;
 
     if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
-       fd = drmOpen(NULL,BusID);
+        int newlyopened;
+       fd = drmOpenOnce(NULL,BusID, &newlyopened);
        Xfree(BusID); /* No longer needed */
 
        err_msg = "open DRM";
@@ -800,7 +874,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
                }
 
                err_msg = "XF86DRIAuthConnection";
-               if (XF86DRIAuthConnection(dpy, scrn, magic)) {
+               if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) {
                    char *driverName;
 
                    /*
@@ -904,7 +978,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc,
        }
 
        if ( fd >= 0 ) {
-           (void)drmClose(fd);
+           (void)drmCloseOnce(fd);
        }
 
        (void)XF86DRICloseConnection(dpy, scrn);
@@ -1016,11 +1090,11 @@ static Bool AllocAndFetchScreenConfigs(Display *dpy, __GLXdisplayPrivate *priv)
        if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
            /* Something is busted. Punt. */
            UnlockDisplay(dpy);
+           SyncHandle();
            FreeScreenConfigs(priv);
            return GL_FALSE;
        }
 
-       UnlockDisplay(dpy);
        if (!reply.numVisuals) {
            /* This screen does not support GL rendering */
            UnlockDisplay(dpy);
@@ -1173,7 +1247,7 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy)
        __glXUnlock();
        return 0;
     }
-    dpyPriv = (__GLXdisplayPrivate *) Xmalloc(sizeof(__GLXdisplayPrivate));
+    dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
     if (!dpyPriv) {
        __glXUnlock();
        Xfree((char*) private);
@@ -1198,12 +1272,7 @@ __GLXdisplayPrivate *__glXInitialize(Display* dpy)
     ** Note: This _must_ be done before calling any other DRI routines
     ** (e.g., those called in AllocAndFetchScreenConfigs).
     */
-    if (getenv("LIBGL_ALWAYS_INDIRECT")) {
-        /* Assinging zero here assures we'll never go direct */
-        dpyPriv->driDisplay.private = 0;
-        dpyPriv->driDisplay.destroyDisplay = 0;
-    }
-    else {
+    if (getenv("LIBGL_ALWAYS_INDIRECT") == NULL) {
         dpyPriv->driDisplay.private =
             driCreateDisplay(dpy, &dpyPriv->driDisplay);
     }
@@ -1415,7 +1484,7 @@ void __glXSendLargeCommand(__GLXcontext *ctx,
 
 /************************************************************************/
 
-GLXContext glXGetCurrentContext(void)
+PUBLIC GLXContext glXGetCurrentContext(void)
 {
     GLXContext cx = __glXGetCurrentContext();
     
@@ -1426,7 +1495,7 @@ GLXContext glXGetCurrentContext(void)
     }
 }
 
-GLXDrawable glXGetCurrentDrawable(void)
+PUBLIC GLXDrawable glXGetCurrentDrawable(void)
 {
     GLXContext gc = __glXGetCurrentContext();
     return gc->currentDrawable;
@@ -1612,7 +1681,7 @@ USED static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
        /* Send a glXMakeCurrent request to bind the new context. */
        bindReturnValue = 
          SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None,
-                                (dpy != oldGC->currentDpy) 
+                                ((dpy != oldGC->currentDpy) || oldGC->isDirect)
                                 ? None : oldGC->currentContextTag,
                                 draw, read, &reply);
     }