evas: add theoric GL backend support.

This commit is contained in:
Cedric BAIL 2015-04-03 16:30:44 +02:00
parent f2380b0920
commit 23c34b96d3
3 changed files with 241 additions and 1 deletions

View File

@ -519,7 +519,9 @@ lib/evas/filters/blur/blur_box_rgba_neon.c
### Engines
if EVAS_STATIC_BUILD_SOFTWARE_GENERIC
evas_eolian_files += modules/evas/engines/software_generic/ector_cairo_software_surface.eo
BUILT_SOURCES += \
modules/evas/engines/software_generic/ector_cairo_software_surface.eo.c \
modules/evas/engines/software_generic/ector_cairo_software_surface.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
lib_evas_libevas_la_LIBADD +=
else
@ -608,6 +610,10 @@ endif
endif
if BUILD_ENGINE_GL_COMMON
BUILT_SOURCES += \
modules/evas/engines/gl_generic/ector_cairo_software_surface.eo.c \
modules/evas/engines/gl_generic/ector_cairo_software_surface.eo.h
GL_COMMON_SOURCES = \
modules/evas/engines/gl_common/evas_gl_private.h \
modules/evas/engines/gl_common/evas_gl_common.h \

View File

@ -0,0 +1,18 @@
class Ector.Cairo_Software.Surface (Ector.Cairo.Surface)
{
eo_prefix: ector_cairo_software_surface;
legacy_prefix: null;
properties {
surface {
set {
}
get {
}
values {
void *pixels;
uint width;
uint height;
}
}
}
}

View File

@ -21,6 +21,10 @@
#include "evas_cs2_private.h"
#endif
#include "cairo/Ector_Cairo.h"
#include "ector_cairo_software_surface.eo.h"
#define EVAS_GL_NO_GL_H_CHECK 1
#include "Evas_GL.h"
@ -2087,6 +2091,127 @@ eng_texture_image_set(void *data EINA_UNUSED, void *texture, void *image)
e3d_texture_import((E3D_Texture *)texture, im->tex->pt->texture);
}
static Ector_Surface *_software_ector = NULL;
static Ector_Surface *
eng_ector_get(void *data EINA_UNUSED)
{
if (!_software_ector)
{
_software_ector = eo_add(ECTOR_CAIRO_SOFTWARE_SURFACE_CLASS, NULL);
}
return _software_ector;
}
static Ector_Rop
_evas_render_op_to_ector_rop(Evas_Render_Op op)
{
switch (op)
{
case EVAS_RENDER_BLEND:
return ECTOR_ROP_BLEND;
case EVAS_RENDER_COPY:
return ECTOR_ROP_COPY;
default:
return ECTOR_ROP_BLEND;
}
}
static void
eng_ector_renderer_draw(void *data EINA_UNUSED, void *context, void *surface, Ector_Renderer *renderer, Eina_Array *clips, int x, int y, Eina_Bool do_async EINA_UNUSED)
{
Evas_GL_Image *dst = surface;
Evas_Engine_GL_Context *gc = context;
Eina_Rectangle *r;
Eina_Array *c;
Eina_Rectangle clip;
Eina_Array_Iterator it;
unsigned int i;
if (gc->dc->clip.use)
{
clip.x = gc->dc->clip.x;
clip.y = gc->dc->clip.y;
clip.w = gc->dc->clip.w;
clip.h = gc->dc->clip.h;
}
else
{
clip.x = 0;
clip.y = 0;
clip.w = dst->w;
clip.h = dst->h;
}
c = eina_array_new(8);
EINA_ARRAY_ITER_NEXT(clips, i, r, it)
{
Eina_Rectangle *rc;
rc = eina_rectangle_new(r->x, r->y, r->w, r->h);
if (!rc) continue;
if (eina_rectangle_intersection(rc, &clip))
eina_array_push(c, rc);
else
eina_rectangle_free(rc);
}
if (eina_array_count(c) == 0 &&
eina_array_count(clips) > 0)
return ;
if (eina_array_count(c) == 0)
eina_array_push(c, eina_rectangle_new(clip.x, clip.y, clip.w, clip.h));
eo_do(renderer,
ector_renderer_draw(_evas_render_op_to_ector_rop(gc->dc->render_op),
c,
x,
y,
// mul_col will be applied by GL during ector_end
0xffffffff));
while ((r = eina_array_pop(c)))
eina_rectangle_free(r);
eina_array_free(c);
}
static void *software_buffer = NULL;
static void
eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, void *surface, Eina_Bool do_async EINA_UNUSED)
{
Evas_GL_Image *dst = surface;
software_buffer = realloc(software_buffer, sizeof (unsigned int) * dst->w * dst->h);
eo_do(_software_ector,
ector_cairo_software_surface_set(software_buffer, dst->w, dst->h));
}
static void
eng_ector_end(void *data, void *context, void *surface, Eina_Bool do_async)
{
Evas_GL_Image *dst = surface;
Evas_GL_Image *im;
eo_do(_software_ector,
ector_cairo_software_surface_set(NULL, 0, 0));
im = evas_gl_common_image_new_from_data(context, dst->w, dst->h, software_buffer, 1, EVAS_COLORSPACE_ARGB8888);
eng_image_draw(data, context, surface, im,
// We actually just bluntly push the pixel all over the
// destination surface. We don't have the actual information
// of the widget size. This is not a problem.
// Later on, we don't want that information and today when
// using GL backend, you just need to turn on Evas_Map on
// the Evas_Object_VG.
0, 0, dst->w, dst->h,
0, 0, dst->w, dst->h, 0, do_async);
evas_common_rgba_image_free(software_buffer);
software_buffer = NULL;
}
static Evas_Func func, pfunc;
static int
@ -2229,6 +2354,11 @@ module_open(Evas_Module *em)
ORD(texture_filter_get);
ORD(texture_image_set);
ORD(ector_get);
ORD(ector_begin);
ORD(ector_renderer_draw);
ORD(ector_end);
/* now advertise out own api */
em->functions = (void *)(&func);
return 1;
@ -2257,3 +2387,89 @@ EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_generic);
#ifndef EVAS_STATIC_BUILD_GL_COMMON
EVAS_EINA_MODULE_DEFINE(engine, gl_generic);
#endif
#define USE(Obj, Sym, Error) \
if (!Sym) _ector_cairo_symbol_get(Obj, #Sym); \
if (!Sym) return Error;
static inline void *
_ector_cairo_symbol_get(Eo *ector_surface, const char *name)
{
void *sym;
eo_do(ector_surface,
sym = ector_cairo_surface_symbol_get(name));
return sym;
}
typedef struct _cairo_surface_t cairo_surface_t;
typedef enum {
CAIRO_FORMAT_INVALID = -1,
CAIRO_FORMAT_ARGB32 = 0,
CAIRO_FORMAT_RGB24 = 1,
CAIRO_FORMAT_A8 = 2,
CAIRO_FORMAT_A1 = 3,
CAIRO_FORMAT_RGB16_565 = 4,
CAIRO_FORMAT_RGB30 = 5
} cairo_format_t;
static cairo_surface_t *(*cairo_image_surface_create_for_data)(unsigned char *data,
cairo_format_t format,
int width,
int height,
int stride) = NULL;
static void (*cairo_surface_destroy)(cairo_surface_t *surface) = NULL;
static cairo_t *(*cairo_create)(cairo_surface_t *target) = NULL;
static void (*cairo_destroy)(cairo_t *cr) = NULL;
typedef struct _Ector_Cairo_Software_Surface_Data Ector_Cairo_Software_Surface_Data;
struct _Ector_Cairo_Software_Surface_Data
{
cairo_surface_t *surface;
cairo_t *ctx;
void *pixels;
unsigned int width;
unsigned int height;
};
static void
_ector_cairo_software_surface_surface_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd, void *pixels, unsigned int width, unsigned int height)
{
USE(obj, cairo_image_surface_create_for_data, );
USE(obj, cairo_surface_destroy, );
USE(obj, cairo_create, );
USE(obj, cairo_destroy, );
cairo_surface_destroy(pd->surface); pd->surface = NULL;
cairo_destroy(pd->ctx); pd->ctx = NULL;
pd->pixels = NULL;
pd->width = 0;
pd->height = 0;
pd->surface = cairo_image_surface_create_for_data(pixels, CAIRO_FORMAT_ARGB32, width, height, width);
if (pd->surface) goto end;
pd->ctx = cairo_create(pd->surface);
if (pd->ctx)
{
pd->pixels = pixels;
pd->width = width;
pd->height = height;
}
end:
eo_do(obj, ector_cairo_surface_context_set(pd->ctx));
}
static void
_ector_cairo_software_surface_surface_get(Eo *obj EINA_UNUSED, Ector_Cairo_Software_Surface_Data *pd, void **pixels, unsigned int *width, unsigned int *height)
{
if (pixels) *pixels = pd->pixels;
if (width) *width = pd->width;
if (height) *height = pd->height;
}
#include "ector_cairo_software_surface.eo.c"