From 356c4ed9ccb317b29fa7a9bb89b43f73cd70053e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 20 Apr 2011 10:34:05 -0700 Subject: [PATCH] Expose 30bpp/10bpc support: CAIRO_FORMAT_RGB30 This is a common format used by framebuffers to drive 10bpc displays and is often hardware accelerated by XRender with underlying support from pixman's x2r10g10b10 format (which provides coercion paths for fallbacks). Signed-off-by: Jesse Barnes Signed-off-by: Chris Wilson --- src/cairo-debug.c | 1 + src/cairo-image-surface.c | 25 ++++++++++++++++++++-- src/cairo-png.c | 4 ++++ src/cairo-xlib-display.c | 1 + src/cairo.h | 4 +++- src/cairoint.h | 2 +- util/cairo-script/cairo-script-operators.c | 4 ++++ util/cairo-trace/trace.c | 4 ++++ 8 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/cairo-debug.c b/src/cairo-debug.c index b8bdfd1f6..1aa57791e 100644 --- a/src/cairo-debug.c +++ b/src/cairo-debug.c @@ -118,6 +118,7 @@ _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface) width = image->width*2; break; case CAIRO_FORMAT_RGB24: + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_ARGB32: width = image->width*4; break; diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 7097fa4c1..6041c4f2f 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -101,6 +101,8 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format) switch (pixman_format) { case PIXMAN_a8r8g8b8: return CAIRO_FORMAT_ARGB32; + case PIXMAN_x2b10g10r10: + return CAIRO_FORMAT_RGB30; case PIXMAN_x8r8g8b8: return CAIRO_FORMAT_RGB24; case PIXMAN_a8: @@ -122,7 +124,6 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format) case PIXMAN_yuy2: case PIXMAN_yv12: case PIXMAN_b8g8r8x8: case PIXMAN_b8g8r8a8: - case PIXMAN_x2b10g10r10: case PIXMAN_a2b10g10r10: case PIXMAN_x2r10g10b10: case PIXMAN_a2r10g10b10: @@ -300,6 +301,9 @@ _cairo_format_to_pixman_format_code (cairo_format_t format) case CAIRO_FORMAT_RGB24: ret = PIXMAN_x8r8g8b8; break; + case CAIRO_FORMAT_RGB30: + ret = PIXMAN_x2r10g10b10; + break; case CAIRO_FORMAT_RGB16_565: ret = PIXMAN_r5g6b5; break; @@ -668,6 +672,8 @@ _cairo_content_from_format (cairo_format_t format) switch (format) { case CAIRO_FORMAT_ARGB32: return CAIRO_CONTENT_COLOR_ALPHA; + case CAIRO_FORMAT_RGB30: + return CAIRO_CONTENT_COLOR; case CAIRO_FORMAT_RGB24: return CAIRO_CONTENT_COLOR; case CAIRO_FORMAT_RGB16_565: @@ -688,7 +694,7 @@ _cairo_format_bits_per_pixel (cairo_format_t format) { switch (format) { case CAIRO_FORMAT_ARGB32: - return 32; + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_RGB24: return 32; case CAIRO_FORMAT_RGB16_565: @@ -1272,6 +1278,21 @@ _pixel_to_solid (cairo_image_surface_t *image, int x, int y) color.blue = expand_channel ((pixel & 0x1f) << 11, 5); return pixman_image_create_solid_fill (&color); + case CAIRO_FORMAT_RGB30: + pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x); + pixel &= 0x3fffffff; /* ignore alpha bits */ + if (pixel == 0) + return _pixman_black_image (); + if (pixel == 0x3fffffff) + return _pixman_white_image (); + + /* convert 10bpc to 16bpc */ + color.alpha = 0xffff; + color.red = expand_channel((pixel >> 20) & 0x3fff, 10); + color.green = expand_channel((pixel >> 10) & 0x3fff, 10); + color.blue = expand_channel(pixel & 0x3fff, 10); + return pixman_image_create_solid_fill (&color); + case CAIRO_FORMAT_ARGB32: case CAIRO_FORMAT_RGB24: pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x); diff --git a/src/cairo-png.c b/src/cairo-png.c index f5c7cb547..e176043db 100644 --- a/src/cairo-png.c +++ b/src/cairo-png.c @@ -241,6 +241,10 @@ write_png (cairo_surface_t *surface, else png_color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; + case CAIRO_FORMAT_RGB30: + depth = 30; + png_color_type = PNG_COLOR_TYPE_RGB; + break; case CAIRO_FORMAT_RGB24: depth = 8; png_color_type = PNG_COLOR_TYPE_RGB; diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c index dd60484c8..bef9c8391 100644 --- a/src/cairo-xlib-display.c +++ b/src/cairo-xlib-display.c @@ -584,6 +584,7 @@ _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display, xrender_format = XRenderFindVisualFormat(display->display, visual); break; } + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_INVALID: default: ASSERT_NOT_REACHED; diff --git a/src/cairo.h b/src/cairo.h index 3495146f0..963259293 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2251,6 +2251,7 @@ cairo_surface_has_show_text_glyphs (cairo_surface_t *surface); * @CAIRO_FORMAT_RGB16_565: each pixel is a 16-bit quantity * with red in the upper 5 bits, then green in the middle * 6 bits, and blue in the lower 5 bits. + * @CAIRO_FORMAT_RGB30: like RGB24 but with 10bpc * * #cairo_format_t is used to identify the memory format of * image data. @@ -2263,7 +2264,8 @@ typedef enum _cairo_format { CAIRO_FORMAT_RGB24 = 1, CAIRO_FORMAT_A8 = 2, CAIRO_FORMAT_A1 = 3, - CAIRO_FORMAT_RGB16_565 = 4 + CAIRO_FORMAT_RGB16_565 = 4, + CAIRO_FORMAT_RGB30 = 5, } cairo_format_t; cairo_public cairo_surface_t * diff --git a/src/cairoint.h b/src/cairoint.h index 8d9bd4423..efe9424ba 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1862,7 +1862,7 @@ _cairo_surface_release_device_reference (cairo_surface_t *surface); * in cairo-xlib-surface.c--again see -Wswitch-enum). */ #define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 && \ - (format) <= CAIRO_FORMAT_RGB16_565) + (format) <= CAIRO_FORMAT_RGB30) /* pixman-required stride alignment in bytes. */ #define CAIRO_STRIDE_ALIGNMENT (sizeof (uint32_t)) diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c index 647975f7c..34b534e09 100644 --- a/util/cairo-script/cairo-script-operators.c +++ b/util/cairo-script/cairo-script-operators.c @@ -2854,6 +2854,7 @@ _image_read_raw (csi_file_t *src, rowlen = 3 * width; break; default: + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_INVALID: case CAIRO_FORMAT_ARGB32: rowlen = 4 * width; @@ -2915,6 +2916,7 @@ _image_read_raw (csi_file_t *src, #endif } break; + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_INVALID: case CAIRO_FORMAT_ARGB32: /* stride == width */ @@ -3003,6 +3005,7 @@ _image_read_raw (csi_file_t *src, #endif } break; + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_INVALID: case CAIRO_FORMAT_ARGB32: /* stride == width */ @@ -3038,6 +3041,7 @@ _image_read_raw (csi_file_t *src, case CAIRO_FORMAT_A8: break; + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_RGB24: case CAIRO_FORMAT_INVALID: default: diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c index 9bdeb01a6..44dc137a7 100644 --- a/util/cairo-trace/trace.c +++ b/util/cairo-trace/trace.c @@ -1451,6 +1451,7 @@ _format_to_string (cairo_format_t format) switch (format) { f(INVALID); f(ARGB32); + f(RGB30); f(RGB24); f(RGB16_565); f(A8); @@ -1584,6 +1585,7 @@ _emit_image (cairo_surface_t *image, case CAIRO_FORMAT_RGB16_565: len = 2*width; break; case CAIRO_FORMAT_RGB24: len = 3*width; break; default: + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_INVALID: case CAIRO_FORMAT_ARGB32: len = 4*width; break; } @@ -1622,6 +1624,7 @@ _emit_image (cairo_surface_t *image, data += stride; } break; + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_ARGB32: for (row = height; row--; ) { _write_data (&stream, data, 4*width); @@ -1681,6 +1684,7 @@ _emit_image (cairo_surface_t *image, data += stride; } break; + case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_ARGB32: for (row = height; row--; ) { uint32_t *src = (uint32_t *) data;