@@ -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 |
@@ -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) | |||
@@ -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); | |||
}; | |||
@@ -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; | |||
} | |||
@@ -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, | |||
}; | |||
@@ -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); | |||
} | |||
/** |