forked from enlightenment/efl
evas: first implementation of an ector drawer inside Evas software engine.
Note: this won't work with the OpenGL backend.
This commit is contained in:
parent
3f3fb4cac7
commit
b6ffe1cc87
|
@ -6,7 +6,7 @@
|
|||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
#include <eina_safety_checks.h>
|
||||
#include <Ector.h>
|
||||
|
||||
#include "Evas.h"
|
||||
|
||||
|
@ -737,6 +737,7 @@ struct _Evas_Public_Data
|
|||
struct {
|
||||
Evas_Module *module;
|
||||
Evas_Func *func;
|
||||
Ector_Surface *surface;
|
||||
struct {
|
||||
void *output;
|
||||
|
||||
|
@ -1365,6 +1366,9 @@ struct _Evas_Func
|
|||
void (*texture_filter_set) (void *data, void *texture, Evas_3D_Texture_Filter min, Evas_3D_Texture_Filter mag);
|
||||
void (*texture_filter_get) (void *data, void *texture, Evas_3D_Texture_Filter *min, Evas_3D_Texture_Filter *mag);
|
||||
void (*texture_image_set) (void *data, void *texture, void *image);
|
||||
|
||||
Ector_Surface *(*ector_get) (void *data);
|
||||
void (*ector_draw) (void *data, void *context, void *surface, Ector_Renderer *r, Eina_Array *clips, int x, int y, Eina_Bool do_async);
|
||||
};
|
||||
|
||||
struct _Evas_Image_Save_Func
|
||||
|
|
|
@ -15,7 +15,4 @@ class Ector.Cairo_Software.Surface (Ector.Cairo.Surface)
|
|||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Eo.Base.finalize;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -296,6 +296,7 @@ typedef struct _Evas_Thread_Command_Image Evas_Thread_Command_Image;
|
|||
typedef struct _Evas_Thread_Command_Font Evas_Thread_Command_Font;
|
||||
typedef struct _Evas_Thread_Command_Map Evas_Thread_Command_Map;
|
||||
typedef struct _Evas_Thread_Command_Multi_Font Evas_Thread_Command_Multi_Font;
|
||||
typedef struct _Evas_Thread_Command_Ector Evas_Thread_Command_Ector;
|
||||
|
||||
struct _Evas_Thread_Command_Rect
|
||||
{
|
||||
|
@ -387,6 +388,19 @@ struct _Evas_Thread_Command_Multi_Font
|
|||
Evas_Font_Array *texts;
|
||||
};
|
||||
|
||||
struct _Evas_Thread_Command_Ector
|
||||
{
|
||||
void *surface;
|
||||
Ector_Renderer *r;
|
||||
Eina_Array *clips;
|
||||
|
||||
DATA32 mul_col;
|
||||
Ector_Rop render_op;
|
||||
int x, y;
|
||||
|
||||
Eina_Bool free_it;
|
||||
};
|
||||
|
||||
Eina_Mempool *_mp_command_rect = NULL;
|
||||
Eina_Mempool *_mp_command_line = NULL;
|
||||
Eina_Mempool *_mp_command_polygon = NULL;
|
||||
|
@ -394,7 +408,7 @@ Eina_Mempool *_mp_command_image = NULL;
|
|||
Eina_Mempool *_mp_command_font = NULL;
|
||||
Eina_Mempool *_mp_command_map = NULL;
|
||||
Eina_Mempool *_mp_command_multi_font = NULL;
|
||||
|
||||
Eina_Mempool *_mp_command_ector = NULL;
|
||||
/*
|
||||
*****
|
||||
**
|
||||
|
@ -3431,6 +3445,148 @@ eng_output_idle_flush(void *data)
|
|||
if (re->outbuf_idle_flush) re->outbuf_idle_flush(re->ob);
|
||||
}
|
||||
|
||||
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
|
||||
_draw_thread_ector_cleanup(Evas_Thread_Command_Ector *ector)
|
||||
{
|
||||
Eina_Rectangle *r;
|
||||
|
||||
while ((r = eina_array_pop(ector->clips)))
|
||||
eina_rectangle_free(r);
|
||||
eina_array_free(ector->clips);
|
||||
eo_unref(ector->r);
|
||||
|
||||
if (ector->free_it)
|
||||
eina_mempool_free(_mp_command_ector, ector);
|
||||
}
|
||||
|
||||
static void
|
||||
_draw_thread_ector_draw(void *data)
|
||||
{
|
||||
Evas_Thread_Command_Ector *ector = data;
|
||||
RGBA_Image *surface = ector->surface;
|
||||
void *pixels = evas_cache_image_pixels(&surface->cache_entry);
|
||||
unsigned int w, h;
|
||||
|
||||
w = surface->cache_entry.w;
|
||||
h = surface->cache_entry.h;
|
||||
|
||||
// FIXME: do not reset cairo context if not necessary
|
||||
eo_do(_software_ector,
|
||||
ector_cairo_software_surface_set(pixels, w, h));
|
||||
|
||||
eo_do(ector->r,
|
||||
ector_renderer_draw(ector->render_op,
|
||||
ector->clips,
|
||||
ector->x,
|
||||
ector->y,
|
||||
ector->mul_col));
|
||||
|
||||
_draw_thread_ector_cleanup(ector);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
RGBA_Image *dst = surface;
|
||||
RGBA_Draw_Context *dc = context;
|
||||
Evas_Thread_Command_Ector ector;
|
||||
Eina_Array *c;
|
||||
Eina_Rectangle *r;
|
||||
Eina_Rectangle clip;
|
||||
Eina_Array_Iterator it;
|
||||
unsigned int i;
|
||||
|
||||
if (dc->clip.use)
|
||||
{
|
||||
clip.x = dc->clip.x;
|
||||
clip.y = dc->clip.y;
|
||||
clip.w = dc->clip.w;
|
||||
clip.h = dc->clip.h;
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.x = 0;
|
||||
clip.y = 0;
|
||||
clip.w = dst->cache_entry.w;
|
||||
clip.h = dst->cache_entry.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));
|
||||
|
||||
ector.surface = surface;
|
||||
ector.r = eo_ref(renderer);
|
||||
ector.clips = c;
|
||||
ector.render_op = _evas_render_op_to_ector_rop(dc->render_op);
|
||||
ector.mul_col = dc->mul.use ? dc->mul.col : 0xffffffff;
|
||||
ector.x = x;
|
||||
ector.y = y;
|
||||
ector.free_it = EINA_FALSE;
|
||||
|
||||
if (do_async)
|
||||
{
|
||||
Evas_Thread_Command_Ector *ne;
|
||||
|
||||
ne = eina_mempool_malloc(_mp_command_ector, sizeof (Evas_Thread_Command_Ector));
|
||||
if (!ne)
|
||||
{
|
||||
_draw_thread_ector_cleanup(&ector);
|
||||
return ;
|
||||
}
|
||||
|
||||
memcpy(ne, &ector, sizeof (Evas_Thread_Command_Ector));
|
||||
ne->free_it = EINA_TRUE;
|
||||
|
||||
evas_thread_cmd_enqueue(_draw_thread_ector_draw, ne);
|
||||
}
|
||||
else
|
||||
{
|
||||
_draw_thread_ector_draw(&ector);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------//
|
||||
|
||||
|
@ -3613,6 +3769,8 @@ static Evas_Func func =
|
|||
NULL, // eng_texture_filter_set
|
||||
NULL, // eng_texture_filter_get
|
||||
NULL, // eng_texture_image_set
|
||||
eng_ector_get,
|
||||
eng_ector_renderer_draw
|
||||
/* FUTURE software generic calls go here */
|
||||
};
|
||||
|
||||
|
@ -4661,6 +4819,9 @@ module_open(Evas_Module *em)
|
|||
_mp_command_multi_font =
|
||||
eina_mempool_add("chained_mempool", "Evas_Thread_Command_Multi_Font",
|
||||
NULL, sizeof(Evas_Thread_Command_Multi_Font), 128);
|
||||
_mp_command_ector =
|
||||
eina_mempool_add("chained_mempool", "Evas_Thread_Command_Ector",
|
||||
NULL, sizeof(Evas_Thread_Command_Ector), 128);
|
||||
|
||||
init_gl();
|
||||
evas_common_pipe_init();
|
||||
|
@ -4679,6 +4840,7 @@ module_close(Evas_Module *em EINA_UNUSED)
|
|||
eina_mempool_del(_mp_command_image);
|
||||
eina_mempool_del(_mp_command_font);
|
||||
eina_mempool_del(_mp_command_map);
|
||||
eina_mempool_del(_mp_command_ector);
|
||||
eina_log_domain_unregister(_evas_soft_gen_log_dom);
|
||||
}
|
||||
|
||||
|
@ -4693,30 +4855,106 @@ static Evas_Module_Api evas_modapi =
|
|||
}
|
||||
};
|
||||
|
||||
EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_generic);
|
||||
Eina_Bool evas_engine_software_generic_init(void)
|
||||
{
|
||||
return evas_module_register(&evas_modapi, EVAS_MODULE_TYPE_ENGINE);
|
||||
}
|
||||
|
||||
// Time to destroy the ector context
|
||||
void evas_engine_software_generic_shutdown(void)
|
||||
{
|
||||
if (_software_ector) eo_del(_software_ector);
|
||||
_software_ector = NULL;
|
||||
|
||||
evas_module_unregister(&evas_modapi, EVAS_MODULE_TYPE_ENGINE);
|
||||
}
|
||||
|
||||
#ifndef EVAS_STATIC_BUILD_SOFTWARE_GENERIC
|
||||
EVAS_EINA_MODULE_DEFINE(engine, software_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;
|
||||
};
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void
|
||||
_ector_cairo_software_surface_surface_get(Eo *obj, Ector_Cairo_Software_Surface_Data *pd, void **pixels, unsigned int *width, unsigned int *height)
|
||||
{
|
||||
}
|
||||
|
||||
Eo *
|
||||
_ector_cairo_software_surface_eo_base_finalize(Eo *obj, Ector_Cairo_Software_Surface_Data *pd)
|
||||
_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"
|
||||
|
|
Loading…
Reference in New Issue