From 2b34d43044c167f6589497da677b965ad2b09ec2 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Wed, 26 Jan 2005 16:42:31 +0000 Subject: [PATCH] well it was an interesting experiment. but the blender code is already so optimal... we dont gain much at all. :( SVN revision: 13102 --- .../src/lib/engines/common/evas_image_main.c | 96 +++++++++++++++++++ .../engines/common/evas_scale_smooth_scaler.c | 2 + .../common/evas_scale_smooth_scaler_noscale.c | 62 +++++++++++- legacy/evas/src/lib/include/evas_common.h | 32 +++++-- 4 files changed, 177 insertions(+), 15 deletions(-) diff --git a/legacy/evas/src/lib/engines/common/evas_image_main.c b/legacy/evas/src/lib/engines/common/evas_image_main.c index d7d2822ac9..41947a05af 100644 --- a/legacy/evas/src/lib/engines/common/evas_image_main.c +++ b/legacy/evas/src/lib/engines/common/evas_image_main.c @@ -76,6 +76,100 @@ evas_common_image_shutdown(void) #endif } +/* alpha tiles! - asctually span lists - need to do it as span lists */ +void +evas_common_image_surface_alpha_tiles_calc(RGBA_Surface *is, int tsize) +{ + int x, y; + DATA32 *ptr; + +#if 1 + return; +#endif + /* hmm i only get about a 15% speedup on my "best cases". the complexity + * imho isn't worth the small gain, so i have disabled it here :( (this + * is best case scenario - average case will be much less gain) + * + * thought for now the only case is + */ + if (is->spans) return; + if (!(is->im->flags & RGBA_IMAGE_HAS_ALPHA)) return; + /* FIXME: dont handle alpha only images yet */ + if ((is->im->flags & RGBA_IMAGE_ALPHA_ONLY)) return; + if (tsize < 0) tsize = 0; + is->spans = calloc(1, sizeof(RGBA_Image_Span *) * is->h); + if (!is->spans) return; + ptr = is->data; + for (y = 0; y < is->h; y++) + { + RGBA_Image_Span *sp; + + sp = NULL; + for (x = 0; x < is->w; x++) + { + DATA8 a; + + a = A_VAL(ptr); + if (sp) + { + if (a == 0) + { + is->spans[y] = evas_object_list_append(is->spans[y], sp); + sp = NULL; + } + else + { + sp->w++; + if ((sp->v == 2) && (a != 255)) sp->v = 1; + } + } + else + { + if (a == 255) + { + sp = calloc(1, sizeof(RGBA_Image_Span)); + sp->x = x; + sp->w = 1; + sp->v = 2; + } + else if (a > 0) + { + sp = calloc(1, sizeof(RGBA_Image_Span)); + sp->x = x; + sp->w = 1; + sp->v = 1; + } + } + ptr++; + } + if (sp) + { + is->spans[y] = evas_object_list_append(is->spans[y], sp); + sp = NULL; + } + } +} + +void +evas_common_image_surface_alpha_tiles_free(RGBA_Surface *is) +{ + int i; + + if (!is->spans) return; + for (i = 0; i < is->h; i++) + { + while (is->spans[i]) + { + RGBA_Image_Span *sp; + + sp = is->spans[i]; + is->spans[i] = evas_object_list_remove(sp, sp); + free(sp); + } + } + free(is->spans); +} + RGBA_Surface * evas_common_image_surface_new(RGBA_Image *im) { @@ -125,6 +219,7 @@ evas_common_image_surface_dealloc(RGBA_Surface *is) free(is->data); is->data = NULL; } + evas_common_image_surface_alpha_tiles_free(is); } RGBA_Image * @@ -429,6 +524,7 @@ evas_common_image_dirty(RGBA_Image *im) { int i; + if (im->image) evas_common_image_surface_alpha_tiles_free(im->image); evas_common_image_unstore(im); im->flags |= RGBA_IMAGE_IS_DIRTY; } diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c index 557c875d49..3df506613d 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c @@ -209,6 +209,8 @@ SCALE_FUNC(RGBA_Image *src, RGBA_Image *dst, * -:- * */ + /* 8x8 tiles - this will incurr about a < 2% memory overhead */ + evas_common_image_surface_alpha_tiles_calc(src->image, 8); /* if 1:1 scale */ if ((dst_region_w == src_region_w) && diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c index f23c8d618e..08b489488e 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_noscale.c @@ -1,7 +1,7 @@ { DATA32 *src_data; - src_data = src->image->data; + src_data = src->image->data; ptr = src_data + ((dst_clip_y - dst_region_y + src_region_y) * src_w) + (dst_clip_x - dst_region_x) + src_region_x; if (dc->mod.use) { @@ -32,11 +32,63 @@ Gfx_Func_Blend_Src_Dst func; func = evas_common_draw_func_blend_get(src, dst, dst_clip_w); - for (y = 0; y < dst_clip_h; y++) +#if 0 + /* part of the spans experiemnt. doesnt seem to help much on top of + * what we already have + */ + if (src->image->spans) { - func(ptr, dst_ptr, dst_clip_w); - ptr += src_w; - dst_ptr += dst_w; + int x2, y2; + int xoff, woff; + RGBA_Image_Flags pflags; + Gfx_Func_Blend_Src_Dst func_solid; + + pflags = src->flags; + src->flags &= ~RGBA_IMAGE_HAS_ALPHA; + func_solid = evas_common_draw_func_blend_get(src, dst, dst_clip_w); + src->flags = pflags; + + x2 = (dst_clip_x - dst_region_x) + src_region_x; + y2 = (dst_clip_y - dst_region_y) + src_region_y; + for (y = 0; y < dst_clip_h; y++, y2++) + { + Evas_Object_List *l; + + for (l = src->image->spans[y2]; l; l = l->next) + { + RGBA_Image_Span *sp; + + sp = l; + if ((sp->x + sp->w) > x2) + { + xoff = sp->x - x2; + woff = sp->w; + if (xoff < 0) + { + woff += xoff; + xoff = 0; + } + if ((xoff + woff) > (dst_clip_w)) + woff += (dst_clip_w) - (xoff + woff); + if (sp->v == 2) + func_solid(ptr + xoff, dst_ptr + xoff, woff); + else + func(ptr + xoff, dst_ptr + xoff, woff); + } + } + ptr += src_w; + dst_ptr += dst_w; + } + } + else +#endif + { + for (y = 0; y < dst_clip_h; y++) + { + func(ptr, dst_ptr, dst_clip_w); + ptr += src_w; + dst_ptr += dst_w; + } } } } diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index e1d1bfa284..14e4108021 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -160,6 +160,7 @@ typedef char Evas_Bool; typedef struct _RGBA_Image RGBA_Image; typedef struct _RGBA_Surface RGBA_Surface; +typedef struct _RGBA_Image_Span RGBA_Image_Span; typedef struct _RGBA_Draw_Context RGBA_Draw_Context; typedef struct _RGBA_Gradient RGBA_Gradient; typedef struct _RGBA_Gradient_Color RGBA_Gradient_Color; @@ -188,12 +189,12 @@ typedef void (*Gfx_Func_Convert) (DATA32 *src, DATA8 *dst, int src_jump, int dst typedef enum _RGBA_Image_Flags { - RGBA_IMAGE_NOTHING = (0), - RGBA_IMAGE_HAS_ALPHA = (1 << 0), - RGBA_IMAGE_IS_DIRTY = (1 << 1), - RGBA_IMAGE_INDEXED = (1 << 2), - RGBA_IMAGE_ALPHA_ONLY = (1 << 3), - RGBA_IMAGE_HAVE_SPANS = (1 << 4) + RGBA_IMAGE_NOTHING = (0), + RGBA_IMAGE_HAS_ALPHA = (1 << 0), + RGBA_IMAGE_IS_DIRTY = (1 << 1), + RGBA_IMAGE_INDEXED = (1 << 2), + RGBA_IMAGE_ALPHA_ONLY = (1 << 3), + RGBA_IMAGE_ALPHA_TILES = (1 << 4) } RGBA_Image_Flags; typedef enum _Convert_Pal_Mode @@ -286,10 +287,18 @@ struct _RGBA_Draw_Context struct _RGBA_Surface { - int w, h; - DATA32 *data; - char no_free : 1; - RGBA_Image *im; + int w, h; + DATA32 *data; + char no_free : 1; + RGBA_Image *im; + RGBA_Image_Span **spans; +}; + +struct _RGBA_Image_Span +{ + Evas_Object_List _list_data; + int x, w; + int v; }; struct _RGBA_Image @@ -761,6 +770,9 @@ void evas_common_scale_rgba_in_to_out_clip_sample (RGBA_Image *src, RGBA_Im void evas_common_image_init (void); void evas_common_image_shutdown (void); +void evas_common_image_surface_alpha_tiles_calc(RGBA_Surface *is, int tsize); +void evas_common_image_surface_alpha_tiles_free(RGBA_Surface *is); + RGBA_Surface *evas_common_image_surface_new (RGBA_Image *im); void evas_common_image_surface_free (RGBA_Surface *is); void evas_common_image_surface_alloc (RGBA_Surface *is);