From 7a8879ba8bf5d9aec15428f94222222eea6c0e2e Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 8 Dec 2015 17:29:54 +0900 Subject: [PATCH] ector: add engine-specific evas image buffer wrapper Since Evas still relies entirely on Image_Entry and Evas_GL_Image, we will need an engine-specific wrapper object creating a Buffer around an existing cached image. Currently only SW support is implemented. GL will be more fun to do (with glReadPixels and whatnot). --- src/Makefile_Evas.am | 18 +++- src/lib/ector/ector_buffer.h | 5 +- src/lib/ector/ector_surface.h | 2 +- .../ector/software/ector_software_buffer.c | 10 +- src/lib/evas/include/evas_ector_buffer.eo | 16 +++ src/lib/evas/include/evas_private.h | 1 + .../evas/engines/gl_generic/evas_engine.c | 15 +++ .../evas_ector_software_buffer.c | 97 +++++++++++++++++++ .../evas_ector_software_buffer.eo | 12 +++ .../engines/software_generic/evas_engine.c | 17 ++++ 10 files changed, 188 insertions(+), 5 deletions(-) create mode 100644 src/lib/evas/include/evas_ector_buffer.eo create mode 100644 src/modules/evas/engines/software_generic/evas_ector_software_buffer.c create mode 100644 src/modules/evas/engines/software_generic/evas_ector_software_buffer.eo diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index be24ba5b6a..2c58f88997 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -42,6 +42,7 @@ evas_eolian_files = \ lib/evas/canvas/efl_vg_gradient_radial.eo \ lib/evas/canvas/efl_vg_gradient_linear.eo \ lib/evas/canvas/evas_filter.eo \ + lib/evas/include/evas_ector_buffer.eo \ $(NULL) evas_eolian_type_files = \ @@ -356,6 +357,7 @@ lib_evas_libevas_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ -I$(top_srcdir)/src/static_libs/libunibreak \ -I$(top_srcdir)/src/static_libs/draw \ -I$(top_builddir)/src/lib/evas/canvas \ +-I$(top_builddir)/src/lib/evas/include \ -I$(top_builddir)/src/modules/evas/engines/software_generic \ -I$(top_builddir)/src/modules/evas/engines/gl_generic \ -DPACKAGE_BIN_DIR=\"$(bindir)\" \ @@ -562,11 +564,25 @@ lib/evas/filters/blur/blur_box_rgba_i386.c \ lib/evas/filters/blur/blur_box_rgba_sse3.c \ lib/evas/filters/blur/blur_box_rgba_neon.c + +### Engine Ector stuff + +EXTRA_DIST += \ +modules/evas/engines/software_generic/evas_ector_software_buffer.eo + + ### Engines if EVAS_STATIC_BUILD_SOFTWARE_GENERIC -lib_evas_libevas_la_SOURCES += modules/evas/engines/software_generic/evas_engine.c modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h +BUILT_SOURCES += \ + modules/evas/engines/software_generic/evas_ector_software_buffer.eo.c \ + modules/evas/engines/software_generic/evas_ector_software_buffer.eo.h +lib_evas_libevas_la_SOURCES += \ + modules/evas/engines/software_generic/evas_engine.c \ + modules/evas/engines/software_generic/Evas_Engine_Software_Generic.h \ + modules/evas/engines/software_generic/evas_ector_software_buffer.c lib_evas_libevas_la_LIBADD += +lib_evas_libevas_la_CPPFLAGS += -I$(top_srcdir)/src/lib/ector else enginesoftwaregenericpkgdir = $(libdir)/evas/modules/engines/software_generic/$(MODULE_ARCH) enginesoftwaregenericpkg_LTLIBRARIES = modules/evas/engines/software_generic/module.la diff --git a/src/lib/ector/ector_buffer.h b/src/lib/ector/ector_buffer.h index 1047482679..afa6f288c5 100644 --- a/src/lib/ector/ector_buffer.h +++ b/src/lib/ector/ector_buffer.h @@ -18,6 +18,7 @@ typedef struct _Ector_Generic_Buffer_Data unsigned int w, h; unsigned char l, r, t, b; Efl_Gfx_Colorspace cspace; + Eina_Bool immutable : 1; // pixels_set is forbidden } Ector_Generic_Buffer_Data; typedef struct _Ector_Software_Buffer_Base_Data @@ -30,9 +31,9 @@ typedef struct _Ector_Software_Buffer_Base_Data unsigned int stride; unsigned int pixel_size; // in bytes unsigned int map_count; - Eina_Bool writable : 1; + Eina_Bool writable : 1; // pixels can be written to Eina_Bool nofree : 1; // pixel data should not be free()'ed - Eina_Bool span_free : 1; + Eina_Bool span_free : 1; // FIXME } Ector_Software_Buffer_Base_Data; #endif diff --git a/src/lib/ector/ector_surface.h b/src/lib/ector/ector_surface.h index 0cc5a32e34..98e4bf0b9c 100644 --- a/src/lib/ector/ector_surface.h +++ b/src/lib/ector/ector_surface.h @@ -1,7 +1,7 @@ #ifndef ECTOR_SURFACE_H #define ECTOR_SURFACE_H -#include "ector_generic_buffer.eo.h" +#include "ector_buffer.h" #include "ector_generic_surface.eo.h" #endif diff --git a/src/lib/ector/software/ector_software_buffer.c b/src/lib/ector/software/ector_software_buffer.c index 89a2cc1995..26c1329cda 100644 --- a/src/lib/ector/software/ector_software_buffer.c +++ b/src/lib/ector/software/ector_software_buffer.c @@ -72,8 +72,16 @@ _ector_software_buffer_base_ector_generic_buffer_pixels_set(Eo *obj, Ector_Softw unsigned char l, unsigned char r, unsigned char t, unsigned char b) { + unsigned px; + + if (pd->generic->immutable) + { + ERR("This buffer is immutable."); + return EINA_FALSE; + } + // safety check - unsigned px = _min_stride_calc(1, cspace); + px = _min_stride_calc(1, cspace); if (px && ((unsigned long long)(uintptr_t)pixels) & (px - 1)) ERR("Pixel data is not aligned to %u bytes!", px); diff --git a/src/lib/evas/include/evas_ector_buffer.eo b/src/lib/evas/include/evas_ector_buffer.eo new file mode 100644 index 0000000000..7dbb5e0842 --- /dev/null +++ b/src/lib/evas/include/evas_ector_buffer.eo @@ -0,0 +1,16 @@ +/* Note: only for internal C API */ + +interface Evas.Ector.Buffer +{ + legacy_prefix: null; + methods { + @property engine_image { + get {} + set { [[This Buffer will hold a reference to the evas image struct.]] } + values { + evas: Evas *; [[The current Evas.]] + image: void *; [[The engine-specific image struct.]] + } + } + } +} diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index b6f8c89d63..854d99d7db 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1450,6 +1450,7 @@ struct _Evas_Func Ector_Surface *(*ector_create) (void *data); void (*ector_destroy) (void *data, Ector_Surface *surface); + Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, void *engine_image); // free it with eo_del void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async); void (*ector_renderer_draw) (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async); void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async); diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index f67ffda148..a052958637 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -2458,6 +2458,20 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector) if (ector) eo_del(ector); } +static Ector_Buffer * +eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image) +{ + Evas_GL_Image *im = engine_image; + Ector_Buffer *buf = NULL; + + if (!im) return NULL; + +#warning FIXME: implement me + (void) e; + + return buf; +} + static Efl_Gfx_Render_Op _evas_render_op_to_ector_rop(Evas_Render_Op op) { @@ -2799,6 +2813,7 @@ module_open(Evas_Module *em) ORD(ector_create); ORD(ector_destroy); + ORD(ector_buffer_new); ORD(ector_begin); ORD(ector_renderer_draw); ORD(ector_end); diff --git a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c new file mode 100644 index 0000000000..3d45862653 --- /dev/null +++ b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.c @@ -0,0 +1,97 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "evas_common_private.h" +#include "evas_private.h" +#include "draw.h" + +#include "evas_ector_buffer.eo.h" +#include "evas_ector_software_buffer.eo.h" + +#define MY_CLASS EVAS_ECTOR_SOFTWARE_BUFFER_CLASS + +typedef struct { + Ector_Software_Buffer_Base_Data *base; + Evas *evas; + Image_Entry *ie; +} Evas_Ector_Software_Buffer_Data; + +#define ENFN e->engine.func +#define ENDT e->engine.data.output + +EOLIAN static void +_evas_ector_software_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ector_Software_Buffer_Data *pd, + Evas *evas, void *image) +{ + Evas_Public_Data *e = eo_data_scope_get(evas, EVAS_CANVAS_CLASS); + Image_Entry *ie = image; + RGBA_Image *im; + Eina_Bool b; + + if (eo_do_ret(obj, b, eo_finalized_get())) + { + CRI("engine_image must be set at construction time only"); + return; + } + + im = (RGBA_Image *) ie; + if (!im->image.data) + { + CRI("image has no pixels yet"); + return; + } + + pd->evas = eo_xref(evas, obj); + pd->ie = ENFN->image_ref(ENDT, ie); + if (!pd->ie) return; + + eo_do(obj, ector_buffer_pixels_set(im->image.data, + im->cache_entry.w, im->cache_entry.h, 0, + _evas_to_gfx_render_op(im->cache_entry.space), + EINA_TRUE, 0, 0, 0, 0)); +} + +EOLIAN static void +_evas_ector_software_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_UNUSED, + Evas_Ector_Software_Buffer_Data *pd, + Evas **evas, void **image) +{ + if (evas) *evas = pd->evas; + if (image) *image = pd->ie; +} + +EOLIAN static Eo * +_evas_ector_software_buffer_eo_base_constructor(Eo *obj, Evas_Ector_Software_Buffer_Data *pd) +{ + eo_do_super(obj, MY_CLASS, obj = eo_constructor()); + pd->base = eo_data_xref(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN, obj); + return obj; +} + +EOLIAN static Eo * +_evas_ector_software_buffer_eo_base_finalize(Eo *obj, Evas_Ector_Software_Buffer_Data *pd) +{ + if (!pd->ie) + { + CRI("engine_image must be set at construction time only"); + return NULL; + } + pd->base->generic->immutable = EINA_TRUE; + return eo_do_super_ret(obj, MY_CLASS, obj, eo_finalize()); +} + +EOLIAN static void +_evas_ector_software_buffer_eo_base_destructor(Eo *obj, Evas_Ector_Software_Buffer_Data *pd) +{ + Evas_Public_Data *e = eo_data_scope_get(pd->evas, EVAS_CANVAS_CLASS); + + eo_data_xunref(obj, pd->base, obj); + ENFN->image_free(ENDT, pd->ie); + eo_xunref(pd->evas, obj); + eo_do_super(obj, MY_CLASS, eo_destructor()); +} + +#include "evas_ector_buffer.eo.c" +#include "evas_ector_software_buffer.eo.c" diff --git a/src/modules/evas/engines/software_generic/evas_ector_software_buffer.eo b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.eo new file mode 100644 index 0000000000..f6a1a200d3 --- /dev/null +++ b/src/modules/evas/engines/software_generic/evas_ector_software_buffer.eo @@ -0,0 +1,12 @@ +class Evas.Ector.Software.Buffer (Ector.Software.Buffer, Evas.Ector.Buffer) +{ + [[A buffer object wrapping an existing Evas Image_Entry.]] + legacy_prefix: null; + implements { + Eo.Base.constructor; + Eo.Base.finalize; + Eo.Base.destructor; + Evas.Ector.Buffer.engine_image.set; + Evas.Ector.Buffer.engine_image.get; + } +} diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index b71399f04f..22967ad14d 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -9,6 +9,8 @@ #include #include "cairo/Ector_Cairo.h" +#include "evas_ector_buffer.eo.h" +#include "evas_ector_software_buffer.eo.h" #if defined HAVE_DLSYM && ! defined _WIN32 # include /* dlopen,dlclose,etc */ @@ -3755,6 +3757,20 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector) if (ector) eo_del(ector); } +static Ector_Buffer * +eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image) +{ + Image_Entry *ie = engine_image; + Ector_Buffer *buf = NULL; + + if (!ie) return NULL; + + buf = eo_add(EVAS_ECTOR_SOFTWARE_BUFFER_CLASS, e, + evas_ector_buffer_engine_image_set(e, ie)); + + return buf; +} + static Efl_Gfx_Render_Op _evas_render_op_to_ector_rop(Evas_Render_Op op) { @@ -4166,6 +4182,7 @@ static Evas_Func func = NULL, // eng_texture_image_get eng_ector_create, eng_ector_destroy, + eng_ector_buffer_new, eng_ector_begin, eng_ector_renderer_draw, eng_ector_end,