glamor: Generalize the a1-to-a8 conversion path.

Pixman is quite qualified to allocate our temporary memory, and all we
need to do is decide what formats to convert from and to.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Eric Anholt 2016-02-01 13:58:11 -08:00 committed by Adam Jackson
parent 8f1411c384
commit 6112fecc3a

View File

@ -204,21 +204,26 @@ glamor_get_tex_format_type_from_pictformat(ScreenPtr pScreen,
return TRUE; return TRUE;
} }
static void * /**
glamor_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride) * Takes a set of source bits with a given format and returns an
* in-memory pixman image of those bits in a destination format.
*/
static pixman_image_t *
glamor_get_converted_image(PictFormatShort dst_format,
PictFormatShort src_format,
void *src_bits,
int src_stride,
int w, int h)
{ {
PictFormatShort dst_format = PICT_a8, src_format = PICT_a1;
pixman_image_t *dst_image; pixman_image_t *dst_image;
pixman_image_t *src_image; pixman_image_t *src_image;
int src_stride = PixmapBytePad(w, 1);
dst_image = pixman_image_create_bits(dst_format, w, h, dst_bits, stride); dst_image = pixman_image_create_bits(dst_format, w, h, NULL, 0);
if (dst_image == NULL) { if (dst_image == NULL) {
return NULL; return NULL;
} }
src_image = pixman_image_create_bits(src_format, src_image = pixman_image_create_bits(src_format, w, h, src_bits, src_stride);
w, h, src_bits, src_stride);
if (src_image == NULL) { if (src_image == NULL) {
pixman_image_unref(dst_image); pixman_image_unref(dst_image);
@ -229,8 +234,7 @@ glamor_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride)
0, 0, 0, 0, 0, 0, w, h); 0, 0, 0, 0, 0, 0, w, h);
pixman_image_unref(src_image); pixman_image_unref(src_image);
pixman_image_unref(dst_image); return dst_image;
return dst_bits;
} }
/** /**
@ -302,34 +306,21 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
glamor_get_screen_private(pixmap->drawable.pScreen); glamor_get_screen_private(pixmap->drawable.pScreen);
float dst_xscale, dst_yscale; float dst_xscale, dst_yscale;
GLuint tex = 0; GLuint tex = 0;
int need_free_bits = 0; pixman_image_t *converted_image = NULL;
if (bits == NULL) if (bits == NULL)
goto ready_to_upload; goto ready_to_upload;
if (revert == REVERT_UPLOADING_A1) { if (revert == REVERT_UPLOADING_A1) {
/* XXX if we are restoring the pixmap, then we may not need to allocate converted_image = glamor_get_converted_image(PICT_a8,
* new buffer */ PICT_a1,
void *converted_bits; bits,
PixmapBytePad(w, 1),
if (pixmap->drawable.depth == 1) w, h);
stride = (((w * 8 + 7) / 8) + 3) & ~3; if (!converted_image)
converted_bits = xallocarray(h, stride);
if (converted_bits == NULL)
return FALSE; return FALSE;
bits = glamor_convert_a1_a8(bits, converted_bits, w, h, stride);
if (bits == NULL) { bits = pixman_image_get_data(converted_image);
free(converted_bits);
ErrorF("Failed to convert pixmap no_alpha %d,"
"revert mode %d, swap mode %d\n", no_alpha, revert, swap_rb);
return FALSE;
}
no_alpha = 0;
revert = REVERT_NONE;
swap_rb = SWAP_NONE_UPLOADING;
need_free_bits = TRUE;
} }
ready_to_upload: ready_to_upload:
@ -355,8 +346,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
x + fbo_x_off, y + fbo_y_off, x + fbo_x_off, y + fbo_y_off,
w, h, w, h,
bits, pbo)) { bits, pbo)) {
if (need_free_bits) if (converted_image)
free(bits); pixman_image_unref(bits);
return FALSE; return FALSE;
} }
} else { } else {
@ -382,8 +373,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
if (!__glamor_upload_pixmap_to_texture(pixmap, &tex, if (!__glamor_upload_pixmap_to_texture(pixmap, &tex,
format, type, 0, 0, w, h, bits, format, type, 0, 0, w, h, bits,
pbo)) { pbo)) {
if (need_free_bits) if (converted_image)
free(bits); pixman_image_unref(bits);
return FALSE; return FALSE;
} }
@ -416,8 +407,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
if (need_free_bits) if (converted_image)
free(bits); pixman_image_unref(bits);
return TRUE; return TRUE;
} }