From 2c44b7dd555ac70bbadfbf71736fa7b0b75b4036 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sat, 7 Nov 2009 05:01:43 +0000 Subject: [PATCH] smart children of mapped objs etc. work work! SVN revision: 43506 --- legacy/evas/src/lib/canvas/evas_map.c | 1 + .../src/lib/canvas/evas_object_gradient.c | 3 +- .../lib/canvas/evas_object_gradient2_linear.c | 1 + .../lib/canvas/evas_object_gradient2_radial.c | 1 + .../evas/src/lib/canvas/evas_object_image.c | 19 +- legacy/evas/src/lib/canvas/evas_object_main.c | 10 +- .../src/lib/canvas/evas_object_rectangle.c | 1 + legacy/evas/src/lib/canvas/evas_render.c | 181 ++++++++++++------ 8 files changed, 148 insertions(+), 69 deletions(-) diff --git a/legacy/evas/src/lib/canvas/evas_map.c b/legacy/evas/src/lib/canvas/evas_map.c index 9c63d5cc52..0b33e6daf1 100644 --- a/legacy/evas/src/lib/canvas/evas_map.c +++ b/legacy/evas/src/lib/canvas/evas_map.c @@ -30,6 +30,7 @@ _evas_map_calc_geom_change(Evas_Object *obj) } evas_object_inform_call_move(obj); evas_object_inform_call_resize(obj); + obj->changed = 1; } static void diff --git a/legacy/evas/src/lib/canvas/evas_object_gradient.c b/legacy/evas/src/lib/canvas/evas_object_gradient.c index bfe54c3368..506708f50d 100644 --- a/legacy/evas/src/lib/canvas/evas_object_gradient.c +++ b/legacy/evas/src/lib/canvas/evas_object_gradient.c @@ -1150,8 +1150,9 @@ evas_object_gradient_is_opaque(Evas_Object *obj) /* currently fully opaque over the entire region it occupies */ o = (Evas_Object_Gradient *)(obj->object_data); if (!o->engine_data) return 0; + if ((obj->cur.map) && (obj->cur.usemap)) return 0; return o->cur.gradient_opaque; - } +} static int evas_object_gradient_was_opaque(Evas_Object *obj) diff --git a/legacy/evas/src/lib/canvas/evas_object_gradient2_linear.c b/legacy/evas/src/lib/canvas/evas_object_gradient2_linear.c index 49c3b20e3d..5150cb1d18 100644 --- a/legacy/evas/src/lib/canvas/evas_object_gradient2_linear.c +++ b/legacy/evas/src/lib/canvas/evas_object_gradient2_linear.c @@ -451,6 +451,7 @@ evas_object_gradient2_linear_is_opaque(Evas_Object *obj) /* this returns 1 if the internal object data implies that the object is */ /* currently fully opaque over the entire region it occupies */ + if ((obj->cur.map) && (obj->cur.usemap)) return 0; o = (Evas_Object_Gradient2_Linear *)(obj->object_data); if (!o->engine_data) return 0; og = (Evas_Object_Gradient2 *)(o); diff --git a/legacy/evas/src/lib/canvas/evas_object_gradient2_radial.c b/legacy/evas/src/lib/canvas/evas_object_gradient2_radial.c index d9373510a4..c43c46e4b0 100644 --- a/legacy/evas/src/lib/canvas/evas_object_gradient2_radial.c +++ b/legacy/evas/src/lib/canvas/evas_object_gradient2_radial.c @@ -448,6 +448,7 @@ evas_object_gradient2_radial_is_opaque(Evas_Object *obj) /* this returns 1 if the internal object data implies that the object is */ /* currently fully opaque over the entire region it occupies */ + if ((obj->cur.map) && (obj->cur.usemap)) return 0; o = (Evas_Object_Gradient2_Radial *)(obj->object_data); if (!o->engine_data) return 0; og = (Evas_Object_Gradient2 *)(o); diff --git a/legacy/evas/src/lib/canvas/evas_object_image.c b/legacy/evas/src/lib/canvas/evas_object_image.c index 0f1f58f463..107e256709 100644 --- a/legacy/evas/src/lib/canvas/evas_object_image.c +++ b/legacy/evas/src/lib/canvas/evas_object_image.c @@ -2741,11 +2741,18 @@ evas_object_image_render_pre(Evas_Object *obj) /* aren't fully opaque and we are visible */ if (evas_object_is_visible(obj) && evas_object_is_opaque(obj)) - obj->layer->evas->engine.func->output_redraws_rect_del(obj->layer->evas->engine.data.output, - obj->cur.cache.clip.x, - obj->cur.cache.clip.y, - obj->cur.cache.clip.w, - obj->cur.cache.clip.h); + { + printf(" %p img rect del %i %i %ix%i\n", obj, + obj->cur.cache.clip.x, + obj->cur.cache.clip.y, + obj->cur.cache.clip.w, + obj->cur.cache.clip.h); + obj->layer->evas->engine.func->output_redraws_rect_del(obj->layer->evas->engine.data.output, + obj->cur.cache.clip.x, + obj->cur.cache.clip.y, + obj->cur.cache.clip.w, + obj->cur.cache.clip.h); + } done: evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, obj, is_v, was_v); } @@ -2836,7 +2843,7 @@ evas_object_image_was_opaque(Evas_Object *obj) (o->prev.border.b != 0)) && (!o->prev.border.fill)) return 0; if (!o->engine_data) return 0; - if ((obj->prev.map) && (obj->prev.usemap)) return 0; + if (obj->prev.usemap) return 0; if (obj->prev.render_op == EVAS_RENDER_COPY) return 1; if (o->prev.has_alpha) return 0; if (obj->prev.render_op != EVAS_RENDER_BLEND) return 0; diff --git a/legacy/evas/src/lib/canvas/evas_object_main.c b/legacy/evas/src/lib/canvas/evas_object_main.c index 6db5664c43..a70b26824b 100644 --- a/legacy/evas/src/lib/canvas/evas_object_main.c +++ b/legacy/evas/src/lib/canvas/evas_object_main.c @@ -82,14 +82,14 @@ void evas_object_change(Evas_Object *obj) { Eina_List *l; - Evas_Object *data; + Evas_Object *obj2; obj->layer->evas->changed = 1; if (obj->changed) return; +// obj->changed = 1; evas_render_object_recalc(obj); /* set changed flag on all objects this one clips too */ - EINA_LIST_FOREACH(obj->clip.clipees, l, data) - evas_object_change(data); + EINA_LIST_FOREACH(obj->clip.clipees, l, obj2) evas_object_change(obj2); if (obj->smart.parent) evas_object_change(obj->smart.parent); } @@ -208,11 +208,9 @@ evas_object_clip_changes_clean(Evas_Object *obj) { Eina_Rectangle *r; - EINA_LIST_FREE(obj->clip.changes, r) - eina_rectangle_free(r); + EINA_LIST_FREE(obj->clip.changes, r) eina_rectangle_free(r); } - void evas_object_render_pre_effect_updates(Eina_Array *rects, Evas_Object *obj, int is_v, int was_v) { diff --git a/legacy/evas/src/lib/canvas/evas_object_rectangle.c b/legacy/evas/src/lib/canvas/evas_object_rectangle.c index a10ae6d6d8..b7593c3e09 100644 --- a/legacy/evas/src/lib/canvas/evas_object_rectangle.c +++ b/legacy/evas/src/lib/canvas/evas_object_rectangle.c @@ -299,6 +299,7 @@ evas_object_rectangle_is_opaque(Evas_Object *obj) { /* this returns 1 if the internal object data implies that the object is */ /* currently fully opaque over the entire rectangle it occupies */ + if ((obj->cur.map) && (obj->cur.usemap)) return 0; if (obj->cur.render_op == EVAS_RENDER_COPY) return 1; if (obj->cur.render_op != EVAS_RENDER_BLEND) diff --git a/legacy/evas/src/lib/canvas/evas_render.c b/legacy/evas/src/lib/canvas/evas_render.c index cd0a043161..5ddb04134c 100644 --- a/legacy/evas/src/lib/canvas/evas_render.c +++ b/legacy/evas/src/lib/canvas/evas_render.c @@ -85,34 +85,6 @@ evas_obscured_clear(Evas *e) } } -static void -_evas_render_phase1_direct(Evas *e, Eina_Array *render_objects) -{ - unsigned int i; - - for (i = 0; i < render_objects->count; ++i) - { - Evas_Object *obj; - - obj = eina_array_data_get(render_objects, i); - if (obj->changed) obj->func->render_pre(obj); - else - { - if (obj->smart.smart) - obj->func->render_pre(obj); - else - if (obj->rect_del) - { - e->engine.func->output_redraws_rect_del(e->engine.data.output, - obj->cur.cache.clip.x, - obj->cur.cache.clip.y, - obj->cur.cache.clip.w, - obj->cur.cache.clip.h); - } - } - } -} - static int _evas_child_changed_propagate(Evas_Object *obj) { @@ -121,28 +93,73 @@ _evas_child_changed_propagate(Evas_Object *obj) EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2) { if ((evas_object_is_visible(obj2) || - evas_object_was_visible(obj2)) - ) + evas_object_was_visible(obj2))) { if (((obj2->restack) && (!obj->clip.clipees)) || (obj2->changed)) { obj->changed = 1; - return 1; +// return 1; } else if (obj2->smart.smart) { + if (obj2->restack) obj->changed = 1; + obj->changed |= _evas_child_changed_propagate(obj2); +/* if (obj2->changed) { obj->changed = 1; - return 1; + return obj->changed; } - if (_evas_child_changed_propagate(obj2)) - return 1; + else if (_evas_child_changed_propagate(obj2)) + return obj->changed; + */ } } } - return 0; + return obj->changed; +} + +static void +_evas_render_phase1_direct(Evas *e, Eina_Array *active_objects, Eina_Array *restack_objects, Eina_Array *delete_objects, Eina_Array *render_objects) +{ + unsigned int i; + + for (i = 0; i < render_objects->count; ++i) + { + Evas_Object *obj; + + obj = eina_array_data_get(render_objects, i); + if (obj->smart.smart) _evas_child_changed_propagate(obj); + if (obj->changed) + { + obj->func->render_pre(obj); + if (obj->pre_render_done) + { + if ((obj->smart.smart) && + (!((obj->func->can_map) && (obj->func->can_map(obj)))) && + ((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap))) + { + eina_array_push(restack_objects, obj); + } + } + } + else + { + if (obj->smart.smart) + { + obj->func->render_pre(obj); + } + else if (obj->rect_del) + { + e->engine.func->output_redraws_rect_del(e->engine.data.output, + obj->cur.cache.clip.x, + obj->cur.cache.clip.y, + obj->cur.cache.clip.w, + obj->cur.cache.clip.h); + } + } + } } static Eina_Bool @@ -180,21 +197,27 @@ _evas_render_phase1_object_process(Evas *e, Evas_Object *obj, Eina_Array *active obj->changed = 1; clean_them = EINA_TRUE; } - + + if (obj->smart.smart) _evas_child_changed_propagate(obj); + if (!((obj->func->can_map) && (obj->func->can_map(obj))) && ((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap))) { - if (obj->smart.smart) _evas_child_changed_propagate(obj); if (obj->changed) { if ((is_active) && (obj->restack) && (!obj->clip.clipees) && ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) - eina_array_push(restack_objects, obj); + { + eina_array_push(render_objects, obj); + eina_array_push(restack_objects, obj); + obj->render_pre = 1; + } else if ((is_active) && (!obj->clip.clipees) && ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || (evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) { + eina_array_push(render_objects, obj); eina_array_push(restack_objects, obj); obj->render_pre = 1; } @@ -283,7 +306,7 @@ _evas_render_phase1_process(Evas *e, Eina_Array *active_objects, Eina_Array *res EINA_INLIST_FOREACH(e->layers, lay) { Evas_Object *obj; - + EINA_INLIST_FOREACH(lay->objects, obj) { clean_them |= _evas_render_phase1_object_process @@ -373,19 +396,22 @@ pending_change(void *data, void *gdata __UNUSED__) obj = data; if (obj->delete_me) return EINA_FALSE; + obj->pre_render_done = 0; if (!obj->layer) obj->changed = 0; return obj->changed ? EINA_TRUE : EINA_FALSE; } static void -evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int off_x, int off_y) +evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, + int off_x, int off_y, int mapped) { + void *ctx; + if (!((obj->func->can_map) && (obj->func->can_map(obj))) && ((obj->cur.map) && (obj->cur.map->count == 4) && (obj->cur.usemap))) { const Evas_Map_Point *p, *p_end; RGBA_Map_Point pts[4], *pt; - void *ctx; int sw, sh; int changed = 0; @@ -434,13 +460,10 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj2) { - if (!obj2->smart.smart) + if (obj2->changed) { - if (obj2->changed) - { - obj2->changed = 0; - changed = 1; - } + changed = 1; + break; } } obj->changed = 0; @@ -467,7 +490,6 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int e->engine.func->context_free(e->engine.data.output, ctx); } ctx = e->engine.func->context_new(e->engine.data.output); - // FIXME: only re-render if obj changed or smart children or size changed etc. if (obj->smart.smart) { Evas_Object *obj2; @@ -481,9 +503,11 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int (!obj2->clip.clipees) && ((evas_object_is_visible(obj2) && (!obj2->cur.have_clipees)))) - evas_render_mapped(e, obj2, ctx, - obj->cur.map->surface, - off_x, off_y); + { + evas_render_mapped(e, obj2, ctx, + obj->cur.map->surface, + off_x, off_y, 1); + } } } else @@ -507,8 +531,43 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface, int // obj->cur.map->surface = NULL; } else - obj->func->render(obj, e->engine.data.output, context, surface, - off_x, off_y); + { + if (mapped) + { + ctx = e->engine.func->context_new(e->engine.data.output); + if (obj->smart.smart) + { + Evas_Object *obj2; + +// off_x = -obj->cur.geometry.x; +// off_y = -obj->cur.geometry.y; + EINA_INLIST_FOREACH + (evas_object_smart_members_get_direct(obj), obj2) + { + if (evas_object_is_active(obj2) && + (!obj2->clip.clipees) && + ((evas_object_is_visible(obj2) && + (!obj2->cur.have_clipees)))) + { + evas_render_mapped(e, obj2, ctx, + surface, + off_x, off_y, 1); + } + } + } + else + { +// off_x = -obj->cur.geometry.x; +// off_y = -obj->cur.geometry.y; + obj->func->render(obj, e->engine.data.output, ctx, + surface, off_x, off_y); + } + e->engine.func->context_free(e->engine.data.output, ctx); + } + else + obj->func->render(obj, e->engine.data.output, context, surface, + off_x, off_y); + } } static Eina_List * @@ -540,8 +599,8 @@ evas_render_updates_internal(Evas *e, /* phase 1. add extra updates for changed objects */ if (e->invalidate || e->render_objects.count <= 0) clean_them = _evas_render_phase1_process(e, &e->active_objects, &e->restack_objects, &e->delete_objects, &e->render_objects); - - _evas_render_phase1_direct(e, &e->render_objects); + + _evas_render_phase1_direct(e, &e->active_objects, &e->restack_objects, &e->delete_objects, &e->render_objects); /* phase 2. force updates for restacks */ for (i = 0; i < e->restack_objects.count; ++i) @@ -590,8 +649,10 @@ evas_render_updates_internal(Evas *e, } /* phase 5. add obscures */ EINA_LIST_FOREACH(e->obscures, ll, r) + { e->engine.func->output_redraws_rect_del(e->engine.data.output, r->x, r->y, r->w, r->h); + } /* build obscure objects list of active objects that obscure */ for (i = 0; i < e->active_objects.count; ++i) { @@ -771,7 +832,7 @@ evas_render_updates_internal(Evas *e, } #endif evas_render_mapped(e, obj, e->engine.data.context, - surface, off_x, off_y); + surface, off_x, off_y, 0); e->engine.func->context_cutout_clear(e->engine.data.output, e->engine.data.context); } @@ -838,6 +899,14 @@ evas_render_updates_internal(Evas *e, e->output.changed = 0; e->invalidate = 0; + for (i = 0; i < e->render_objects.count; ++i) + { + Evas_Object *obj; + + obj = eina_array_data_get(&e->render_objects, i); + obj->pre_render_done = 0; + } + /* If their are some object to restack or some object to delete, it's useless to keep the render object list around. */ if (clean_them) {