glamor: Use GL_MESA_pack_invert to avoid complexity in prepare_access.

This commit is contained in:
Eric Anholt 2010-02-08 11:58:52 +01:00 committed by Zhigang Gong
parent e9d4794cd0
commit 72a757ba00

View File

@ -293,25 +293,24 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
return TRUE; return TRUE;
} }
stride = PixmapBytePad(drawable->width, drawable->depth); stride = PixmapBytePad(pixmap->drawable.width, drawable->depth);
read_stride = stride; read_stride = stride;
data = xalloc(stride * drawable->height); data = xalloc(stride * pixmap->drawable.height);
switch (drawable->depth) { switch (drawable->depth) {
case 1: case 1:
format = GL_ALPHA; format = GL_ALPHA;
type = GL_UNSIGNED_BYTE; type = GL_UNSIGNED_BYTE;
read_stride = drawable->width; read_stride = pixmap->drawable.width;
break; break;
case 8: case 8:
format = GL_ALPHA; format = GL_ALPHA;
type = GL_UNSIGNED_BYTE; type = GL_UNSIGNED_BYTE;
break; break;
case 24: case 24:
format = GL_RGB; assert(drawable->bitsPerPixel == 32);
type = GL_UNSIGNED_BYTE; /* FALLTHROUGH */
break;
case 32: case 32:
format = GL_BGRA; format = GL_BGRA;
type = GL_UNSIGNED_INT_8_8_8_8_REV; type = GL_UNSIGNED_INT_8_8_8_8_REV;
@ -323,47 +322,55 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
} }
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
glGenBuffersARB(1, &pixmap_priv->pbo);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
read_stride * pixmap->drawable.height,
NULL, GL_DYNAMIC_DRAW_ARB);
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 / glPixelStorei(GL_PACK_ROW_LENGTH, read_stride * 8 /
pixmap->drawable.bitsPerPixel); pixmap->drawable.bitsPerPixel);
glReadPixels(0, 0, if (GLEW_MESA_pack_invert && drawable->depth != 1) {
pixmap->drawable.width, pixmap->drawable.height, glPixelStorei(GL_PACK_INVERT_MESA, 1);
format, type, 0); glReadPixels(0, 0,
pixmap->drawable.width, pixmap->drawable.height,
read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB); format, type, data);
glPixelStorei(GL_PACK_INVERT_MESA, 0);
if (pixmap->drawable.depth == 1) {
for (y = 0; y < pixmap->drawable.height; y++) {
uint8_t *read_row = read + read_stride * (pixmap->drawable.height -
y - 1);
for (x = 0; x < pixmap->drawable.width; x++) {
int index = x / 8;
int bit = 1 << (x % 8);
if (read_row[x])
data[index] |= bit;
else
data[index] &= ~bit;
}
}
} else { } else {
for (y = 0; y < pixmap->drawable.height; y++) glGenBuffersARB(1, &pixmap_priv->pbo);
memcpy(data + y * stride, glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pixmap_priv->pbo);
read + (pixmap->drawable.height - y - 1) * stride, stride); glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT,
} read_stride * pixmap->drawable.height,
pixmap->devPrivate.ptr = data; NULL, GL_DYNAMIC_DRAW_ARB);
glReadPixels(0, 0,
pixmap->drawable.width, pixmap->drawable.height,
format, type, 0);
glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); read = glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, GL_READ_WRITE_ARB);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
glDeleteBuffersARB(1, &pixmap_priv->pbo); if (pixmap->drawable.depth == 1) {
pixmap_priv->pbo = 0; for (y = 0; y < pixmap->drawable.height; y++) {
uint8_t *read_row = read +
read_stride * (pixmap->drawable.height - y - 1);
for (x = 0; x < pixmap->drawable.width; x++) {
int index = x / 8;
int bit = 1 << (x % 8);
if (read_row[x])
data[index] |= bit;
else
data[index] &= ~bit;
}
}
} else {
for (y = 0; y < pixmap->drawable.height; y++)
memcpy(data + y * stride,
read + (pixmap->drawable.height - y - 1) * stride, stride);
}
glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
glDeleteBuffersARB(1, &pixmap_priv->pbo);
pixmap_priv->pbo = 0;
}
pixmap->devPrivate.ptr = data;
return TRUE; return TRUE;
} }
@ -397,9 +404,8 @@ glamor_finish_access(DrawablePtr drawable)
type = GL_UNSIGNED_BYTE; type = GL_UNSIGNED_BYTE;
break; break;
case 24: case 24:
format = GL_RGB; assert(drawable->bitsPerPixel == 32);
type = GL_UNSIGNED_BYTE; /* FALLTHROUGH */
break;
case 32: case 32:
format = GL_BGRA; format = GL_BGRA;
type = GL_UNSIGNED_INT_8_8_8_8_REV; type = GL_UNSIGNED_INT_8_8_8_8_REV;
@ -409,7 +415,7 @@ glamor_finish_access(DrawablePtr drawable)
return; return;
} }
stride = PixmapBytePad(drawable->width, drawable->depth); stride = PixmapBytePad(pixmap->drawable.width, drawable->depth);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, pixmap_priv->fb);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);