diff --git a/src/lib/ector/ector_private.h b/src/lib/ector/ector_private.h index 8604768e16..8e128201e2 100644 --- a/src/lib/ector/ector_private.h +++ b/src/lib/ector/ector_private.h @@ -1,123 +1,129 @@ #ifndef ECTOR_PRIVATE_H_ #define ECTOR_PRIVATE_H_ #include "Ector.h" #include "ector_gl_internal.h" /* * variable and macros used for the eina_log module */ extern int _ector_log_dom_global; /* * Macros that are used everywhere * * the first four macros are the general macros for the lib */ #ifdef ECTOR_DEFAULT_LOG_COLOR # undef ECTOR_DEFAULT_LOG_COLOR #endif /* ifdef ECTOR_DEFAULT_LOG_COLOR */ #define ECTOR_DEFAULT_LOG_COLOR EINA_COLOR_CYAN #ifdef ERR # undef ERR #endif /* ifdef ERR */ #define ERR(...) EINA_LOG_DOM_ERR(_ector_log_dom_global, __VA_ARGS__) #ifdef DBG # undef DBG #endif /* ifdef DBG */ #define DBG(...) EINA_LOG_DOM_DBG(_ector_log_dom_global, __VA_ARGS__) #ifdef INF # undef INF #endif /* ifdef INF */ #define INF(...) EINA_LOG_DOM_INFO(_ector_log_dom_global, __VA_ARGS__) #ifdef WRN # undef WRN #endif /* ifdef WRN */ #define WRN(...) EINA_LOG_DOM_WARN(_ector_log_dom_global, __VA_ARGS__) #ifdef CRI # undef CRI #endif /* ifdef CRI */ #define CRI(...) EINA_LOG_DOM_CRIT(_ector_log_dom_global, __VA_ARGS__) /* The following macro are internal to Ector only at this stage */ typedef struct _Ector_Renderer_Data Ector_Renderer_Data; typedef struct _Ector_Renderer_Gradient_Data Ector_Renderer_Gradient_Data; typedef struct _Ector_Renderer_Gradient_Linear_Data Ector_Renderer_Gradient_Linear_Data; typedef struct _Ector_Renderer_Gradient_Radial_Data Ector_Renderer_Gradient_Radial_Data; typedef struct _Ector_Renderer_Shape_Data Ector_Renderer_Shape_Data; +typedef struct _Ector_Renderer_Image_Data Ector_Renderer_Image_Data; typedef struct _Ector_Renderer_Buffer_Data Ector_Renderer_Buffer_Data; struct _Ector_Renderer_Data { Ector_Surface *surface; Eina_Matrix3 *m; struct { double x; double y; } origin; struct { int r, g, b, a; } color; Eina_Bool visibility : 1; Eina_Bool finalized : 1; }; struct _Ector_Renderer_Gradient_Data { Efl_Gfx_Gradient_Stop *colors; unsigned int colors_count; Efl_Gfx_Gradient_Spread s; }; struct _Ector_Renderer_Gradient_Linear_Data { struct { double x, y; } start, end; }; struct _Ector_Renderer_Gradient_Radial_Data { struct { double x, y; } radial, focal; double radius; }; struct _Ector_Renderer_Shape_Data { Ector_Renderer *fill; struct { Ector_Renderer *fill; Ector_Renderer *marker; } stroke; }; +struct _Ector_Renderer_Image_Data +{ + Ector_Buffer *buffer; +}; + struct _Ector_Renderer_Buffer_Data { Ector_Buffer *eo_buffer; struct { /* Efl_Gfx_Fill_Spread spread; */ int x, y, w, h; } fill; }; static inline unsigned int _renderer_crc_get(Eo *obj, unsigned int crc) { unsigned int id; id = ector_renderer_crc_get(obj); crc = eina_crc((void*) &id, sizeof (id), crc, EINA_FALSE); return crc; } #include "ector_buffer.h" #endif diff --git a/src/lib/ector/ector_renderer.h b/src/lib/ector/ector_renderer.h index c8d20d2fb3..482f6cb0d4 100644 --- a/src/lib/ector/ector_renderer.h +++ b/src/lib/ector/ector_renderer.h @@ -1,10 +1,11 @@ #ifndef ECTOR_RENDERER_H #define ECTOR_RENDERER_H #include "ector_renderer.eo.h" #include "ector_renderer_shape.eo.h" +#include "ector_renderer_image.eo.h" #include "ector_renderer_gradient.eo.h" #include "ector_renderer_gradient_linear.eo.h" #include "ector_renderer_gradient_radial.eo.h" #endif diff --git a/src/lib/ector/ector_renderer_image.c b/src/lib/ector/ector_renderer_image.c new file mode 100644 index 0000000000..3e34254f29 --- /dev/null +++ b/src/lib/ector/ector_renderer_image.c @@ -0,0 +1,22 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "ector_private.h" + +#define MY_CLASS ECTOR_RENDERER_IMAGE_MIXIN + + +static void +_ector_renderer_image_buffer_set(Eo *obj EINA_UNUSED, + Ector_Renderer_Image_Data *pd, + Ector_Buffer *buffer) +{ + pd->buffer = buffer; +} + + +#include "ector_renderer_image.eo.c" diff --git a/src/lib/ector/ector_renderer_image.eo b/src/lib/ector/ector_renderer_image.eo new file mode 100644 index 0000000000..9c2e7b3448 --- /dev/null +++ b/src/lib/ector/ector_renderer_image.eo @@ -0,0 +1,16 @@ +import ector_renderer; + +mixin @beta Ector.Renderer.Image +{ + [[Ector image renderer mixin]] + c_prefix: ector_renderer_image; + methods { + @property buffer { + set { + } + values { + buffer : Ector.Buffer; [[Image buffer]] + } + } + } +} diff --git a/src/lib/ector/meson.build b/src/lib/ector/meson.build index 069e98d9e7..5bedb7e82b 100644 --- a/src/lib/ector/meson.build +++ b/src/lib/ector/meson.build @@ -1,98 +1,100 @@ ector_deps = [eina, emile, eet, eo, efl] ector_pub_deps = [eina, efl] pub_eo_file_target = [] ector_opt_lib = [ ] ector_header_src = [ # nothing for now ector stays only intree ] ector_src = [ 'ector_main.c', 'ector_gl_internal.h', 'ector_buffer.c', 'ector_renderer_shape.c', + 'ector_renderer_image.c', 'ector_renderer.c', 'ector_renderer_gradient.c', 'ector_renderer_gradient_radial.c', 'ector_renderer_gradient_linear.c' ] pub_eo_files = [ 'ector_surface.eo', 'ector_buffer.eo', 'ector_renderer.eo', 'ector_renderer_shape.eo', + 'ector_renderer_image.eo', 'ector_renderer_gradient.eo', 'ector_renderer_gradient_radial.eo', 'ector_renderer_gradient_linear.eo' ] ector_pub_eo_files = pub_eo_files foreach eo_file : pub_eo_files pub_eo_file_target += custom_target('eolian_gen_' + eo_file, input : eo_file, output : [eo_file + '.h'], depfile : eo_file + '.d', install : false, install_dir : dir_package_include, command : eolian_gen + [ '-I', meson.current_source_dir(), eolian_include_directories, '-o', 'h:' + join_paths(meson.current_build_dir(), eo_file + '.h'), '-o', 'c:' + join_paths(meson.current_build_dir(), eo_file + '.c'), '-o', 'd:' + join_paths(meson.current_build_dir(), eo_file + '.d'), '-gchd', '@INPUT@']) endforeach eolian_include_directories += ['-I', meson.current_source_dir()] subdir('cairo') subdir('gl') pub_eo_types_files = [ 'ector_types.eot' ] if get_option('install-eo-files') install_data(ector_pub_eo_files + pub_eo_types_files, install_dir: join_paths(eolian_include_dir, package_version_name) ) endif foreach eo_file : pub_eo_types_files pub_eo_file_target += custom_target('eolian_gen_' + eo_file, input : eo_file, output : [eo_file + '.h'], depfile : eo_file + '.d', install : false, install_dir : dir_package_include, command : eolian_gen + [ '-I', meson.current_source_dir(), eolian_include_directories, '-o', 'h:' + join_paths(meson.current_build_dir(), eo_file + '.h'), '-o', 'd:' + join_paths(meson.current_build_dir(), eo_file + '.d'), '-ghd', '@INPUT@']) endforeach subdir('software') ector_lib = library('ector', ector_src, pub_eo_file_target, dependencies: ector_pub_deps + [triangulator, freetype, draw, m] + ector_deps, include_directories : config_dir, install: true, version : meson.project_version(), link_with: ector_opt_lib ) ector = declare_dependency( include_directories: [include_directories('.')], link_with: ector_lib, sources : pub_eo_file_target + priv_eo_file_target, dependencies: ector_pub_deps, ) install_headers(ector_header_src, install_dir : dir_package_include, ) diff --git a/src/lib/ector/software/Ector_Software.h b/src/lib/ector/software/Ector_Software.h index 2f9192ff30..85529e6f21 100644 --- a/src/lib/ector/software/Ector_Software.h +++ b/src/lib/ector/software/Ector_Software.h @@ -1,47 +1,48 @@ #ifndef ECTOR_SOFTWARE_H_ #define ECTOR_SOFTWARE_H_ #include #ifdef EAPI # undef EAPI #endif #ifdef _WIN32 # ifdef EFL_BUILD # ifdef DLL_EXPORT # define EAPI __declspec(dllexport) # else # define EAPI # endif # else # define EAPI __declspec(dllimport) # endif #else # ifdef __GNUC__ # if __GNUC__ >= 4 # define EAPI __attribute__ ((visibility("default"))) # else # define EAPI # endif # else # define EAPI # endif #endif #ifdef EFL_BETA_API_SUPPORT #include "software/ector_software_surface.eo.h" #include "software/ector_software_buffer.eo.h" #include "software/ector_software_buffer_base.eo.h" #include "software/ector_renderer_software.eo.h" #include "software/ector_renderer_software_shape.eo.h" +#include "software/ector_renderer_software_image.eo.h" #include "software/ector_renderer_software_gradient_linear.eo.h" #include "software/ector_renderer_software_gradient_radial.eo.h" #endif #undef EAPI #define EAPI #endif diff --git a/src/lib/ector/software/ector_renderer_software_image.c b/src/lib/ector/software/ector_renderer_software_image.c new file mode 100644 index 0000000000..cb8d93ad6c --- /dev/null +++ b/src/lib/ector/software/ector_renderer_software_image.c @@ -0,0 +1,194 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include +#include +#include + +#include "ector_private.h" +#include "ector_software_private.h" + +#define MY_CLASS ECTOR_RENDERER_SOFTWARE_IMAGE_CLASS + +typedef struct _Ector_Renderer_Software_Image_Data Ector_Renderer_Software_Image_Data; + +struct _Ector_Renderer_Software_Image_Data +{ + Ector_Software_Surface_Data *surface; + Ector_Renderer_Image_Data *image; + Ector_Renderer_Data *base; + Ector_Buffer *mask; + int mask_op; + int opacity; + Eina_Matrix3 inv_m; + struct { + int x1, y1, x2, y2; + } boundary; +}; + +static Eina_Bool +_ector_renderer_software_image_ector_renderer_prepare(Eo *obj, + Ector_Renderer_Software_Image_Data *pd) +{ + if (!pd->surface) + pd->surface = efl_data_xref(pd->base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj); + + if (!pd->image->buffer || !pd->surface->rasterizer->fill_data.raster_buffer) + return EINA_FALSE; + + Eina_Matrix3 m; + double m11, m12, m21, m22, m31, m32; + int x = pd->surface->x + (int)pd->base->origin.x; + int y = pd->surface->y + (int)pd->base->origin.y; + int image_w, image_h; + ector_buffer_size_get(pd->image->buffer, &image_w, &image_h); + + double px[4] = {x, x + image_w, x, x + image_w}; + double py[4] = {y, y, y + image_h, y + image_h}; + + //Only use alpha color + pd->opacity = pd->base->color.a; + /*ector_software_rasterizer_color_set(pd->surface->rasterizer, + pd->base->color.r, + pd->base->color.g, + pd->base->color.b, + pd->base->color.a);*/ + + if (!pd->base->m) + { + eina_matrix3_identity(&m); + eina_matrix3_scale(&m, (double)pd->surface->rasterizer->fill_data.raster_buffer->generic->w / (double)image_w, + (double)pd->surface->rasterizer->fill_data.raster_buffer->generic->h / (double)image_h); + } + else + eina_matrix3_copy(&m, pd->base->m); + eina_matrix3_values_get(&m, &m11, &m12, NULL, + &m21, &m22, NULL, + &m31, &m32, NULL); + //Calc draw boundbox + pd->boundary.x1 = MAX(pd->surface->rasterizer->fill_data.raster_buffer->generic->w , (unsigned int)image_w); + pd->boundary.y1 = MAX(pd->surface->rasterizer->fill_data.raster_buffer->generic->h , (unsigned int)image_h); + pd->boundary.x2 = 0; pd->boundary.y2 = 0; + for (int i = 0; i < 4; i++) + { + pd->boundary.x1 = MIN(pd->boundary.x1, (int)(((px[i] * m11) + (py[i] * m21) + m31) + 0.5)); + pd->boundary.y1 = MIN(pd->boundary.y1, (int)(((px[i] * m12) + (py[i] * m22) + m32) + 0.5)); + + pd->boundary.x2 = MAX(pd->boundary.x2, (int)(((px[i] * m11) + (py[i] * m21) + m31) + 0.5)); + pd->boundary.y2 = MAX(pd->boundary.y2, (int)(((px[i] * m12) + (py[i] * m22) + m32) + 0.5)); + } + + eina_matrix3_inverse(&m, &pd->inv_m); + + return EINA_TRUE; +} + +//FIXME: We need to implement that apply op, clips and mul_col. +static Eina_Bool +_ector_renderer_software_image_ector_renderer_draw(Eo *obj EINA_UNUSED, + Ector_Renderer_Software_Image_Data *pd, + Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED, + unsigned int mul_col EINA_UNUSED) +{ + if (!pd->image->buffer || !pd->surface->rasterizer->fill_data.raster_buffer->pixels.u32) + return EINA_FALSE; + + if (pd->opacity == 0) + return EINA_TRUE; + + const int pix_stride = pd->surface->rasterizer->fill_data.raster_buffer->stride / 4; + Ector_Software_Buffer_Base_Data *mask = pd->mask ? efl_data_scope_get(pd->mask, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN) : NULL; + Ector_Software_Buffer_Base_Data *bpd = efl_data_scope_get(pd->image->buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN); + double im11, im12, im21, im22, im31, im32; + uint32_t *dst_buf, *src_buf; + int image_w, image_h; + ector_buffer_size_get(pd->image->buffer, &image_w, &image_h); + + dst_buf = pd->surface->rasterizer->fill_data.raster_buffer->pixels.u32; + src_buf = bpd->pixels.u32; + + eina_matrix3_values_get(&pd->inv_m, &im11, &im12, NULL, + &im21, &im22, NULL, + &im31, &im32, NULL); + + //Draw + for (int local_y = pd->boundary.y1; local_y < pd->boundary.y2; local_y++) + { + for (int local_x = pd->boundary.x1; local_x < pd->boundary.x2; local_x++) + { + uint32_t *dst = dst_buf + ((int)local_x + ((int)local_y * pix_stride)); + int rx, ry; + rx = (int)(((double)local_x * im11) + ((double)local_y * im21) + im31 + 0.5); + ry = (int)(((double)local_x * im12) + ((double)local_y * im22) + im32 + 0.5); + if (rx < 0 || rx >= image_w || ry < 0 || ry >= image_h) + continue; + uint32_t *src = src_buf + (rx + (ry * image_w)); //FIXME: use to stride + uint32_t temp = 0x0; + if (mask) + { + uint32_t *m = mask->pixels.u32 + ((int)local_x + ((int)local_y * mask->generic->w)); + //FIXME : This masking can work only matte case. + // We need consider to inverse matte case. + temp = draw_mul_256((((*m)>>24) * pd->opacity)>>8, *src); + } + else + { + temp = draw_mul_256(pd->opacity, *src); + } + int inv_alpha = 255 - ((temp) >> 24); + *dst = temp + draw_mul_256(inv_alpha, *dst); + } + } + + return EINA_TRUE; +} + +static Eo * +_ector_renderer_software_image_efl_object_constructor(Eo *obj, Ector_Renderer_Software_Image_Data *pd) +{ + obj = efl_constructor(efl_super(obj, MY_CLASS)); + if (!obj) return NULL; + + pd->image = efl_data_xref(obj, ECTOR_RENDERER_IMAGE_MIXIN, obj); + pd->base = efl_data_xref(obj, ECTOR_RENDERER_CLASS, obj); + + return obj; +} + +static void +_ector_renderer_software_image_efl_object_destructor(Eo *obj, Ector_Renderer_Software_Image_Data *pd) +{ + efl_data_xunref(pd->base->surface, pd->surface, obj); + efl_data_xunref(obj, pd->base, obj); + efl_data_xunref(obj, pd->image, obj); + + efl_destructor(efl_super(obj, MY_CLASS)); +} + +unsigned int +_ector_renderer_software_image_ector_renderer_crc_get(const Eo *obj, + Ector_Renderer_Software_Image_Data *pd) +{ + unsigned int crc; + + crc = ector_renderer_crc_get(efl_super(obj, MY_CLASS)); + + crc = eina_crc((void*) pd->image, sizeof (Ector_Renderer_Image_Data), crc, EINA_FALSE); + return crc; +} + +static void +_ector_renderer_software_image_ector_renderer_mask_set(Eo *obj EINA_UNUSED, + Ector_Renderer_Software_Image_Data *pd, + Ector_Buffer *mask, + int op) +{ + pd->mask = mask; + pd->mask_op = op; +} + +#include "ector_renderer_software_image.eo.c" diff --git a/src/lib/ector/software/ector_renderer_software_image.eo b/src/lib/ector/software/ector_renderer_software_image.eo new file mode 100644 index 0000000000..8a3f9c51e7 --- /dev/null +++ b/src/lib/ector/software/ector_renderer_software_image.eo @@ -0,0 +1,13 @@ +class @beta Ector.Renderer.Software.Image extends Ector.Renderer.Software implements Ector.Renderer.Image +{ + [[Ector software renderer image class]] + c_prefix: ector_renderer_software_image; + implements { + Ector.Renderer.prepare; + Ector.Renderer.draw; + Ector.Renderer.mask { set; } + Ector.Renderer.crc { get; } + Efl.Object.constructor; + Efl.Object.destructor; + } +} diff --git a/src/lib/ector/software/ector_software_surface.c b/src/lib/ector/software/ector_software_surface.c index 08a2786f16..1008fe52b6 100644 --- a/src/lib/ector/software/ector_software_surface.c +++ b/src/lib/ector/software/ector_software_surface.c @@ -1,275 +1,277 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include "ector_private.h" #include "ector_software_private.h" #define MY_CLASS ECTOR_SOFTWARE_SURFACE_CLASS typedef struct _Ector_Software_Task Ector_Software_Task; struct _Ector_Software_Task { Eina_Thread_Queue_Msg member; Ector_Thread_Worker_Cb cb; Eina_Free_Cb done; void *data; }; static int _count_init = 0; static unsigned int current = 0; static unsigned int cpu_core = 0; static Ector_Software_Thread *ths = NULL; static Eina_Thread_Queue *render_queue = NULL; static Ector_Software_Thread render_thread; static void * _prepare_process(void *data, Eina_Thread t) { Ector_Software_Thread *th = data; eina_thread_name_set(t, "Ector Preparing Thread"); do { Ector_Software_Task *task, todo; void *ref; task = eina_thread_queue_wait(th->queue, &ref); if (!task) break ; todo.cb = task->cb; todo.data = task->data; todo.done = task->done; eina_thread_queue_wait_done(th->queue, ref); if (!todo.cb) break ; todo.cb(todo.data, th); task = eina_thread_queue_send(render_queue, sizeof (Ector_Software_Task), &ref); task->cb = todo.cb; task->data = todo.data; task->done = todo.done; eina_thread_queue_send_done(render_queue, ref); } while (1); return th; } static void _ector_software_init(void) { int cpu, i; ++_count_init; if (_count_init != 1) return; cpu = eina_cpu_count() - 1; if (cpu < 1) { render_thread.queue = NULL; ector_software_thread_init(&render_thread); return ; } cpu = cpu > 8 ? 8 : cpu; cpu_core = cpu; render_queue = eina_thread_queue_new(); ths = malloc(sizeof(Ector_Software_Thread) * cpu); for (i = 0; i < cpu; i++) { Ector_Software_Thread *t; t = &ths[i]; t->queue = eina_thread_queue_new(); ector_software_thread_init(t); if (!eina_thread_create(&t->thread, EINA_THREAD_NORMAL, -1, _prepare_process, t)) { eina_thread_queue_free(t->queue); t->queue = NULL; } } } static void _ector_software_shutdown(void) { Ector_Software_Thread *t; unsigned int i; --_count_init; if (_count_init != 0) return; if (!ths) { ector_software_thread_shutdown(&render_thread); return ; } for (i = 0; i < cpu_core; i++) { Ector_Software_Task *task; void *ref; t = &ths[i]; task = eina_thread_queue_send(t->queue, sizeof (Ector_Software_Task), &ref); task->cb = NULL; task->data = NULL; eina_thread_queue_send_done(t->queue, ref); eina_thread_join(t->thread); eina_thread_queue_free(t->queue); ector_software_thread_shutdown(t); } eina_thread_queue_free(render_queue); render_queue = NULL; free(ths); ths = NULL; } void ector_software_schedule(Ector_Thread_Worker_Cb cb, Eina_Free_Cb done, void *data) { Ector_Software_Thread *t; Ector_Software_Task *task; void *ref; // Not enough CPU, doing it inline in the rendering thread if (!ths) return ; t = &ths[current]; current = (current + 1) % cpu_core; task = eina_thread_queue_send(t->queue, sizeof (Ector_Software_Task), &ref); task->cb = cb; task->done = done; task->data = data; eina_thread_queue_send_done(t->queue, ref); } // Do not call this function if the done function has already called void ector_software_wait(Ector_Thread_Worker_Cb cb, Eina_Free_Cb done, void *data) { Ector_Software_Task *task, covering; // First handle case with just inlined prepare code call inside the rendering thread if (!ths) { render_thread.thread = eina_thread_self(); cb(data, &render_thread); done(data); return ; } // We don't know which task is going to be done first, so // we iterate until we find ourself back and trigger all // the done call along the way. do { void *ref; task = eina_thread_queue_wait(render_queue, &ref); if (!task) break; covering.cb = task->cb; covering.done = task->done; covering.data = task->data; eina_thread_queue_wait_done(render_queue, ref); covering.done(covering.data); } while (covering.cb != cb || covering.done != done || covering.data != data); } static Ector_Renderer * _ector_software_surface_ector_surface_renderer_factory_new(Eo *obj, Ector_Software_Surface_Data *pd EINA_UNUSED, const Efl_Class *type) { if (type == ECTOR_RENDERER_SHAPE_MIXIN) return efl_add_ref(ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); + else if (type == ECTOR_RENDERER_IMAGE_MIXIN) + return efl_add_ref(ECTOR_RENDERER_SOFTWARE_IMAGE_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); else if (type == ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN) return efl_add_ref(ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); else if (type == ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN) return efl_add_ref(ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, NULL, ector_renderer_surface_set(efl_added, obj)); ERR("Couldn't find class for type: %s", efl_class_name_get(type)); return NULL; } static Eo * _ector_software_surface_efl_object_constructor(Eo *obj, Ector_Software_Surface_Data *pd) { _ector_software_init(); obj = efl_constructor(efl_super(obj, MY_CLASS)); pd->rasterizer = (Software_Rasterizer *) calloc(1, sizeof(Software_Rasterizer)); ector_software_rasterizer_init(pd->rasterizer); pd->rasterizer->fill_data.raster_buffer = efl_data_ref(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN); return obj; } static void _ector_software_surface_efl_object_destructor(Eo *obj, Ector_Software_Surface_Data *pd) { efl_data_unref(obj, pd->rasterizer->fill_data.raster_buffer); free(pd->rasterizer); pd->rasterizer = NULL; efl_destructor(efl_super(obj, ECTOR_SOFTWARE_SURFACE_CLASS)); _ector_software_shutdown(); } static void _ector_software_surface_ector_surface_reference_point_set(Eo *obj EINA_UNUSED, Ector_Software_Surface_Data *pd, int x, int y) { pd->x = x; pd->y = y; } static Eina_Bool _ector_software_surface_ector_surface_draw_image(Eo *obj EINA_UNUSED, Ector_Software_Surface_Data *pd, Ector_Buffer *buffer, int x, int y, int alpha) { if (!buffer || !pd->rasterizer || !pd->rasterizer->fill_data.raster_buffer->pixels.u32) return EINA_FALSE; Ector_Software_Buffer_Base_Data *bd = efl_data_scope_get(buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN); const int pix_stride = pd->rasterizer->fill_data.raster_buffer->stride / 4; uint32_t *src = bd->pixels.u32; for (unsigned int local_y = 0; local_y < bd->generic->h; local_y++) { uint32_t *dst = pd->rasterizer->fill_data.raster_buffer->pixels.u32 + (x + ((local_y + y) * pix_stride)); for (unsigned int local_x = 0; local_x < bd->generic->w; local_x++) { *src = draw_mul_256(alpha, *src); int inv_alpha = 255 - ((*src) >> 24); *dst = *src + draw_mul_256(inv_alpha, *dst); dst++; src++; } } return EINA_TRUE; } #include "ector_software_surface.eo.c" #include "ector_renderer_software.eo.c" diff --git a/src/lib/ector/software/meson.build b/src/lib/ector/software/meson.build index 2dff5be26c..7374252729 100644 --- a/src/lib/ector/software/meson.build +++ b/src/lib/ector/software/meson.build @@ -1,53 +1,55 @@ ector_src += files([ 'ector_renderer_software_gradient_linear.c', 'ector_renderer_software_gradient_radial.c', 'ector_renderer_software_shape.c', + 'ector_renderer_software_image.c', 'ector_software_gradient.c', 'ector_software_rasterizer.c', 'ector_software_surface.c', 'ector_software_buffer.c', ]) pub_eo_files = [ 'ector_software_surface.eo', 'ector_software_buffer.eo', 'ector_software_buffer_base.eo', 'ector_renderer_software.eo', 'ector_renderer_software_shape.eo', + 'ector_renderer_software_image.eo', 'ector_renderer_software_gradient_radial.eo', 'ector_renderer_software_gradient_linear.eo', ] foreach eo_file : pub_eo_files pub_eo_file_target += custom_target('eolian_gen_' + eo_file, input : eo_file, output : [eo_file + '.h'], depfile : eo_file + '.d', install : false, install_dir : dir_package_include, command : eolian_gen + [ '-I', meson.current_source_dir(), eolian_include_directories, '-o', 'h:' + join_paths(meson.current_build_dir(), eo_file + '.h'), '-o', 'c:' + join_paths(meson.current_build_dir(), eo_file + '.c'), '-o', 'd:' + join_paths(meson.current_build_dir(), eo_file + '.d'), '-gchd', '@INPUT@']) endforeach if cpu_sse3 == true ector_opt = static_library('ector_opt', sources: pub_eo_file_target + [ 'ector_software_gradient_sse3.c' ], dependencies: ector_pub_deps + [triangulator, freetype, draw, m] + ector_deps, include_directories: config_dir + [ include_directories('..') ], c_args: native_arch_opt_c_args, ) ector_opt_lib += [ ector_opt ] endif if get_option('install-eo-files') install_data(pub_eo_files, install_dir: join_paths(eolian_include_dir, package_version_name) ) endif