diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-10-04 20:38:01 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-10-04 20:38:01 -0400 |
commit | 413b32014e7ee5bfeccd8c47d4aa49b9b1f084e2 (patch) | |
tree | bcd7a9dcd7315637e38a75a2a92680256d1e8f58 | |
parent | 7707f3487b16a49b74e700a2e4c2ba8f33afa6c3 (diff) |
full apply
-rw-r--r-- | fragment.c | 103 |
1 files changed, 92 insertions, 11 deletions
@@ -296,25 +296,70 @@ fragment_free (fragment_t *fragment) state_unref (fragment->state); } +static const pixman_color_t white = +{ + 0xffff, 0xffff, 0xffff, 0xffff +}; + static void -state_apply (state_t *state, pixman_op_t op, pixman_image_t *image) +state_apply (state_t *state, pixman_image_t *image) { int width = pixman_image_get_width (image); int height = pixman_image_get_height (image); + pixman_image_t *white_img, *temp; + pixman_format_code_t mask_format; + pixman_glyph_cache_t *glyph_cache; + pixman_glyph_t *glyphs; + int n_glyphs; + + white_img = pixman_image_create_solid_fill (&white); + if (!white_img) + return; /* FIXME status - FIXME: only create when necessary */ switch (state->common.type) { + case STATE_BLANK: + pixman_image_composite32 ( + PIXMAN_OP_CLEAR, white_img, NULL, image, + 0, 0, 0, 0, 0, 0, width, height); + break; + + case STATE_TRAPS: + /* FIXME: there may be a pixman bug here that we need + * to work around: it incorrectly clips rendering to the extent + * of the trapezoids + */ + pixman_composite_trapezoids ( + PIXMAN_OP_SRC, white_img, image, PIXMAN_a8, + 0, 0, 0, 0, state->traps.n_traps, state->traps.traps); + break; + + case STATE_GLYPHS: + glyph_cache = state->glyphs.cache; + n_glyphs = state->glyphs.n_glyphs; + glyphs = state->glyphs.glyphs; + + mask_format = pixman_glyph_get_mask_format ( + glyph_cache, n_glyphs, glyphs); + pixman_composite_glyphs ( + PIXMAN_OP_SRC, white_img, image, mask_format, + 0, 0, 0, 0, 0, 0, width, height, + glyph_cache, n_glyphs, glyphs); + break; + + case STATE_WHITE: + pixman_image_composite32 ( + PIXMAN_OP_SRC, white_img, NULL, image, + 0, 0, 0, 0, 0, 0, width, height); + break; + case STATE_IMAGE: if (state->image.image == image) - { - assert (op == PIXMAN_OP_SRC); - break; - } + return; pixman_image_composite ( - op, state->image.image, NULL, image, - 0, 0, 0, 0, 0, 0, - width, height); + PIXMAN_OP_SRC, state->image.image, NULL, image, + 0, 0, 0, 0, 0, 0, width, height); break; case STATE_COMMAND: @@ -334,9 +379,45 @@ state_apply (state_t *state, pixman_op_t op, pixman_image_t *image) * * In the case where source is just a "foo IN bar", * we can simpify to "apply (foo, bar, dest)". + * + * The correct thing is actually to: + * - copy dest to a temp image + * - composite SRC onto temp using command.op + * - composite temp onto image using argument op. + * + * which simplifies a bit if one or both of the ops is SRC + * if both: simply SRC source onto image + * if op, but not comamnd.op: + * SRC dst onto image, then source command.op onto image. + * if command.op, but not op: + * apply source to image using command.op + * These optimizations should probably take place at + * composite time, not apply time. + */ + /* What if there is no arg-op (or equivalently defined to be SRC? + * Then the answer is + * - apply dest to image + * - create temp image + * - apply source to temp + * - composite temp with command op to image */ - state_apply (state->command.dest, PIXMAN_OP_SRC, image); - state_apply (state->command.source, state->command.op, image); + /* FIXME: track alpha-only */ + temp = pixman_image_create_bits ( + PIXMAN_a8r8g8b8, width, height, NULL, -1); + + if (!temp) + break; /* FIXME: status */ + + state_apply (state->command.dest, image); + + /* FIXME: check if source can be expressed as (s IN m) */ + state_apply (state->command.source, temp); + + pixman_image_composite32 ( + state->command.op, temp, NULL, image, + 0, 0, 0, 0, 0, 0, width, height); + + pixman_image_unref (temp); break; } } @@ -349,7 +430,7 @@ fragment_apply (fragment_t *fragment, pixman_image_t *image) pixman_image_set_clip_region32 (image, &fragment->region); - state_apply (fragment->state, PIXMAN_OP_SRC, image); + state_apply (fragment->state, image); return TRUE; } |