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).
This commit is contained in:
Jean-Philippe Andre 2016-01-04 17:48:48 +09:00
parent a02c810059
commit 6696112691
6 changed files with 144 additions and 12 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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 *

View File

@ -0,0 +1,117 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "evas_common_private.h"
#include "evas_gl_private.h"
#include <software/Ector_Software.h>
#include <gl/Ector_GL.h>
#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"

View File

@ -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;
}
}

View File

@ -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 <dlfcn.h> /* 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
{