diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c index beebbb3926..79babed6f0 100644 --- a/src/lib/evas/canvas/evas_main.c +++ b/src/lib/evas/canvas/evas_main.c @@ -164,6 +164,7 @@ _constructor(Eo *eo_obj, void *class_data, va_list *list EINA_UNUSED) EVAS_ARRAY_SET(e, obscuring_objects); EVAS_ARRAY_SET(e, temporary_objects); EVAS_ARRAY_SET(e, calculate_objects); + EVAS_ARRAY_SET(e, clipped_objects); EVAS_ARRAY_SET(e, clip_changes); EVAS_ARRAY_SET(e, scie_unref_queue); EVAS_ARRAY_SET(e, image_unref_queue); @@ -276,6 +277,7 @@ _destructor(Eo *eo_e, void *_pd, va_list *list EINA_UNUSED) eina_array_flush(&e->obscuring_objects); eina_array_flush(&e->temporary_objects); eina_array_flush(&e->calculate_objects); + eina_array_flush(&e->clipped_objects); eina_array_flush(&e->clip_changes); eina_array_flush(&e->scie_unref_queue); eina_array_flush(&e->image_unref_queue); diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index ecdad310b2..23c081da28 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -1431,6 +1431,103 @@ _drop_image_cache_ref(const void *container EINA_UNUSED, void *data, void *fdata return EINA_TRUE; } +static void +_framespace_clipper_add(Evas *eo_e, Evas_Public_Data *e) +{ + Eina_Rectangle clip_rect; + unsigned int i; + Evas_Object *eo_obj; + Evas_Object_Protected_Data *obj; + + if (strncmp(e->engine.module->definition->name, "wayland", 7)) + return; + + /* see if the master clip has been added yet, if not, then create */ + if (!e->framespace.clip) + { + e->framespace.clip = evas_object_rectangle_add(eo_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); + } + else + { + /* master clip is already present. check for size changes in the + * 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); + } + } + + Evas_Object_Protected_Data *framespace_clip = + eo_data_get(e->framespace.clip, EVAS_OBJ_CLASS); + + EINA_RECTANGLE_SET(&clip_rect, + framespace_clip->cur->geometry.x, + framespace_clip->cur->geometry.y, + framespace_clip->cur->geometry.w, + framespace_clip->cur->geometry.h); + + evas_object_show(e->framespace.clip); + /* With the master clip all setup, we need to loop the objects on this + * 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 to + * clip the object to the master clip so that it does not draw on top + * 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 (obj->is_frame) continue; + + if (obj->delete_me) continue; + + eo_obj = obj->object; + + /* skip clipping if the object is itself the + * framespace clip */ + if (eo_obj == framespace_clip->object) 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(eo_obj))) + { + /* clip this object so it does not draw on the window frame */ + evas_object_clip_set(eo_obj, framespace_clip->object); + eina_array_push(&e->clipped_objects, eo_obj); + } + } +} + +static void +_framespace_clipper_del(Evas_Public_Data *e) +{ + Evas_Object *eo_obj; + + while ((eo_obj = eina_array_pop(&e->clipped_objects))) + evas_object_clip_unset(eo_obj); + + if (e->framespace.clip) + evas_object_hide(e->framespace.clip); +} + static Eina_Bool evas_render_updates_internal(Evas *eo_e, unsigned char make_updates, @@ -1574,82 +1671,7 @@ evas_render_updates_internal(Evas *eo_e, * 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(eo_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 the - * 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); - } - } - - Evas_Object_Protected_Data *framespace_clip = - eo_data_get(e->framespace.clip, EVAS_OBJ_CLASS); - - EINA_RECTANGLE_SET(&clip_rect, - framespace_clip->cur->geometry.x, - framespace_clip->cur->geometry.y, - framespace_clip->cur->geometry.w, - framespace_clip->cur->geometry.h) - - /* With the master clip all setup, we need to loop the objects on this - * 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 to - * clip the object to the master clip so that it does not draw on top - * 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 (obj->is_frame) continue; - - if (obj->delete_me) continue; - - eo_obj = obj->object; - - /* skip clipping if the object is itself the - * framespace clip */ - if (eo_obj == framespace_clip->object) 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(eo_obj))) - { - /* clip this object so it does not draw on the window frame */ - evas_object_clip_set(eo_obj, framespace_clip->object); - } - } - } + _framespace_clipper_add(eo_e, e); if (redraw_all) { @@ -1938,6 +1960,8 @@ evas_render_updates_internal(Evas *eo_e, e->invalidate = EINA_TRUE; } + _framespace_clipper_del(e); + evas_module_clean(); if (!do_async) diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 9defa266f6..fcf812831f 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -388,6 +388,7 @@ struct _Evas_Public_Data Eina_Array obscuring_objects; Eina_Array temporary_objects; Eina_Array calculate_objects; + Eina_Array clipped_objects; // to the framespace clipper Eina_Array clip_changes; Eina_Array scie_unref_queue; Eina_Array image_unref_queue;