mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 23:00:11 +01:00
mesa: add a couple fast-paths to fast_read_rgba_pixels_memcpy()
Accelerates a few glReadPixels cases for WebGL. See https://bugs.freedesktop.org/show_bug.cgi?id=48545 v2: Per Jose, use bit twiddling for the swizzle case instead of ubyte arrays (it's about 44% faster). Note: This is a candidate for the 8.0 branch. Reviewed-by: José Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
b814506e87
commit
a5e95a419e
1 changed files with 54 additions and 6 deletions
|
|
@ -208,6 +208,11 @@ read_stencil_pixels( struct gl_context *ctx,
|
|||
ctx->Driver.UnmapRenderbuffer(ctx, rb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to do glReadPixels of RGBA data using a simple memcpy or swizzle.
|
||||
* \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path)
|
||||
*/
|
||||
static GLboolean
|
||||
fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
|
||||
GLint x, GLint y,
|
||||
|
|
@ -220,9 +225,23 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
|
|||
struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
|
||||
GLubyte *dst, *map;
|
||||
int dstStride, stride, j, texelBytes;
|
||||
GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE;
|
||||
|
||||
if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
|
||||
ctx->Pack.SwapBytes))
|
||||
/* XXX we could check for other swizzle/special cases here as needed */
|
||||
if (rb->Format == MESA_FORMAT_RGBA8888_REV &&
|
||||
format == GL_BGRA &&
|
||||
type == GL_UNSIGNED_INT_8_8_8_8_REV &&
|
||||
!ctx->Pack.SwapBytes) {
|
||||
swizzle_rb = GL_TRUE;
|
||||
}
|
||||
else if (rb->Format == MESA_FORMAT_XRGB8888 &&
|
||||
format == GL_BGRA &&
|
||||
type == GL_UNSIGNED_INT_8_8_8_8_REV &&
|
||||
!ctx->Pack.SwapBytes) {
|
||||
copy_xrgb = GL_TRUE;
|
||||
}
|
||||
else if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
|
||||
ctx->Pack.SwapBytes))
|
||||
return GL_FALSE;
|
||||
|
||||
/* If the format is unsigned normalized then we can ignore clamping
|
||||
|
|
@ -247,10 +266,39 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
|
|||
}
|
||||
|
||||
texelBytes = _mesa_get_format_bytes(rb->Format);
|
||||
for (j = 0; j < height; j++) {
|
||||
memcpy(dst, map, width * texelBytes);
|
||||
dst += dstStride;
|
||||
map += stride;
|
||||
|
||||
if (swizzle_rb) {
|
||||
/* swap R/B */
|
||||
for (j = 0; j < height; j++) {
|
||||
int i;
|
||||
for (i = 0; i < width; i++) {
|
||||
GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map;
|
||||
GLuint pixel = map4[i];
|
||||
dst4[i] = (pixel & 0xff00ff00)
|
||||
| ((pixel & 0x00ff0000) >> 16)
|
||||
| ((pixel & 0x000000ff) << 16);
|
||||
}
|
||||
dst += dstStride;
|
||||
map += stride;
|
||||
}
|
||||
} else if (copy_xrgb) {
|
||||
/* convert xrgb -> argb */
|
||||
for (j = 0; j < height; j++) {
|
||||
GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map;
|
||||
int i;
|
||||
for (i = 0; i < width; i++) {
|
||||
dst4[i] = map4[i] | 0xff000000; /* set A=0xff */
|
||||
}
|
||||
dst += dstStride;
|
||||
map += stride;
|
||||
}
|
||||
} else {
|
||||
/* just memcpy */
|
||||
for (j = 0; j < height; j++) {
|
||||
memcpy(dst, map, width * texelBytes);
|
||||
dst += dstStride;
|
||||
map += stride;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->Driver.UnmapRenderbuffer(ctx, rb);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue