jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=68beccd1a957724aa03f788a96128ac25cef85be
commit 68beccd1a957724aa03f788a96128ac25cef85be Author: Jean-Philippe Andre <jp.an...@samsung.com> Date: Mon Mar 14 19:10:54 2016 +0900 Evas.Image: Add new classes Snapshot and Proxy Efl.Canvas.Snapshot and Efl.Canvas.Proxy are specialized classes previously implemented as features of Evas.Image. Note: this half of the work, as I suffered from a bad merge and rebase with my work branch on top of master. --- src/Makefile_Evas.am | 6 +- src/lib/evas/Evas_Eo.h | 3 + src/lib/evas/canvas/efl_canvas_proxy.c | 117 +++++++++++++++++++++++ src/lib/evas/canvas/efl_canvas_proxy.eo | 77 +++++++++++++++ src/lib/evas/canvas/efl_canvas_snapshot.c | 25 +++++ src/lib/evas/canvas/efl_canvas_snapshot.eo | 14 +++ src/lib/evas/canvas/evas_image_private.h | 145 +++++++++++++++++++++++++++++ 7 files changed, 386 insertions(+), 1 deletion(-) diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index e4fd440..e6aa6cf 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -41,6 +41,8 @@ evas_eolian_pub_files = \ lib/evas/canvas/efl_vg_gradient.eo \ lib/evas/canvas/efl_vg_gradient_radial.eo \ lib/evas/canvas/efl_vg_gradient_linear.eo \ + lib/evas/canvas/efl_canvas_snapshot.eo \ + lib/evas/canvas/efl_canvas_proxy.eo \ lib/evas/canvas/evas_filter.eo \ $(NULL) @@ -172,7 +174,9 @@ lib/evas/canvas/evas_stats.c \ lib/evas/canvas/evas_touch_point.c \ lib/evas/canvas/evas_map.c \ lib/evas/canvas/evas_gl.c \ -lib/evas/canvas/evas_out.c +lib/evas/canvas/evas_out.c \ +lib/evas/canvas/efl_canvas_proxy.c \ +lib/evas/canvas/efl_canvas_snapshot.c EXTRA_DIST += \ lib/evas/canvas/render2/evas_render2_th_main.c \ diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h index 29d1a95..d23d654 100644 --- a/src/lib/evas/Evas_Eo.h +++ b/src/lib/evas/Evas_Eo.h @@ -342,6 +342,9 @@ typedef void (Evas_Canvas3D_Surface_Func)(Evas_Real *out_x, #include "canvas/evas_image.eo.h" +#include "canvas/efl_canvas_snapshot.eo.h" +#include "canvas/efl_canvas_proxy.eo.h" + /** * @ingroup Evas_Object_VG * diff --git a/src/lib/evas/canvas/efl_canvas_proxy.c b/src/lib/evas/canvas/efl_canvas_proxy.c new file mode 100644 index 0000000..5c8ac4b --- /dev/null +++ b/src/lib/evas/canvas/efl_canvas_proxy.c @@ -0,0 +1,117 @@ +#include "evas_image_private.h" +#include "efl_canvas_proxy.eo.h" + +#define MY_CLASS EFL_CANVAS_PROXY_CLASS + +EOLIAN static Eina_Bool +_efl_canvas_proxy_source_set(Eo *eo_obj, void *pd EINA_UNUSED, Evas_Object *eo_src) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS); + + if (obj->delete_me && eo_src) + { + WRN("Setting deleted object %p as image source %p", eo_src, eo_obj); + return EINA_FALSE; + } + if (eo_src) + { + Evas_Object_Protected_Data *src = eo_data_scope_get(eo_src, EVAS_OBJECT_CLASS); + if (src->delete_me) + { + WRN("Setting object %p to deleted image source %p", eo_src, eo_obj); + return EINA_FALSE; + } + if (!src->layer) + { + CRI("No evas surface associated with source object (%p)", eo_src); + return EINA_FALSE; + } + if (!obj->layer) + { + CRI("No evas surface associated with destination object (%p)", eo_obj); + return EINA_FALSE; + } + if ((obj->layer && src->layer) && + (obj->layer->evas != src->layer->evas)) + { + CRI("Setting object %p from Evas (%p) from another Evas (%p)", eo_src, src->layer->evas, obj->layer->evas); + return EINA_FALSE; + } + if (eo_src == eo_obj) + { + CRI("Setting object %p as a source for itself", obj); + return EINA_FALSE; + } + } + if (o->cur->source == eo_src) return EINA_TRUE; + evas_object_async_block(obj); + _evas_object_image_cleanup(eo_obj, obj, o); + /* Kill the image if any */ + if (o->cur->u.file || o->cur->key) + evas_object_image_file_set(eo_obj, NULL, NULL); + + if (eo_src) _proxy_set(eo_obj, eo_src); + else _proxy_unset(eo_obj, obj, o); + + return EINA_TRUE; +} + +EOLIAN static Evas_Object * +_efl_canvas_proxy_source_get(Eo *eo_obj EINA_UNUSED, void *pd EINA_UNUSED) +{ + Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS); + return o->cur->source; +} + +EOLIAN static void +_efl_canvas_proxy_source_clip_set(Eo *eo_obj EINA_UNUSED, void *pd EINA_UNUSED, Eina_Bool source_clip) +{ + Evas_Object_Protected_Data *src_obj; + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS); + + source_clip = !!source_clip; + if (o->proxy_src_clip == source_clip) return; + evas_object_async_block(obj); + o->proxy_src_clip = source_clip; + + if (!o->cur->source) return; + + src_obj = eo_data_scope_get(o->cur->source, EVAS_OBJECT_CLASS); + evas_object_change(o->cur->source, src_obj); +} + +EOLIAN static Eina_Bool +_efl_canvas_proxy_source_clip_get(Eo *eo_obj EINA_UNUSED, void *pd EINA_UNUSED) +{ + Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS); + return o->proxy_src_clip; +} + +EOLIAN static void +_efl_canvas_proxy_source_events_set(Eo *eo_obj EINA_UNUSED, void *pd EINA_UNUSED, Eina_Bool source_events) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS); + + source_events = !!source_events; + if (obj->proxy->src_events == source_events) return; + + EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, Evas_Object_Proxy_Data, proxy_write) + proxy_write->src_events = source_events; + EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write); + + if (!o->cur->source) return; + if ((obj->proxy->src_invisible) || (!source_events)) return; + //FIXME: Feed mouse events here. +} + +EOLIAN static Eina_Bool +_efl_canvas_proxy_source_events_get(Eo *eo_obj, void *pd EINA_UNUSED) +{ + Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + return obj->proxy->src_events; +} + +#include "efl_canvas_proxy.eo.c" diff --git a/src/lib/evas/canvas/efl_canvas_proxy.eo b/src/lib/evas/canvas/efl_canvas_proxy.eo new file mode 100644 index 0000000..6c061c7 --- /dev/null +++ b/src/lib/evas/canvas/efl_canvas_proxy.eo @@ -0,0 +1,77 @@ +class Efl.Canvas.Proxy (Evas.Image, Efl.Gfx.Base, Efl.Image, Efl.Gfx.Buffer, Efl.Gfx.Fill, Efl.Gfx.View, Efl.Gfx.Filter) +{ + [[Low-level proxy image object. + + A proxy is a special kind of image containing the pixels from a source + object attached to it. It can be used to apply some sort of image + transformation to any object (eg. filters, map or zoom). + ]] + legacy_prefix: null; + data: null; + methods { + @property source { + [[The source object for this proxy. + + The proxy object will mirror the rendering contents of a given + source object in its drawing region, without affecting that + source in any way. The source must be another valid @Evas.Object. + Other effects may be applied to the proxy, such as a map (see + @Evas.Object.map) to create a reflection of the original object + (for example). + + Any existing source object will be removed after this call. + + Note: This property should be set as soon as creating a proxy + object, otherwise the proxy will do nothing. + + Warning: You cannot set a proxy as another proxy's source. + ]] + set { + return: bool; [[Returns $true in case of success.]] + } + get {} + values { + src: Evas.Object * @nonull; [[Source object to use for the proxy.]] + } + } + @property source_clip { + [[Clip this proxy object with the source object's clipper. + + Use this if you want to overlay an existing object with its proxy, + and apply some sort of transformation on it. + + $true means both objects will share the same clip. + + @since 1.8 + ]] + set {} + get {} + values { + source_clip: bool; [[Whether $obj is clipped by the source + clipper ($true) or not ($false).]] + } + } + @property source_events { + [[Defines whether the events on this object are repeated to the source. + + If $source is $true, it will make events on $obj to also be + repeated for the source object (see @.source.set). Even the + $obj and source geometries are different, the event position + will be transformed to the source object's space. + + If $source is $false, events occurring on $obj will be + processed only on it. + + @since 1.8 + ]] + set {} + get {} + values { + source: bool; [[Whether this object should pass events ($true) or not + ($false) to its source.]] + } + } + } + implements { + } +} diff --git a/src/lib/evas/canvas/efl_canvas_snapshot.c b/src/lib/evas/canvas/efl_canvas_snapshot.c new file mode 100644 index 0000000..bd97c04 --- /dev/null +++ b/src/lib/evas/canvas/efl_canvas_snapshot.c @@ -0,0 +1,25 @@ +#include "evas_image_private.h" +#include "efl_canvas_snapshot.eo.h" + +#define MY_CLASS EFL_CANVAS_SNAPSHOT_CLASS + +EOLIAN static Eo * +_efl_canvas_snapshot_eo_base_constructor(Eo *eo_obj, void *pd EINA_UNUSED) +{ + Evas_Object_Protected_Data *obj; + + eo_obj = eo_constructor(eo_super(eo_obj, MY_CLASS)); + if (!eo_obj) return NULL; + + efl_gfx_fill_filled_set(eo_obj, EINA_TRUE); + evas_obj_pass_events_set(eo_obj, EINA_TRUE); + + obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS); + EINA_COW_STATE_WRITE_BEGIN(obj, sw, cur) + sw->snapshot = EINA_TRUE; + EINA_COW_STATE_WRITE_END(obj, sw, cur); + + return eo_obj; +} + +#include "efl_canvas_snapshot.eo.c" diff --git a/src/lib/evas/canvas/efl_canvas_snapshot.eo b/src/lib/evas/canvas/efl_canvas_snapshot.eo new file mode 100644 index 0000000..527583e --- /dev/null +++ b/src/lib/evas/canvas/efl_canvas_snapshot.eo @@ -0,0 +1,14 @@ +class Efl.Canvas.Snapshot (Evas.Image, Efl.Gfx.Base, Efl.Image, Efl.Gfx.Buffer, Efl.Gfx.Fill, Efl.Gfx.View, Efl.Gfx.Filter) +{ + [[Low-level snapshot image object. + + A snapshot is a special kind of image containing the pixels from + all the objects below it. This allows applications to save screenshots + of all or part of their UI, or apply filters to parts of the UI. + ]] + legacy_prefix: null; + data: null; + implements { + Eo.Base.constructor; + } +} diff --git a/src/lib/evas/canvas/evas_image_private.h b/src/lib/evas/canvas/evas_image_private.h new file mode 100644 index 0000000..dfbfc09 --- /dev/null +++ b/src/lib/evas/canvas/evas_image_private.h @@ -0,0 +1,145 @@ +#ifndef EVAS_IMAGE_PRIVATE_H +#define EVAS_IMAGE_PRIVATE_H + +/* Those functions are shared between legacy evas_object_image.c and the + * new efl_canvas classes (image, snapshot, proxy, ...) + */ + +#define EVAS_FILTER_PROTECTED +#define EVAS_OBJECT_PROTECTED + +#include "evas_common_private.h" + +#include <sys/types.h> +#include <unistd.h> +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +#endif +#include <math.h> + +#include "evas_private.h" +#ifdef EVAS_CSERVE2 +#include "../cserve2/evas_cs2_private.h" +#endif +#include "../common/evas_convert_color.h" +#include "../common/evas_convert_colorspace.h" +#include "../common/evas_convert_yuv.h" + +#include "evas_filter.eo.h" +#include "evas_filter.h" + +/* private struct for rectangle object internal data */ +typedef struct _Evas_Image_Data Evas_Image_Data; +typedef struct _Evas_Object_Image_Load_Opts Evas_Object_Image_Load_Opts; +typedef struct _Evas_Object_Image_Pixels Evas_Object_Image_Pixels; +typedef struct _Evas_Object_Image_State Evas_Object_Image_State; + +struct _Evas_Object_Image_Load_Opts +{ + unsigned char scale_down_by; + double dpi; + short w, h; + struct { + short x, y, w, h; + } region; + struct { + int src_x, src_y, src_w, src_h; + int dst_w, dst_h; + int smooth; + int scale_hint; + } scale_load; + Eina_Bool orientation : 1; +}; + +struct _Evas_Object_Image_Pixels +{ + Eina_List *pixel_updates; + struct { + /* FIXME: no good match for eo */ + Evas_Object_Image_Pixels_Get_Cb get_pixels; + void *get_pixels_data; + } func; + + Evas_Video_Surface video; + unsigned int video_caps; +}; + +struct _Evas_Object_Image_State +{ + Evas_Coord_Rectangle fill; + struct { + short w, h, stride; + } image; + struct { + double scale; + short l, r, t, b; + unsigned char fill; + } border; + + Evas_Object *source; + Evas_Map *defmap; + Evas_Canvas3D_Scene *scene; + + union { + const char *file; + Eina_File *f; + } u; + const char *key; + int frame; + + Evas_Colorspace cspace; + Evas_Image_Orient orient; + + Eina_Bool smooth_scale : 1; + Eina_Bool has_alpha :1; + Eina_Bool opaque_valid : 1; + Eina_Bool opaque : 1; + Eina_Bool mmaped_source : 1; +}; + +struct _Evas_Image_Data +{ + const Evas_Object_Image_State *cur; + const Evas_Object_Image_State *prev; + const Evas_Object_Image_Load_Opts *load_opts; + const Evas_Object_Image_Pixels *pixels; + + void *engine_data; + + int pixels_checked_out; + int load_error; + + Evas_Image_Scale_Hint scale_hint; + Evas_Image_Content_Hint content_hint; + + Eina_Bool changed : 1; + Eina_Bool dirty_pixels : 1; + Eina_Bool filled : 1; + Eina_Bool filled_set : 1; + Eina_Bool proxyrendering : 1; + Eina_Bool preloading : 1; + Eina_Bool video_surface : 1; + Eina_Bool video_visible : 1; + Eina_Bool created : 1; + Eina_Bool proxyerror : 1; + Eina_Bool proxy_src_clip : 1; + Eina_Bool written : 1; + Eina_Bool direct_render : 1; + Eina_Bool has_filter : 1; + struct + { + Eina_Bool video_move : 1; + Eina_Bool video_resize : 1; + Eina_Bool video_show : 1; + Eina_Bool video_hide : 1; + } delayed; + Eina_Bool legacy_type : 1; +}; + +/* shared functions between legacy and new eo classes */ +void _evas_object_image_cleanup(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Image_Data *o); +void _proxy_unset(Evas_Object *proxy, Evas_Object_Protected_Data *obj, Evas_Image_Data *o); +void _proxy_set(Evas_Object *proxy, Evas_Object *src); +void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y, Eina_Bool do_async); + +#endif // EVAS_IMAGE_PRIVATE_H --