From 111e51a6ff35c3bf4dc835775b44b630e0191ba1 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 12 May 2015 17:37:01 +0900 Subject: [PATCH] Evas: Add "no-render" flag for proxy sources & clippers Those objects should never be rendered on the canvas, even if they are visible. On the other hand, they need to be rendered in mask or proxy surfaces. note: this patch includes some extra whitespaces changes :( @feature --- src/bin/edje/edje_cc_handlers.c | 27 ++++++++++++++++++++++ src/bin/edje/edje_cc_out.c | 10 ++++----- src/lib/edje/edje_data.c | 1 + src/lib/edje/edje_load.c | 3 +++ src/lib/edje/edje_private.h | 1 + src/lib/evas/canvas/evas_clip.c | 11 +++++++++ src/lib/evas/canvas/evas_object.eo | 35 +++++++++++++++++++++++++++++ src/lib/evas/canvas/evas_render.c | 21 +++++++++-------- src/lib/evas/include/evas_inline.x | 2 +- src/lib/evas/include/evas_private.h | 1 + 10 files changed, 97 insertions(+), 15 deletions(-) diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c index b371aec5ca..d9ddbd3898 100644 --- a/src/bin/edje/edje_cc_handlers.c +++ b/src/bin/edje/edje_cc_handlers.c @@ -258,6 +258,7 @@ static void st_collections_group_parts_part_pointer_mode(void); static void st_collections_group_parts_part_precise_is_inside(void); static void st_collections_group_parts_part_use_alternate_font_metrics(void); static void st_collections_group_parts_part_clip_to_id(void); +static void st_collections_group_parts_part_no_render(void); static void st_collections_group_parts_part_source(void); static void st_collections_group_parts_part_source2(void); static void st_collections_group_parts_part_source3(void); @@ -693,6 +694,7 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.precise_is_inside", st_collections_group_parts_part_precise_is_inside}, {"collections.group.parts.part.use_alternate_font_metrics", st_collections_group_parts_part_use_alternate_font_metrics}, {"collections.group.parts.part.clip_to", st_collections_group_parts_part_clip_to_id}, + {"collections.group.parts.part.no_render", st_collections_group_parts_part_no_render}, {"collections.group.parts.part.source", st_collections_group_parts_part_source}, {"collections.group.parts.part.source2", st_collections_group_parts_part_source2}, {"collections.group.parts.part.source3", st_collections_group_parts_part_source3}, @@ -4417,6 +4419,7 @@ st_collections_group_parts_alias(void) source: "groupname"; pointer_mode: AUTOGRAB; use_alternate_font_metrics: 0; + no_render: 0; dragable { } items { } @@ -4469,6 +4472,7 @@ edje_cc_handlers_part_make(int id) ep->use_alternate_font_metrics = 0; ep->access = 0; ep->clip_to_id = -1; + ep->no_render = 0; ep->dragable.confine_id = -1; ep->dragable.threshold_id = -1; ep->dragable.event_id = -1; @@ -5393,6 +5397,29 @@ st_collections_group_parts_part_clip_to_id(void) } } +/** + @page edcref + @property + no_render + @parameters + [1 or 0] + @effect + Setting the no_render flag on an object will make it never render + directly on the canvas, regardless of the visible and color properties. + But the object will still be rendered in a dedicated surface when + required if it is a proxy source or a mask (clipper). + Strongly recommended for use with mask objects and proxy sources + (instead of setting "source_visible" on the proxy itself). + @endproperty +*/ +static void +st_collections_group_parts_part_no_render(void) +{ + check_arg_count(1); + + current_part->no_render = parse_bool(0); +} + /** @page edcref @property diff --git a/src/bin/edje/edje_cc_out.c b/src/bin/edje/edje_cc_out.c index 78d3fab431..be534aab5f 100755 --- a/src/bin/edje/edje_cc_out.c +++ b/src/bin/edje/edje_cc_out.c @@ -485,20 +485,20 @@ check_part(Edje_Part_Collection *pc, Edje_Part *ep, Eet_File *ef) /* FIXME: check image set and sort them. */ if (!ep->default_desc) error_and_abort(ef, "Collection %i: default description missing " - "for part \"%s\"", pc->id, ep->name); + "for part \"%s\"", pc->id, ep->name); for (i = 0; i < ep->other.desc_count; ++i) check_state(pc, ep, ep->other.desc[i], ef); if (ep->type == EDJE_PART_TYPE_IMAGE) { - check_image_part_desc(pc, ep, (Edje_Part_Description_Image*) ep->default_desc, ef); + check_image_part_desc(pc, ep, (Edje_Part_Description_Image*) ep->default_desc, ef); - for (i = 0; i < ep->other.desc_count; ++i) - check_image_part_desc (pc, ep, (Edje_Part_Description_Image*) ep->other.desc[i], ef); + for (i = 0; i < ep->other.desc_count; ++i) + check_image_part_desc(pc, ep, (Edje_Part_Description_Image*) ep->other.desc[i], ef); } else if ((ep->type == EDJE_PART_TYPE_BOX) || - (ep->type == EDJE_PART_TYPE_TABLE)) + (ep->type == EDJE_PART_TYPE_TABLE)) check_packed_items(pc, ep, ef); else if (ep->type == EDJE_PART_TYPE_GROUP) check_source_links(pc, ep, ef, group_path); diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index d81ad241ff..2352e8541f 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -1197,6 +1197,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "source6", source6, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "id", id, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "clip_to_id", clip_to_id, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "no_render", no_render, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.x", dragable.x, EET_T_CHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.step_x", dragable.step_x, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.count_x", dragable.count_x, EET_T_INT); diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 5839e6dc03..e9c4f20441 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -774,6 +774,9 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch nested_smart = NULL; } + if (ep->no_render) + eo_do(rp->object, evas_obj_no_render_set(1)); + if (st_nested && st_nested->nested_children_count) /* Add this to list of children */ { evas_object_smart_member_add(rp->object, diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index ee28bba0c8..d3507cb581 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -1140,6 +1140,7 @@ struct _Edje_Part unsigned char access; /* it will be used accessibility feature */ Edje_Part_Api api; unsigned char nested_children_count; + unsigned char no_render; /* for proxy sources and masks, since 1.15 */ }; struct _Edje_Part_Image_Id diff --git a/src/lib/evas/canvas/evas_clip.c b/src/lib/evas/canvas/evas_clip.c index a6f1e6f124..cf5b1cc6a9 100644 --- a/src/lib/evas/canvas/evas_clip.c +++ b/src/lib/evas/canvas/evas_clip.c @@ -491,3 +491,14 @@ _evas_object_clipees_has(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj return (obj->clip.clipees ? EINA_TRUE : EINA_FALSE); } +EOLIAN void +_evas_object_no_render_set(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, Eina_Bool enable) +{ + obj->no_render = enable; +} + +EOLIAN Eina_Bool +_evas_object_no_render_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj) +{ + return obj->no_render; +} diff --git a/src/lib/evas/canvas/evas_object.eo b/src/lib/evas/canvas/evas_object.eo index 809a45099a..060b0692ea 100644 --- a/src/lib/evas/canvas/evas_object.eo +++ b/src/lib/evas/canvas/evas_object.eo @@ -1280,6 +1280,41 @@ abstract Evas.Object (Eo.Base, Evas.Common_Interface, Efl.Gfx.Base, Efl.Gfx.Stac @in type: const(char)* @nonull; /*@ The type (name string) to check for. Must be the name */ } } + @property no_render { + get { + /*@ + Returns the state of the "no-render" flag, which means, when true, + that an object should never be rendered on the canvas. + + This flag can be used to avoid rendering visible clippers on the + canvas, even if they currently don't clip any object. + + @since 1.15 */ + legacy: null; + } + set { + /*@ + Disable all rendering on the canvas. + + This flag will be used to indicate to Evas that this object should + never be rendered on the canvas under any circurmstances. In + particular, this is useful to avoid drawing clipper objects (or masks) + even when they don't clip any object. This can also be used to replace + the old source_visible flag with proxy objects. + + This is different to the visible property, as even visible objects + marked as "no-render" will never appear on screen. But those objects + can still be used as proxy sources or clippers. When hidden, all + "no-render" objects will completely disappear from the canvas, and + hide their clippees or be invisible when used as proxy sources. + + @since 1.15 */ + legacy: null; + } + values { + enable: bool; /*@ Enable "no-render" mode. */ + } + } } implements { Eo.Base.constructor; diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index b97552cd11..ed75d0a56f 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -227,7 +227,8 @@ _evas_render_is_relevant(Evas_Object *eo_obj) static Eina_Bool _evas_render_can_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) { - return (evas_object_is_visible(eo_obj, obj) && (!obj->cur->have_clipees)); + return (evas_object_is_visible(eo_obj, obj) && (!obj->cur->have_clipees) && + !obj->no_render); } static void @@ -1232,7 +1233,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, else RD(0, "\n"); if (obj->cur->clipper) { - RD(level, " clipper: '%s'%s%s %p (mask %p) %d,%d %dx%d\n", + RD(level, " clipper: '%s'%s%s %p (mask: %p) %d,%d %dx%d\n", obj->cur->clipper->type, obj->cur->clipper->name ? ":" : "", obj->cur->clipper->name ? obj->cur->clipper->name : "", @@ -1263,14 +1264,16 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, return clean_them; } } - else - { - if (!evas_object_is_proxy_visible(eo_obj, obj) || + else if (!evas_object_is_proxy_visible(eo_obj, obj) || (obj->clip.clipees) || (obj->cur->have_clipees)) - { - RD(level, "}\n"); - return clean_them; - } + { + RD(level, "}\n"); + return clean_them; + } + else if (obj->no_render) + { + RD(level, " no render\n}\n"); + return clean_them; } } else if (!(((evas_object_is_active(eo_obj, obj) && (!obj->clip.clipees) && diff --git a/src/lib/evas/include/evas_inline.x b/src/lib/evas/include/evas_inline.x index 3426d15fec..83fa4b41c8 100644 --- a/src/lib/evas/include/evas_inline.x +++ b/src/lib/evas/include/evas_inline.x @@ -66,7 +66,7 @@ evas_common_draw_context_cutouts_add(Cutout_Rects* rects, static inline int evas_object_is_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) { - if (obj->is_smart) return 0; + if (obj->is_smart || obj->no_render) return 0; /* If clipped: Assume alpha */ if (obj->cur->cache.clip.a == 255) { diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index b2678df042..967a02aeef 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1105,6 +1105,7 @@ struct _Evas_Object_Protected_Data Eina_Bool child_has_map : 1; Eina_Bool eo_del_called : 1; Eina_Bool is_smart : 1; + Eina_Bool no_render : 1; // since 1.15 }; struct _Evas_Data_Node