bdilly pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=0fa8dc48cd79eec2c4d140001a2c3da2afff682c

commit 0fa8dc48cd79eec2c4d140001a2c3da2afff682c
Author: Guilherme Iscaro <[email protected]>
Date:   Mon Sep 26 15:43:25 2016 -0300

    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 b548237..12c5067 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 9457485..3156b95 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 <Ecore.h>
+#include <Eina.h>
+
 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 424d47c..44e4991 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 7727428..46b0441 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);
          }
      }
 }

-- 


Reply via email to