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