summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2015-05-09 20:02:13 +0200
committerCedric BAIL <cedric@osg.samsung.com>2015-08-05 15:12:33 +0200
commit033658d1caf0624fac71d482be5c8f14622b09b7 (patch)
tree3df916048def3d0b82ce07890daec126e54ec884
parent8b31b7c33a8f7e35e95e9e8b01eb0fc826787fa9 (diff)
downloadefl-033658d1caf0624fac71d482be5c8f14622b09b7.tar.gz
evas: implementation of snapshot feature.
This should theorically work, need some test. Design is easy to understand. Render every part of a snapshot object by rendering the content below it, before rendering the stack above it using that object content.
-rw-r--r--src/lib/evas/canvas/evas_main.c4
-rw-r--r--src/lib/evas/canvas/evas_object_image.c41
-rw-r--r--src/lib/evas/canvas/evas_object_main.c2
-rw-r--r--src/lib/evas/canvas/evas_render.c81
-rw-r--r--src/lib/evas/include/evas_inline.x3
-rw-r--r--src/lib/evas/include/evas_private.h2
6 files changed, 118 insertions, 15 deletions
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 32191fdabf..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;
@@ -4758,6 +4769,34 @@ _evas_image_snapshot_get(Eo *eo, Evas_Image_Data *pd EINA_UNUSED)
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)
{
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 c308cb0b8f..f178ff56f9 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;
@@ -2124,13 +2133,13 @@ _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,
+ 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 make_updates,
Eina_Bool do_async,
- Evas_Render_Mode render_mode,
unsigned int *offset)
{
Evas_Object *eo_obj;
@@ -2210,6 +2219,8 @@ evas_render_updates_internal_loop(Evas *eo_e, Evas_Public_Data *e,
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);
@@ -2279,6 +2290,9 @@ evas_render_updates_internal_loop(Evas *eo_e, Evas_Public_Data *e,
obj2 = (Evas_Object_Protected_Data *)eina_array_data_get
(&e->temporary_objects, j);
+
+ if (obj2 == top) break;
+
_evas_render_cutout_add(e, obj2, off_x + fx, off_y + fy);
}
#endif
@@ -2302,14 +2316,6 @@ evas_render_updates_internal_loop(Evas *eo_e, Evas_Public_Data *e,
}
eina_evlog("-render_objects", eo_e, 0.0, NULL);
-
- eina_evlog("+render_push", eo_e, 0.0, NULL);
- e->engine.func->output_redraws_next_update_push(e->engine.data.output,
- surface,
- 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");
@@ -2394,6 +2400,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);
}
@@ -2569,6 +2576,7 @@ evas_render_updates_internal(Evas *eo_e,
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();
@@ -2581,13 +2589,59 @@ evas_render_updates_internal(Evas *eo_e,
{
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 *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);
+
+ clean_them |= evas_render_updates_internal_loop(eo_e, e, pseudo_canvas,
+ obj,
+ ur.x, ur.y, ur.w, ur.h,
+ cr.x, cr.y, cr.w, cr.h,
+ fx, fy, alpha,
+ make_updates, do_async,
+ &offset);
+
+ offset = restore_offset;
+ }
+ }
+
+ /* phase 6.2 render all the object on the target surface */
clean_them |= evas_render_updates_internal_loop(eo_e, e, surface,
+ NULL,
ux, uy, uw, uh,
cx, cy, cw, ch,
fx, fy, alpha,
make_updates, do_async,
- render_mode,
&offset);
+
+ eina_evlog("+render_push", eo_e, 0.0, NULL);
+ e->engine.func->output_redraws_next_update_push(e->engine.data.output,
+ surface,
+ ux, uy, uw, uh,
+ render_mode);
+ eina_evlog("-render_push", eo_e, 0.0, NULL);
}
eina_evlog("+render_output_flush", eo_e, 0.0, NULL);
@@ -2725,6 +2779,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
@@ -3131,6 +3186,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 fe838d0f14..f4e019ee7a 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1880,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;