evas_render.c   evas_render.c 
#include "evas_common.h" #include "evas_common.h"
#include "evas_private.h" #include "evas_private.h"
#include <math.h> #include <math.h>
#ifdef EVAS_CSERVE2
#include "evas_cs2_private.h"
#endif
// debug rendering // debug rendering
/* #define REND_DGB 1 */ /* #define REND_DGB 1 */
/* #define STDOUT_DBG 1 */ /* #define STDOUT_DBG 1 */
#ifdef REND_DGB #ifdef REND_DGB
static FILE *dbf = NULL; static FILE *dbf = NULL;
static void static void
rend_dbg(const char *txt) rend_dbg(const char *txt)
skipping to change at line 61 skipping to change at line 64
evas_damage_rectangle_add(Evas *e, int x, int y, int w, int h) evas_damage_rectangle_add(Evas *e, int x, int y, int w, int h)
{ {
Eina_Rectangle *r; Eina_Rectangle *r;
MAGIC_CHECK(e, Evas, MAGIC_EVAS); MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
NEW_RECT(r, x, y, w, h); NEW_RECT(r, x, y, w, h);
if (!r) return; if (!r) return;
e->damages = eina_list_append(e->damages, r); e->damages = eina_list_append(e->damages, r);
e->changed = 1; e->changed = EINA_TRUE;
} }
EAPI void EAPI void
evas_obscured_rectangle_add(Evas *e, int x, int y, int w, int h) evas_obscured_rectangle_add(Evas *e, int x, int y, int w, int h)
{ {
Eina_Rectangle *r; Eina_Rectangle *r;
MAGIC_CHECK(e, Evas, MAGIC_EVAS); MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
skipping to change at line 92 skipping to change at line 95
MAGIC_CHECK(e, Evas, MAGIC_EVAS); MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
EINA_LIST_FREE(e->obscures, r) EINA_LIST_FREE(e->obscures, r)
{ {
eina_rectangle_free(r); eina_rectangle_free(r);
} }
} }
static Eina_Bool 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) _evas_render_had_map(Evas_Object *obj)
{ {
return ((obj->prev.map) && (obj->prev.usemap)); return ((obj->prev.map) && (obj->prev.usemap));
// return ((!obj->cur.map) && (obj->prev.usemap)); // return ((!obj->cur.map) && (obj->prev.usemap));
} }
static Eina_Bool static Eina_Bool
_evas_render_is_relevant(Evas_Object *obj) _evas_render_is_relevant(Evas_Object *obj)
{ {
return ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || return ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) ||
skipping to change at line 176 skipping to change at line 171
RD(" [--- PHASE 1 DIRECT\n"); RD(" [--- PHASE 1 DIRECT\n");
for (i = 0; i < active_objects->count; i++) for (i = 0; i < active_objects->count; i++)
{ {
Evas_Object *obj; Evas_Object *obj;
obj = eina_array_data_get(active_objects, i); obj = eina_array_data_get(active_objects, i);
if (obj->changed) if (obj->changed)
{ {
/* Flag need redraw on proxy too */ /* Flag need redraw on proxy too */
evas_object_clip_recalc(obj); evas_object_clip_recalc(obj);
if (obj->proxy.proxies) EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy)
{ proxy->proxy.redraw = EINA_TRUE;
EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy)
proxy->proxy.redraw = 1;
}
} }
} }
for (i = 0; i < render_objects->count; i++) for (i = 0; i < render_objects->count; i++)
{ {
Evas_Object *obj; Evas_Object *obj;
obj = eina_array_data_get(render_objects, i); obj = eina_array_data_get(render_objects, i);
RD(" OBJ [%p] changed %i\n", obj, obj->changed); RD(" OBJ [%p] changed %i\n", obj, obj->changed);
if (obj->changed) if (obj->changed)
{ {
/* Flag need redraw on proxy too */ /* Flag need redraw on proxy too */
evas_object_clip_recalc(obj); evas_object_clip_recalc(obj);
obj->func->render_pre(obj); obj->func->render_pre(obj);
if (obj->proxy.redraw)
_evas_render_prev_cur_clip_cache_add(e, obj);
if (obj->proxy.proxies) if (obj->proxy.proxies)
{ {
obj->proxy.redraw = 1; obj->proxy.redraw = EINA_TRUE;
EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy) EINA_LIST_FOREACH(obj->proxy.proxies, l, proxy)
{ {
proxy->func->render_pre(proxy); proxy->func->render_pre(proxy);
_evas_render_prev_cur_clip_cache_add(e, proxy); _evas_render_prev_cur_clip_cache_add(e, proxy);
} }
} }
else if (obj->proxy.redraw)
{ RD(" pre-render-done smart:%p|%p [%p, %i] | [%p, %i] has
_evas_render_prev_cur_clip_cache_add(e, obj); _map:%i had_map:%i\n",
} obj->smart.smart,
if (obj->pre_render_done) evas_object_smart_members_get_direct(obj),
{ obj->cur.map, obj->cur.usemap,
RD(" pre-render-done smart:%p|%p [%p, %i] | [%p, %i obj->prev.map, obj->prev.usemap,
] has_map:%i had_map:%i\n", _evas_render_has_map(obj),
obj->smart.smart, _evas_render_had_map(obj));
evas_object_smart_members_get_direct(obj), if ((obj->smart.smart) &&
obj->cur.map, obj->cur.usemap, (_evas_render_has_map(obj)))
obj->prev.map, obj->prev.usemap,
_evas_render_has_map(obj),
_evas_render_had_map(obj));
if ((obj->smart.smart) &&
(_evas_render_has_map(obj)))
{
RD(" has map + smart\n");
_evas_render_prev_cur_clip_cache_add(e, obj);
}
}
else if (_evas_render_had_map(obj))
{ {
RD(" no pre-render done\n"); RD(" has map + smart\n");
_evas_render_prev_cur_clip_cache_add(e, obj); _evas_render_prev_cur_clip_cache_add(e, obj);
} }
} }
else else
{ {
if (obj->smart.smart) if (obj->smart.smart)
{ {
// obj->func->render_pre(obj); // obj->func->render_pre(obj);
} }
else if ((obj->rect_del) || else if ((obj->rect_del) ||
skipping to change at line 252 skipping to change at line 235
} }
RD(" ---]\n"); RD(" ---]\n");
} }
static Eina_Bool static Eina_Bool
_evas_render_phase1_object_process(Evas *e, Evas_Object *obj, _evas_render_phase1_object_process(Evas *e, Evas_Object *obj,
Eina_Array *active_objects, Eina_Array *active_objects,
Eina_Array *restack_objects, Eina_Array *restack_objects,
Eina_Array *delete_objects, Eina_Array *delete_objects,
Eina_Array *render_objects, Eina_Array *render_objects,
int restack, int map, int restack,
int *redraw_all int *redraw_all,
Eina_Bool mapped_parent
#ifdef REND_DGB #ifdef REND_DGB
, int level , int level
#endif #endif
) )
{ {
Eina_Bool clean_them = EINA_FALSE; Eina_Bool clean_them = EINA_FALSE;
Evas_Object *obj2; Evas_Object *obj2;
int is_active; int is_active;
Eina_Bool hmap; Eina_Bool map, hmap;
//Need pre render for the children of mapped object.
//But only when they have changed.
if (mapped_parent && (!obj->changed)) return EINA_FALSE;
obj->rect_del = 0; obj->rect_del = EINA_FALSE;
obj->render_pre = 0; obj->render_pre = EINA_FALSE;
#ifndef EVAS_FRAME_QUEUING
/* because of clip objects - delete 2 cycles later */
if (obj->delete_me == 2) if (obj->delete_me == 2)
#else eina_array_push(delete_objects, obj);
if (obj->delete_me == evas_common_frameq_get_frameq_sz() + 2) else if (obj->delete_me != 0) obj->delete_me++;
#endif
eina_array_push(delete_objects, obj);
else if (obj->delete_me != 0) obj->delete_me++;
/* If the object will be removed, we should not cache anything during th is run. */ /* If the object will be removed, we should not cache anything during th is run. */
if (obj->delete_me != 0) clean_them = EINA_TRUE; if (obj->delete_me != 0) clean_them = EINA_TRUE;
/* build active object list */ /* build active object list */
evas_object_clip_recalc(obj); evas_object_clip_recalc(obj);
is_active = evas_object_is_active(obj); is_active = evas_object_is_active(obj);
obj->is_active = is_active; obj->is_active = is_active;
RDI(level); RDI(level);
RD(" [--- PROCESS [%p] '%s' active = %i, del = %i | %i %i %ix%i\n", o bj, obj->type, is_active, obj->delete_me, obj->cur.geometry.x, obj->cur.geo metry.y, obj->cur.geometry.w, obj->cur.geometry.h); RD(" [--- PROCESS [%p] '%s' active = %i, del = %i | %i %i %ix%i\n", o bj, obj->type, is_active, obj->delete_me, obj->cur.geometry.x, obj->cur.geo metry.y, obj->cur.geometry.w, obj->cur.geometry.h);
if ((is_active) || (obj->delete_me != 0))
if ((!mapped_parent) && ((is_active) || (obj->delete_me != 0)))
eina_array_push(active_objects, obj); eina_array_push(active_objects, obj);
#ifdef REND_DGB #ifdef REND_DGB
if (!is_active) if (!is_active)
{ {
RDI(level); RDI(level);
RD(" [%p] vis: %i, cache.clip.vis: %i cache.clip.a: %i [%p]\n", obj, obj->cur.visible, obj->cur.cache.clip.visible, obj->cur.cache.clip.a, obj->func->is_visible); RD(" [%p] vis: %i, cache.clip.vis: %i cache.clip.a: %i [%p]\n", obj, obj->cur.visible, obj->cur.cache.clip.visible, obj->cur.cache.clip.a, obj->func->is_visible);
} }
#endif #endif
map = _evas_render_has_map(obj); map = _evas_render_has_map(obj);
hmap = _evas_render_had_map(obj); hmap = _evas_render_had_map(obj);
if ((restack) && (!map)) if ((restack) && (!map))
{ {
if (!obj->changed) if (!obj->changed)
{ {
eina_array_push(&e->pending_objects, obj); eina_array_push(&e->pending_objects, obj);
obj->changed = 1; obj->changed = EINA_TRUE;
} }
obj->restack = 1; obj->restack = EINA_TRUE;
clean_them = EINA_TRUE; clean_them = EINA_TRUE;
} }
if (map) if (map)
{ {
RDI(level); RDI(level);
RD(" obj mapped\n"); RD(" obj mapped\n");
if (obj->changed) if (obj->changed)
{ {
if (map != hmap) if (map != hmap) *redraw_all = 1;
{
*redraw_all = 1; if ((is_active) && (!obj->clip.clipees) &&
}
evas_object_clip_recalc(obj);
if ((obj->restack) &&
(is_active) && (!obj->clip.clipees) &&
((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) || ((evas_object_is_visible(obj) && (!obj->cur.have_clipees)) ||
(evas_object_was_visible(obj) && (!obj->prev.have_clipees )))) (evas_object_was_visible(obj) && (!obj->prev.have_clipees ))))
{ {
eina_array_push(render_objects, obj); eina_array_push(render_objects, obj);
_evas_render_prev_cur_clip_cache_add(e, obj); _evas_render_prev_cur_clip_cache_add(e, obj);
obj->render_pre = 1; obj->render_pre = EINA_TRUE;
}
else if ((is_active) && (!obj->clip.clipees) && if (obj->smart.smart)
((evas_object_is_visible(obj) && (!obj->cur.have_clip {
ees)) || EINA_INLIST_FOREACH(evas_object_smart_members_get_di
(evas_object_was_visible(obj) && (!obj->prev.have_cl rect(obj), obj2)
ipees)))) {
{ _evas_render_phase1_object_process(e, obj2,
eina_array_push(render_objects, obj); active_objec
_evas_render_prev_cur_clip_cache_add(e, obj); ts,
obj->render_pre = 1; restack_obje
cts,
delete_objec
ts,
render_objec
ts,
obj->restack
,
redraw_all,
EINA_TRUE
#ifdef REND_DGB
, level + 1
#endif
);
}
}
} }
} }
return clean_them; return clean_them;
} }
else if (_evas_render_had_map(obj)) else if (hmap)
{ {
RDI(level); RDI(level);
RD(" had map - restack objs\n"); RD(" had map - restack objs\n");
// eina_array_push(restack_objects, obj); // eina_array_push(restack_objects, obj);
_evas_render_prev_cur_clip_cache_add(e, obj); _evas_render_prev_cur_clip_cache_add(e, obj);
if (obj->changed) if (obj->changed)
{ {
if (hmap) if (!map)
{ {
if (!map) if ((obj->cur.map) && (obj->cur.usemap)) map = EINA_TRUE;
{
if ((obj->cur.map) && (obj->cur.usemap)) map = 1;
}
} }
if (map != hmap) if (map != hmap)
{ {
*redraw_all = 1; *redraw_all = 1;
} }
} }
} }
/* handle normal rendering. this object knows how to handle maps */ /* handle normal rendering. this object knows how to handle maps */
if (obj->changed) if (obj->changed)
{ {
if (obj->smart.smart) if (obj->smart.smart)
{ {
RDI(level); RDI(level);
RD(" changed + smart - render ok\n"); RD(" changed + smart - render ok\n");
eina_array_push(render_objects, obj); eina_array_push(render_objects, obj);
obj->render_pre = 1; obj->render_pre = EINA_TRUE;
EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj),
obj2) obj2)
{ {
_evas_render_phase1_object_process(e, obj2, _evas_render_phase1_object_process(e, obj2,
active_objects, active_objects,
restack_objects, restack_objects,
delete_objects, delete_objects,
render_objects, render_objects,
obj->restack, obj->restack,
map, redraw_all,
redraw_all mapped_parent
#ifdef REND_DGB #ifdef REND_DGB
, level + 1 , level + 1
#endif #endif
); );
} }
} }
else else
{ {
if ((is_active) && (!obj->clip.clipees) && if ((is_active) && (!obj->clip.clipees) &&
_evas_render_is_relevant(obj)) _evas_render_is_relevant(obj))
{ {
RDI(level); RDI(level);
RD(" relevant + active\n"); RD(" relevant + active\n");
if (obj->restack) if (obj->restack)
eina_array_push(restack_objects, obj); eina_array_push(restack_objects, obj);
else else
{ {
eina_array_push(render_objects, obj); eina_array_push(render_objects, obj);
obj->render_pre = 1; obj->render_pre = EINA_TRUE;
} }
} }
else else
{ {
RDI(level); RDI(level);
RD(" skip - not smart, not active or clippees or not relevant\n"); RD(" skip - not smart, not active or clippees or not relevant\n");
} }
} }
} }
else else
{ {
RD(" not changed... [%i] -> (%i %i %p %i) [%i]\n", RD(" not changed... [%i] -> (%i %i %p %i) [%i]\n",
evas_object_is_visible(obj), evas_object_is_visible(obj),
obj->cur.visible, obj->cur.cache.clip.visible, obj->smart.smart, obj->cur.visible, obj->cur.cache.clip.visible, obj->smart.smart,
obj->cur.cache.clip.a, obj->cur.cache.clip.a, evas_object_was_visible(obj));
evas_object_was_visible(obj));
if ((!obj->clip.clipees) && (obj->delete_me == 0) && if ((!obj->clip.clipees) && (obj->delete_me == 0) &&
(_evas_render_can_render(obj) || (_evas_render_can_render(obj) ||
(evas_object_was_visible(obj) && (!obj->prev.have_clipees)))) (evas_object_was_visible(obj) && (!obj->prev.have_clipees))))
{ {
if (obj->smart.smart) if (obj->smart.smart)
{ {
RDI(level); RDI(level);
RD(" smart + visible/was visible + not clip\n"); RD(" smart + visible/was visible + not clip\n");
eina_array_push(render_objects, obj); eina_array_push(render_objects, obj);
obj->render_pre = 1; obj->render_pre = EINA_TRUE;
EINA_INLIST_FOREACH EINA_INLIST_FOREACH
(evas_object_smart_members_get_direct(obj), obj2) (evas_object_smart_members_get_direct(obj), obj2)
{ {
_evas_render_phase1_object_process(e, obj2, _evas_render_phase1_object_process(e, obj2,
active_objects , active_objects ,
restack_object s, restack_object s,
delete_objects , delete_objects ,
render_objects , render_objects ,
restack, map, restack,
redraw_all redraw_all,
mapped_parent
#ifdef REND_DGB #ifdef REND_DGB
, level + 1 , level + 1
#endif #endif
); );
} }
} }
else else
{ {
if (evas_object_is_opaque(obj) && if (evas_object_is_opaque(obj) &&
evas_object_is_visible(obj)) evas_object_is_visible(obj))
{ {
RDI(level); RDI(level);
RD(" opaque + visible\n"); RD(" opaque + visible\n");
eina_array_push(render_objects, obj); eina_array_push(render_objects, obj);
obj->rect_del = 1; obj->rect_del = EINA_TRUE;
} }
else if (evas_object_is_visible(obj)) else if (evas_object_is_visible(obj))
{ {
RDI(level); RDI(level);
RD(" visible\n"); RD(" visible\n");
eina_array_push(render_objects, obj); eina_array_push(render_objects, obj);
obj->render_pre = 1; obj->render_pre = EINA_TRUE;
} }
else else
{ {
RDI(level); RDI(level);
RD(" skip\n"); RD(" skip\n");
} }
} }
} }
/* /* else if (obj->smart.smart)
else if (obj->smart.smart) {
{ RDI(level);
RDI(level); RD(" smart + mot visible/was visible\n");
RD(" smart + mot visible/was visible\n"); eina_array_push(render_objects, obj);
eina_array_push(render_objects, obj); obj->render_pre = 1;
obj->render_pre = 1; EINA_INLIST_FOREACH (evas_object_smart_members_get_direct(obj)
EINA_INLIST_FOREACH ,
(evas_object_smart_members_get_direct(obj), obj2) obj2)
{ {
_evas_render_phase1_object_process(e, obj2, _evas_render_phase1_object_process(e, obj2,
active_objects, active_objects,
restack_objects, restack_objects,
delete_objects, delete_objects,
render_objects, render_objects,
restack, map, restack,
redraw_all redraw_all
#ifdef REND_DGB #ifdef REND_DGB
, level + 1 , level + 1
#endif #endif
); );
} }
} }
*/ */
} }
if (!is_active) obj->restack = 0; if (!is_active) obj->restack = EINA_FALSE;
RDI(level); RDI(level);
RD(" ---]\n"); RD(" ---]\n");
return clean_them; return clean_them;
} }
static Eina_Bool static Eina_Bool
_evas_render_phase1_process(Evas *e, _evas_render_phase1_process(Evas *e,
Eina_Array *active_objects, Eina_Array *active_objects,
Eina_Array *restack_objects, Eina_Array *restack_objects,
Eina_Array *delete_objects, Eina_Array *delete_objects,
Eina_Array *render_objects, Eina_Array *render_objects,
int *redraw_all) int *redraw_all)
{ {
skipping to change at line 517 skipping to change at line 507
RD(" [--- PHASE 1\n"); RD(" [--- PHASE 1\n");
EINA_INLIST_FOREACH(e->layers, lay) EINA_INLIST_FOREACH(e->layers, lay)
{ {
Evas_Object *obj; Evas_Object *obj;
EINA_INLIST_FOREACH(lay->objects, obj) EINA_INLIST_FOREACH(lay->objects, obj)
{ {
clean_them |= _evas_render_phase1_object_process clean_them |= _evas_render_phase1_object_process
(e, obj, active_objects, restack_objects, delete_objects, (e, obj, active_objects, restack_objects, delete_objects,
render_objects, 0, 0, redraw_all render_objects, 0, redraw_all, EINA_FALSE
#ifdef REND_DGB #ifdef REND_DGB
, 1 , 1
#endif #endif
); );
} }
} }
RD(" ---]\n"); RD(" ---]\n");
return clean_them; return clean_them;
} }
static void static void
_evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *e) _evas_render_check_pending_objects(Eina_Array *pending_objects, Evas *e)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < pending_objects->count; ++i) for (i = 0; i < pending_objects->count; ++i)
{ {
Evas_Object *obj, *parent; Evas_Object *obj;
int is_active, ok = 0; int is_active;
Eina_Bool ok = EINA_FALSE;
obj = eina_array_data_get(pending_objects, i); obj = eina_array_data_get(pending_objects, i);
if (!obj->layer) goto clean_stuff; if (!obj->layer) goto clean_stuff;
parent = evas_object_smart_parent_get(obj); //If the children are in active objects, They should be cleaned up.
if (parent && _evas_render_has_map(parent)) if (obj->changed_map && _evas_render_has_map(obj))
goto clean_stuff; goto clean_stuff;
evas_object_clip_recalc(obj); evas_object_clip_recalc(obj);
is_active = evas_object_is_active(obj); is_active = evas_object_is_active(obj);
if ((!is_active) && (!obj->is_active) && (!obj->render_pre) && if ((!is_active) && (!obj->is_active) && (!obj->render_pre) &&
(!obj->rect_del)) (!obj->rect_del))
{ {
ok = 1; ok = EINA_TRUE;
goto clean_stuff; goto clean_stuff;
} }
if (obj->is_active == is_active) if (obj->is_active == is_active)
{ {
if (obj->changed) if (obj->changed)
{ {
if (obj->smart.smart) if (obj->smart.smart)
{ {
if (obj->render_pre || obj->rect_del) ok = 1; if (obj->render_pre || obj->rect_del) ok = EINA_TRUE ;
} }
else else
if ((is_active) && (obj->restack) && (!obj->clip.clipee s) && if ((is_active) && (obj->restack) && (!obj->clip.clipee s) &&
(_evas_render_can_render(obj) || (_evas_render_can_render(obj) ||
(evas_object_was_visible(obj) && (!obj->prev.have_ clipees)))) (evas_object_was_visible(obj) && (!obj->prev.have_ clipees))))
{ {
if (!(obj->render_pre || obj->rect_del)) ok = 1; if (!(obj->render_pre || obj->rect_del))
ok = EINA_TRUE;
} }
else else
if (is_active && (!obj->clip.clipees) && if (is_active && (!obj->clip.clipees) &&
(_evas_render_can_render(obj) || (_evas_render_can_render(obj) ||
(evas_object_was_visible(obj) && (!obj->prev.hav e_clipees)))) (evas_object_was_visible(obj) && (!obj->prev.hav e_clipees))))
{ {
if (obj->render_pre || obj->rect_del) ok = 1; if (obj->render_pre || obj->rect_del) ok = EINA_ TRUE;
} }
} }
else else
{ {
if ((!obj->clip.clipees) && (obj->delete_me == 0) && if ((!obj->clip.clipees) && (obj->delete_me == 0) &&
(!obj->cur.have_clipees || (evas_object_was_visible(o bj) && (!obj->prev.have_clipees))) (!obj->cur.have_clipees || (evas_object_was_visible(o bj) && (!obj->prev.have_clipees)))
&& evas_object_is_opaque(obj) && evas_object_is_visib le(obj)) && evas_object_is_opaque(obj) && evas_object_is_visib le(obj))
{ {
if (obj->rect_del || obj->smart.smart) ok = 1; if (obj->rect_del || obj->smart.smart) ok = EINA_TRU E;
} }
} }
} }
clean_stuff: clean_stuff:
if (!ok) if (!ok)
{ {
eina_array_clean(&e->active_objects); eina_array_clean(&e->active_objects);
eina_array_clean(&e->render_objects); eina_array_clean(&e->render_objects);
eina_array_clean(&e->restack_objects); eina_array_clean(&e->restack_objects);
eina_array_clean(&e->delete_objects); eina_array_clean(&e->delete_objects);
e->invalidate = 1; e->invalidate = EINA_TRUE;
return ; return ;
} }
} }
} }
Eina_Bool Eina_Bool
pending_change(void *data, void *gdata __UNUSED__) pending_change(void *data, void *gdata __UNUSED__)
{ {
Evas_Object *obj; Evas_Object *obj;
skipping to change at line 678 skipping to change at line 669
break; break;
EINA_RECTANGLE_SET(&self, EINA_RECTANGLE_SET(&self,
current->cur.cache.clip.x, current->cur.cache.clip.x,
current->cur.cache.clip.y, current->cur.cache.clip.y,
current->cur.cache.clip.w, current->cur.cache.clip.w,
current->cur.cache.clip.h); current->cur.cache.clip.h);
/* This doesn't cover the area of the video object, so don't bother with that object */ /* This doesn't cover the area of the video object, so don't bother with that object */
if (!eina_rectangles_intersect(&zone, &self)) if (!eina_rectangles_intersect(&zone, &self))
continue ; continue;
xc1 = current->cur.cache.clip.x; xc1 = current->cur.cache.clip.x;
yc1 = current->cur.cache.clip.y; yc1 = current->cur.cache.clip.y;
xc2 = current->cur.cache.clip.x + current->cur.cache.clip.w; xc2 = current->cur.cache.clip.x + current->cur.cache.clip.w;
yc2 = current->cur.cache.clip.y + current->cur.cache.clip.h; yc2 = current->cur.cache.clip.y + current->cur.cache.clip.h;
if (evas_object_is_visible(current) && if (evas_object_is_visible(current) &&
(!current->clip.clipees) && (!current->clip.clipees) &&
(current->cur.visible) && (current->cur.visible) &&
(!current->delete_me) && (!current->delete_me) &&
skipping to change at line 826 skipping to change at line 817
#ifdef REND_DGB #ifdef REND_DGB
, int level , int level
#endif #endif
) )
{ {
void *ctx; void *ctx;
Evas_Object *obj2; Evas_Object *obj2;
Eina_Bool clean_them = EINA_FALSE; Eina_Bool clean_them = EINA_FALSE;
evas_object_clip_recalc(obj); evas_object_clip_recalc(obj);
RDI(level); RDI(level);
RD(" { evas_render_mapped(%p, %p, %p, %p, %i, %i, %i, %i)\n ", e, obj, context, surface, off_x, off_y, mapped, level); RD(" { evas_render_mapped(%p, %p, %p, %p, %i, %i, %i, %i)\n ", e, obj, context, surface, off_x, off_y, mapped, level);
if (mapped) if (mapped)
{ {
if ((!evas_object_is_visible(obj)) || (obj->clip.clipees) || if ((!evas_object_is_visible(obj)) || (obj->clip.clipees) ||
(obj->cur.have_clipees)) (obj->cur.have_clipees))
{ {
RDI(level); RDI(level);
RD(" }\n"); RD(" }\n");
return clean_them; return clean_them;
skipping to change at line 848 skipping to change at line 840
else if (!(((evas_object_is_active(obj) && (!obj->clip.clipees) && else if (!(((evas_object_is_active(obj) && (!obj->clip.clipees) &&
(_evas_render_can_render(obj)))) (_evas_render_can_render(obj))))
)) ))
{ {
RDI(level); RDI(level);
RD(" }\n"); RD(" }\n");
return clean_them; return clean_them;
} }
// set render_pre - for child objs that may not have gotten it. // set render_pre - for child objs that may not have gotten it.
obj->pre_render_done = 1; obj->pre_render_done = EINA_TRUE;
RD(" Hasmap: %p (%d) %p %d -> %d\n",obj->func->can_map, RD(" Hasmap: %p (%d) %p %d -> %d\n",obj->func->can_map,
obj->func->can_map ? obj->func->can_map(obj): -1, obj->func->can_map ? obj->func->can_map(obj): -1,
obj->cur.map, obj->cur.usemap, obj->cur.map, obj->cur.usemap,
_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[4], *pt;
int sw, sh; int sw, sh;
int changed = 0, rendered = 0; Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE;
clean_them = EINA_TRUE; clean_them = EINA_TRUE;
sw = obj->cur.geometry.w; sw = obj->cur.geometry.w;
sh = obj->cur.geometry.h; sh = obj->cur.geometry.h;
RDI(level); RDI(level);
RD(" mapped obj: %ix%i\n", sw, sh); RD(" mapped obj: %ix%i\n", sw, sh);
if ((sw <= 0) || (sh <= 0)) if ((sw <= 0) || (sh <= 0))
{ {
RDI(level); RDI(level);
RD(" }\n"); RD(" }\n");
return clean_them; return clean_them;
} }
evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh);
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];
}
if (obj->cur.map->surface) if (obj->cur.map->surface)
{ {
if ((obj->cur.map->surface_w != sw) || if ((obj->cur.map->surface_w != sw) ||
(obj->cur.map->surface_h != sh)) (obj->cur.map->surface_h != sh))
{ {
RDI(level); RDI(level);
RD(" new surf: %ix%i\n", sw, sh); RD(" new surf: %ix%i\n", sw, sh);
obj->layer->evas->engine.func->image_map_surface_free obj->layer->evas->engine.func->image_map_surface_free
(e->engine.data.output, obj->cur.map->surface); (e->engine.data.output, obj->cur.map->surface);
skipping to change at line 927 skipping to change at line 888
obj->cur.map->surface_w = sw; obj->cur.map->surface_w = sw;
obj->cur.map->surface_h = sh; obj->cur.map->surface_h = sh;
obj->cur.map->surface = obj->cur.map->surface =
obj->layer->evas->engine.func->image_map_surface_new obj->layer->evas->engine.func->image_map_surface_new
(e->engine.data.output, obj->cur.map->surface_w, (e->engine.data.output, obj->cur.map->surface_w,
obj->cur.map->surface_h, obj->cur.map->surface_h,
obj->cur.map->alpha); obj->cur.map->alpha);
RDI(level); RDI(level);
RD(" fisrt surf: %ix%i\n", sw, sh); RD(" fisrt surf: %ix%i\n", sw, sh);
changed = 1; changed = EINA_TRUE;
} }
if (obj->smart.smart) if (obj->smart.smart)
{ {
Evas_Object *o2; Evas_Object *o2;
EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), o2) EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), o2)
{ {
if (!evas_object_is_visible(o2) && if (!evas_object_is_visible(o2) &&
!evas_object_was_visible(o2)) !evas_object_was_visible(o2))
{ {
skipping to change at line 959 skipping to change at line 920
evas_object_change_reset(obj); evas_object_change_reset(obj);
} }
else if (obj->changed) else if (obj->changed)
{ {
if (((obj->changed_pchange) && (obj->changed_map)) || if (((obj->changed_pchange) && (obj->changed_map)) ||
(obj->changed_color)) (obj->changed_color))
changed = EINA_TRUE; changed = EINA_TRUE;
evas_object_change_reset(obj); evas_object_change_reset(obj);
} }
/* mark the old map as invalid, so later we don't reuse it as a
* cache. */
if (changed && obj->prev.map)
obj->prev.valid_map = EINA_FALSE;
// clear surface before re-render // clear surface before re-render
if ((changed) && (obj->cur.map->surface)) if ((changed) && (obj->cur.map->surface))
{ {
int off_x2, off_y2; int off_x2, off_y2;
RDI(level); RDI(level);
RD(" children redraw\n"); RD(" children redraw\n");
// FIXME: calculate "changes" within map surface and only clea r // FIXME: calculate "changes" within map surface and only clea r
// and re-render those // and re-render those
if (obj->cur.map->alpha) if (obj->cur.map->alpha)
skipping to change at line 1019 skipping to change at line 985
obj->cur.geometry.y + off_y2, obj->cur.geometry.y + off_y2,
obj->cur.geometry.w, obj->cur.geometry.w,
obj->cur.geometry.h); obj->cur.geometry.h);
e->engine.func->context_clip_set(e->engine.data.output, e->engine.func->context_clip_set(e->engine.data.output,
ctx, x, y, w, h); ctx, x, y, w, h);
obj->func->render(obj, e->engine.data.output, ctx, obj->func->render(obj, e->engine.data.output, ctx,
obj->cur.map->surface, off_x2, off_y2); obj->cur.map->surface, off_x2, off_y2);
} }
e->engine.func->context_free(e->engine.data.output, ctx); e->engine.func->context_free(e->engine.data.output, ctx);
rendered = 1; rendered = EINA_TRUE;
} }
RDI(level); RDI(level);
RD(" draw map\n"); RD(" draw map\n");
if (rendered) if (rendered)
{ {
obj->cur.map->surface = e->engine.func->image_dirty_region obj->cur.map->surface = e->engine.func->image_dirty_region
(e->engine.data.output, obj->cur.map->surface, (e->engine.data.output, obj->cur.map->surface,
0, 0, obj->cur.map->surface_w, obj->cur.map->surface_h); 0, 0, obj->cur.map->surface_w, obj->cur.map->surface_h);
obj->cur.valid_map = EINA_TRUE;
} }
e->engine.func->context_clip_unset(e->engine.data.output, e->engine.func->context_clip_unset(e->engine.data.output,
e->engine.data.context); context);
if (obj->cur.map->surface) if (obj->cur.map->surface)
{ {
if (obj->smart.smart) if (obj->cur.clipper)
{ {
if (obj->cur.clipper) int x, y, w, h;
evas_object_clip_recalc(obj);
x = obj->cur.cache.clip.x;
y = obj->cur.cache.clip.y;
w = obj->cur.cache.clip.w;
h = obj->cur.cache.clip.h;
if (obj->smart.smart)
{ {
int x, y, w, h;
Evas_Object *tobj; Evas_Object *tobj;
obj->cur.cache.clip.dirty = 1; obj->cur.cache.clip.dirty = EINA_TRUE;
tobj = obj->cur.map_parent; tobj = obj->cur.map_parent;
obj->cur.map_parent = obj->cur.clipper->cur.map_pare nt; obj->cur.map_parent = obj->cur.clipper->cur.map_pare nt;
evas_object_clip_recalc(obj);
obj->cur.map_parent = tobj; obj->cur.map_parent = tobj;
x = obj->cur.cache.clip.x;
y = obj->cur.cache.clip.y;
w = obj->cur.cache.clip.w;
h = obj->cur.cache.clip.h;
RECTS_CLIP_TO_RECT(x, y, w, h,
obj->cur.clipper->cur.cache.clip.
x,
obj->cur.clipper->cur.cache.clip.
y,
obj->cur.clipper->cur.cache.clip.
w,
obj->cur.clipper->cur.cache.clip.
h);
e->engine.func->context_clip_set(e->engine.data.outp
ut,
e->engine.data.cont
ext,
x + off_x, y + off_
y, w, h);
} }
}
else
{
if (obj->cur.clipper)
{
int x, y, w, h;
evas_object_clip_recalc(obj); RECTS_CLIP_TO_RECT(x, y, w, h,
x = obj->cur.cache.clip.x; obj->cur.clipper->cur.cache.clip.x,
y = obj->cur.cache.clip.y; obj->cur.clipper->cur.cache.clip.y,
w = obj->cur.cache.clip.w; obj->cur.clipper->cur.cache.clip.w,
h = obj->cur.cache.clip.h; obj->cur.clipper->cur.cache.clip.h);
RECTS_CLIP_TO_RECT(x, y, w, h,
obj->cur.clipper->cur.cache.clip. e->engine.func->context_clip_set(e->engine.data.output,
x, context,
obj->cur.clipper->cur.cache.clip. x + off_x, y + off_y, w,
y, h);
obj->cur.clipper->cur.cache.clip.
w,
obj->cur.clipper->cur.cache.clip.
h);
e->engine.func->context_clip_set(e->engine.data.outp
ut,
e->engine.data.cont
ext,
x + off_x, y + off_
y, w, h);
}
} }
} }
// if (surface == e->engine.data.output) // if (surface == e->engine.data.output)
e->engine.func->context_clip_clip(e->engine.data.output, e->engine.func->context_clip_clip(e->engine.data.output,
e->engine.data.context, context,
ecx, ecy, ecw, ech); ecx, ecy, ecw, ech);
if (obj->cur.cache.clip.visible) if (obj->cur.cache.clip.visible)
{ {
obj->layer->evas->engine.func->context_multiplier_unset obj->layer->evas->engine.func->context_multiplier_unset
(e->engine.data.output, e->engine.data.context); (e->engine.data.output, context);
obj->layer->evas->engine.func->image_map_draw obj->layer->evas->engine.func->image_map_draw
(e->engine.data.output, e->engine.data.context, surface, (e->engine.data.output, context, surface,
obj->cur.map->surface, obj->cur.map->count, pts, obj->cur.map->surface, obj->spans,
obj->cur.map->smooth, 0); obj->cur.map->smooth, 0);
} }
// FIXME: needs to cache these maps and // FIXME: needs to cache these maps and
// keep them only rendering updates // keep them only rendering updates
// obj->layer->evas->engine.func->image_map_surface_free // obj->layer->evas->engine.func->image_map_surface_free
// (e->engine.data.output, obj->cur.map->surface); // (e->engine.data.output, obj->cur.map->surface);
// obj->cur.map->surface = NULL; // obj->cur.map->surface = NULL;
} }
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);
RD(" draw child of mapped obj\n"); RD(" draw child of mapped obj\n");
ctx = e->engine.func->context_new(e->engine.data.output); ctx = e->engine.func->context_new(e->engine.data.output);
if (obj->smart.smart) if (obj->smart.smart)
{ {
EINA_INLIST_FOREACH EINA_INLIST_FOREACH
(evas_object_smart_members_get_direct(obj), obj2) (evas_object_smart_members_get_direct(obj), obj2)
{ {
skipping to change at line 1126 skipping to change at line 1081
off_x, off_y, 1, off_x, off_y, 1,
ecx, ecy, ecw, e ch ecx, ecy, ecw, e ch
#ifdef REND_DGB #ifdef REND_DGB
, level + 1 , level + 1
#endif #endif
); );
} }
} }
else else
{ {
if (!obj->cur.map) RDI(level);
{
int x, y, w, h;
RDI(level);
x = obj->cur.cache.clip.x + off_x;
y = obj->cur.cache.clip.y + off_y;
w = obj->cur.cache.clip.w;
h = obj->cur.cache.clip.h;
if (obj->cur.clipper)
{
if (_evas_render_has_map(obj))
evas_object_clip_recalc(obj);
RD(" clipper: %i %i %ix%i\n",
obj->cur.clipper->cur.cache.clip.x + off_x,
obj->cur.clipper->cur.cache.clip.y + off_y,
obj->cur.clipper->cur.cache.clip.w,
obj->cur.clipper->cur.cache.clip.h);
RECTS_CLIP_TO_RECT(x, y, w, h,
obj->cur.clipper->cur.cache.
clip.x + off_x,
obj->cur.clipper->cur.cache.
clip.y + off_y,
obj->cur.clipper->cur.cache.
clip.w,
obj->cur.clipper->cur.cache.
clip.h);
}
if (obj->cur.clipper)
{
RD(" clip: %i %i %ix%i [%i %i %ix%i]\n", RD(" clip: %i %i %ix%i [%i %i %ix%i]\n",
obj->cur.cache.clip.x + off_x, obj->cur.cache.clip.x + off_x,
obj->cur.cache.clip.y + off_y, obj->cur.cache.clip.y + off_y,
obj->cur.cache.clip.w, obj->cur.cache.clip.w,
obj->cur.cache.clip.h, obj->cur.cache.clip.h,
obj->cur.geometry.x + off_x, obj->cur.geometry.x + off_x,
obj->cur.geometry.y + off_y, obj->cur.geometry.y + off_y,
obj->cur.geometry.w, obj->cur.geometry.w,
obj->cur.geometry.h); obj->cur.geometry.h);
RD(" clipper: %i %i %ix%i\n",
obj->cur.clipper->cur.cache.clip.x + off_x,
obj->cur.clipper->cur.cache.clip.y + off_y,
obj->cur.clipper->cur.cache.clip.w,
obj->cur.clipper->cur.cache.clip.h);
int x, y, w, h;
if (_evas_render_has_map(obj))
evas_object_clip_recalc(obj);
x = obj->cur.cache.clip.x + off_x;
y = obj->cur.cache.clip.y + off_y;
w = obj->cur.cache.clip.w;
h = obj->cur.cache.clip.h;
RECTS_CLIP_TO_RECT(x, y, w, h,
obj->cur.clipper->cur.cache.clip.
x + off_x,
obj->cur.clipper->cur.cache.clip.
y + off_y,
obj->cur.clipper->cur.cache.clip.
w,
obj->cur.clipper->cur.cache.clip.
h);
e->engine.func->context_clip_set(e->engine.data.outp ut, e->engine.func->context_clip_set(e->engine.data.outp ut,
ctx, x, y, w, h); ctx, x, y, w, h);
} }
else
{
RDI(level);
RD(" noclip\n");
}
obj->func->render(obj, e->engine.data.output, ctx, obj->func->render(obj, e->engine.data.output, ctx,
surface, off_x, off_y); surface, off_x, off_y);
/*
obj->layer->evas->engine.func->contex
t_color_set(e->engine.data.output,
ctx,
0, 30, 0, 30);
obj->layer->evas->engine.func->rectan
gle_draw(e->engine.data.output,
ctx,
surface,
0, 0, 9999, 9999);
*/
} }
e->engine.func->context_free(e->engine.data.output, ctx); e->engine.func->context_free(e->engine.data.output, ctx);
} }
else else
{ {
if (obj->cur.clipper) if (obj->cur.clipper)
{ {
int x, y, w, h; int x, y, w, h;
if (_evas_render_has_map(obj)) if (_evas_render_has_map(obj))
skipping to change at line 1204 skipping to change at line 1143
x = obj->cur.cache.clip.x; x = obj->cur.cache.clip.x;
y = obj->cur.cache.clip.y; y = obj->cur.cache.clip.y;
w = obj->cur.cache.clip.w; w = obj->cur.cache.clip.w;
h = obj->cur.cache.clip.h; h = obj->cur.cache.clip.h;
RECTS_CLIP_TO_RECT(x, y, w, h, RECTS_CLIP_TO_RECT(x, y, w, h,
obj->cur.clipper->cur.cache.clip.x, obj->cur.clipper->cur.cache.clip.x,
obj->cur.clipper->cur.cache.clip.y, obj->cur.clipper->cur.cache.clip.y,
obj->cur.clipper->cur.cache.clip.w, obj->cur.clipper->cur.cache.clip.w,
obj->cur.clipper->cur.cache.clip.h); obj->cur.clipper->cur.cache.clip.h);
e->engine.func->context_clip_set(e->engine.data.output, e->engine.func->context_clip_set(e->engine.data.output,
e->engine.data.context, context,
x + off_x, y + off_y, w, h); x + off_x, y + off_y, w, h);
e->engine.func->context_clip_clip(e->engine.data.output, e->engine.func->context_clip_clip(e->engine.data.output,
e->engine.data.context, context,
ecx, ecy, ecw, ech); ecx, ecy, ecw, ech);
} }
RDI(level); RDI(level);
RD(" draw normal obj\n"); RD(" draw normal obj\n");
obj->func->render(obj, e->engine.data.output, context, surface , obj->func->render(obj, e->engine.data.output, context, surface ,
off_x, off_y); off_x, off_y);
} }
if (obj->changed_map) clean_them = EINA_TRUE;
} }
RDI(level); RDI(level);
RD(" }\n"); RD(" }\n");
return clean_them; return clean_them;
} }
static void static void
_evas_render_cutout_add(Evas *e, Evas_Object *obj, int off_x, int off_y) _evas_render_cutout_add(Evas *e, Evas_Object *obj, int off_x, int off_y)
{ {
skipping to change at line 1296 skipping to change at line 1236
Evas_Object *obj; Evas_Object *obj;
Eina_List *updates = NULL; Eina_List *updates = NULL;
Eina_List *ll; Eina_List *ll;
void *surface; void *surface;
Eina_Bool clean_them = EINA_FALSE; Eina_Bool clean_them = EINA_FALSE;
Eina_Bool alpha; Eina_Bool alpha;
Eina_Rectangle *r; Eina_Rectangle *r;
int ux, uy, uw, uh; int ux, uy, uw, uh;
int cx, cy, cw, ch; int cx, cy, cw, ch;
unsigned int i, j; unsigned int i, j;
int haveup = 0;
int redraw_all = 0; int redraw_all = 0;
Eina_Bool haveup = 0;
MAGIC_CHECK(e, Evas, MAGIC_EVAS); MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return NULL; return NULL;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
if (!e->changed) return NULL; if (!e->changed) return NULL;
#ifdef EVAS_CSERVE2
if (evas_cserve2_use_get())
evas_cserve2_dispatch();
#endif
evas_call_smarts_calculate(e); evas_call_smarts_calculate(e);
RD("[--- RENDER EVAS (size: %ix%i)\n", e->viewport.w, e->viewport.h); RD("[--- RENDER EVAS (size: %ix%i)\n", e->viewport.w, e->viewport.h);
evas_event_callback_call(e, EVAS_CALLBACK_RENDER_PRE, NULL); evas_event_callback_call(e, EVAS_CALLBACK_RENDER_PRE, NULL);
/* Check if the modified object mean recalculating every thing */ /* Check if the modified object mean recalculating every thing */
if (!e->invalidate) if (!e->invalidate)
_evas_render_check_pending_objects(&e->pending_objects, e); _evas_render_check_pending_objects(&e->pending_objects, e);
skipping to change at line 1325 skipping to change at line 1269
if (e->invalidate || e->render_objects.count <= 0) if (e->invalidate || e->render_objects.count <= 0)
clean_them = _evas_render_phase1_process(e, clean_them = _evas_render_phase1_process(e,
&e->active_objects, &e->active_objects,
&e->restack_objects, &e->restack_objects,
&e->delete_objects, &e->delete_objects,
&e->render_objects, &e->render_objects,
&redraw_all); &redraw_all);
/* phase 1.5. check if the video should be inlined or stay in their over lay */ /* phase 1.5. check if the video should be inlined or stay in their over lay */
alpha = e->engine.func->canvas_alpha_get(e->engine.data.output, alpha = e->engine.func->canvas_alpha_get(e->engine.data.output,
e->engine.data.context); e->engine.data.context);
EINA_LIST_FOREACH(e->video_objects, ll, obj) EINA_LIST_FOREACH(e->video_objects, ll, obj)
{ {
/* we need the surface to be transparent to display the underlying overlay */ /* we need the surface to be transparent to display the underlying overlay */
if (alpha && _evas_render_can_use_overlay(e, obj)) if (alpha && _evas_render_can_use_overlay(e, obj))
_evas_object_image_video_overlay_show(obj); _evas_object_image_video_overlay_show(obj);
else else
_evas_object_image_video_overlay_hide(obj); _evas_object_image_video_overlay_hide(obj);
} }
/* phase 1.8. pre render for proxy */ /* phase 1.8. pre render for proxy */
_evas_render_phase1_direct(e, &e->active_objects, &e->restack_objects, _evas_render_phase1_direct(e, &e->active_objects, &e->restack_objects,
&e->delete_objects, &e->render_objects); &e->delete_objects, &e->render_objects);
/* phase 2. force updates for restacks */ /* phase 2. force updates for restacks */
for (i = 0; i < e->restack_objects.count; ++i) for (i = 0; i < e->restack_objects.count; ++i)
{ {
obj = eina_array_data_get(&e->restack_objects, i); obj = eina_array_data_get(&e->restack_objects, i);
obj->func->render_pre(obj); obj->func->render_pre(obj);
_evas_render_prev_cur_clip_cache_add(e, obj); _evas_render_prev_cur_clip_cache_add(e, obj);
skipping to change at line 1358 skipping to change at line 1301
/* phase 3. add exposes */ /* phase 3. add exposes */
EINA_LIST_FREE(e->damages, r) EINA_LIST_FREE(e->damages, r)
{ {
e->engine.func->output_redraws_rect_add(e->engine.data.output, e->engine.func->output_redraws_rect_add(e->engine.data.output,
r->x, r->y, r->w, r->h); r->x, r->y, r->w, r->h);
eina_rectangle_free(r); eina_rectangle_free(r);
} }
/* phase 4. framespace, output & viewport changes */ /* phase 4. framespace, output & viewport changes */
if (e->framespace.changed)
{
int fx, fy, fw, fh;
fx = e->viewport.x - e->framespace.x;
fy = e->viewport.y - e->framespace.y;
fw = e->viewport.w + e->framespace.w;
fh = e->viewport.h + e->framespace.h;
e->engine.func->output_redraws_rect_add(e->engine.data.output,
fx, fy, fw, fh);
}
if (e->viewport.changed) if (e->viewport.changed)
{ {
e->engine.func->output_redraws_rect_add(e->engine.data.output, e->engine.func->output_redraws_rect_add(e->engine.data.output,
0, 0, 0, 0,
e->output.w, e->output.h); e->output.w, e->output.h);
} }
if (e->output.changed) if (e->output.changed)
{ {
e->engine.func->output_resize(e->engine.data.output, e->engine.func->output_resize(e->engine.data.output,
e->output.w, e->output.h); e->output.w, e->output.h);
e->engine.func->output_redraws_rect_add(e->engine.data.output, e->engine.func->output_redraws_rect_add(e->engine.data.output,
0, 0, 0, 0,
e->output.w, e->output.h); e->output.w, e->output.h);
} }
if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h)) if ((e->output.w != e->viewport.w) || (e->output.h != e->viewport.h))
{ {
ERR("viewport size != output size!"); ERR("viewport size != output size!");
} }
if (redraw_all)
if (e->framespace.changed)
{ {
int fx, fy, fw, fh;
fx = e->viewport.x - e->framespace.x;
fy = e->viewport.y - e->framespace.y;
fw = e->viewport.w + e->framespace.w;
fh = e->viewport.h + e->framespace.h;
if (fx < 0) fx = 0;
if (fy < 0) fy = 0;
e->engine.func->output_redraws_rect_add(e->engine.data.output, e->engine.func->output_redraws_rect_add(e->engine.data.output,
0, 0, fx, fy, fw, fh);
}
/* phase 4.5: check if object is not in framespace. if not, we need to c
lip
* it to the 'master' clip.
*
* NB: This is for the wayland engine(s). If we do not do this, then
* objects will draw outside the viewport and potentially onto the frame
* itself */
if (!strncmp(e->engine.module->definition->name, "wayland", 7))
{
Eina_Rectangle clip_rect;
/* see if the master clip has been added yet, if not, then create *
/
if (!e->framespace.clip)
{
e->framespace.clip = evas_object_rectangle_add(e);
evas_object_color_set(e->framespace.clip, 255, 255, 255, 255);
evas_object_move(e->framespace.clip,
e->framespace.x, e->framespace.y);
evas_object_resize(e->framespace.clip,
e->viewport.w - e->framespace.w,
e->viewport.h - e->framespace.h);
evas_object_show(e->framespace.clip);
}
else
{
/* master clip is already present. check for size changes in t
he
* viewport, and update master clip size if needed */
if ((e->viewport.changed) || (e->output.changed) ||
(e->framespace.changed))
{
evas_object_move(e->framespace.clip,
e->framespace.x, e->framespace.y);
evas_object_resize(e->framespace.clip,
e->viewport.w - e->framespace.w,
e->viewport.h - e->framespace.h);
}
}
EINA_RECTANGLE_SET(&clip_rect,
e->framespace.clip->cur.geometry.x,
e->framespace.clip->cur.geometry.y,
e->framespace.clip->cur.geometry.w,
e->framespace.clip->cur.geometry.h)
/* With the master clip all setup, we need to loop the objects on t
his
* canvas and determine if the object is in the viewport space. If
it
* is in the viewport space (and not in framespace), then we need t
o
* clip the object to the master clip so that it does not draw on t
op
* of the frame (eg: elm 3d test) */
for (i = 0; i < e->render_objects.count; ++i)
{
Eina_Rectangle obj_rect;
Evas_Object *pclip;
obj = eina_array_data_get(&e->render_objects, i);
if (evas_object_is_frame_object_get(obj))
continue;
if (obj->delete_me) continue;
EINA_RECTANGLE_SET(&obj_rect,
obj->cur.geometry.x, obj->cur.geometry.y,
obj->cur.geometry.w, obj->cur.geometry.h);
/* if the object does not intersect our clip rect, ignore it *
/
if (!eina_rectangles_intersect(&clip_rect, &obj_rect))
continue;
if (!(pclip = evas_object_clip_get(obj)))
{
/* skip clipping if the object is itself the
* framespace clip */
if (obj == e->framespace.clip) continue;
/* clip this object so it does not draw on the window fra
me */
evas_object_clip_set(obj, e->framespace.clip);
}
}
}
if (redraw_all)
{
e->engine.func->output_redraws_rect_add(e->engine.data.output, 0, 0
,
e->output.w, e->output.h); e->output.w, e->output.h);
} }
/* phase 5. add obscures */ /* phase 5. add obscures */
EINA_LIST_FOREACH(e->obscures, ll, r) EINA_LIST_FOREACH(e->obscures, ll, r)
{ {
e->engine.func->output_redraws_rect_del(e->engine.data.output, e->engine.func->output_redraws_rect_del(e->engine.data.output,
r->x, r->y, r->w, r->h); r->x, r->y, r->w, r->h);
} }
/* build obscure objects list of active objects that obscure */ /* build obscure objects list of active objects that obscure */
skipping to change at line 1443 skipping to change at line 1467
RD(" [--- UPDATE %i %i %ix%i\n", ux, uy, uw, uh); RD(" [--- UPDATE %i %i %ix%i\n", ux, uy, uw, uh);
if (make_updates) if (make_updates)
{ {
Eina_Rectangle *rect; Eina_Rectangle *rect;
NEW_RECT(rect, ux, uy, uw, uh); NEW_RECT(rect, ux, uy, uw, uh);
if (rect) if (rect)
updates = eina_list_append(updates, rect); updates = eina_list_append(updates, rect);
} }
haveup = 1; haveup = EINA_TRUE;
off_x = cx - ux; off_x = cx - ux;
off_y = cy - uy; off_y = cy - uy;
/* build obscuring objects list (in order from bottom to top) */ /* build obscuring objects list (in order from bottom to top) */
if (alpha) if (alpha)
{ {
e->engine.func->context_clip_set(e->engine.data.output, e->engine.func->context_clip_set(e->engine.data.output,
e->engine.data.context, e->engine.data.context,
ux + off_x, uy + off_y, uw, uh); ux + off_x, uy + off_y, uw, uh);
} }
for (i = 0; i < e->obscuring_objects.count; ++i) for (i = 0; i < e->obscuring_objects.count; ++i)
skipping to change at line 1485 skipping to change at line 1509
EVAS_RENDER_COPY); EVAS_RENDER_COPY);
e->engine.func->rectangle_draw(e->engine.data.output, e->engine.func->rectangle_draw(e->engine.data.output,
e->engine.data.context, e->engine.data.context,
surface, surface,
cx, cy, cw, ch); cx, cy, cw, ch);
e->engine.func->context_cutout_clear(e->engine.data.outpu t, e->engine.func->context_cutout_clear(e->engine.data.outpu t,
e->engine.data.conte xt); e->engine.data.conte xt);
e->engine.func->context_clip_unset(e->engine.data.output, e->engine.func->context_clip_unset(e->engine.data.output,
e->engine.data.context ); e->engine.data.context );
} }
/* render all object that intersect with rect */ /* render all object that intersect with rect */
for (i = 0; i < e->active_objects.count; ++i) for (i = 0; i < e->active_objects.count; ++i)
{ {
obj = eina_array_data_get(&e->active_objects, i); obj = eina_array_data_get(&e->active_objects, i);
/* if it's in our outpout rect and it doesn't clip anythi ng */ /* if it's in our outpout rect and it doesn't clip anythi ng */
RD(" OBJ: [%p] '%s' %i %i %ix%i\n", obj, obj->type, ob j->cur.geometry.x, obj->cur.geometry.y, obj->cur.geometry.w, obj->cur.geome try.h); RD(" OBJ: [%p] '%s' %i %i %ix%i\n", obj, obj->type, ob j->cur.geometry.x, obj->cur.geometry.y, obj->cur.geometry.w, obj->cur.geome try.h);
if ((evas_object_is_in_output_rect(obj, ux, uy, uw, uh) | | if ((evas_object_is_in_output_rect(obj, ux, uy, uw, uh) | |
(obj->smart.smart)) && (obj->smart.smart)) &&
(!obj->clip.clipees) && (!obj->clip.clipees) &&
skipping to change at line 1576 skipping to change at line 1601
e->engine.func->output_flush(e->engine.data.output); e->engine.func->output_flush(e->engine.data.output);
evas_event_callback_call(e, EVAS_CALLBACK_RENDER_FLUSH_POST, N ULL); evas_event_callback_call(e, EVAS_CALLBACK_RENDER_FLUSH_POST, N ULL);
} }
} }
/* clear redraws */ /* clear redraws */
e->engine.func->output_redraws_clear(e->engine.data.output); e->engine.func->output_redraws_clear(e->engine.data.output);
/* and do a post render pass */ /* and do a post render pass */
for (i = 0; i < e->active_objects.count; ++i) for (i = 0; i < e->active_objects.count; ++i)
{ {
obj = eina_array_data_get(&e->active_objects, i); obj = eina_array_data_get(&e->active_objects, i);
obj->pre_render_done = 0; obj->pre_render_done = EINA_FALSE;
RD(" OBJ [%p] post... %i %i\n", obj, obj->changed, do_draw); RD(" OBJ [%p] post... %i %i\n", obj, obj->changed, do_draw);
if ((obj->changed) && (do_draw)) if ((obj->changed) && (do_draw))
{ {
RD(" OBJ [%p] post... func1\n", obj); RD(" OBJ [%p] post... func1\n", obj);
obj->func->render_post(obj); obj->func->render_post(obj);
obj->restack = EINA_FALSE; obj->restack = EINA_FALSE;
evas_object_change_reset(obj); evas_object_change_reset(obj);
} }
else if ((obj->cur.map != obj->prev.map) || else if (clean_them)
(obj->cur.usemap != obj->prev.usemap) || clean_them)
{ {
RD(" OBJ [%p] post... func2\n", obj); RD(" OBJ [%p] post... func2\n", obj);
obj->func->render_post(obj); obj->func->render_post(obj);
obj->restack = EINA_FALSE; obj->restack = EINA_FALSE;
evas_object_change_reset(obj); evas_object_change_reset(obj);
} }
/* moved to other pre-process phase 1 /* moved to other pre-process phase 1
if (obj->delete_me == 2) if (obj->delete_me == 2)
{ {
delete_objects = eina_list_append(delete_objects, obj); delete_objects = eina_list_append(delete_objects, obj);
skipping to change at line 1611 skipping to change at line 1635
/* free our obscuring object list */ /* free our obscuring object list */
eina_array_clean(&e->obscuring_objects); eina_array_clean(&e->obscuring_objects);
/* If some object are still marked as changed, do not remove /* If some object are still marked as changed, do not remove
them from the pending list. */ them from the pending list. */
eina_array_remove(&e->pending_objects, pending_change, NULL); eina_array_remove(&e->pending_objects, pending_change, NULL);
for (i = 0; i < e->render_objects.count; ++i) for (i = 0; i < e->render_objects.count; ++i)
{ {
obj = eina_array_data_get(&e->render_objects, i); obj = eina_array_data_get(&e->render_objects, i);
obj->pre_render_done = 0; obj->pre_render_done = EINA_FALSE;
} }
/* delete all objects flagged for deletion now */ /* delete all objects flagged for deletion now */
for (i = 0; i < e->delete_objects.count; ++i) for (i = 0; i < e->delete_objects.count; ++i)
{ {
obj = eina_array_data_get(&e->delete_objects, i); obj = eina_array_data_get(&e->delete_objects, i);
evas_object_free(obj, 1); evas_object_free(obj, 1);
} }
eina_array_clean(&e->delete_objects); eina_array_clean(&e->delete_objects);
e->changed = 0; e->changed = EINA_FALSE;
e->viewport.changed = 0; e->viewport.changed = EINA_FALSE;
e->output.changed = 0; e->output.changed = EINA_FALSE;
e->framespace.changed = 0; e->framespace.changed = EINA_FALSE;
e->invalidate = 0; e->invalidate = EINA_FALSE;
// always clean... lots of mem waste! // always clean... lots of mem waste!
/* If their are some object to restack or some object to delete, /* If their are some object to restack or some object to delete,
* it's useless to keep the render object list around. */ * it's useless to keep the render object list around. */
if (clean_them) if (clean_them)
{ {
eina_array_clean(&e->active_objects); eina_array_clean(&e->active_objects);
eina_array_clean(&e->render_objects); eina_array_clean(&e->render_objects);
eina_array_clean(&e->restack_objects); eina_array_clean(&e->restack_objects);
eina_array_clean(&e->delete_objects);
eina_array_clean(&e->obscuring_objects);
eina_array_clean(&e->temporary_objects); eina_array_clean(&e->temporary_objects);
eina_array_clean(&e->clip_changes); eina_array_clean(&e->clip_changes);
/* we should flush here and have a mempool system for this /* we should flush here and have a mempool system for this
eina_array_flush(&e->active_objects); eina_array_flush(&e->active_objects);
eina_array_flush(&e->render_objects); eina_array_flush(&e->render_objects);
eina_array_flush(&e->restack_objects); eina_array_flush(&e->restack_objects);
eina_array_flush(&e->delete_objects); eina_array_flush(&e->delete_objects);
eina_array_flush(&e->obscuring_objects); eina_array_flush(&e->obscuring_objects);
eina_array_flush(&e->temporary_objects); eina_array_flush(&e->temporary_objects);
eina_array_flush(&e->clip_changes); eina_array_flush(&e->clip_changes);
*/ */
e->invalidate = 1; e->invalidate = EINA_TRUE;
} }
evas_module_clean(); evas_module_clean();
evas_event_callback_call(e, EVAS_CALLBACK_RENDER_POST, NULL); evas_event_callback_call(e, EVAS_CALLBACK_RENDER_POST, NULL);
RD("---]\n"); RD("---]\n");
return updates; return updates;
} }
skipping to change at line 1677 skipping to change at line 1699
eina_rectangle_free(r); eina_rectangle_free(r);
} }
EAPI Eina_List * EAPI Eina_List *
evas_render_updates(Evas *e) evas_render_updates(Evas *e)
{ {
MAGIC_CHECK(e, Evas, MAGIC_EVAS); MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return NULL; return NULL;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush_ready ();
#endif
if (!e->changed) return NULL; if (!e->changed) return NULL;
return evas_render_updates_internal(e, 1, 1); return evas_render_updates_internal(e, 1, 1);
} }
EAPI void EAPI void
evas_render(Evas *e) evas_render(Evas *e)
{ {
MAGIC_CHECK(e, Evas, MAGIC_EVAS); MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifdef EVAS_FRAME_QUEUING
evas_common_frameq_flush_ready ();
#endif
if (!e->changed) return; if (!e->changed) return;
evas_render_updates_internal(e, 0, 1); evas_render_updates_internal(e, 0, 1);
} }
EAPI void EAPI void
evas_norender(Evas *e) evas_norender(Evas *e)
{ {
MAGIC_CHECK(e, Evas, MAGIC_EVAS); MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
skipping to change at line 1731 skipping to change at line 1745
(e->engine.data.output)) (e->engine.data.output))
e->engine.func->output_idle_flush(e->engine.data.output); e->engine.func->output_idle_flush(e->engine.data.output);
eina_array_flush(&e->active_objects); eina_array_flush(&e->active_objects);
eina_array_flush(&e->render_objects); eina_array_flush(&e->render_objects);
eina_array_flush(&e->restack_objects); eina_array_flush(&e->restack_objects);
eina_array_flush(&e->delete_objects); eina_array_flush(&e->delete_objects);
eina_array_flush(&e->obscuring_objects); eina_array_flush(&e->obscuring_objects);
eina_array_flush(&e->temporary_objects); eina_array_flush(&e->temporary_objects);
eina_array_flush(&e->clip_changes); eina_array_flush(&e->clip_changes);
eina_array_flush(&e->temporary_objects);
e->invalidate = 1; e->invalidate = EINA_TRUE;
} }
EAPI void EAPI void
evas_sync(Evas *e) evas_sync(Evas *e)
{ {
#ifdef EVAS_FRAME_QUEUING (void) e;
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return;
MAGIC_CHECK_END();
evas_common_frameq_flush();
#else
(void) e;
#endif
} }
static void static void
_evas_render_dump_map_surfaces(Evas_Object *obj) _evas_render_dump_map_surfaces(Evas_Object *obj)
{ {
if ((obj->cur.map) && obj->cur.map->surface) if ((obj->cur.map) && obj->cur.map->surface)
{ {
obj->layer->evas->engine.func->image_map_surface_free obj->layer->evas->engine.func->image_map_surface_free
(obj->layer->evas->engine.data.output, obj->cur.map->surface); (obj->layer->evas->engine.data.output, obj->cur.map->surface);
obj->cur.map->surface = NULL; obj->cur.map->surface = NULL;
skipping to change at line 1807 skipping to change at line 1812
MAGIC_CHECK(e, Evas, MAGIC_EVAS); MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
eina_array_clean(&e->active_objects); eina_array_clean(&e->active_objects);
eina_array_clean(&e->render_objects); eina_array_clean(&e->render_objects);
eina_array_flush(&e->restack_objects); eina_array_flush(&e->restack_objects);
eina_array_flush(&e->delete_objects); eina_array_flush(&e->delete_objects);
e->invalidate = 1; e->invalidate = EINA_TRUE;
} }
void void
evas_render_object_recalc(Evas_Object *obj) evas_render_object_recalc(Evas_Object *obj)
{ {
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return; return;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
#ifndef EVAS_FRAME_QUEUING
if ((!obj->changed) && (obj->delete_me < 2)) if ((!obj->changed) && (obj->delete_me < 2))
#else {
if ((!obj->changed)) Evas *e;
#endif
{
Evas *e;
e = obj->layer->evas; e = obj->layer->evas;
if ((!e) || (e->cleanup)) return; if ((!e) || (e->cleanup)) return;
#ifdef EVAS_FRAME_QUEUING eina_array_push(&e->pending_objects, obj);
if (obj->delete_me >= evas_common_frameq_get_frameq_sz() + 2) ret obj->changed = EINA_TRUE;
urn; }
#endif
eina_array_push(&e->pending_objects, obj);
obj->changed = 1;
}
} }
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
 End of changes. 100 change blocks. 
341 lines changed or deleted 336 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/