xserver: Branch 'master'

Kristian Høgsberg krh at kemper.freedesktop.org
Wed Jun 28 02:48:15 EEST 2006


 GL/glx/glxcmds.c     |    1 
 GL/glx/glxdrawable.h |    4 +
 GL/glx/glxdri.c      |  142 +++++++++++++++++++++++++++++++++++----------------
 GL/glx/glxext.c      |    4 +
 4 files changed, 108 insertions(+), 43 deletions(-)

New commits:
diff-tree 54d9acd5113318274e291abab4554b8e678227df (from adfe8e7437ff739f54d1d074008e8cc0e3bcb4d3)
Author: Kristian Høgsberg <krh at redhat.com>
Date:   Tue Jun 27 19:44:52 2006 -0400

    Add damage tracking to GLX_EXT_tfp implementation.
    
    - Only update when pixmap content actually change;
    - Only update the regions that acutally changed.
    
    This is a worthwhile optimization, but it doesn't completely remove
    the bottleneck, as mesa still uploads then entire texture whenever
    it changes.

diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c
index 3202f75..79fee20 100644
--- a/GL/glx/glxcmds.c
+++ b/GL/glx/glxcmds.c
@@ -1263,6 +1263,7 @@ int DoCreateGLXPixmap(__GLXclientState *
     pGlxPixmap->pGlxScreen = pGlxScreen;
     pGlxPixmap->pScreen = pScreen;
     pGlxPixmap->idExists = True;
+    pGlxPixmap->pDamage = NULL;
     pGlxPixmap->refcnt = 0;
 
     pGlxPixmap->modes = modes;
diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h
index 2d5d07a..4514e26 100644
--- a/GL/glx/glxdrawable.h
+++ b/GL/glx/glxdrawable.h
@@ -41,6 +41,8 @@
 **
 */
 
+#include <damage.h>
+
 typedef struct {
 
     DrawablePtr pDraw;
@@ -49,7 +51,7 @@ typedef struct {
     ScreenPtr pScreen;
     Bool idExists;
     int refcnt;
-
+    DamagePtr pDamage;
 } __GLXpixmap;
 
 struct __GLXdrawable {
diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c
index 4935b0a..c033905 100644
--- a/GL/glx/glxdri.c
+++ b/GL/glx/glxdri.c
@@ -296,24 +296,18 @@ glxCountBits(int word)
 }
 
 static void
-glxFillAlphaChannel (PixmapPtr pixmap)
+glxFillAlphaChannel (PixmapPtr pixmap, int x, int y, int width, int height)
 {
-    int i, j;
-    CARD32 *pixels = (CARD32 *)pixmap->devPrivate.ptr;
+    int i;
+    CARD32 *p, *end, *pixels = (CARD32 *)pixmap->devPrivate.ptr;
     CARD32 rowstride = pixmap->devKind / 4;
-    CARD32 x, y;
-
-    x = pixmap->drawable.x;
-    y = pixmap->drawable.y;
     
-    for (i = y; i < pixmap->drawable.height + y; ++i)
+    for (i = y; i < y + height; i++)
     {
-        for (j = x; j < pixmap->drawable.width + x; ++j)
-        {
-            int index = i * rowstride + j;
-
-            pixels[index] |= 0xFF000000;
-        }
+	p = &pixels[i * rowstride + x];
+	end = p + width;
+	while (p < end)
+	  *p++ |= 0xFF000000;
     }
 }
 
@@ -326,7 +320,6 @@ glxFillAlphaChannel (PixmapPtr pixmap)
  * - No fbconfig handling for TEXTURE_TARGET
  * - No fbconfig exposure of Y inversion state
  * - No GenerateMipmapEXT support (due to no FBO support)
- * - No damage tracking between binds
  * - No support for anything but 16bpp and 32bpp-sparse pixmaps
  */
 
@@ -335,38 +328,103 @@ __glXDRIbindTexImage(__GLXcontext *baseC
 		     int buffer,
 		     __GLXpixmap *glxPixmap)
 {
+    RegionPtr	pRegion;
     PixmapPtr	pixmap;
     int		bpp;
-    Bool	npot;
+    GLenum	target, format, type;
 
     pixmap = (PixmapPtr) glxPixmap->pDraw;
-    bpp = pixmap->drawable.depth >= 24 ? 4 : 2; /* XXX 24bpp packed, 8, etc */
-    
+    if (!glxPixmap->pDamage) {
+        glxPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
+					  TRUE, glxPixmap->pScreen, NULL);
+	if (!glxPixmap->pDamage)
+            return BadAlloc;
+
+	DamageRegister ((DrawablePtr) pixmap, glxPixmap->pDamage);
+	pRegion = NULL;
+    } else {
+	pRegion = DamageRegion(glxPixmap->pDamage);
+	if (REGION_NIL(pRegion))
+	    return Success;
+    }
+
+    /* XXX 24bpp packed, 8, etc */
+    if (pixmap->drawable.depth >= 24) {
+	bpp = 4;
+	format = GL_BGRA;
+	type = GL_UNSIGNED_BYTE;
+    } else {
+	bpp = 2;
+	format = GL_RGB;
+	type = GL_UNSIGNED_SHORT_5_6_5;
+    }
+
+    if (!(glxCountBits(pixmap->drawable.width) == 1 &&
+	  glxCountBits(pixmap->drawable.height) == 1)
+	/* || strstr(CALL_GetString(GL_EXTENSIONS,
+	             "GL_ARB_texture_non_power_of_two")) */)
+	target = GL_TEXTURE_RECTANGLE_ARB;
+    else
+	target = GL_TEXTURE_2D;
+
     CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
-                                       pixmap->devKind / bpp) );
-    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS,
-                                       pixmap->drawable.y) );
-    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS,
-                                       pixmap->drawable.x) );
-
-    if (pixmap->drawable.depth == 24)
-        glxFillAlphaChannel(pixmap);
-
-    npot = !(glxCountBits(pixmap->drawable.width) == 1 &&
-             glxCountBits(pixmap->drawable.height) == 1) /* ||
-             strstr(CALL_GetString(GL_EXTENSIONS,
-                    "GL_ARB_texture_non_power_of_two")) */ ;
-    
-    CALL_TexImage2D( GET_DISPATCH(),
-		     ( npot ? GL_TEXTURE_RECTANGLE_ARB : GL_TEXTURE_2D,
-		       0,
-		       bpp == 4 ? 4 : 3,
-		       pixmap->drawable.width,
-		       pixmap->drawable.height,
-		       0,
-		       bpp == 4 ? GL_BGRA : GL_RGB,
-		       bpp == 4 ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,
-		       pixmap->devPrivate.ptr ) );
+				       pixmap->devKind / bpp) );
+    if (pRegion == NULL)
+    {
+	if (pixmap->drawable.depth == 24)
+	    glxFillAlphaChannel(pixmap,
+				pixmap->drawable.x,
+				pixmap->drawable.y,
+				pixmap->drawable.width,
+				pixmap->drawable.height);
+
+        CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS,
+					   pixmap->drawable.x) );
+	CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS,
+					   pixmap->drawable.y) );
+
+	CALL_TexImage2D( GET_DISPATCH(),
+			 (target,
+			  0,
+			  bpp == 4 ? 4 : 3,
+			  pixmap->drawable.width,
+			  pixmap->drawable.height,
+			  0,
+			  format,
+			  type,
+			  pixmap->devPrivate.ptr) );
+    } else {
+        int i, numRects;
+	BoxPtr p;
+
+	numRects = REGION_NUM_RECTS (pRegion);
+	p = REGION_RECTS (pRegion);
+	for (i = 0; i < numRects; i++)
+	{
+	    if (pixmap->drawable.depth == 24)
+		glxFillAlphaChannel(pixmap,
+				    pixmap->drawable.x + p[i].x1,
+				    pixmap->drawable.y + p[i].y1,
+				    p[i].x2 - p[i].x1,
+				    p[i].y2 - p[i].y1);
+
+	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS,
+					       pixmap->drawable.x + p[i].x1) );
+	    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS,
+					       pixmap->drawable.y + p[i].y1) );
+
+	    CALL_TexSubImage2D( GET_DISPATCH(),
+				(target,
+				 0,
+				 p[i].x1, p[i].y1,
+				 p[i].x2 - p[i].x1, p[i].y2 - p[i].y1,
+				 format,
+				 type,
+				 pixmap->devPrivate.ptr) );
+	}
+    }
+
+    DamageEmpty(glxPixmap->pDamage);
 
     return Success;
 }
diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c
index c2a165e..cc5dd96 100644
--- a/GL/glx/glxext.c
+++ b/GL/glx/glxext.c
@@ -141,6 +141,10 @@ static int PixmapGone(__GLXpixmap *pGlxP
 
     pGlxPixmap->idExists = False;
     if (!pGlxPixmap->refcnt) {
+	if (pGlxPixmap->pDamage) {
+	    DamageUnregister (pGlxPixmap->pDraw, pGlxPixmap->pDamage);
+	    DamageDestroy(pGlxPixmap->pDamage);
+	}
 	/*
 	** The DestroyPixmap routine should decrement the refcount and free
 	** only if it's zero.



More information about the xorg-commit mailing list