diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-10-02 15:08:53 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-10-02 15:08:53 -0400 |
commit | 77b0f810ae08a4dcddad31893ed993f7f03c2e87 (patch) | |
tree | cd5be6f3859f2c368f41fbd5ae743557b4f3ee9f | |
parent | 179bf69ffaf55854be017e742ac8aff12e11ee97 (diff) |
Notes about memory management
-rw-r--r-- | fragments.c | 110 |
1 files changed, 76 insertions, 34 deletions
diff --git a/fragments.c b/fragments.c index 670e97f..dd0f867 100644 --- a/fragments.c +++ b/fragments.c @@ -1,6 +1,26 @@ #include <stdlib.h> #include <pixman.h> +/* + + Memory management: + + For traps we don't want to copy them, so the image should take ownership. + Maybe the cairo->pixman conversion should just take place inside the image? + Maybe it doesn't matter that much. + Maybe polygon images will make the question irrelevant. + + For pimages, have the image take a ref would be more convenient. + + For initializing with a region, it would be convenient, but not essential, + if we can avoid copying the region parameter. + + Structures internal to the images and fragments are of course managed and + owned by the structures in question. + +*/ + + typedef struct fragment_t fragment_t; typedef struct image_t image_t; typedef struct command_buffer_t command_buffer_t; @@ -23,7 +43,7 @@ struct fragment_t pixman_bool_t broken; pixman_region32_t region; fragment_t * next; - + /* State - should this be a separate structure? */ state_t state; pixman_bool_t alpha_only; @@ -61,12 +81,12 @@ static fragment_t * fragment_new (int width, int height) { fragment_t *result = malloc (sizeof *result); - + if (!result) return (fragment_t *)&broken_fragment; - + pixman_region32_init_rect (&result->region, 0, 0, width, height); - + return result; } @@ -81,7 +101,7 @@ fragment_set_blank (fragment_t *fragment) { if (fragment->broken) return; - + fragment->state = BLANK; } @@ -90,13 +110,13 @@ fragment_set_pixman (fragment_t *fragment, pixman_image_t *image) { if (fragment->broken) return; - + fragment->state = PIXMAN; fragment->u.image = image; } -/* Split @fragment into two parts: one that intersects with other, - * and one that doesn't. +/* Split @fragment into two parts: one that intersects @source + * and one that doesn't. Both may be NULL. @dest is freed or reused. */ static void fragment_intersect (fragment_t *dest, fragment_t *source, @@ -104,13 +124,13 @@ fragment_intersect (fragment_t *dest, fragment_t *source, fragment_t **remains) { *intersection = NULL; - + if (dest->broken) { *remains = NULL; return; } - + *remains = dest; if (source->broken) @@ -118,9 +138,9 @@ fragment_intersect (fragment_t *dest, fragment_t *source, *intersection = NULL; return; } - + *intersection = fragment_new (0, 0); - + if ((*intersection)->broken) { *intersection = NULL; @@ -135,7 +155,7 @@ fragment_intersect (fragment_t *dest, fragment_t *source, *intersection = NULL; return; } - + if (!pixman_region32_subtract (&(dest->region), &(dest->region), &(*intersection)->region)) { @@ -145,13 +165,13 @@ fragment_intersect (fragment_t *dest, fragment_t *source, *intersection = NULL; return; } - + if (!pixman_region32_not_empty (&(*intersection)->region)) { fragment_free (*intersection); *intersection = NULL; } - + if (!pixman_region32_not_empty (&dest->region)) { fragment_free (dest); @@ -163,13 +183,32 @@ static void fragment_composite (fragment_t *result, pixman_op_t op, fragment_t *dest, fragment_t *src) { + if ((op == PIXMAN_OP_ADD && dest->state == BLANK) || + (op == PIXMAN_OP_IN && is_opaque (dest))) + { + op = PIXMAN_OP_SRC; + } + switch (op) { + case PIXMAN_OP_SRC: + copy_state (result, src); + break; + case PIXMAN_OP_IN: if (dest->state == BLANK || src->state == BLANK) result->state == BLANK; - else if (is_opaque (dest)) - copy_state (result, src); + break; + + case PIXMAN_OP_OUT_REVERSE: + if (is_opaque (src)) + result->state == BLANK; + else if (src->state == BLANK) + copy_state (result, dest->state); + break; + + default: + /* FIXME: add command to composite the images */ break; } } @@ -178,14 +217,14 @@ static image_t * allocate_image (int width, int height) { image_t *image = malloc (sizeof *image); - + if (!image) return (image_t *)&broken; image->width = width; image->height = height; image->fragments = fragment_new (width, height); - + return image; } @@ -193,11 +232,11 @@ static image_t * image_new_blank (int width, int height) { image_t *image; - + image = allocate_image (width, height); if (image->broken) return image; - + fragment_set_blank (image->fragments); return image; } @@ -205,6 +244,9 @@ image_new_blank (int width, int height) void image_free (image_t *image) { + if (image->broken) + return; + /* FIXME */ } @@ -212,11 +254,11 @@ static image_t * image_new_pixman (int width, int height, pixman_image_t *pimage) { image_t *image; - + image = allocate_image (width, height); if (image->broken) return image; - + fragment_set_pixman (image->fragments, pimage); return image; } @@ -225,37 +267,37 @@ static void image_composite (image_t *dest, pixman_op_t op, image_t *src, image_t *mask) { fragment_t *sfrag; - + if (dest->broken || src->broken || (mask && mask->broken)) return; if (mask) { image_t *tmp = allocate_image (dest->width, dest->height); - + image_composite (tmp, PIXMAN_OP_SRC, mask, NULL); image_composite (tmp, PIXMAN_OP_IN, src, NULL); image_composite (dest, op, tmp, NULL); - + image_free (tmp); return; } - + sfrag = src->fragments; while (sfrag) { fragment_t *new_fragments = NULL; fragment_t *dfrag; - + dfrag = dest->fragments; while (dfrag != NULL) { fragment_t *intersection, *remains; fragment_t *next = dfrag->next; - + fragment_intersect (dfrag, sfrag, &intersection, &remains); - + if (intersection) { fragment_composite (intersect, op, dfrag, sfrag); @@ -263,18 +305,18 @@ image_composite (image_t *dest, pixman_op_t op, image_t *src, image_t *mask) intersection->next = new_fragments; new_fragments = intersection; } - + if (remains) { remains->next = new_fragments; new_fragments = remains; } - + dfrag = next; } - + sfrag = sfrag->next; } - + dest->fragments = new_fragments; } |