From 0fa8dc48cd79eec2c4d140001a2c3da2afff682c Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Mon, 26 Sep 2016 15:43:25 -0300 Subject: [PATCH] Evas FB: Add support for region push hook. This will be useful to support the Ecore_Evas VNC server under FB backend. --- src/modules/evas/engines/fb/Evas_Engine_FB.h | 4 ++ src/modules/evas/engines/fb/evas_engine.c | 76 ++++++++++++++++++-- src/modules/evas/engines/fb/evas_engine.h | 7 ++ src/modules/evas/engines/fb/evas_outbuf.c | 1 + 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/src/modules/evas/engines/fb/Evas_Engine_FB.h b/src/modules/evas/engines/fb/Evas_Engine_FB.h index b548237857..12c50670f6 100644 --- a/src/modules/evas/engines/fb/Evas_Engine_FB.h +++ b/src/modules/evas/engines/fb/Evas_Engine_FB.h @@ -19,6 +19,10 @@ struct _Evas_Engine_Info_FB /* non-blocking or blocking mode */ Evas_Engine_Render_Mode render_mode; + + struct { + void (*region_push_hook)(Evas *e, int x, int y, int w, int h, const void *pixels); + } func; }; #endif diff --git a/src/modules/evas/engines/fb/evas_engine.c b/src/modules/evas/engines/fb/evas_engine.c index 9457485dd9..3156b95a78 100644 --- a/src/modules/evas/engines/fb/evas_engine.c +++ b/src/modules/evas/engines/fb/evas_engine.c @@ -3,8 +3,13 @@ #include "evas_engine.h" #include "Evas_Engine_FB.h" +#include +#include + int _evas_engine_fb_log_dom = -1; +static Eina_List *_outbufs = NULL; + /* function tables - filled in later (func and parent func) */ static Evas_Func func, pfunc; @@ -16,17 +21,76 @@ struct _Render_Engine Render_Engine_Software_Generic generic; }; +typedef struct _Region_Push_Hook_Ctx { + void *pixels; + Outbuf *buf; + int x; + int y; + int w; + int h; +} Region_Push_Hook_Ctx; + /* prototypes we will use here */ -static void *_output_setup(int w, int h, int rot, int vt, int dev, int refresh); +static void *_output_setup(Evas *eo_e, int w, int h, int rot, int vt, int dev, int refresh, + void (*region_push_hook)(Evas *e, int x, int y, int w, int h, + const void *pixels)); static void *eng_info(Evas *eo_e); static void eng_info_free(Evas *eo_e, void *info); static int eng_setup(Evas *eo_e, void *info); static void eng_output_free(void *data); +static void +_evas_fb_region_push_hook_call(void *data) +{ + Region_Push_Hook_Ctx *ctx = data; + + + if (eina_list_data_find(_outbufs, ctx->buf)) + { + ctx->buf->region_push_hook.cb(ctx->buf->region_push_hook.evas, + ctx->x, ctx->y, ctx->w, ctx->h, + ctx->pixels); + } + + free(ctx->pixels); + free(ctx); +} + +void +evas_fb_region_push_hook_call(Outbuf *buf, int x, int y, int w, int h, + const void *pixels) +{ + Region_Push_Hook_Ctx *ctx; + size_t s; + + if (!buf->region_push_hook.cb) + return; + + s = w * h * buf->priv.fb.fb->bpp; + ctx = malloc(sizeof(Region_Push_Hook_Ctx)); + EINA_SAFETY_ON_NULL_RETURN(ctx); + ctx->pixels = malloc(s); + EINA_SAFETY_ON_NULL_GOTO(ctx->pixels, err_pixels); + ctx->x = x; + ctx->y = y; + ctx->w = w; + ctx->h = h; + ctx->buf = buf; + memcpy(ctx->pixels, pixels, s); + + ecore_main_loop_thread_safe_call_async(_evas_fb_region_push_hook_call, ctx); + return; + + err_pixels: + free(ctx); +} + /* internal engine routines */ static void * -_output_setup(int w, int h, int rot, int vt, int dev, int refresh) +_output_setup(Evas *eo_e, int w, int h, int rot, int vt, int dev, int refresh, + void (*region_push_hook)(Evas *e, int x, int y, int w, int h, + const void *pixels)) { Render_Engine *re; Outbuf *ob; @@ -43,6 +107,8 @@ _output_setup(int w, int h, int rot, int vt, int dev, int refresh) ob = evas_fb_outbuf_fb_setup_fb(w, h, rot, OUTBUF_DEPTH_INHERIT, vt, dev, refresh); if (!ob) goto on_error; + ob->region_push_hook.cb = region_push_hook; + ob->region_push_hook.evas = eo_e; if (!evas_render_engine_software_generic_init(&re->generic, ob, NULL, evas_fb_outbuf_fb_get_rot, evas_fb_outbuf_fb_reconfigure, @@ -61,6 +127,7 @@ _output_setup(int w, int h, int rot, int vt, int dev, int refresh) /* no backbuf! */ evas_fb_outbuf_fb_set_have_backbuf(ob, 0); + _outbufs = eina_list_append(_outbufs, ob); return re; on_error: @@ -98,12 +165,12 @@ eng_setup(Evas *eo_e, void *in) Evas_Engine_Info_FB *info; info = (Evas_Engine_Info_FB *)in; - re = _output_setup(e->output.w, + re = _output_setup(eo_e, e->output.w, e->output.h, info->info.rotation, info->info.virtual_terminal, info->info.device_number, - info->info.refresh); + info->info.refresh, info->func.region_push_hook); e->engine.data.output = re; if (!e->engine.data.output) return 0; e->engine.data.context = e->engine.func->context_new(e->engine.data.output); @@ -119,6 +186,7 @@ eng_output_free(void *data) re = (Render_Engine *)data; if (re) { + _outbufs = eina_list_remove(_outbufs, re->generic.ob); evas_render_engine_software_generic_clean(&re->generic); free(re); } diff --git a/src/modules/evas/engines/fb/evas_engine.h b/src/modules/evas/engines/fb/evas_engine.h index 424d47cbbe..44e4991034 100644 --- a/src/modules/evas/engines/fb/evas_engine.h +++ b/src/modules/evas/engines/fb/evas_engine.h @@ -46,6 +46,11 @@ struct _Outbuf } mask; RGBA_Image *back_buf; } priv; + + struct { + void (*cb)(Evas *e, int x, int y, int w, int h, const void *pixels); + Evas *evas; + } region_push_hook; }; /****/ @@ -68,4 +73,6 @@ int evas_fb_outbuf_fb_get_rot (Outbuf *buf); int evas_fb_outbuf_fb_get_have_backbuf (Outbuf *buf); void evas_fb_outbuf_fb_set_have_backbuf (Outbuf *buf, int have_backbuf); +void evas_fb_region_push_hook_call(Outbuf *buf, int x, int y, int w, int h, const void *pixels); + #endif diff --git a/src/modules/evas/engines/fb/evas_outbuf.c b/src/modules/evas/engines/fb/evas_outbuf.c index 77274289db..46b0441fea 100644 --- a/src/modules/evas/engines/fb/evas_outbuf.c +++ b/src/modules/evas/engines/fb/evas_outbuf.c @@ -357,6 +357,7 @@ evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, in h, w, x, y, NULL); } + evas_fb_region_push_hook_call(buf, x, y, w, h, src_data); } } }