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
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)
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);
};
* 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;
}
#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"
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.
__glXGetUST,
__glXGetMscRateOML,
+
+ __glXReportDamage,
};
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);
}
/**