From 66961126916f6ab61ba6549f7ad96399bdf773af Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Mon, 4 Jan 2016 17:48:48 +0900 Subject: [PATCH] Evas filters: Add GL buffer backed by RGBA_Image Dumb implementation of a "smart" buffer capable of wrapping an RGBA_Image but that can still be rendered on screen (ie, an Evas_GL_Image is attached to it). --- src/Makefile_Evas.am | 4 +- .../evas/engines/gl_common/evas_gl_common.h | 1 + src/modules/evas/engines/gl_common/evas_gl_image.c | 14 +-- .../gl_generic/evas_ector_gl_rgbaimage_buffer.c | 117 +++++++++++++++++++++ .../gl_generic/evas_ector_gl_rgbaimage_buffer.eo | 12 +++ src/modules/evas/engines/gl_generic/evas_engine.c | 8 +- 6 files changed, 144 insertions(+), 12 deletions(-) create mode 100644 src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c create mode 100644 src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index 6b4f239..24e9929 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -755,12 +755,14 @@ GL_GENERIC_SOURCES = \ modules/evas/engines/gl_generic/evas_engine.c \ modules/evas/engines/gl_generic/Evas_Engine_GL_Generic.h \ modules/evas/engines/gl_generic/evas_ector_gl_buffer.c \ -modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c +modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c \ +modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c \ $(NULL) evas_gl_generic_eolian_files = \ modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo \ modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo \ +modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo \ $(NULL) evas_gl_generic_eolian_c = $(evas_gl_generic_eolian_files:%.eo=%.eo.c) diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index 09b4cb5..93e30f4 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -660,6 +660,7 @@ Evas_GL_Image *evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const ch Evas_GL_Image *evas_gl_common_image_mmap(Evas_Engine_GL_Context *gc, Eina_File *f, const char *key, Evas_Image_Load_Opts *lo, int *error); Evas_GL_Image *evas_gl_common_image_new_from_copied_data(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, DATA32 *data, int alpha, Evas_Colorspace cspace); Evas_GL_Image *evas_gl_common_image_new(Evas_Engine_GL_Context *gc, unsigned int w, unsigned int h, int alpha, Evas_Colorspace cspace); +Evas_GL_Image *evas_gl_common_image_new_from_rgbaimage(Evas_Engine_GL_Context *gc, RGBA_Image *im, Evas_Image_Load_Opts *lo, int *error); Evas_GL_Image *evas_gl_common_image_alpha_set(Evas_GL_Image *im, int alpha); void evas_gl_common_image_scale_hint_set(Evas_GL_Image *im, int hint); void evas_gl_common_image_content_hint_set(Evas_GL_Image *im, int hint); diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c index 664b4e4..e62cfdc 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_image.c +++ b/src/modules/evas/engines/gl_common/evas_gl_image.c @@ -150,9 +150,9 @@ _evas_gl_cspace_list_fill(Evas_Engine_GL_Context *gc) CS_APPEND(EVAS_COLORSPACE_ARGB8888); } -static Evas_GL_Image * -_evas_gl_common_image(Evas_Engine_GL_Context *gc, RGBA_Image *im_im, - Evas_Image_Load_Opts *lo, int *error) +Evas_GL_Image * +evas_gl_common_image_new_from_rgbaimage(Evas_Engine_GL_Context *gc, RGBA_Image *im_im, + Evas_Image_Load_Opts *lo, int *error) { Evas_GL_Image *im; Eina_List *l; @@ -260,7 +260,7 @@ evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const ch im_im = NULL; } else - return _evas_gl_common_image(gc, im_im, lo, error); + return evas_gl_common_image_new_from_rgbaimage(gc, im_im, lo, error); } } #endif @@ -268,7 +268,7 @@ evas_gl_common_image_load(Evas_Engine_GL_Context *gc, const char *file, const ch im_im = evas_common_load_image_from_file(file, key, lo, error); if (!im_im) return NULL; - return _evas_gl_common_image(gc, im_im, lo, error); + return evas_gl_common_image_new_from_rgbaimage(gc, im_im, lo, error); } Evas_GL_Image * @@ -291,7 +291,7 @@ evas_gl_common_image_mmap(Evas_Engine_GL_Context *gc, Eina_File *f, const char * im_im = NULL; } else - return _evas_gl_common_image(gc, im_im, lo, error); + return evas_gl_common_image_new_from_rgbaimage(gc, im_im, lo, error); } } #endif @@ -299,7 +299,7 @@ evas_gl_common_image_mmap(Evas_Engine_GL_Context *gc, Eina_File *f, const char * im_im = evas_common_load_image_from_mmap(f, key, lo, error); if (!im_im) return NULL; - return _evas_gl_common_image(gc, im_im, lo, error); + return evas_gl_common_image_new_from_rgbaimage(gc, im_im, lo, error); } EAPI Evas_GL_Image * diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c new file mode 100644 index 0000000..03d957a --- /dev/null +++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c @@ -0,0 +1,117 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "evas_common_private.h" +#include "evas_gl_private.h" + +#include +#include +#include "Evas_Engine_GL_Generic.h" + +#include "evas_ector_buffer.eo.h" +#include "evas_ector_gl_rgbaimage_buffer.eo.h" +#include "../software_generic/evas_ector_software_buffer.eo.h" + +#define MY_CLASS EVAS_ECTOR_GL_RGBAIMAGE_BUFFER_CLASS + +typedef struct { + Ector_Software_Buffer_Base_Data *base; + Evas *evas; + RGBA_Image *image; + Evas_GL_Image *glim; +} Evas_Ector_GL_RGBAImage_Buffer_Data; + +// GL engine stuff, do not use with RGBA_Image / Image_Entry +#define ENFN e->engine.func +#define ENDT e->engine.data.output + +EOLIAN static void +_evas_ector_gl_rgbaimage_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd, + Evas *evas, void *image) +{ + RGBA_Image *im = image; + Eina_Bool b; + + EINA_SAFETY_ON_NULL_RETURN(image); + if (eo_do_ret(obj, b, eo_finalized_get())) + { + CRI("engine_image must be set at construction time only"); + return; + } + + if (!im->image.data) + { + CRI("image has no pixels yet"); + return; + } + + pd->evas = eo_xref(evas, obj); + evas_cache_image_ref(&im->cache_entry); + pd->image = im; + if (!pd->image) return; + + eo_do(obj, ector_buffer_pixels_set(im->image.data, + im->cache_entry.w, im->cache_entry.h, 0, + (Efl_Gfx_Colorspace) im->cache_entry.space, + EINA_TRUE, 0, 0, 0, 0)); +} + +EOLIAN static void +_evas_ector_gl_rgbaimage_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_UNUSED, + Evas_Ector_GL_RGBAImage_Buffer_Data *pd, + Evas **evas, void **image) +{ + Evas_Public_Data *e = eo_data_scope_get(pd->evas, EVAS_CANVAS_CLASS); + Render_Engine_GL_Generic *re = e->engine.data.output; + Evas_Engine_GL_Context *gc = NULL; + int err = EVAS_LOAD_ERROR_NONE; + + if (evas) *evas = pd->evas; + if (image) *image = NULL; + if (pd->glim) + goto end; + + EINA_SAFETY_ON_NULL_RETURN(re); + gc = re->window_gl_context_get(re->software.ob); + pd->glim = evas_gl_common_image_new_from_rgbaimage(gc, pd->image, NULL, &err); + if ((err != EVAS_LOAD_ERROR_NONE) || !pd->glim) + { + ERR("Failed to create GL image! error %d", err); + return; + } + +end: + if (image) *image = pd->glim; +} + +EOLIAN static Eo * +_evas_ector_gl_rgbaimage_buffer_eo_base_constructor(Eo *obj, Evas_Ector_GL_RGBAImage_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_gl_rgbaimage_buffer_eo_base_finalize(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(pd->base, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(pd->image, NULL); + pd->base->generic->immutable = EINA_TRUE; + return eo_do_super_ret(obj, MY_CLASS, obj, eo_finalize()); +} + +EOLIAN static void +_evas_ector_gl_rgbaimage_buffer_eo_base_destructor(Eo *obj, Evas_Ector_GL_RGBAImage_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->glim); + evas_cache_image_drop(&pd->image->cache_entry); + eo_xunref(pd->evas, obj); + eo_do_super(obj, MY_CLASS, eo_destructor()); +} + +#include "evas_ector_gl_rgbaimage_buffer.eo.c" diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo b/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo new file mode 100644 index 0000000..3c8f383 --- /dev/null +++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo @@ -0,0 +1,12 @@ +class Evas.Ector.GL.RGBAImage.Buffer (Ector.Software.Buffer, Evas.Ector.Buffer) +{ + [[A buffer object wrapping an existing Evas RGBA_Image for the GL Engine.]] + legacy_prefix: null; + implements { + Eo.Base.constructor; + Eo.Base.finalize; + Eo.Base.destructor; + Evas.Ector.Buffer.engine_image.get; + Evas.Ector.Buffer.engine_image.set; + } +} diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 27aae7f..fc9caf0 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -7,7 +7,7 @@ #include "evas_ector_buffer.eo.h" #include "evas_ector_gl_buffer.eo.h" #include "evas_ector_gl_image_buffer.eo.h" -#include "../software_generic/evas_ector_software_buffer.eo.h" +#include "evas_ector_gl_rgbaimage_buffer.eo.h" #if defined HAVE_DLSYM && ! defined _WIN32 # include /* dlopen,dlclose,etc */ @@ -2475,10 +2475,10 @@ eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image, Eina_ EINA_SAFETY_ON_NULL_RETURN_VAL(engine_image, NULL); if (is_rgba_image) { - Image_Entry *ie = engine_image; + RGBA_Image *im = engine_image; - buf = eo_add(EVAS_ECTOR_SOFTWARE_BUFFER_CLASS, e, - evas_ector_buffer_engine_image_set(e, ie)); + buf = eo_add(EVAS_ECTOR_GL_RGBAIMAGE_BUFFER_CLASS, e, + evas_ector_buffer_engine_image_set(e, im)); } else { -- 2.7.4