summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/freebsd-dri3
-rw-r--r--configs/linux-dri3
-rw-r--r--include/GL/internal/dri_interface.h20
-rw-r--r--src/glx/x11/glxcmds.c3
-rw-r--r--src/glx/x11/glxext.c66
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c21
6 files changed, 112 insertions, 4 deletions
diff --git a/configs/freebsd-dri b/configs/freebsd-dri
index 68877c612e..1492e4a4d9 100644
--- a/configs/freebsd-dri
+++ b/configs/freebsd-dri
@@ -28,7 +28,8 @@ ASM_SOURCES =
LIBDRM_CFLAGS = `pkg-config --cflags libdrm`
LIBDRM_LIB = `pkg-config --libs libdrm`
DRI_LIB_DEPS = -L/usr/local/lib -lm -lpthread -lexpat $(LIBDRM_LIB)
-GL_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXext -lXxf86vm -lm -lpthread $(LIBDRM_LIB)
+GL_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \
+ -lm -lpthread $(LIBDRM_LIB)
GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -L/usr/X11R6/lib -lGLU -lGL -lX11 -lXmu -lXt -lXi -lm
GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -L/usr/X11R6/lib -lGL -lXt -lX11
diff --git a/configs/linux-dri b/configs/linux-dri
index 7e822e2eb6..5f945a73f1 100644
--- a/configs/linux-dri
+++ b/configs/linux-dri
@@ -41,7 +41,8 @@ EXTRA_LIB_PATH=-L/usr/X11R6/lib
LIBDRM_CFLAGS = `pkg-config --cflags libdrm`
LIBDRM_LIB = `pkg-config --libs libdrm`
DRI_LIB_DEPS = $(EXTRA_LIB_PATH) -lm -lpthread -lexpat -ldl $(LIBDRM_LIB)
-GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lm -lpthread -ldl \
+GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \
+ -lm -lpthread -ldl \
$(LIBDRM_LIB)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index c204ecfe62..a3de2c6aab 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -237,6 +237,26 @@ struct __DRIinterfaceMethodsRec {
GLboolean (*getMSCRate)(__DRInativeDisplay * dpy, __DRIid drawable,
int32_t * numerator, int32_t * denominator);
/*@}*/
+
+ /**
+ * Reports areas of the given drawable which have been modified by the
+ * driver.
+ *
+ * \param drawable which the drawing was done to.
+ * \param rects rectangles affected, with the drawable origin as the
+ * origin.
+ * \param x X offset of the drawable within the screen (used in the
+ * front_buffer case)
+ * \param y Y offset of the drawable within the screen.
+ * \param front_buffer boolean flag for whether the drawing to the
+ * drawable was actually done directly to the front buffer (instead
+ * of backing storage, for example)
+ */
+ void (*reportDamage)(__DRInativeDisplay * dpy, int screen,
+ __DRIid drawable,
+ int x, int y,
+ drm_clip_rect_t *rects, int num_rects,
+ int front_buffer);
};
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index 9d1bb2a0b5..f52b71ffcd 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -2883,8 +2883,9 @@ int __glXGetInternalVersion(void)
* 20050727 - Gut all the old interfaces. This breaks compatability with
* any DRI driver built to any previous version.
* 20060314 - Added support for GLX_MESA_copy_sub_buffer.
+ * 20070105 - Added support for damage reporting.
*/
- return 20060314;
+ return 20070105;
}
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index 8bec2c34c6..29b3a1c01c 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -48,6 +48,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"
@@ -698,6 +700,68 @@ 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);
+ XDamagePost(dpy, drawable, region);
+ XFixesDestroyRegion(dpy, region);
+#endif
+}
/**
* Table of functions exported by the loader to the driver.
@@ -720,6 +784,8 @@ static const __DRIinterfaceMethods interface_methods = {
__glXGetUST,
__glXGetMscRateOML,
+
+ __glXReportDamage,
};
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index ba251a8143..cc3dcf9d8d 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -482,8 +482,27 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate )
{
__DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ drm_clip_rect_t rect;
+
dPriv->swapBuffers(dPriv);
- (void) dpy;
+
+ /* Check that we actually have the new damage report method */
+ if (api_ver < 20070105 || dri_interface->reportDamage == NULL)
+ return;
+
+ /* Assume it's affecting the whole drawable for now */
+ rect.x1 = 0;
+ rect.y1 = 0;
+ rect.x2 = rect.x1 + dPriv->w;
+ rect.y2 = rect.y1 + dPriv->h;
+
+ /* Report the damage. Currently, all our drivers draw directly to the
+ * front buffer, so we report the damage there rather than to the backing
+ * store (if any).
+ */
+ (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw,
+ dPriv->x, dPriv->y,
+ &rect, 1, GL_TRUE);
}
/**