summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2015-08-06 11:06:55 +0200
committerCedric BAIL <cedric@osg.samsung.com>2015-08-06 11:06:55 +0200
commit79f2576a8919c288f51939b12cc4edfd67023c17 (patch)
tree3a3b6859febe339fb5a538c0cda7ff416af64409
parent0d44b94248465a634720cce00ef9d477c8fb5b82 (diff)
parenta7fd98f8f6d411c120e9c1c8ceeedbeb54d675a5 (diff)
downloadefl-79f2576a8919c288f51939b12cc4edfd67023c17.tar.gz
Merge branch 'devs/cedric/evas_snapshot'
Evas snapshot feature is a new attribute for Evas_Objet_Image that allow the object to get the pixels of the object below it in its own buffer. This can be used for two typicall use case. First is improving accessibility by offering a magnifying glass using snapshot together with Evas_Map. Second is to make it possible to blur the underlying content (in conjunction with filters). This should make it possible to do some nice new theme and effect. NOTE: As a technical note, this feature is very costly at the point. We do not support partial update on surface and we can't know if the object below did change, so we are forced to redraw the full content of the snapshot object for every frame. The only way to fix it is to add per surface damage detection. I guess it is time to start rolling this in.
-rw-r--r--src/bin/edje/edje_cc_handlers.c9
-rw-r--r--src/lib/edje/Edje_Common.h3
-rw-r--r--src/lib/edje/edje_cache.c3
-rw-r--r--src/lib/edje/edje_calc.c7
-rw-r--r--src/lib/edje/edje_data.c20
-rw-r--r--src/lib/edje/edje_load.c5
-rw-r--r--src/lib/edje/edje_private.h4
-rw-r--r--src/lib/evas/canvas/evas_image.eo22
-rw-r--r--src/lib/evas/canvas/evas_main.c4
-rw-r--r--src/lib/evas/canvas/evas_object_image.c63
-rw-r--r--src/lib/evas/canvas/evas_object_main.c2
-rw-r--r--src/lib/evas/canvas/evas_render.c440
-rw-r--r--src/lib/evas/include/evas_inline.x3
-rw-r--r--src/lib/evas/include/evas_private.h4
14 files changed, 416 insertions, 173 deletions
diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c
index e002d19aa4..3138300936 100644
--- a/src/bin/edje/edje_cc_handlers.c
+++ b/src/bin/edje/edje_cc_handlers.c
@@ -1270,6 +1270,7 @@ New_Object_Handler object_handlers[] =
external{}
proxy{}
spacer{}
+ snapshot{}
part {
desc {
}
@@ -1422,6 +1423,7 @@ _edje_part_description_alloc(unsigned char type, const char *collection, const c
case EDJE_PART_TYPE_RECTANGLE:
case EDJE_PART_TYPE_SWALLOW:
case EDJE_PART_TYPE_GROUP:
+ case EDJE_PART_TYPE_SNAPSHOT:
result = mem_alloc(SZ(Edje_Part_Description_Common));
break;
case EDJE_PART_TYPE_TEXT:
@@ -4882,6 +4884,7 @@ ob_collections_group_parts_part_short(void)
"external", EDJE_PART_TYPE_EXTERNAL,
"proxy", EDJE_PART_TYPE_PROXY,
"spacer", EDJE_PART_TYPE_SPACER,
+ "snapshot", EDJE_PART_TYPE_SNAPSHOT,
NULL);
stack_pop_quick(EINA_TRUE, EINA_TRUE);
@@ -4918,6 +4921,7 @@ _part_desc_free(Edje_Part_Collection *pc,
case EDJE_PART_TYPE_RECTANGLE:
case EDJE_PART_TYPE_SWALLOW:
case EDJE_PART_TYPE_GROUP:
+ case EDJE_PART_TYPE_SNAPSHOT:
/* Nothing todo, this part only have a common description. */
break;
case EDJE_PART_TYPE_BOX:
@@ -5289,6 +5293,7 @@ st_collections_group_parts_part_name(void)
@li EXTERNAL
@li PROXY
@li SPACER
+ @li SNAPSHOT
@endproperty
*/
static void
@@ -5310,7 +5315,8 @@ st_collections_group_parts_part_type(void)
"TABLE", EDJE_PART_TYPE_TABLE,
"EXTERNAL", EDJE_PART_TYPE_EXTERNAL,
"PROXY", EDJE_PART_TYPE_PROXY,
- "SPACER", EDJE_PART_TYPE_SPACER,
+ "SPACER", EDJE_PART_TYPE_SPACER,
+ "SNAPSHOT", EDJE_PART_TYPE_SNAPSHOT,
NULL);
_part_type_set(type);
@@ -7025,6 +7031,7 @@ st_collections_group_parts_part_description_inherit(void)
case EDJE_PART_TYPE_RECTANGLE:
case EDJE_PART_TYPE_SWALLOW:
case EDJE_PART_TYPE_GROUP:
+ case EDJE_PART_TYPE_SNAPSHOT:
/* Nothing todo, this part only have a common description. */
break;
case EDJE_PART_TYPE_TEXT:
diff --git a/src/lib/edje/Edje_Common.h b/src/lib/edje/Edje_Common.h
index e8bc7191bc..468b163c0a 100644
--- a/src/lib/edje/Edje_Common.h
+++ b/src/lib/edje/Edje_Common.h
@@ -1235,7 +1235,8 @@ typedef enum _Edje_Part_Type
EDJE_PART_TYPE_MESH_NODE = 13,
EDJE_PART_TYPE_LIGHT = 14,
EDJE_PART_TYPE_CAMERA = 15,
- EDJE_PART_TYPE_LAST = 16 /**< Last type value */
+ EDJE_PART_TYPE_SNAPSHOT = 16,
+ EDJE_PART_TYPE_LAST = 17 /**< Last type value */
} Edje_Part_Type;
/**
* @}
diff --git a/src/lib/edje/edje_cache.c b/src/lib/edje/edje_cache.c
index 13f83767f9..10fa3fa7b8 100644
--- a/src/lib/edje/edje_cache.c
+++ b/src/lib/edje/edje_cache.c
@@ -33,6 +33,7 @@ edje_cache_emp_alloc(Edje_Part_Collection_Directory_Entry *ce)
INIT_EMP_BOTH(TABLE, Edje_Part_Description_Table, ce);
INIT_EMP_BOTH(EXTERNAL, Edje_Part_Description_External, ce);
INIT_EMP_BOTH(SPACER, Edje_Part_Description_Common, ce);
+ INIT_EMP_BOTH(SNAPSHOT, Edje_Part_Description_Common, ce);
INIT_EMP(part, Edje_Part, ce);
}
@@ -51,6 +52,7 @@ edje_cache_emp_free(Edje_Part_Collection_Directory_Entry *ce)
eina_mempool_del(ce->mp.TABLE);
eina_mempool_del(ce->mp.EXTERNAL);
eina_mempool_del(ce->mp.SPACER);
+ eina_mempool_del(ce->mp.SNAPSHOT);
eina_mempool_del(ce->mp.part);
memset(&ce->mp, 0, sizeof (ce->mp));
@@ -65,6 +67,7 @@ edje_cache_emp_free(Edje_Part_Collection_Directory_Entry *ce)
eina_mempool_del(ce->mp_rtl.TABLE);
eina_mempool_del(ce->mp_rtl.EXTERNAL);
eina_mempool_del(ce->mp_rtl.SPACER);
+ eina_mempool_del(ce->mp_rtl.SNAPSHOT);
memset(&ce->mp_rtl, 0, sizeof (ce->mp_rtl));
ce->ref = NULL;
}
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c
index 16d0c1ad77..dcf868a11a 100644
--- a/src/lib/edje/edje_calc.c
+++ b/src/lib/edje/edje_calc.c
@@ -326,6 +326,13 @@ case EDJE_PART_TYPE_##Short: \
memsize = sizeof(Edje_Part_Description_Common);
break;
+ case EDJE_PART_TYPE_SNAPSHOT:
+ desc_rtl = eina_mempool_malloc(ce->mp_rtl.SNAPSHOT,
+ sizeof (Edje_Part_Description_Common));
+ ce->count.SNAPSHOT++;
+ memsize = sizeof(Edje_Part_Description_Common);
+ break;
+
case EDJE_PART_TYPE_SWALLOW:
desc_rtl = eina_mempool_malloc(ce->mp_rtl.SWALLOW,
sizeof (Edje_Part_Description_Common));
diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c
index cedda6d413..19176d8c26 100644
--- a/src/lib/edje/edje_data.c
+++ b/src/lib/edje/edje_data.c
@@ -36,6 +36,7 @@ Eet_Data_Descriptor *_edje_edd_edje_part = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_pointer = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_variant = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_rectangle = NULL;
+Eet_Data_Descriptor *_edje_edd_edje_part_description_snapshot = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_spacer = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_swallow = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_group = NULL;
@@ -54,6 +55,7 @@ Eet_Data_Descriptor *_edje_edd_edje_part_description_light = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_camera = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_variant_list = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_rectangle_pointer = NULL;
+Eet_Data_Descriptor *_edje_edd_edje_part_description_snapshot_pointer = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_spacer_pointer = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_swallow_pointer = NULL;
Eet_Data_Descriptor *_edje_edd_edje_part_description_group_pointer = NULL;
@@ -116,6 +118,7 @@ EMP(SPACER, spacer)
EMP(MESH_NODE, mesh_node)
EMP(LIGHT, light)
EMP(CAMERA, camera)
+EMP(SNAPSHOT, snapshot)
#undef EMP
EAPI Eina_Mempool *_emp_part = NULL;
@@ -164,7 +167,8 @@ struct
{ EDJE_PART_TYPE_SPACER, "spacer" },
{ EDJE_PART_TYPE_MESH_NODE, "mesh_node" },
{ EDJE_PART_TYPE_LIGHT, "light" },
- { EDJE_PART_TYPE_CAMERA, "camera" }
+ { EDJE_PART_TYPE_CAMERA, "camera" },
+ { EDJE_PART_TYPE_SNAPSHOT, "snapshot" }
};
static const char *
@@ -254,6 +258,7 @@ _edje_edd_shutdown(void)
FREED(_edje_edd_edje_part_pointer);
FREED(_edje_edd_edje_part_description_variant);
FREED(_edje_edd_edje_part_description_rectangle);
+ FREED(_edje_edd_edje_part_description_snapshot);
FREED(_edje_edd_edje_part_description_spacer);
FREED(_edje_edd_edje_part_description_swallow);
FREED(_edje_edd_edje_part_description_group);
@@ -272,6 +277,7 @@ _edje_edd_shutdown(void)
FREED(_edje_edd_edje_part_description_3d_vec);
FREED(_edje_edd_edje_part_description_variant_list);
FREED(_edje_edd_edje_part_description_rectangle_pointer);
+ FREED(_edje_edd_edje_part_description_snapshot_pointer);
FREED(_edje_edd_edje_part_description_spacer_pointer);
FREED(_edje_edd_edje_part_description_swallow_pointer);
FREED(_edje_edd_edje_part_description_group_pointer);
@@ -491,6 +497,7 @@ _edje_edd_init(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.TABLE", count.TABLE, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.EXTERNAL", count.EXTERNAL, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.SPACER", count.SPACER, EET_T_INT);
+ EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.SNAPSHOT", count.SNAPSHOT, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.MESH_NODE", count.MESH_NODE, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.LIGHT", count.LIGHT, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.CAMERA", count.CAMERA, EET_T_INT);
@@ -865,6 +872,14 @@ _edje_edd_init(void)
EDJE_DATA_DESCRIPTOR_DESCRIPTION_COMMON(_edje_edd_edje_part_description_spacer, Edje_Part_Description_Common);
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Common);
+ eddc.func.mem_free = mem_free_snapshot;
+ eddc.func.mem_alloc = mem_alloc_snapshot;
+ _edje_edd_edje_part_description_snapshot =
+ eet_data_descriptor_file_new(&eddc);
+ EDJE_DATA_DESCRIPTOR_DESCRIPTION_COMMON(_edje_edd_edje_part_description_snapshot, Edje_Part_Description_Common);
+
+
+ EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Common);
eddc.func.mem_free = mem_free_swallow;
eddc.func.mem_alloc = mem_alloc_swallow;
_edje_edd_edje_part_description_swallow =
@@ -1117,6 +1132,7 @@ _edje_edd_init(void)
EDJE_DEFINE_POINTER_TYPE(Part_Description_Common, part_description_rectangle);
EDJE_DEFINE_POINTER_TYPE(Part_Description_Common, part_description_swallow);
EDJE_DEFINE_POINTER_TYPE(Part_Description_Common, part_description_group);
+ EDJE_DEFINE_POINTER_TYPE(Part_Description_Common, part_description_snapshot);
EDJE_DEFINE_POINTER_TYPE(Part_Description_Image, part_description_image);
EDJE_DEFINE_POINTER_TYPE(Part_Description_Proxy, part_description_proxy);
EDJE_DEFINE_POINTER_TYPE(Part_Description_Text, part_description_text);
@@ -1135,6 +1151,7 @@ _edje_edd_init(void)
EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "spacer", _edje_edd_edje_part_description_spacer);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "rectangle", _edje_edd_edje_part_description_rectangle);
+ EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "snapshot", _edje_edd_edje_part_description_snapshot);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "swallow", _edje_edd_edje_part_description_swallow);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "group", _edje_edd_edje_part_description_group);
EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "image", _edje_edd_edje_part_description_image);
@@ -1162,6 +1179,7 @@ _edje_edd_init(void)
_edje_edd_edje_part_description_variant_list = eet_data_descriptor_file_new(&eddc);
EDJE_ADD_ARRAY_MAPPING(_edje_edd_edje_part_description_variant_list, "rectangle", rectangle);
+ EDJE_ADD_ARRAY_MAPPING(_edje_edd_edje_part_description_variant_list, "snapshot", snapshot);
EDJE_ADD_ARRAY_MAPPING(_edje_edd_edje_part_description_variant_list, "spacer", spacer);
EDJE_ADD_ARRAY_MAPPING(_edje_edd_edje_part_description_variant_list, "swallow", swallow);
EDJE_ADD_ARRAY_MAPPING(_edje_edd_edje_part_description_variant_list, "group", group);
diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c
index 6f29897a32..2ab9862b8b 100644
--- a/src/lib/edje/edje_load.c
+++ b/src/lib/edje/edje_load.c
@@ -710,7 +710,10 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch
case EDJE_PART_TYPE_PROXY:
case EDJE_PART_TYPE_IMAGE:
+ case EDJE_PART_TYPE_SNAPSHOT:
rp->object = evas_object_image_add(ed->base->evas);
+ if (ep->type == EDJE_PART_TYPE_SNAPSHOT)
+ evas_object_image_snapshot_set(rp->object, EINA_TRUE);
break;
case EDJE_PART_TYPE_TEXT:
@@ -1958,6 +1961,8 @@ case EDJE_PART_TYPE_##Type: eina_mempool_free(Ce->mp.Type, Desc); \
FREE_POOL(BOX, ce, desc);
FREE_POOL(TABLE, ce, desc);
FREE_POOL(EXTERNAL, ce, desc);
+ FREE_POOL(SNAPSHOT, ce, desc);
+ FREE_POOL(SPACER, ce, desc);
}
}
diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h
index e629923596..8fec707968 100644
--- a/src/lib/edje/edje_private.h
+++ b/src/lib/edje/edje_private.h
@@ -837,7 +837,8 @@ struct _Edje_Limit
TYPE EXTERNAL; \
TYPE MESH_NODE; \
TYPE LIGHT; \
- TYPE CAMERA;
+ TYPE CAMERA; \
+ TYPE SNAPSHOT;
struct _Edje_Part_Collection_Directory_Entry
{
@@ -2239,6 +2240,7 @@ EAPI extern Eina_Mempool *_emp_SPACER;
EAPI extern Eina_Mempool *_emp_MESH_NODE;
EAPI extern Eina_Mempool *_emp_LIGHT;
EAPI extern Eina_Mempool *_emp_CAMERA;
+EAPI extern Eina_Mempool *_emp_SNAPSHOT;
EAPI extern Eina_Mempool *_emp_part;
void _edje_part_pos_set(Edje *ed, Edje_Real_Part *ep, int mode, FLOAT_T pos, FLOAT_T v1, FLOAT_T v2, FLOAT_T v3, FLOAT_T v4);
diff --git a/src/lib/evas/canvas/evas_image.eo b/src/lib/evas/canvas/evas_image.eo
index 53c9076bcf..58a7baf524 100644
--- a/src/lib/evas/canvas/evas_image.eo
+++ b/src/lib/evas/canvas/evas_image.eo
@@ -784,6 +784,28 @@ class Evas.Image (Evas.Object, Efl.File, Efl.Image, Efl.Gfx.Fill, Efl.Gfx.View,
Default is #EVAS_IMAGE_ORIENT_NONE. */
}
}
+ @property snapshot {
+ set {
+ /*@
+ The content below the Evas_Object_Image will be rendered inside it and
+ you can reuse it as a source for any kind of effect.
+
+ @since 1.15
+ */
+ }
+ get {
+ /*@
+ Determine wether the Evas_Object_Image replicate the content of the
+ canvas below.
+
+ @return @c EINA_TRUE if it does, @c EINA_FALSE if it doesn't.
+ @since 1.15
+ */
+ }
+ values {
+ s: bool; /*@ Wether to put the content of the canvas below inside the Evas_Object_Image. */
+ }
+ }
preload_begin {
/*@ Begin preloading an image object's image data in the background */
legacy: null;
diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c
index e20f748941..5e7e6ee242 100644
--- a/src/lib/evas/canvas/evas_main.c
+++ b/src/lib/evas/canvas/evas_main.c
@@ -175,7 +175,7 @@ _evas_canvas_eo_base_constructor(Eo *eo_obj, Evas_Public_Data *e)
#define EVAS_ARRAY_SET(E, Array) \
eina_array_step_set(&E->Array, sizeof (E->Array), \
- ((1024 * sizeof (void*)) - sizeof (E->Array)) / sizeof (void*));
+ ((1024 * sizeof (void*)) - sizeof (E->Array)) / sizeof (void*));
EVAS_ARRAY_SET(e, delete_objects);
EVAS_ARRAY_SET(e, active_objects);
@@ -184,6 +184,7 @@ _evas_canvas_eo_base_constructor(Eo *eo_obj, Evas_Public_Data *e)
EVAS_ARRAY_SET(e, pending_objects);
EVAS_ARRAY_SET(e, obscuring_objects);
EVAS_ARRAY_SET(e, temporary_objects);
+ EVAS_ARRAY_SET(e, snapshot_objects);
EVAS_ARRAY_SET(e, clip_changes);
EVAS_ARRAY_SET(e, scie_unref_queue);
EVAS_ARRAY_SET(e, image_unref_queue);
@@ -300,6 +301,7 @@ _evas_canvas_eo_base_destructor(Eo *eo_e, Evas_Public_Data *e)
eina_array_flush(&e->pending_objects);
eina_array_flush(&e->obscuring_objects);
eina_array_flush(&e->temporary_objects);
+ eina_array_flush(&e->snapshot_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_object_image.c b/src/lib/evas/canvas/evas_object_image.c
index 8956f815bf..2f8561f219 100644
--- a/src/lib/evas/canvas/evas_object_image.c
+++ b/src/lib/evas/canvas/evas_object_image.c
@@ -69,6 +69,8 @@ struct _Evas_Object_Image_Pixels
Evas_Video_Surface video;
unsigned int video_caps;
+
+ int surface_w, surface_h; /* used by snapshot feature */
};
struct _Evas_Object_Image_State
@@ -233,7 +235,7 @@ static const Evas_Object_Image_Load_Opts default_load_opts = {
};
static const Evas_Object_Image_Pixels default_pixels = {
- NULL, { NULL, NULL }, { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, ~0x0
+ NULL, { NULL, NULL }, { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, ~0x0, 0, 0
};
static const Evas_Object_Image_State default_state = {
@@ -3301,6 +3303,14 @@ _evas_image_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
uvw = imagew;
uvh = imageh;
}
+ else if (obj->cur->snapshot)
+ {
+ pixels = o->engine_data;
+ imagew = o->pixels->surface_w;
+ imageh = o->pixels->surface_h;
+ uvw = imagew;
+ uvh = imageh;
+ }
else if (!o->cur->source)
{
pixels = evas_process_dirty_pixels(eo_obj, obj, o, output, surface, o->engine_data);
@@ -3322,6 +3332,7 @@ _evas_image_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
((Evas_Image_Data *)eo_data_scope_get(o->cur->source, MY_CLASS))->engine_data)
{
Evas_Image_Data *oi;
+
oi = eo_data_scope_get(o->cur->source, MY_CLASS);
pixels = oi->engine_data;
imagew = oi->cur->image.w;
@@ -4738,7 +4749,53 @@ _evas_object_image_video_overlay_do(Evas_Object *eo_obj)
o->delayed.video_hide = EINA_FALSE;
}
-/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
+static void
+_evas_image_snapshot_set(Eo *eo, Evas_Image_Data *pd EINA_UNUSED, Eina_Bool s)
+{
+ Evas_Object_Protected_Data *obj = eo_data_scope_get(eo, EVAS_OBJECT_CLASS);
+
+ if (obj->cur->snapshot == s) return ;
+
+ EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
+ state_write->snapshot = !!s;
+ EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+}
+
+static Eina_Bool
+_evas_image_snapshot_get(Eo *eo, Evas_Image_Data *pd EINA_UNUSED)
+{
+ Evas_Object_Protected_Data *obj = eo_data_scope_get(eo, EVAS_OBJECT_CLASS);
+
+ return obj->cur->snapshot;
+}
+
+void *
+_evas_object_image_surface_get(Evas_Object *eo, Evas_Object_Protected_Data *obj)
+{
+ Evas_Image_Data *pd = eo_data_scope_get(eo, EVAS_IMAGE_CLASS);
+
+ if (pd->engine_data &&
+ pd->pixels->surface_w == obj->cur->geometry.w &&
+ pd->pixels->surface_h == obj->cur->geometry.h)
+ return pd->engine_data;
+
+ if (pd->engine_data)
+ ENFN->image_free(ENDT, pd->engine_data);
+
+ // FIXME: alpha forced to 1 for now, need to figure out Evas alpha here
+ EINA_COW_PIXEL_WRITE_BEGIN(pd, pixi_write)
+ {
+ pd->engine_data = ENFN->image_map_surface_new(ENDT,
+ obj->cur->geometry.w,
+ obj->cur->geometry.h,
+ 1);
+ pixi_write->surface_w = obj->cur->geometry.w;
+ pixi_write->surface_h = obj->cur->geometry.h;
+ }
+ EINA_COW_PIXEL_WRITE_END(pd, pixi_write);
+
+ return pd->engine_data;
+}
EAPI void
evas_object_image_file_set(Eo *obj, const char *file, const char *key)
@@ -4811,3 +4868,5 @@ _evas_image_efl_gfx_filter_program_set(Eo *obj, Evas_Image_Data *pd EINA_UNUSED,
}
#include "canvas/evas_image.eo.c"
+
+/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c
index 3de8510d12..91d6761b41 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -30,7 +30,7 @@ static const Evas_Object_Protected_State default_state = {
NULL, { 0, 0, 0, 0 },
{ { 0, 0, 0, 0, 0, 0, 0, 0, EINA_FALSE, EINA_FALSE } },
{ 255, 255, 255, 255 },
- 1.0, 0, EVAS_RENDER_BLEND, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE
+ 1.0, 0, EVAS_RENDER_BLEND, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE
};
static const Evas_Object_Filter_Data default_filter = {
NULL, NULL, NULL, NULL, NULL, NULL, { { "default", 0.0 }, { "default", 0.0 }, 0.0 }, EINA_FALSE, EINA_FALSE
diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c
index 80faf6f3c5..0618e1aeb6 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -496,6 +496,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
Eina_Array *restack_objects,
Eina_Array *delete_objects,
Eina_Array *render_objects,
+ Eina_Array *snapshot_objects,
int restack,
int *redraw_all,
Eina_Bool mapped_parent,
@@ -538,6 +539,8 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
if ((!mapped_parent) && ((is_active) || (obj->delete_me != 0)))
OBJ_ARRAY_PUSH(active_objects, obj);
+ if (is_active && obj->cur->snapshot)
+ OBJ_ARRAY_PUSH(snapshot_objects, obj);
#ifdef REND_DBG
if (!is_active)
@@ -596,6 +599,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
restack_objects,
delete_objects,
render_objects,
+ snapshot_objects,
obj->restack,
redraw_all,
EINA_TRUE,
@@ -653,6 +657,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
restack_objects,
delete_objects,
render_objects,
+ snapshot_objects,
obj->restack,
redraw_all,
mapped_parent,
@@ -731,6 +736,7 @@ _evas_render_phase1_object_process(Evas_Public_Data *e, Evas_Object *eo_obj,
restack_objects,
delete_objects,
render_objects,
+ snapshot_objects,
restack,
redraw_all,
mapped_parent,
@@ -798,6 +804,7 @@ _evas_render_phase1_process(Evas_Public_Data *e,
Eina_Array *restack_objects,
Eina_Array *delete_objects,
Eina_Array *render_objects,
+ Eina_Array *snapshot_objects,
int *redraw_all)
{
Evas_Layer *lay;
@@ -812,7 +819,8 @@ _evas_render_phase1_process(Evas_Public_Data *e,
{
clean_them |= _evas_render_phase1_object_process
(e, obj->object, active_objects, restack_objects, delete_objects,
- render_objects, 0, redraw_all, EINA_FALSE, EINA_FALSE, 2);
+ render_objects, snapshot_objects, 0, redraw_all,
+ EINA_FALSE, EINA_FALSE, 2);
}
}
RD(0, " ---]\n");
@@ -891,6 +899,7 @@ clean_stuff:
OBJS_ARRAY_CLEAN(&e->render_objects);
OBJS_ARRAY_CLEAN(&e->restack_objects);
OBJS_ARRAY_CLEAN(&e->delete_objects);
+ OBJS_ARRAY_CLEAN(&e->snapshot_objects);
e->invalidate = EINA_TRUE;
return;
}
@@ -934,7 +943,7 @@ _evas_render_can_use_overlay(Evas_Public_Data *e, Evas_Object *eo_obj)
Evas_Object *video_parent = NULL;
Eina_Rectangle zone;
Evas_Coord xc1, yc1, xc2, yc2;
- unsigned int i;
+ int i;
Eina_Bool nooverlay;
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Evas_Object_Protected_Data *tmp = NULL;
@@ -2007,7 +2016,7 @@ end:
}
static void
-_evas_render_cutout_add(Evas_Public_Data *e, Evas_Object_Protected_Data *obj, int off_x, int off_y)
+_evas_render_cutout_add(Evas_Public_Data *e, void *context, Evas_Object_Protected_Data *obj, int off_x, int off_y)
{
if (evas_object_is_source_invisible(obj->object, obj)) return;
if (evas_object_is_opaque(obj->object, obj))
@@ -2041,7 +2050,7 @@ _evas_render_cutout_add(Evas_Public_Data *e, Evas_Object_Protected_Data *obj, in
}
}
e->engine.func->context_cutout_add
- (e->engine.data.output, e->engine.data.context,
+ (e->engine.data.output, context,
cox + off_x, coy + off_y, cow, coh);
}
else
@@ -2061,7 +2070,7 @@ _evas_render_cutout_add(Evas_Public_Data *e, Evas_Object_Protected_Data *obj, in
obj->cur->cache.clip.w,
obj->cur->cache.clip.h);
e->engine.func->context_cutout_add
- (e->engine.data.output, e->engine.data.context,
+ (e->engine.data.output, context,
obx, oby, obw, obh);
}
}
@@ -2122,6 +2131,179 @@ _cb_always_call(Evas *eo_e, Evas_Callback_Type type, void *event_info)
}
static Eina_Bool
+evas_render_updates_internal_loop(Evas *eo_e, Evas_Public_Data *e,
+ void *surface, void *context,
+ Evas_Object_Protected_Data *top,
+ int ux, int uy, int uw, int uh,
+ int cx, int cy, int cw, int ch,
+ int fx, int fy,
+ Eina_Bool alpha,
+ Eina_Bool do_async,
+ unsigned int *offset)
+{
+ Evas_Object *eo_obj;
+ Evas_Object_Protected_Data *obj;
+ int off_x, off_y;
+ unsigned int i, j;
+ Eina_Bool clean_them = EINA_FALSE;
+
+ eina_evlog("+render_setup", eo_e, 0.0, NULL);
+ RD(0, " [--- UPDATE %i %i %ix%i\n", ux, uy, uw, uh);
+
+ off_x = cx - ux;
+ off_y = cy - uy;
+ /* build obscuring objects list (in order from bottom to top) */
+ if (alpha)
+ {
+ e->engine.func->context_clip_set(e->engine.data.output,
+ context,
+ ux + off_x, uy + off_y, uw, uh);
+ }
+ for (i = 0; i < e->obscuring_objects.count; ++i)
+ {
+ obj = (Evas_Object_Protected_Data *)eina_array_data_get
+ (&e->obscuring_objects, i);
+ if (evas_object_is_in_output_rect(obj->object, obj, ux - fx, uy - fy, uw, uh))
+ {
+ OBJ_ARRAY_PUSH(&e->temporary_objects, obj);
+
+ if (obj == top) break;
+
+ /* reset the background of the area if needed (using cutout and engine alpha flag to help) */
+ if (alpha)
+ _evas_render_cutout_add(e, context, obj, off_x + fx, off_y + fy);
+ }
+ }
+ if (alpha)
+ {
+ e->engine.func->context_color_set(e->engine.data.output,
+ context,
+ 0, 0, 0, 0);
+ e->engine.func->context_multiplier_unset
+ (e->engine.data.output, e->engine.data.context);
+ e->engine.func->context_render_op_set(e->engine.data.output,
+ context,
+ EVAS_RENDER_COPY);
+ e->engine.func->rectangle_draw(e->engine.data.output,
+ context, surface,
+ cx, cy, cw, ch, do_async);
+ e->engine.func->context_cutout_clear(e->engine.data.output, context);
+ e->engine.func->context_clip_unset(e->engine.data.output, context);
+ }
+ eina_evlog("-render_setup", eo_e, 0.0, NULL);
+
+ eina_evlog("+render_objects", eo_e, 0.0, NULL);
+ /* render all object that intersect with rect */
+ for (i = 0; i < e->active_objects.count; ++i)
+ {
+ obj = eina_array_data_get(&e->active_objects, i);
+ eo_obj = obj->object;
+
+ if (obj == top) break;
+
+ /* if it's in our outpout rect and it doesn't clip anything */
+ RD(0, " OBJ: [%p", obj);
+ IFRD(0, " '%s'", obj->name);
+ RD(0, "] '%s' %i %i %ix%i\n", obj->type, obj->cur->geometry.x, obj->cur->geometry.y, obj->cur->geometry.w, obj->cur->geometry.h);
+ if ((evas_object_is_in_output_rect(eo_obj, obj, ux - fx, uy - fy, uw, uh) ||
+ (obj->is_smart)) &&
+ (!obj->clip.clipees) &&
+ (obj->cur->visible) &&
+ (!obj->delete_me) &&
+ (obj->cur->cache.clip.visible) &&
+ // (!obj->is_smart) &&
+ ((obj->cur->color.a > 0 || obj->cur->render_op != EVAS_RENDER_BLEND)))
+ {
+ int x, y, w, h;
+
+ RD(0, " DRAW (vis: %i, a: %i, clipees: %p)\n", obj->cur->visible, obj->cur->color.a, obj->clip.clipees);
+ if ((e->temporary_objects.count > *offset) &&
+ (eina_array_data_get(&e->temporary_objects, *offset) == obj))
+ (*offset)++;
+ x = cx; y = cy; w = cw; h = ch;
+ if (((w > 0) && (h > 0)) || (obj->is_smart))
+ {
+ Evas_Object_Protected_Data *prev_mask = NULL;
+ Evas_Object_Protected_Data *mask = NULL;
+
+ if (!obj->is_smart)
+ {
+ RECTS_CLIP_TO_RECT(x, y, w, h,
+ obj->cur->cache.clip.x + off_x + fx,
+ obj->cur->cache.clip.y + off_y + fy,
+ obj->cur->cache.clip.w,
+ obj->cur->cache.clip.h);
+ }
+
+ e->engine.func->context_clip_set(e->engine.data.output,
+ context,
+ x, y, w, h);
+
+ /* Clipper masks */
+ if (_evas_render_object_is_mask(obj->cur->clipper))
+ mask = obj->cur->clipper; // main object clipped by this mask
+ else if (obj->clip.mask)
+ mask = obj->clip.mask; // propagated clip
+ prev_mask = obj->clip.prev_mask;
+
+ if (mask)
+ {
+ if (mask->mask->redraw || !mask->mask->surface)
+ evas_render_mask_subrender(obj->layer->evas, mask, prev_mask, 4);
+
+ if (mask->mask->surface)
+ {
+ e->engine.func->context_clip_image_set
+ (e->engine.data.output,
+ context,
+ mask->mask->surface,
+ mask->cur->geometry.x + off_x,
+ mask->cur->geometry.y + off_y,
+ e, do_async);
+ }
+ }
+
+#if 1 /* FIXME: this can slow things down... figure out optimum... coverage */
+ for (j = *offset; j < e->temporary_objects.count; ++j)
+ {
+ Evas_Object_Protected_Data *obj2;
+
+ obj2 = (Evas_Object_Protected_Data *)eina_array_data_get
+ (&e->temporary_objects, j);
+
+ if (obj2 == top) break;
+
+ _evas_render_cutout_add(e, context, obj2, off_x + fx, off_y + fy);
+ }
+#endif
+ clean_them |= evas_render_mapped(e, eo_obj, obj, context,
+ surface, off_x + fx,
+ off_y + fy, 0,
+ cx, cy, cw, ch,
+ NULL, 4,
+ EINA_FALSE,
+ do_async);
+ e->engine.func->context_cutout_clear(e->engine.data.output,
+ context);
+
+ if (mask)
+ {
+ e->engine.func->context_clip_image_unset
+ (e->engine.data.output, context);
+ }
+ }
+ }
+ }
+
+ eina_evlog("-render_objects", eo_e, 0.0, NULL);
+ /* free obscuring objects list */
+ OBJS_ARRAY_CLEAN(&e->temporary_objects);
+ RD(0, " ---]\n");
+
+ return clean_them;
+}
+
+static Eina_Bool
evas_render_updates_internal(Evas *eo_e,
unsigned char make_updates,
unsigned char do_draw,
@@ -2133,17 +2315,14 @@ evas_render_updates_internal(Evas *eo_e,
Evas_Object_Protected_Data *obj;
Evas_Public_Data *e;
Eina_List *ll;
- void *surface;
Eina_Bool clean_them = EINA_FALSE;
Eina_Bool alpha;
Eina_Rectangle *r;
- int ux, uy, uw, uh;
- int cx, cy, cw, ch;
- unsigned int i, j;
+ unsigned int i;
int redraw_all = 0;
- Eina_Bool haveup = 0;
- Evas_Render_Mode render_mode = EVAS_RENDER_MODE_UNDEF;
-
+ Evas_Render_Mode render_mode = !do_async ?
+ EVAS_RENDER_MODE_SYNC :
+ EVAS_RENDER_MODE_ASYNC_INIT;
Eina_Rectangle clip_rect;
MAGIC_CHECK(eo_e, Evas, MAGIC_EVAS);
@@ -2201,6 +2380,7 @@ evas_render_updates_internal(Evas *eo_e,
&e->restack_objects,
&e->delete_objects,
&e->render_objects,
+ &e->snapshot_objects,
&redraw_all);
eina_evlog("-render_phase1", eo_e, 0.0, NULL);
}
@@ -2334,6 +2514,25 @@ evas_render_updates_internal(Evas *eo_e,
e->engine.func->output_redraws_rect_add(e->engine.data.output, 0, 0,
e->output.w, e->output.h);
}
+
+ // Add redraw for all snapshot object due to potential use of pixels outside
+ // of the update area by filters.
+ // The side effect is that it also fix rendering of partial update of filter...
+ // As they are never partially updated anymore !
+
+ // FIXME: don't add redraw rect for snapshot with no filter applied on
+ // Also damage the filter object that use a snapshot.
+ for (i = 0; i < e->snapshot_objects.count; i++)
+ {
+ obj = (Evas_Object_Protected_Data *)eina_array_data_get(&e->snapshot_objects, i);
+
+ if (evas_object_is_visible(obj->object, obj))
+ e->engine.func->output_redraws_rect_add(e->engine.data.output,
+ obj->cur->geometry.x,
+ obj->cur->geometry.y,
+ obj->cur->geometry.w,
+ obj->cur->geometry.h);
+ }
eina_evlog("-render_phase4", eo_e, 0.0, NULL);
/* phase 5. add obscures */
@@ -2370,9 +2569,15 @@ evas_render_updates_internal(Evas *eo_e,
eina_evlog("+render_phase6", eo_e, 0.0, NULL);
if (do_draw)
{
+ Render_Updates *ru;
+ void *surface;
+ int ux, uy, uw, uh;
+ int cx, cy, cw, ch;
unsigned int offset = 0;
int fx = e->framespace.x;
int fy = e->framespace.y;
+ int j;
+ Eina_Bool haveup = EINA_FALSE;
if (do_async) _evas_render_busy_begin();
eina_evlog("+render_surface", eo_e, 0.0, NULL);
@@ -2382,11 +2587,54 @@ evas_render_updates_internal(Evas *eo_e,
&ux, &uy, &uw, &uh,
&cx, &cy, &cw, &ch)))
{
- int off_x, off_y;
- Render_Updates *ru;
+ haveup = EINA_TRUE;
+
+ /* phase 6.1 render every snapshot that needs to be updated
+ for this part of the screen */
+ for (j = e->snapshot_objects.count - 1; j >= 0; j--)
+ {
+ Eina_Rectangle output, cr, ur;
+
+ obj = (Evas_Object_Protected_Data *)eina_array_data_get(&e->snapshot_objects, j);
+
+ EINA_RECTANGLE_SET(&output,
+ obj->cur->geometry.x,
+ obj->cur->geometry.y,
+ obj->cur->geometry.w,
+ obj->cur->geometry.h);
+ EINA_RECTANGLE_SET(&ur, ux, uy, uw, uh);
+
+ if (eina_rectangle_intersection(&ur, &output))
+ {
+ void *ctx;
+ void *pseudo_canvas;
+ unsigned int restore_offset = offset;
+
+ EINA_RECTANGLE_SET(&cr,
+ ur.x - output.x, ur.y - output.y,
+ ur.w, ur.h);
+
+ pseudo_canvas = _evas_object_image_surface_get(obj->object, obj);
+
+ ctx = e->engine.func->context_new(e->engine.data.output);
+ clean_them |= evas_render_updates_internal_loop(eo_e, e, pseudo_canvas, ctx,
+ obj,
+ ur.x, ur.y, ur.w, ur.h,
+ cr.x, cr.y, cr.w, cr.h,
+ fx, fy, alpha,
+ do_async,
+ &offset);
+ e->engine.func->context_free(e->engine.data.output, ctx);
+
+ // Force the object has changed for filter to take it into
+ // account. It won't be in the pending object array.
+ obj->changed = EINA_TRUE;
+
+ offset = restore_offset;
+ }
+ }
- eina_evlog("+render_setup", eo_e, 0.0, NULL);
- RD(0, " [--- UPDATE %i %i %ix%i\n", ux, uy, uw, uh);
+ /* phase 6.2 render all the object on the target surface */
if (do_async)
{
ru = malloc(sizeof(*ru));
@@ -2401,154 +2649,17 @@ evas_render_updates_internal(Evas *eo_e,
NEW_RECT(rect, ux, uy, uw, uh);
if (rect)
- e->render.updates = eina_list_append(e->render.updates,
- rect);
- }
- haveup = EINA_TRUE;
- off_x = cx - ux;
- off_y = cy - uy;
- /* build obscuring objects list (in order from bottom to top) */
- if (alpha)
- {
- e->engine.func->context_clip_set(e->engine.data.output,
- e->engine.data.context,
- ux + off_x, uy + off_y, uw, uh);
- }
- for (i = 0; i < e->obscuring_objects.count; ++i)
- {
- obj = (Evas_Object_Protected_Data *)eina_array_data_get
- (&e->obscuring_objects, i);
- if (evas_object_is_in_output_rect(obj->object, obj, ux - fx, uy - fy, uw, uh))
- {
- OBJ_ARRAY_PUSH(&e->temporary_objects, obj);
-
- /* reset the background of the area if needed (using cutout and engine alpha flag to help) */
- if (alpha)
- _evas_render_cutout_add(e, obj, off_x + fx, off_y + fy);
- }
+ e->render.updates = eina_list_append(e->render.updates,
+ rect);
}
- if (alpha)
- {
- e->engine.func->context_color_set(e->engine.data.output,
- e->engine.data.context,
- 0, 0, 0, 0);
- e->engine.func->context_multiplier_unset
- (e->engine.data.output, e->engine.data.context);
- e->engine.func->context_render_op_set(e->engine.data.output,
- e->engine.data.context,
- EVAS_RENDER_COPY);
- e->engine.func->rectangle_draw(e->engine.data.output,
- e->engine.data.context,
- surface,
- cx, cy, cw, ch, do_async);
- e->engine.func->context_cutout_clear(e->engine.data.output,
- e->engine.data.context);
- e->engine.func->context_clip_unset(e->engine.data.output,
- e->engine.data.context);
- }
- eina_evlog("-render_setup", eo_e, 0.0, NULL);
-
- eina_evlog("+render_objects", eo_e, 0.0, NULL);
- /* render all object that intersect with rect */
- for (i = 0; i < e->active_objects.count; ++i)
- {
- obj = eina_array_data_get(&e->active_objects, i);
- eo_obj = obj->object;
-
- /* if it's in our outpout rect and it doesn't clip anything */
- RD(0, " OBJ: [%p", obj);
- IFRD(obj->name, 0, " '%s'", obj->name);
- RD(0, "] '%s' %i %i %ix%i\n", obj->type, obj->cur->geometry.x, obj->cur->geometry.y, obj->cur->geometry.w, obj->cur->geometry.h);
- if ((evas_object_is_in_output_rect(eo_obj, obj, ux - fx, uy - fy, uw, uh) ||
- (obj->is_smart)) &&
- (!obj->clip.clipees) &&
- (obj->cur->visible) &&
- (!obj->delete_me) &&
- (obj->cur->cache.clip.visible) &&
-// (!obj->is_smart) &&
- ((obj->cur->color.a > 0 || obj->cur->render_op != EVAS_RENDER_BLEND)))
- {
- int x, y, w, h;
-
- RD(0, " DRAW (vis: %i, a: %i, clipees: %p)\n", obj->cur->visible, obj->cur->color.a, obj->clip.clipees);
- if ((e->temporary_objects.count > offset) &&
- (eina_array_data_get(&e->temporary_objects, offset) == obj))
- offset++;
- x = cx; y = cy; w = cw; h = ch;
- if (((w > 0) && (h > 0)) || (obj->is_smart))
- {
- Evas_Object_Protected_Data *prev_mask = NULL;
- Evas_Object_Protected_Data *mask = NULL;
-
- if (!obj->is_smart)
- {
- RECTS_CLIP_TO_RECT(x, y, w, h,
- obj->cur->cache.clip.x + off_x + fx,
- obj->cur->cache.clip.y + off_y + fy,
- obj->cur->cache.clip.w,
- obj->cur->cache.clip.h);
- }
-
- e->engine.func->context_clip_set(e->engine.data.output,
- e->engine.data.context,
- x, y, w, h);
-
- /* Clipper masks */
- if (_evas_render_object_is_mask(obj->cur->clipper))
- mask = obj->cur->clipper; // main object clipped by this mask
- else if (obj->clip.mask)
- mask = obj->clip.mask; // propagated clip
- prev_mask = obj->clip.prev_mask;
-
- if (mask)
- {
- if (mask->mask->redraw || !mask->mask->surface)
- evas_render_mask_subrender(obj->layer->evas, mask, prev_mask, 4);
-
- if (mask->mask->surface)
- {
- e->engine.func->context_clip_image_set
- (e->engine.data.output,
- e->engine.data.context,
- mask->mask->surface,
- mask->cur->geometry.x + off_x,
- mask->cur->geometry.y + off_y,
- e, do_async);
- }
- }
-
-#if 1 /* FIXME: this can slow things down... figure out optimum... coverage */
- for (j = offset; j < e->temporary_objects.count; ++j)
- {
- Evas_Object_Protected_Data *obj2;
- obj2 = (Evas_Object_Protected_Data *)eina_array_data_get
- (&e->temporary_objects, j);
- _evas_render_cutout_add(e, obj2, off_x + fx, off_y + fy);
- }
-#endif
- clean_them |= evas_render_mapped(e, eo_obj, obj, e->engine.data.context,
- surface, off_x + fx,
- off_y + fy, 0,
+ clean_them |= evas_render_updates_internal_loop(eo_e, e, surface, e->engine.data.context,
+ NULL,
+ ux, uy, uw, uh,
cx, cy, cw, ch,
- NULL, 4,
- EINA_FALSE,
- do_async);
- e->engine.func->context_cutout_clear(e->engine.data.output,
- e->engine.data.context);
-
- if (mask)
- {
- e->engine.func->context_clip_image_unset
- (e->engine.data.output, e->engine.data.context);
- }
- }
- }
- }
- eina_evlog("-render_objects", eo_e, 0.0, NULL);
-
- if (!do_async) render_mode = EVAS_RENDER_MODE_SYNC;
- else render_mode = EVAS_RENDER_MODE_ASYNC_INIT;
+ fx, fy, alpha,
+ do_async,
+ &offset);
eina_evlog("+render_push", eo_e, 0.0, NULL);
e->engine.func->output_redraws_next_update_push(e->engine.data.output,
@@ -2556,10 +2667,6 @@ evas_render_updates_internal(Evas *eo_e,
ux, uy, uw, uh,
render_mode);
eina_evlog("-render_push", eo_e, 0.0, NULL);
-
- /* free obscuring objects list */
- OBJS_ARRAY_CLEAN(&e->temporary_objects);
- RD(0, " ---]\n");
}
eina_evlog("+render_output_flush", eo_e, 0.0, NULL);
@@ -2697,6 +2804,7 @@ evas_render_updates_internal(Evas *eo_e,
OBJS_ARRAY_CLEAN(&e->render_objects);
OBJS_ARRAY_CLEAN(&e->restack_objects);
OBJS_ARRAY_CLEAN(&e->temporary_objects);
+ OBJS_ARRAY_CLEAN(&e->snapshot_objects);
eina_array_foreach(&e->clip_changes, _evas_clip_changes_free, NULL);
eina_array_clean(&e->clip_changes);
/* we should flush here and have a mempool system for this
@@ -3103,6 +3211,8 @@ evas_render_invalidate(Evas *eo_e)
OBJS_ARRAY_FLUSH(&e->restack_objects);
OBJS_ARRAY_FLUSH(&e->delete_objects);
+ OBJS_ARRAY_FLUSH(&e->snapshot_objects);
+
e->invalidate = EINA_TRUE;
}
diff --git a/src/lib/evas/include/evas_inline.x b/src/lib/evas/include/evas_inline.x
index 4614737911..29cc7d9744 100644
--- a/src/lib/evas/include/evas_inline.x
+++ b/src/lib/evas/include/evas_inline.x
@@ -74,6 +74,9 @@ evas_object_is_opaque(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
if ((obj->cur->clipper && obj->cur->clipper->mask->is_mask) ||
(obj->clip.mask))
return 0;
+ /* Non masked snapshot are supposed to be opaque */
+ if (obj->cur->snapshot)
+ return 1;
if (obj->func->is_opaque)
return obj->func->is_opaque(eo_obj, obj, obj->private_data);
return 1;
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 01b43401a5..f4e019ee7a 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -808,6 +808,7 @@ struct _Evas_Public_Data
Eina_Array pending_objects;
Eina_Array obscuring_objects;
Eina_Array temporary_objects;
+ Eina_Array snapshot_objects;
Eina_Array clip_changes;
Eina_Array scie_unref_queue;
Eina_Array image_unref_queue;
@@ -1004,6 +1005,7 @@ struct _Evas_Object_Protected_State
Eina_Bool cached_surface : 1;
Eina_Bool parent_cached_surface : 1;
+ Eina_Bool snapshot : 1;
};
struct _Evas_Object_Protected_Data
@@ -1878,6 +1880,8 @@ void _evas_device_unref(Evas_Device *dev);
Eina_Bool evas_vg_loader_svg(Evas_Object *vg, const Eina_File *f, const char *key EINA_UNUSED);
+void *_evas_object_image_surface_get(Evas_Object *eo, Evas_Object_Protected_Data *obj);
+
extern Eina_Cow *evas_object_proxy_cow;
extern Eina_Cow *evas_object_map_cow;
extern Eina_Cow *evas_object_state_cow;