evas: cache conversion from Evas_Map to RGBA_Map.

SVN revision: 72119
This commit is contained in:
Cedric BAIL 2012-06-14 09:58:16 +00:00
parent e3c44bee13
commit d636db3c66
8 changed files with 132 additions and 71 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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
}

View File

@ -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,

View File

@ -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);

View File

@ -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
{

View File

@ -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)
{

View File

@ -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);