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).
This commit is contained in:
Jean-Philippe Andre 2015-12-08 17:29:54 +09:00
parent 85f23d96e7
commit 7a8879ba8b
10 changed files with 188 additions and 5 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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.]]
}
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -9,6 +9,8 @@
#include <software/Ector_Software.h>
#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 <dlfcn.h> /* 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,