From 7529b47ee5f55e7b16bdfa750dd18dac11194210 Mon Sep 17 00:00:00 2001 From: Soren Sandmann Pedersen Date: Wed, 9 May 2007 11:00:06 -0400 Subject: [PATCH] Make images ref counted. Memory management. --- pixman/pixman-compose.c | 34 +++++++------- pixman/pixman-image.c | 120 ++++++++++++++++++++++++++++++++---------------- pixman/pixman-private.h | 5 +- pixman/pixman-region.c | 2 +- pixman/pixman.h | 103 ++++++++++++++++++++++------------------- 5 files changed, 156 insertions(+), 108 deletions(-) diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c index cd6308e..632197e 100644 --- a/pixman/pixman-compose.c +++ b/pixman/pixman-compose.c @@ -3836,7 +3836,7 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin if (pict->common.filter == PIXMAN_FILTER_NEAREST || pict->common.filter == PIXMAN_FILTER_FAST) { if (pict->common.repeat == PIXMAN_REPEAT_NORMAL) { - if (pixman_region_n_rects (pict->common.clip_region) == 1) { + if (pixman_region_n_rects (&pict->common.clip_region) == 1) { for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3872,7 +3872,7 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin y = MOD(v.vector[1]>>16, pict->height); x = MOD(v.vector[0]>>16, pict->width); } - if (pixman_region_contains_point (pict->common.clip_region, x, y, &box)) + if (pixman_region_contains_point (&pict->common.clip_region, x, y, &box)) WRITE(buffer + i, fetch(bits + y*stride, x, indexed)); else WRITE(buffer + i, 0); @@ -3885,8 +3885,8 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin } } } else { - if (pixman_region_n_rects(pict->common.clip_region) == 1) { - box = pict->common.clip_region->extents; + if (pixman_region_n_rects(&pict->common.clip_region) == 1) { + box = pict->common.clip_region.extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -3922,7 +3922,7 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin y = v.vector[1]>>16; x = v.vector[0]>>16; } - if (pixman_region_contains_point (pict->common.clip_region, x, y, &box)) + if (pixman_region_contains_point (&pict->common.clip_region, x, y, &box)) WRITE(buffer + i, fetch(bits + y*stride, x, indexed)); else WRITE(buffer + i, 0); @@ -3945,7 +3945,7 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin unit.vector[1] -= unit.vector[2] / 2; if (pict->common.repeat == PIXMAN_REPEAT_NORMAL) { - if (pixman_region_n_rects(pict->common.clip_region) == 1) { + if (pixman_region_n_rects(&pict->common.clip_region) == 1) { for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -4048,14 +4048,14 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin b = bits + y1*stride; - tl = pixman_region_contains_point(pict->common.clip_region, x1, y1, &box) + tl = pixman_region_contains_point(&pict->common.clip_region, x1, y1, &box) ? fetch(b, x1, indexed) : 0; - tr = pixman_region_contains_point(pict->common.clip_region, x2, y1, &box) + tr = pixman_region_contains_point(&pict->common.clip_region, x2, y1, &box) ? fetch(b, x2, indexed) : 0; b = bits + (y2)*stride; - bl = pixman_region_contains_point(pict->common.clip_region, x1, y2, &box) + bl = pixman_region_contains_point(&pict->common.clip_region, x1, y2, &box) ? fetch(b, x1, indexed) : 0; - br = pixman_region_contains_point(pict->common.clip_region, x2, y2, &box) + br = pixman_region_contains_point(&pict->common.clip_region, x2, y2, &box) ? fetch(b, x2, indexed) : 0; ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; @@ -4080,8 +4080,8 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin } } } else { - if (pixman_region_n_rects(pict->common.clip_region) == 1) { - box = pict->common.clip_region->extents; + if (pixman_region_n_rects(&pict->common.clip_region) == 1) { + box = pict->common.clip_region.extents; for (i = 0; i < width; ++i) { if (!mask || mask[i] & maskBits) { @@ -4183,14 +4183,14 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin b = bits + (y1)*stride; x_off = x1; - tl = pixman_region_contains_point(pict->common.clip_region, x1, y1, &box) + tl = pixman_region_contains_point(&pict->common.clip_region, x1, y1, &box) ? fetch(b, x_off, indexed) : 0; - tr = pixman_region_contains_point(pict->common.clip_region, x2, y1, &box) + tr = pixman_region_contains_point(&pict->common.clip_region, x2, y1, &box) ? fetch(b, x_off + 1, indexed) : 0; b += stride; - bl = pixman_region_contains_point(pict->common.clip_region, x1, y2, &box) + bl = pixman_region_contains_point(&pict->common.clip_region, x1, y2, &box) ? fetch(b, x_off, indexed) : 0; - br = pixman_region_contains_point(pict->common.clip_region, x2, y2, &box) + br = pixman_region_contains_point(&pict->common.clip_region, x2, y2, &box) ? fetch(b, x_off + 1, indexed) : 0; ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx; @@ -4252,7 +4252,7 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin for (x = x1; x < x2; x++) { if (*p) { int tx = (pict->common.repeat == PIXMAN_REPEAT_NORMAL) ? MOD (x, pict->width) : x; - if (pixman_region_contains_point (pict->common.clip_region, tx, ty, &box)) { + if (pixman_region_contains_point (&pict->common.clip_region, tx, ty, &box)) { uint32_t *b = bits + (ty)*stride; uint32_t c = fetch(b, tx, indexed); diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index 3b441b5..dd26b39 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -34,22 +34,8 @@ enum }; static void -init_common (image_common_t *common) -{ - common->transform = NULL; - common->clip_region = NULL; - common->repeat = PIXMAN_REPEAT_NONE; - common->filter = PIXMAN_FILTER_NEAREST; - common->filter_params = NULL; - common->n_filter_params = 0; - common->alpha_map = NULL; - common->component_alpha = FALSE; -} - -static void init_source_image (source_image_t *image) { - init_common (&image->common); image->class = SOURCE_IMAGE_CLASS_UNKNOWN; } @@ -90,14 +76,57 @@ color_to_uint32 (const pixman_color_t *color) static pixman_image_t * allocate_image (void) { - return malloc (sizeof (pixman_image_t *)); + pixman_image_t *image = malloc (sizeof (pixman_image_t *)); + + if (image) + { + image_common_t *common = &image->common; + + pixman_region_init (&common->clip_region); + common->transform = NULL; + common->repeat = PIXMAN_REPEAT_NONE; + common->filter = PIXMAN_FILTER_NEAREST; + common->filter_params = NULL; + common->n_filter_params = 0; + common->alpha_map = NULL; + common->component_alpha = FALSE; + common->ref_count = 1; + } + + return image; +} + +/* Ref Counting */ +pixman_image_t * +pixman_image_ref (pixman_image_t *image) +{ + image->common.ref_count++; + + return image; } -/* Destructor */ void -pixman_image_destroy (pixman_image_t *image) +pixman_image_unref (pixman_image_t *image) { - + image->common.ref_count--; + + if (image->common.ref_count == 0) + { + image_common_t *common = (image_common_t *)image; + + pixman_region_fini (&common->clip_region); + + if (common->transform) + free (common->transform); + + if (common->filter_params) + free (common->filter_params); + + if (common->alpha_map) + pixman_image_unref ((pixman_image_t *)common->alpha_map); + + free (image); + } } /* Constructors */ @@ -238,8 +267,6 @@ pixman_image_create_bits (pixman_format_code_t format, if (!image) return NULL; - init_common (&image->common); - image->type = BITS; image->bits.format = format; image->bits.width = width; @@ -255,14 +282,18 @@ void pixman_image_set_clip_region (pixman_image_t *image, pixman_region16_t *region) { - image->common.clip_region = region; + image_common_t *common = (image_common_t *)image; + + pixman_region_copy (&common->clip_region, region); } void pixman_image_set_transform (pixman_image_t *image, - pixman_transform_t *transform) + const pixman_transform_t *transform) { - image->common.transform = transform; + image->common.transform = malloc (sizeof (pixman_transform_t)); + if (image->common.transform) + *(image->common.transform) = *transform; } void @@ -274,18 +305,22 @@ pixman_image_set_repeat (pixman_image_t *image, void pixman_image_set_filter (pixman_image_t *image, - pixman_filter_t filter) + pixman_filter_t filter, + const pixman_fixed_t *params, + int n_params) { - image->common.filter = filter; -} + image_common_t *common = (image_common_t *)image; + + if (params != common->filter_params) + { + if (common->filter_params) + free (common->filter_params); -void -pixman_image_set_filter_params (pixman_image_t *image, - pixman_fixed_t *params, - int n_params) -{ - image->common.filter_params = params; - image->common.n_filter_params = n_params; + common->filter_params = malloc (n_params * sizeof (pixman_fixed_t)); + memcpy (common->filter_params, params, n_params * sizeof (pixman_fixed_t)); + } + + common->n_filter_params = n_params; } void @@ -294,15 +329,20 @@ pixman_image_set_alpha_map (pixman_image_t *image, int16_t x, int16_t y) { - if (alpha_map && alpha_map->type != BITS) + image_common_t *common = (image_common_t *)image; + + return_if_fail (!alpha_map || alpha_map->type == BITS); + + if (common->alpha_map != (bits_image_t *)alpha_map) { - image->common.alpha_map = NULL; - return; + if (common->alpha_map) + pixman_image_unref ((pixman_image_t *)common->alpha_map); + + common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map); } - - image->common.alpha_map = (bits_image_t *)alpha_map; - image->common.alpha_origin.x = x; - image->common.alpha_origin.y = y; + + common->alpha_origin.x = x; + common->alpha_origin.y = y; } void diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index 87b9965..4299b58 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -12,7 +12,7 @@ #if DEBUG -#define return_if_fail(expr) { \ +#define return_if_fail(expr) \ do \ { \ if (!(expr)) \ @@ -114,7 +114,8 @@ struct point struct image_common { image_type_t type; - pixman_region16_t *clip_region; + int32_t ref_count; + pixman_region16_t clip_region; pixman_transform_t *transform; pixman_repeat_t repeat; pixman_filter_t filter; diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c index ec4da71..38d6510 100644 --- a/pixman/pixman-region.c +++ b/pixman/pixman-region.c @@ -411,7 +411,7 @@ pixman_rect_alloc (pixman_region16_t * region, int n) } pixman_bool_t -pixman_region_copy(pixman_region16_t *dst, pixman_region16_t *src) +pixman_region_copy (pixman_region16_t *dst, pixman_region16_t *src) { good(dst); good(src); diff --git a/pixman/pixman.h b/pixman/pixman.h index 1a2dc5c..8cab2df 100644 --- a/pixman/pixman.h +++ b/pixman/pixman.h @@ -380,63 +380,70 @@ typedef enum { } pixman_format_code_t; /* Constructors */ -pixman_image_t *pixman_image_create_solid_fill (pixman_color_t *color, - int *error); -pixman_image_t *pixman_image_create_linear_gradient (pixman_point_fixed_t *p1, - pixman_point_fixed_t *p2, +pixman_image_t *pixman_image_create_solid_fill (pixman_color_t *color, + int *error); +pixman_image_t *pixman_image_create_linear_gradient (pixman_point_fixed_t *p1, + pixman_point_fixed_t *p2, const pixman_gradient_stop_t *stops, - int n_stops); -pixman_image_t *pixman_image_create_radial_gradient (pixman_point_fixed_t *inner, - pixman_point_fixed_t *outer, - pixman_fixed_t inner_radius, - pixman_fixed_t outer_radius, + int n_stops); +pixman_image_t *pixman_image_create_radial_gradient (pixman_point_fixed_t *inner, + pixman_point_fixed_t *outer, + pixman_fixed_t inner_radius, + pixman_fixed_t outer_radius, const pixman_gradient_stop_t *stops, - int n_stops); -pixman_image_t *pixman_image_create_conical_gradient (pixman_point_fixed_t *center, - pixman_fixed_t angle, + int n_stops); +pixman_image_t *pixman_image_create_conical_gradient (pixman_point_fixed_t *center, + pixman_fixed_t angle, const pixman_gradient_stop_t *stops, - int n_stops); -pixman_image_t *pixman_image_create_bits (pixman_format_code_t format, - int width, - int height, - uint32_t *bits, - int rowstride_bytes); + int n_stops); +pixman_image_t *pixman_image_create_bits (pixman_format_code_t format, + int width, + int height, + uint32_t *bits, + int rowstride_bytes); /* Destructor */ -void pixman_image_destroy (pixman_image_t *image); +pixman_image_t *pixman_image_ref (pixman_image_t *image); +void pixman_image_unref (pixman_image_t *image); + /* Set properties */ -void pixman_image_set_clip_region (pixman_image_t *image, - pixman_region16_t *region); -void pixman_image_set_transform (pixman_image_t *image, - pixman_transform_t *transform); -void pixman_image_set_repeat (pixman_image_t *image, - pixman_repeat_t repeat); -void pixman_image_set_filter (pixman_image_t *image, - pixman_filter_t filter); -void pixman_image_set_filter_params (pixman_image_t *image, - pixman_fixed_t *params, - int n_params); -void pixman_image_set_alpha_map (pixman_image_t *image, - pixman_image_t *alpha_map, - int16_t x, - int16_t y); -void pixman_image_set_component_alpha (pixman_image_t *image, - pixman_bool_t component_alpha); +void pixman_image_set_clip_region (pixman_image_t *image, + pixman_region16_t *region); +void pixman_image_set_transform (pixman_image_t *image, + const pixman_transform_t *transform); +void pixman_image_set_repeat (pixman_image_t *image, + pixman_repeat_t repeat); +void pixman_image_set_filter (pixman_image_t *image, + pixman_filter_t filter, + const pixman_fixed_t *filter_params, + int n_filter_params); +void pixman_image_set_filter_params (pixman_image_t *image, + pixman_fixed_t *params, + int n_params); +void pixman_image_set_alpha_map (pixman_image_t *image, + pixman_image_t *alpha_map, + int16_t x, + int16_t y); +void pixman_image_set_component_alpha (pixman_image_t *image, + pixman_bool_t component_alpha); + /* Composite */ -void pixman_image_composite (pixman_op_t op, - pixman_image_t *src, - pixman_image_t *mask, - pixman_image_t *dest, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dest_x, - int dest_y, - int width, - int height); +void pixman_image_composite (pixman_op_t op, + pixman_image_t *src, + pixman_image_t *mask, + pixman_image_t *dest, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dest_x, + int dest_y, + int width, + int height); + + -- 2.7.4