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 * Fix crash in evas_object_image_add() when called prior to setting an engine
for the given canvas. 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. * 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. * Don't wake up prepare thread if there is nothing to prepare.
* Limit the updated region to fit in CPU cache for Pipe rendering. * Limit the updated region to fit in CPU cache for Pipe rendering.
* Cache convertion from Evas_Map to RGBA_Map.
Fixes: Fixes:
* Add missing files in the tarball. * Add missing files in the tarball.

View File

@ -174,6 +174,13 @@ _evas_map_free(Evas_Object *obj, Evas_Map *m)
} }
m->magic = 0; m->magic = 0;
free(m); 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; if (count > 0) return EINA_TRUE;
return EINA_FALSE; 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)) if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
{ {
const Evas_Map_Point *p, *p_end; RGBA_Map_Point *pts;
RGBA_Map_Point pts[obj->cur.map->count], *pt;
p = obj->cur.map->points; evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh);
p_end = p + obj->cur.map->count; pts = obj->spans->pts;
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];
}
obj->layer->evas->engine.func->image_map_draw obj->layer->evas->engine.func->image_map_draw
(output, context, surface, pixels, obj->cur.map->count, (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 static Eina_Bool
_evas_render_had_map(Evas_Object *obj) _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)); _evas_render_has_map(obj));
if (_evas_render_has_map(obj)) if (_evas_render_has_map(obj))
{ {
const Evas_Map_Point *p, *p_end; RGBA_Map_Point *pts;
RGBA_Map_Point pts[4], *pt;
int sw, sh; int sw, sh;
Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE; 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; return clean_them;
} }
pts[0].px = obj->cur.map->persp.px << FP; evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh);
pts[0].py = obj->cur.map->persp.py << FP; pts = obj->spans->pts;
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];
}
if (obj->cur.map->surface) if (obj->cur.map->surface)
{ {
@ -1080,6 +1043,11 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
} }
else 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) if (mapped)
{ {
RDI(level); 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_Draw_Context RGBA_Draw_Context;
typedef struct _RGBA_Polygon_Point RGBA_Polygon_Point; typedef struct _RGBA_Polygon_Point RGBA_Polygon_Point;
typedef struct _RGBA_Map_Point RGBA_Map_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 RGBA_Font;
typedef struct _RGBA_Font_Int RGBA_Font_Int; typedef struct _RGBA_Font_Int RGBA_Font_Int;
typedef struct _RGBA_Font_Source RGBA_Font_Source; typedef struct _RGBA_Font_Source RGBA_Font_Source;
@ -852,6 +853,20 @@ struct _RGBA_Map_Point
FPc px, py, z0, foc; 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 #if 0 // filtering disabled
struct _Filtered_Image struct _Filtered_Image
{ {

View File

@ -1,6 +1,14 @@
#ifndef EVAS_INLINE_H #ifndef EVAS_INLINE_H
#define 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 static inline void
_evas_object_event_new(void) _evas_object_event_new(void)
{ {

View File

@ -530,6 +530,8 @@ struct _Evas_Object
Evas_Render_Op render_op : 4; Evas_Render_Op render_op : 4;
Eina_Bool valid_bounding_box : 1; Eina_Bool valid_bounding_box : 1;
Eina_Bool cached_surface : 1;
Eina_Bool parent_cached_surface : 1;
} cur, prev; } cur, prev;
char *name; char *name;
@ -571,6 +573,8 @@ struct _Evas_Object
Evas_Size_Hints *size_hints; Evas_Size_Hints *size_hints;
RGBA_Map *spans;
int last_mouse_down_counter; int last_mouse_down_counter;
int last_mouse_up_counter; int last_mouse_up_counter;
int mouse_grabbed; 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_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); 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); Eina_List *evas_module_engine_list(void);