summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-02-19 14:10:14 +0100
committerSøren Sandmann Pedersen <ssp@redhat.com>2010-07-07 10:23:04 -0400
commitf19c5bb90bfe103a01514a554d45ad1f4614d011 (patch)
treeb3d5be407b9c82cfd0af1156689f042dd025dafb
parent800ed14a5720622c3f06fd6f54b6b54ba70dd272 (diff)
Select better color space for compositing
Instead of always compositing in ARGB, code can now select the best color space for compositing. This should be the destination color space unless the operator is not per-component or the ARGB-to-destination is nonlinear.
-rw-r--r--pixman/pixman-general.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 13ecc185..3ea11d17 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -41,6 +41,27 @@
#define SCANLINE_BUFFER_LENGTH 8192
+static pixman_color_space_t
+_pixman_color_space_select_for_composite (pixman_op_t op,
+ pixman_color_space_t dest)
+{
+ /* XXX: This function can optimize a lot more cases. */
+ if (op == PIXMAN_OP_CLEAR ||
+ op == PIXMAN_OP_SRC)
+ return dest;
+
+ return PIXMAN_COLOR_SPACE_ARGB;
+}
+
+static pixman_color_space_t
+_pixman_image_get_color_space (pixman_image_t *image)
+{
+ if (image->common.type == BITS)
+ return image->bits.color_space;
+
+ return PIXMAN_COLOR_SPACE_ARGB;
+}
+
static void
general_composite_rect (pixman_implementation_t *imp,
pixman_op_t op,
@@ -76,6 +97,7 @@ general_composite_rect (pixman_implementation_t *imp,
pixman_combine_32_func_t compose;
store_scanline_t store;
source_image_class_t src_class, mask_class;
+ pixman_color_space_t color_space;
pixman_bool_t component_alpha;
uint32_t *bits;
int32_t stride;
@@ -93,6 +115,8 @@ general_composite_rect (pixman_implementation_t *imp,
mask_buffer = src_buffer + width * Bpp;
dest_buffer = mask_buffer + width * Bpp;
+ color_space = _pixman_color_space_select_for_composite (op, dest->bits.color_space);
+
src_class = _pixman_image_classify (src,
src_x, src_y,
width, height);
@@ -110,11 +134,10 @@ general_composite_rect (pixman_implementation_t *imp,
fetch_src = NULL;
else
fetch_src = wide ? _pixman_image_get_scanline_64 : _pixman_image_get_scanline_32;
- if (fetch_src &&
- src->common.type == BITS)
+ if (fetch_src)
{
- _pixman_color_space_get_converter (src->bits.color_space,
- PIXMAN_COLOR_SPACE_ARGB,
+ _pixman_color_space_get_converter (_pixman_image_get_color_space (src),
+ color_space,
PIXMAN_FORMAT_A (src->bits.format),
wide,
&convert_src,
@@ -133,8 +156,8 @@ general_composite_rect (pixman_implementation_t *imp,
if (fetch_mask &&
mask->common.type == BITS)
{
- _pixman_color_space_get_converter (mask->bits.color_space,
- PIXMAN_COLOR_SPACE_ARGB,
+ _pixman_color_space_get_converter (_pixman_image_get_color_space (mask),
+ color_space,
PIXMAN_FORMAT_A (mask->bits.format),
wide,
&convert_mask,
@@ -153,8 +176,8 @@ general_composite_rect (pixman_implementation_t *imp,
if (fetch_dest &&
dest->common.type == BITS)
{
- _pixman_color_space_get_converter (dest->bits.color_space,
- PIXMAN_COLOR_SPACE_ARGB,
+ _pixman_color_space_get_converter (_pixman_image_get_color_space (dest),
+ color_space,
PIXMAN_FORMAT_A (dest->bits.format),
wide,
&convert_dest,
@@ -171,8 +194,8 @@ general_composite_rect (pixman_implementation_t *imp,
store = _pixman_image_store_scanline_64;
else
store = _pixman_image_store_scanline_32;
- _pixman_color_space_get_converter (PIXMAN_COLOR_SPACE_ARGB,
- dest->bits.color_space,
+ _pixman_color_space_get_converter (color_space,
+ _pixman_image_get_color_space (dest),
PIXMAN_FORMAT_A (dest->bits.format),
wide,
&convert_dest_inv,