Biggest problem with using Xgl and compiz on DRI drivers is that I can't
efficiently update part of the screen. On proprietary drivers it's
efficiently done by using DrawBuffer (GL_FRONT) and CopyPixels.
The attached patch for mesa 6.4.2 is just something I created to prove
that Xgl and compiz runs very well on the Intel driver once this is
fixed.
I'd like to get this solved asap. I suggest that we add support for
GLX_MESA_copy_sub_buffer. If I remove the CopyPixel hack from my Intel
driver patch, that's pretty much what we have.
Xgl will use GLX_MESA_copy_sub_buffer instead of CopyPixels when
available and we'll add protocol support so that compositing managers
can use it.
Thoughts?
I'll probably go ahead and get this done in the next few days if no one
objects.
-David
diff -ur ../Mesa-6.4.2/src/mesa/drivers/dri/i915/intel_batchbuffer.c ./src/mesa/drivers/dri/i915/intel_batchbuffer.c
--- ../Mesa-6.4.2/src/mesa/drivers/dri/i915/intel_batchbuffer.c 2005-05-04 22:11:37.000000000 +0200
+++ ./src/mesa/drivers/dri/i915/intel_batchbuffer.c 2006-03-07 00:04:02.000000000 +0100
@@ -318,7 +318,8 @@
/*
* Copy the back buffer to the front buffer.
*/
-void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
+void intelCopyBuffer( const __DRIdrawablePrivate *dPriv,
+ const drm_clip_rect_t *rect)
{
intelContextPtr intel;
@@ -338,6 +339,7 @@
__DRIdrawablePrivate *dPriv = intel->driDrawable;
int nbox = dPriv->numClipRects;
drm_clip_rect_t *pbox = dPriv->pClipRects;
+ drm_clip_rect_t box;
int pitch = intelScreen->frontPitch;
int cpp = intelScreen->cpp;
int i;
@@ -370,19 +372,36 @@
pbox->x2 > intelScreen->width ||
pbox->y2 > intelScreen->height)
continue;
+
+ box = *pbox;
+
+ if (rect)
+ {
+ if (rect->x1 > box.x1)
+ box.x1 = rect->x1;
+ if (rect->y1 > box.y1)
+ box.y1 = rect->y1;
+ if (rect->x2 < box.x2)
+ box.x2 = rect->x2;
+ if (rect->y2 < box.y2)
+ box.y2 = rect->y2;
+
+ if (box.x1 > box.x2 || box.y1 > box.y2)
+ continue;
+ }
BEGIN_BATCH( 8);
OUT_BATCH( CMD );
OUT_BATCH( BR13 );
- OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
- OUT_BATCH( (pbox->y2 << 16) | pbox->x2 );
+ OUT_BATCH( (box.y1 << 16) | box.x1 );
+ OUT_BATCH( (box.y2 << 16) | box.x2 );
if (intel->sarea->pf_current_page == 0)
OUT_BATCH( intelScreen->frontOffset );
else
OUT_BATCH( intelScreen->backOffset );
- OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
+ OUT_BATCH( (box.y1 << 16) | box.x1 );
OUT_BATCH( BR13 & 0xffff );
if (intel->sarea->pf_current_page == 0)
diff -ur ../Mesa-6.4.2/src/mesa/drivers/dri/i915/intel_batchbuffer.h ./src/mesa/drivers/dri/i915/intel_batchbuffer.h
--- ../Mesa-6.4.2/src/mesa/drivers/dri/i915/intel_batchbuffer.h 2004-06-18 12:54:48.000000000 +0200
+++ ./src/mesa/drivers/dri/i915/intel_batchbuffer.h 2006-03-07 00:04:36.000000000 +0100
@@ -74,7 +74,8 @@
extern GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
int primitive, int dwords,
int vertex_size);
-extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv );
+extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv,
+ const drm_clip_rect_t *rect);
extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx1, GLint cy1, GLint cw, GLint ch);
diff -ur ../Mesa-6.4.2/src/mesa/drivers/dri/i915/intel_context.c ./src/mesa/drivers/dri/i915/intel_context.c
--- ../Mesa-6.4.2/src/mesa/drivers/dri/i915/intel_context.c 2005-09-10 18:44:26.000000000 +0200
+++ ./src/mesa/drivers/dri/i915/intel_context.c 2006-03-07 00:05:38.000000000 +0100
@@ -617,7 +617,7 @@
if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
intelPageFlip( dPriv );
} else {
- intelCopyBuffer( dPriv );
+ intelCopyBuffer( dPriv, NULL );
}
}
} else {
diff -ur ../Mesa-6.4.2/src/mesa/drivers/dri/i915/intel_pixel.c ./src/mesa/drivers/dri/i915/intel_pixel.c
--- ../Mesa-6.4.2/src/mesa/drivers/dri/i915/intel_pixel.c 2005-05-09 19:42:18.000000000 +0200
+++ ./src/mesa/drivers/dri/i915/intel_pixel.c 2006-03-07 00:00:01.000000000 +0100
@@ -464,7 +464,32 @@
srcx, srcy, width, height, destx, desty);
}
#else
- _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type );
+ if (type == GL_COLOR &&
+ ctx->Pixel.ReadBuffer == GL_BACK &&
+ ctx->Color.DrawBuffer[0] == GL_FRONT &&
+ srcx == destx && srcy == desty &&
+ ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */
+ ctx->Pixel.ZoomX == 1.0 && /* no zooming */
+ ctx->Pixel.ZoomY == 1.0)
+ {
+ intelContextPtr intel = INTEL_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ drm_clip_rect_t rect;
+
+ /* convert to screen coords (y=0=top) */
+ srcy = dPriv->h - srcy - height;
+ srcx += dPriv->x;
+ srcy += dPriv->y;
+
+ rect.x1 = srcx;
+ rect.y1 = srcy;
+ rect.x2 = rect.x1 + width;
+ rect.y2 = rect.y1 + height;
+
+ intelCopyBuffer( dPriv, &rect );
+ }
+ else
+ _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type );
#endif
}