* 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.
* 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.
}
m->magic = 0;
free(m);
+
+ if (obj->spans)
+ {
+ // FIXME: destroy engine side spans
+ free(obj->spans);
+ obj->spans = NULL;
+ }
}
/****************************************************************************/
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
+}
}
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,
}
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)
{
return ((obj->prev.map) && (obj->prev.usemap));
_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;
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)
{
}
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);
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;
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
{
#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)
{
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;
Evas_Size_Hints *size_hints;
+ RGBA_Map *spans;
+
int last_mouse_down_counter;
int last_mouse_up_counter;
int mouse_grabbed;
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);