diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog index 3949decdab..cb1005e876 100644 --- a/legacy/evas/ChangeLog +++ b/legacy/evas/ChangeLog @@ -805,3 +805,7 @@ * Fix crash in evas_object_image_add() when called prior to setting an engine for the given canvas. + +2012-06-14 Cedric Bail + + * Cache convertion from Evas_Map to RGBA_Map. diff --git a/legacy/evas/NEWS b/legacy/evas/NEWS index 33eb364a03..3c3cdc95ba 100644 --- a/legacy/evas/NEWS +++ b/legacy/evas/NEWS @@ -8,6 +8,7 @@ Improvements: * Reduce cost of propagating event by limiting the object we explore by using a bouncing box. * Don't wake up prepare thread if there is nothing to prepare. * Limit the updated region to fit in CPU cache for Pipe rendering. + * Cache convertion from Evas_Map to RGBA_Map. Fixes: * Add missing files in the tarball. diff --git a/legacy/evas/src/lib/canvas/evas_map.c b/legacy/evas/src/lib/canvas/evas_map.c index 0f2ccf78d6..2b0591b6eb 100644 --- a/legacy/evas/src/lib/canvas/evas_map.c +++ b/legacy/evas/src/lib/canvas/evas_map.c @@ -174,6 +174,13 @@ _evas_map_free(Evas_Object *obj, Evas_Map *m) } m->magic = 0; free(m); + + if (obj->spans) + { + // FIXME: destroy engine side spans + free(obj->spans); + obj->spans = NULL; + } } /****************************************************************************/ @@ -1021,3 +1028,84 @@ evas_map_util_clockwise_get(Evas_Map *m) if (count > 0) return EINA_TRUE; return EINA_FALSE; } + +void +evas_object_map_update(Evas_Object *obj, + int x, int y, + int imagew, int imageh, + int uvw, int uvh) +{ + const Evas_Map_Point *p, *p_end; + RGBA_Map_Point *pts, *pt; + + if (obj->spans) + { + if (obj->spans->x != x || obj->spans->y != y || + obj->spans->image.w != imagew || obj->spans->image.h != imageh || + obj->spans->uv.w != uvw || obj->spans->uv.h != uvh) + obj->changed_map = EINA_TRUE; + } + + if (!obj->changed_map) return ; + + if (obj->cur.map && obj->spans && obj->cur.map->count != obj->spans->count) + { + if (obj->spans) + { + // Destroy engine side spans + free(obj->spans); + } + obj->spans = NULL; + } + + if (!((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))) + return ; + + if (!obj->spans) + obj->spans = calloc(1, sizeof (RGBA_Map) + + sizeof (RGBA_Map_Point) * (obj->cur.map->count - 1)); + + if (!obj->spans) return ; + + obj->spans->count = obj->cur.map->count; + obj->spans->x = x; + obj->spans->y = y; + obj->spans->uv.w = uvw; + obj->spans->uv.h = uvh; + obj->spans->image.w = imagew; + obj->spans->image.h = imageh; + + pts = obj->spans->pts; + + p = obj->cur.map->points; + p_end = p + obj->cur.map->count; + pt = pts; + + pts[0].px = obj->cur.map->persp.px << FP; + pts[0].py = obj->cur.map->persp.py << FP; + pts[0].foc = obj->cur.map->persp.foc << FP; + pts[0].z0 = obj->cur.map->persp.z0 << FP; + // draw geom +x +y + for (; p < p_end; p++, pt++) + { + pt->x = (lround(p->x) + x) * FP1; + pt->y = (lround(p->y) + y) * FP1; + pt->z = (lround(p->z) ) * FP1; + pt->fx = p->px; + pt->fy = p->py; + pt->fz = p->z; + pt->u = ((lround(p->u) * imagew) / uvw) * FP1; + pt->v = ((lround(p->v) * imageh) / uvh) * FP1; + if (pt->u < 0) pt->u = 0; + else if (pt->u > (imagew * FP1)) pt->u = (imagew * FP1); + if (pt->v < 0) pt->v = 0; + else if (pt->v > (imageh * FP1)) pt->v = (imageh * FP1); + pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b); + } + if (obj->cur.map->count & 0x1) + { + pts[obj->cur.map->count] = pts[obj->cur.map->count -1]; + } + + // Request engine to update it's point +} diff --git a/legacy/evas/src/lib/canvas/evas_object_image.c b/legacy/evas/src/lib/canvas/evas_object_image.c index aa7efd8388..1d974d8e9e 100644 --- a/legacy/evas/src/lib/canvas/evas_object_image.c +++ b/legacy/evas/src/lib/canvas/evas_object_image.c @@ -2933,38 +2933,10 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su } if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap)) { - const Evas_Map_Point *p, *p_end; - RGBA_Map_Point pts[obj->cur.map->count], *pt; + RGBA_Map_Point *pts; - p = obj->cur.map->points; - p_end = p + obj->cur.map->count; - pt = pts; - - pts[0].px = obj->cur.map->persp.px << FP; - pts[0].py = obj->cur.map->persp.py << FP; - pts[0].foc = obj->cur.map->persp.foc << FP; - pts[0].z0 = obj->cur.map->persp.z0 << FP; - // draw geom +x +y - for (; p < p_end; p++, pt++) - { - pt->x = (lround(p->x) + x) * FP1; - pt->y = (lround(p->y) + y) * FP1; - pt->z = (lround(p->z) ) * FP1; - pt->fx = p->px; - pt->fy = p->py; - pt->fz = p->z; - pt->u = ((lround(p->u) * imagew) / uvw) * FP1; - pt->v = ((lround(p->v) * imageh) / uvh) * FP1; - if (pt->u < 0) pt->u = 0; - else if (pt->u > (imagew * FP1)) pt->u = (imagew * FP1); - if (pt->v < 0) pt->v = 0; - else if (pt->v > (imageh * FP1)) pt->v = (imageh * FP1); - pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b); - } - if (obj->cur.map->count & 0x1) - { - pts[obj->cur.map->count] = pts[obj->cur.map->count -1]; - } + evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh); + pts = obj->spans->pts; obj->layer->evas->engine.func->image_map_draw (output, context, surface, pixels, obj->cur.map->count, diff --git a/legacy/evas/src/lib/canvas/evas_render.c b/legacy/evas/src/lib/canvas/evas_render.c index 70fbffa859..79570039e8 100644 --- a/legacy/evas/src/lib/canvas/evas_render.c +++ b/legacy/evas/src/lib/canvas/evas_render.c @@ -91,14 +91,6 @@ evas_obscured_clear(Evas *e) } } -static Eina_Bool -_evas_render_has_map(Evas_Object *obj) -{ - return ((!((obj->func->can_map) && (obj->func->can_map(obj)))) && - ((obj->cur.map) && (obj->cur.usemap))); - // return ((obj->cur.map) && (obj->cur.usemap)); -} - static Eina_Bool _evas_render_had_map(Evas_Object *obj) { @@ -830,8 +822,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, _evas_render_has_map(obj)); if (_evas_render_has_map(obj)) { - const Evas_Map_Point *p, *p_end; - RGBA_Map_Point pts[4], *pt; + RGBA_Map_Point *pts; int sw, sh; Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE; @@ -848,36 +839,8 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, return clean_them; } - pts[0].px = obj->cur.map->persp.px << FP; - pts[0].py = obj->cur.map->persp.py << FP; - pts[0].foc = obj->cur.map->persp.foc << FP; - pts[0].z0 = obj->cur.map->persp.z0 << FP; - - p = obj->cur.map->points; - p_end = p + obj->cur.map->count; - pt = pts; - for (; p < p_end; p++, pt++) - { - pt->x = (lround(p->x) + off_x) * FP1; - pt->y = (lround(p->y) + off_y) * FP1; - pt->z = (lround(p->z) ) * FP1; - pt->fx = p->px; - pt->fy = p->py; - pt->fz = p->z; - pt->u = lround(p->u) * FP1; - pt->v = lround(p->v) * FP1; - if (pt->u < 0) pt->u = 0; - else if (pt->u > (sw * FP1)) pt->u = (sw * FP1); - if (pt->v < 0) pt->v = 0; - else if (pt->v > (sh * FP1)) pt->v = (sh * FP1); - pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b); - } - /* Copy last for software engine */ - if (obj->cur.map->count & 0x1) - { - pts[obj->cur.map->count] = pts[obj->cur.map->count - 1]; - } - + evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh); + pts = obj->spans->pts; if (obj->cur.map->surface) { @@ -1080,6 +1043,11 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, } else { + if (0 && obj->cur.cached_surface) + fprintf(stderr, "We should cache '%s' [%i, %i, %i, %i]\n", + evas_object_type_get(obj), + obj->cur.bounding_box.x, obj->cur.bounding_box.x, + obj->cur.bounding_box.w, obj->cur.bounding_box.h); if (mapped) { RDI(level); diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index b60dde0d06..3ace2b6432 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -395,6 +395,7 @@ typedef struct _RGBA_Image_Span RGBA_Image_Span; typedef struct _RGBA_Draw_Context RGBA_Draw_Context; typedef struct _RGBA_Polygon_Point RGBA_Polygon_Point; typedef struct _RGBA_Map_Point RGBA_Map_Point; +typedef struct _RGBA_Map RGBA_Map; typedef struct _RGBA_Font RGBA_Font; typedef struct _RGBA_Font_Int RGBA_Font_Int; typedef struct _RGBA_Font_Source RGBA_Font_Source; @@ -852,6 +853,20 @@ struct _RGBA_Map_Point FPc px, py, z0, foc; }; +struct _RGBA_Map +{ + void *engine_data; + + struct { + int w, h; + } image, uv; + + int x, y; + int count; + + RGBA_Map_Point pts[1]; +}; + #if 0 // filtering disabled struct _Filtered_Image { diff --git a/legacy/evas/src/lib/include/evas_inline.x b/legacy/evas/src/lib/include/evas_inline.x index 43a41c489c..535bb7af90 100644 --- a/legacy/evas/src/lib/include/evas_inline.x +++ b/legacy/evas/src/lib/include/evas_inline.x @@ -1,6 +1,14 @@ #ifndef EVAS_INLINE_H #define EVAS_INLINE_H +static inline Eina_Bool +_evas_render_has_map(Evas_Object *obj) +{ + return ((!((obj->func->can_map) && (obj->func->can_map(obj)))) && + ((obj->cur.map) && (obj->cur.usemap))); + // return ((obj->cur.map) && (obj->cur.usemap)); +} + static inline void _evas_object_event_new(void) { diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index c45ea86738..162bf87815 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -530,6 +530,8 @@ struct _Evas_Object Evas_Render_Op render_op : 4; Eina_Bool valid_bounding_box : 1; + Eina_Bool cached_surface : 1; + Eina_Bool parent_cached_surface : 1; } cur, prev; char *name; @@ -571,6 +573,8 @@ struct _Evas_Object Evas_Size_Hints *size_hints; + RGBA_Map *spans; + int last_mouse_down_counter; int last_mouse_up_counter; int mouse_grabbed; @@ -1051,6 +1055,7 @@ void evas_render_object_recalc(Evas_Object *obj); Eina_Bool evas_map_inside_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y); Eina_Bool evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord *mx, Evas_Coord *my, int grab); +void evas_object_map_update(Evas_Object *obj, int x, int y, int imagew, int imageh, int uvw, int uvh); Eina_List *evas_module_engine_list(void);