Evas: Add a Wayland Shared Memory engine (similar to the buffer &
authordevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 14 Dec 2011 18:44:20 +0000 (18:44 +0000)
committerdevilhorns <devilhorns@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 14 Dec 2011 18:44:20 +0000 (18:44 +0000)
framebuffer engines). Add Evas framespace set/get functions.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@66223 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

14 files changed:
Makefile.am
configure.ac
evas-wayland-shm.pc.in [new file with mode: 0644]
m4/evas_check_engine.m4
src/lib/Evas.h
src/lib/Makefile.am
src/lib/canvas/evas_main.c
src/lib/include/evas_private.h
src/modules/engines/Makefile.am
src/modules/engines/wayland_shm/Evas_Engine_Wayland_Shm.h [new file with mode: 0644]
src/modules/engines/wayland_shm/Makefile.am [new file with mode: 0644]
src/modules/engines/wayland_shm/evas_engine.c [new file with mode: 0644]
src/modules/engines/wayland_shm/evas_engine.h [new file with mode: 0644]
src/modules/engines/wayland_shm/evas_outbuf.c [new file with mode: 0644]

index 665f988..8a9445e 100644 (file)
@@ -45,6 +45,7 @@ evas-direct3d.pc.in \
 evas-software-16-wince.pc.in \
 evas-software-sdl.pc.in \
 evas-psl1ght.pc.in \
+evas-wayland-shm.pc.in \
 evas.spec.in \
 evas.spec \
 m4/efl_attribute.m4 \
@@ -127,6 +128,10 @@ if BUILD_ENGINE_PSL1GHT
 pkgconfig_DATA += evas-psl1ght.pc
 endif
 
+if BUILD_ENGINE_WAYLAND_SHM
+pkgconfig_DATA += evas-wayland-shm.pc
+endif
+
 .PHONY: doc coverage
 
 doc:
index ee9a4cc..6b5609c 100644 (file)
@@ -112,6 +112,7 @@ want_evas_engine_direct3d="no"
 want_evas_engine_fb="no"
 want_evas_engine_directfb="no"
 want_evas_engine_psl1ght="no"
+want_evas_engine_wayland_shm="no"
 
 want_evas_image_loader_edb="yes"
 want_evas_image_loader_eet="yes"
@@ -703,6 +704,8 @@ EVAS_CHECK_ENGINE([software-16-wince], [${want_evas_engine_software_16_wince}],
 
 EVAS_CHECK_ENGINE([software-16-sdl], [${want_evas_engine_software_16_sdl}], [no], [Software SDL 16 bits])
 
+EVAS_CHECK_ENGINE([wayland-shm], [${want_evas_engine_wayland_shm}], [no], [Wayland Shm])
+
 # SDL primitive
 sdl_primitive="no"
 
@@ -1820,6 +1823,7 @@ evas-direct3d.pc
 evas-software-16-wince.pc
 evas-software-sdl.pc
 evas-psl1ght.pc
+evas-wayland-shm.pc
 evas.pc
 doc/evas.dox
 doc/Makefile
@@ -1864,6 +1868,7 @@ src/modules/engines/software_16/Makefile
 src/modules/engines/software_16_x11/Makefile
 src/modules/engines/software_16_ddraw/Makefile
 src/modules/engines/software_16_sdl/Makefile
+src/modules/engines/wayland_shm/Makefile
 src/modules/loaders/Makefile
 src/modules/loaders/edb/Makefile
 src/modules/loaders/eet/Makefile
@@ -1960,6 +1965,7 @@ echo "  Software 16bit X11.........: $have_evas_engine_software_16_x11"
 echo "  Software 16bit Directdraw..: $have_evas_engine_software_16_ddraw"
 echo "  Software 16bit WinCE.......: $have_evas_engine_software_16_wince"
 echo "  Software 16bit SDL.........: $have_evas_engine_software_16_sdl (primitive: $sdl_primitive)"
+echo "  Wayland Shm................: $have_evas_engine_wayland_shm"
 echo
 echo "Image Loaders:"
 echo "  BMP.....................: $have_evas_image_loader_bmp"
diff --git a/evas-wayland-shm.pc.in b/evas-wayland-shm.pc.in
new file mode 100644 (file)
index 0000000..5576681
--- /dev/null
@@ -0,0 +1,3 @@
+Name: evas-wayland-shm
+Description: Evas Wayland Shm engine
+Version: @VERSION@
index 5294100..45a5871 100644 (file)
@@ -873,6 +873,80 @@ fi
 
 ])
 
+
+dnl use: EVAS_CHECK_ENGINE_DEP_WAYLAND_SHM(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+
+AC_DEFUN([EVAS_CHECK_ENGINE_DEP_WAYLAND_SHM],
+[
+
+have_dep="yes"
+evas_engine_[]$1[]_cflags=""
+evas_engine_[]$1[]_libs=""
+
+AC_SUBST([evas_engine_$1_cflags])
+AC_SUBST([evas_engine_$1_libs])
+
+if test "x${have_dep}" = "xyes" ; then
+  m4_default([$4], [:])
+else
+  m4_default([$5], [:])
+fi
+
+])
+
+
+dnl use: EVAS_CHECK_ENGINE_DEP_WAYLAND_EGL(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+
+AC_DEFUN([EVAS_CHECK_ENGINE_DEP_WAYLAND_EGL],
+[
+
+requirement=""
+have_dep="no"
+evas_engine_[]$1[]_cflags=""
+evas_engine_[]$1[]_libs=""
+
+PKG_CHECK_MODULES([WAYLAND_EGL],
+   [wayland-egl],
+   [
+    have_dep="yes"
+    requirement="wayland-egl"
+    evas_engine_[]$1[]_cflags="${WAYLAND_EGL_CFLAGS}"
+    evas_engine_[]$1[]_libs="${WAYLAND_EGL_LIBS}"
+   ],[
+    have_dep="no"
+   ]
+)
+
+if test "x${have_dep}" = "xyes" ; then
+   AC_CHECK_HEADER([GLES2/gl2.h],
+      [have_egl="yes"],
+      [have_egl="no"],
+      [
+#include <GLES2/gl2.h>
+#include <EGL/egl.h>
+      ])
+   if test "x${have_egl}" = "xyes" ; then
+      evas_engine_[]$1[]_cflags="${WAYLAND_EGL_CFLAGS}"
+      evas_engine_[]$1[]_libs="${WAYLAND_EGL_LIBS} -lGLESv2 -lEGL"
+   fi
+fi
+
+AC_SUBST([evas_engine_$1_cflags])
+AC_SUBST([evas_engine_$1_libs])
+
+if test "x$3" = "xstatic" ; then
+   requirement_evas="${requirement} ${requirement_evas}"
+fi
+
+if test "x${have_dep}" = "xyes" ; then
+  m4_default([$4], [:])
+else
+  m4_default([$5], [:])
+fi
+
+])
+
+
 dnl use: EVAS_CHECK_ENGINE(engine, want_engine, simple, description)
 
 
index de1cb78..72a79b4 100644 (file)
@@ -1877,6 +1877,38 @@ EAPI void              evas_output_viewport_set          (Evas *e, Evas_Coord x,
 EAPI void              evas_output_viewport_get          (const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) EINA_ARG_NONNULL(1);
 
 /**
+ * Sets the output framespace size of the render engine of the given evas.
+ *
+ * The framespace size is used in the Wayland engines to denote space where 
+ * the output is not drawn. This is mainly used in ecore_evas to draw borders
+ *
+ * The units used for @p w and @p h depend on the engine used by the
+ * evas.
+ *
+ * @param   e The given evas.
+ * @param   x The left coordinate in output units, usually pixels.
+ * @param   y The top coordinate in output units, usually pixels.
+ * @param   w The width in output units, usually pixels.
+ * @param   h The height in output units, usually pixels.
+ * @ingroup Evas_Output_Size
+ * @since 1.1.0
+ */
+EAPI void              evas_output_framespace_set        (Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
+
+/**
+ * Get the render engine's output framespace co-ordinates in canvas units.
+ * 
+ * @param e The pointer to the Evas Canvas
+ * @param x The pointer to a x variable to be filled in
+ * @param y The pointer to a y variable to be filled in
+ * @param w The pointer to a width variable to be filled in
+ * @param h The pointer to a height variable to be filled in
+ * @ingroup Evas_Output_Size
+ * @since 1.1.0
+ */
+EAPI void              evas_output_framespace_get        (const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
+
+/**
  * @defgroup Evas_Coord_Mapping_Group Coordinate Mapping Functions
  *
  * Functions that are used to map coordinates from the canvas to the
index 878888c..2a1a92d 100644 (file)
@@ -100,6 +100,11 @@ SUBDIRS += ../modules/engines/software_x11/
 EVAS_STATIC_MODULE += ../modules/engines/software_x11/libevas_engine_software_x11.la
 EVAS_STATIC_LIBADD += @evas_engine_software_xlib_libs@ @evas_engine_software_xcb_libs@
 endif
+if EVAS_STATIC_BUILD_WAYLAND_SHM
+SUBDIRS += ../modules/engines/wayland_shm/
+EVAS_STATIC_MODULE += ../modules/engines/wayland_shm/libevas_engine_wayland_shm.la
+EVAS_STATIC_LIBADD += @evas_engine_wayland_shm_libs@
+endif
 if EVAS_STATIC_BUILD_BMP
 SUBDIRS += ../modules/loaders/bmp
 EVAS_STATIC_MODULE += ../modules/loaders/bmp/libevas_loader_bmp.la
index 0a37b2c..2466a37 100644 (file)
@@ -408,6 +408,49 @@ evas_output_viewport_get(const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord
    if (h) *h = e->viewport.h;
 }
 
+EAPI void 
+evas_output_framespace_set(Evas *e, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) 
+{
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return;
+   MAGIC_CHECK_END();
+
+   if ((x == e->framespace.x) && (y == e->framespace.y) &&
+       (w == e->framespace.w) && (h == e->framespace.h)) return;
+   if (w <= 0) return;
+   if (h <= 0) return;
+   /* if ((x != 0) || (y != 0)) */
+   /*   { */
+   /*  ERR("Compat error. viewport x,y != 0,0 not supported"); */
+   /*  x = 0; */
+   /*  y = 0; */
+   /*   } */
+   e->framespace.x = x;
+   e->framespace.y = y;
+   e->framespace.w = w;
+   e->framespace.h = h;
+   e->framespace.changed = 1;
+   /* e->output_validity++; */
+   e->changed = 1;
+}
+
+EAPI void 
+evas_output_framespace_get(const Evas *e, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) 
+{
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   if (x) *x = 0;
+   if (y) *y = 0;
+   if (w) *w = 0;
+   if (h) *h = 0;
+   return;
+   MAGIC_CHECK_END();
+
+   if (x) *x = e->framespace.x;
+   if (y) *y = e->framespace.y;
+   if (w) *w = e->framespace.w;
+   if (h) *h = e->framespace.h;
+}
+
 EAPI Evas_Coord
 evas_coord_screen_x_to_world(const Evas *e, int x)
 {
index b5cd4c5..776847a 100644 (file)
@@ -321,6 +321,12 @@ struct _Evas
       unsigned char  changed : 1;
    } output;
 
+   struct 
+     {
+        Evas_Coord x, y, w, h;
+        Eina_Bool changed : 1;
+     } framespace;
+
    Eina_List        *damages;
    Eina_List        *obscures;
 
index 7d870a1..2fdac8c 100644 (file)
@@ -68,4 +68,6 @@ endif
 if !EVAS_STATIC_BUILD_SOFTWARE_X11
 SUBDIRS += software_x11
 endif
-
+if !EVAS_STATIC_BUILD_WAYLAND_SHM
+SUBDIRS += wayland_shm
+endif
diff --git a/src/modules/engines/wayland_shm/Evas_Engine_Wayland_Shm.h b/src/modules/engines/wayland_shm/Evas_Engine_Wayland_Shm.h
new file mode 100644 (file)
index 0000000..b34b2c1
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _EVAS_ENGINE_WAYLAND_SHM_H
+# define _EVAS_ENGINE_WAYLAND_SHM_H
+
+typedef struct _Evas_Engine_Info_Wayland_Shm Evas_Engine_Info_Wayland_Shm;
+struct _Evas_Engine_Info_Wayland_Shm 
+{
+   Evas_Engine_Info magic;
+
+   struct 
+     {
+        void *dest;
+        int rotation;
+
+        unsigned char debug : 1;
+     } info;
+
+   Evas_Engine_Render_Mode render_mode;
+};
+
+#endif
diff --git a/src/modules/engines/wayland_shm/Makefile.am b/src/modules/engines/wayland_shm/Makefile.am
new file mode 100644 (file)
index 0000000..455b82c
--- /dev/null
@@ -0,0 +1,45 @@
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/modules/engines \
+@FREETYPE_CFLAGS@ \
+@EINA_CFLAGS@ \
+@evas_engine_wayland_shm_cflags@
+
+if BUILD_ENGINE_WAYLAND_SHM
+
+WAYLAND_SHM_SOURCES = \
+evas_engine.c \
+evas_outbuf.c
+
+WAYLAND_SHM_LIBADD = @FREETYPE_LIBS@ @EINA_LIBS@ @evas_engine_wayland_shm_libs@
+
+includes_HEADERS = Evas_Engine_Wayland_Shm.h
+includesdir = $(includedir)/evas-@VMAJ@
+
+if !EVAS_STATIC_BUILD_WAYLAND_SHM
+
+pkgdir = $(libdir)/evas/modules/engines/wayland_shm/$(MODULE_ARCH)
+pkg_LTLIBRARIES        = module.la
+
+module_la_SOURCES = $(WAYLAND_SHM_SOURCES)
+module_la_LIBADD = $(WAYLAND_SHM_LIBADD) $(top_builddir)/src/lib/libevas.la
+module_la_LDFLAGS = -no-undefined -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+else
+
+noinst_LTLIBRARIES = libevas_engine_wayland_shm.la
+
+libevas_engine_wayland_shm_la_SOURCES = $(WAYLAND_SHM_SOURCES)
+libevas_engine_wayland_shm_la_LIBADD = $(WAYLAND_SHM_LIBADD)
+
+endif
+endif
+
+EXTRA_DIST = \
+evas_engine.h
diff --git a/src/modules/engines/wayland_shm/evas_engine.c b/src/modules/engines/wayland_shm/evas_engine.c
new file mode 100644 (file)
index 0000000..466ac9d
--- /dev/null
@@ -0,0 +1,379 @@
+#include "evas_common.h"
+#include "evas_private.h"
+#include "evas_engine.h"
+#include "Evas_Engine_Wayland_Shm.h"
+
+/* local structures */
+typedef struct _Render_Engine Render_Engine;
+struct _Render_Engine 
+{
+   Tilebuf *tb;
+   Tilebuf_Rect *rects;
+   Outbuf *ob;
+   Eina_Inlist *cur_rect;
+
+   Eina_Bool end : 1;
+
+   void (*outbuf_free)(Outbuf *ob);
+   void (*outbuf_resize)(Outbuf *ob, int w, int h);
+   RGBA_Image *(*outbuf_new_region_for_update)(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
+   void (*outbuf_push_updated_region)(Outbuf *ob, RGBA_Image *surface, int x, int y, int w, int h);
+   void (*outbuf_free_region_for_update)(Outbuf *ob, RGBA_Image *update);
+};
+
+/* local variables */
+static Evas_Func func, pfunc;
+
+/* external variables */
+int _evas_engine_way_shm_log_dom = -1;
+
+/* local function prototypes */
+static void *_output_setup(int w, int h, int rotation, void *dest);
+
+/* engine function prototypes */
+static void *eng_info(Evas *evas __UNUSED__);
+static void eng_info_free(Evas *evas __UNUSED__, void *info);
+static int eng_setup(Evas *evas, void *info);
+static void eng_output_free(void *data);
+static void eng_output_resize(void *data, int w, int h);
+static void eng_output_tile_size_set(void *data, int w, int h);
+static void eng_output_redraws_rect_add(void *data, int x, int y, int w, int h);
+static void eng_output_redraws_rect_del(void *data, int x, int y, int w, int h);
+static void eng_output_redraws_clear(void *data);
+static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch);
+static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h);
+static void eng_output_flush(void *data);
+static void eng_output_idle_flush(void *data);
+static Eina_Bool eng_canvas_alpha_get(void *data, void *context __UNUSED__);
+
+/* local functions */
+static void *
+_output_setup(int w, int h, int rotation, void *dest) 
+{
+   Render_Engine *re = NULL;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
+
+   if (!(re->ob = evas_outbuf_setup(w, h, rotation, dest))) 
+     {
+        free(re);
+        return NULL;
+     }
+
+   if (!(re->tb = evas_common_tilebuf_new(w, h))) 
+     {
+        evas_outbuf_free(re->ob);
+        free(re);
+        return NULL;
+     }
+
+   evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
+   return re;
+}
+
+/* engine functions */
+static void *
+eng_info(Evas *evas __UNUSED__) 
+{
+   Evas_Engine_Info_Wayland_Shm *info;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(info = calloc(1, sizeof(Evas_Engine_Info_Wayland_Shm))))
+     return NULL;
+
+   info->magic.magic = rand();
+   info->info.debug = EINA_FALSE;
+   info->render_mode = EVAS_RENDER_MODE_BLOCKING;
+
+   return info;
+}
+
+static void 
+eng_info_free(Evas *evas __UNUSED__, void *info) 
+{
+   Evas_Engine_Info_Wayland_Shm *in;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(in = (Evas_Engine_Info_Wayland_Shm *)info)) return;
+   free(in);
+}
+
+static int 
+eng_setup(Evas *evas, void *info) 
+{
+   Evas_Engine_Info_Wayland_Shm *in;
+   Render_Engine *re = NULL;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(in = (Evas_Engine_Info_Wayland_Shm *)info)) return 0;
+
+   if (!evas->engine.data.output) 
+     {
+        evas_common_cpu_init();
+        evas_common_blend_init();
+        evas_common_image_init();
+        evas_common_convert_init();
+        evas_common_scale_init();
+        evas_common_rectangle_init();
+        evas_common_polygon_init();
+        evas_common_line_init();
+        evas_common_font_init();
+        evas_common_draw_init();
+        evas_common_tilebuf_init();
+
+        re = _output_setup(evas->output.w, evas->output.h, 
+                           in->info.rotation, in->info.dest);
+        if (!re) return 0;
+
+        re->outbuf_free = evas_outbuf_free;
+        re->outbuf_resize = evas_outbuf_resize;
+        re->outbuf_new_region_for_update = evas_outbuf_new_region_for_update;
+        re->outbuf_push_updated_region = evas_outbuf_push_updated_region;
+        re->outbuf_free_region_for_update = evas_outbuf_free_region_for_update;
+     }
+   else 
+     {
+        if (!(re = evas->engine.data.output)) return 0;
+        if (re->ob) re->outbuf_free(re->ob);
+        re->ob = evas_outbuf_setup(evas->output.w, evas->output.h, 
+                                   in->info.rotation, in->info.dest);
+        if (re->tb) evas_common_tilebuf_free(re->tb);
+        if ((re->tb = evas_common_tilebuf_new(evas->output.w, evas->output.h)))
+          evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
+     }
+
+   evas->engine.data.output = re;
+
+   if (!evas->engine.data.context) 
+     {
+        evas->engine.data.context = 
+          evas->engine.func->context_new(evas->engine.data.output);
+     }
+
+   return 1;
+}
+
+static void 
+eng_output_free(void *data) 
+{
+   Render_Engine *re = NULL;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if ((re = (Render_Engine *)data)) 
+     {
+        if (re->ob) re->outbuf_free(re->ob);
+        if (re->tb) evas_common_tilebuf_free(re->tb);
+        if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
+        free(re);
+     }
+   evas_common_font_shutdown();
+   evas_common_image_shutdown();
+}
+
+static void 
+eng_output_resize(void *data, int w, int h) 
+{
+   Render_Engine *re = NULL;
+
+   LOGFN(__FILE__, __LINE__, __FUNCTION__);
+
+   if (!(re = (Render_Engine *)data)) return;
+
+   if (re->ob) 
+     {
+        re->outbuf_resize(re->ob, w, h);
+        /* int rot; */
+        /* void *dest; */
+
+        /* dest = re->ob->priv.dest; */
+        /* rot = re->ob->rotation; */
+        /* re->outbuf_free(re->ob); */
+        /* re->ob = evas_outbuf_setup(w, h, rot, dest); */
+     }
+
+   if (re->tb) evas_common_tilebuf_free(re->tb);
+   if ((re->tb = evas_common_tilebuf_new(w, h)))
+     evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
+}
+
+static void 
+eng_output_tile_size_set(void *data, int w, int h) 
+{
+   Render_Engine *re = NULL;
+
+   if (!(re = (Render_Engine *)data)) return;
+   if (re->tb) evas_common_tilebuf_set_tile_size(re->tb, w, h);
+}
+
+static void 
+eng_output_redraws_rect_add(void *data, int x, int y, int w, int h) 
+{
+   Render_Engine *re = NULL;
+
+   if (!(re = (Render_Engine *)data)) return;
+   if (re->tb) evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
+}
+
+static void 
+eng_output_redraws_rect_del(void *data, int x, int y, int w, int h) 
+{
+   Render_Engine *re = NULL;
+
+   if (!(re = (Render_Engine *)data)) return;
+   if (re->tb) evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
+}
+
+static void 
+eng_output_redraws_clear(void *data) 
+{
+   Render_Engine *re = NULL;
+
+   if (!(re = (Render_Engine *)data)) return;
+   if (re->tb) evas_common_tilebuf_clear(re->tb);
+}
+
+static void *
+eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) 
+{
+   Render_Engine *re = NULL;
+   RGBA_Image *surface;
+   Tilebuf_Rect *rect;
+   int ux = 0, uy = 0, uw = 0, uh = 0;
+
+   if (!(re = (Render_Engine *)data)) return NULL;
+   if (re->end) 
+     {
+        re->end = EINA_FALSE;
+        return NULL;
+     }
+   if (!re->rects) 
+     {
+        re->rects = evas_common_tilebuf_get_render_rects(re->tb);
+        re->cur_rect = EINA_INLIST_GET(re->rects);
+     }
+   if (!re->cur_rect) return NULL;
+   rect = (Tilebuf_Rect *)re->cur_rect;
+   ux = rect->x;
+   uy = rect->y;
+   uw = rect->w;
+   uh = rect->h;
+   re->cur_rect = re->cur_rect->next;
+   if (!re->cur_rect) 
+     {
+        evas_common_tilebuf_free_render_rects(re->rects);
+        evas_common_tilebuf_clear(re->tb);
+        re->rects = NULL;
+        re->end = EINA_TRUE;
+     }
+   surface = 
+     re->outbuf_new_region_for_update(re->ob, ux, uy, uw, uh, cx, cy, cw, ch);
+   if (x) *x = ux;
+   if (y) *y = uy;
+   if (w) *w = uw;
+   if (h) *h = uh;
+   return surface;
+}
+
+static void 
+eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h) 
+{
+   Render_Engine *re = NULL;
+
+   if (!(re = (Render_Engine *)data)) return;
+#ifdef BUILD_PIPE_RENDER
+   evas_common_pipe_map_begin(surface);
+#endif
+   if (re->ob) 
+     {
+        re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
+        re->outbuf_free_region_for_update(re->ob, surface);
+     }
+   evas_common_cpu_end_opt();
+}
+
+static void 
+eng_output_flush(void *data) 
+{
+   Render_Engine *re = NULL;
+
+   if (!(re = (Render_Engine *)data)) return;
+}
+
+static void 
+eng_output_idle_flush(void *data) 
+{
+   Render_Engine *re = NULL;
+
+   if (!(re = (Render_Engine *)data)) return;
+}
+
+static Eina_Bool 
+eng_canvas_alpha_get(void *data, void *context __UNUSED__) 
+{
+   Render_Engine *re = NULL;
+
+   if (!(re = (Render_Engine *)data)) return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+/* module functions */
+static int 
+module_open(Evas_Module *em) 
+{
+   if (!em) return 0;
+
+   if (!_evas_module_engine_inherit(&pfunc, "software_generic"))
+     return 0;
+
+   _evas_engine_way_shm_log_dom = 
+     eina_log_domain_register("evas-wayland_shm", EVAS_DEFAULT_LOG_COLOR);
+   if (_evas_engine_way_shm_log_dom < 0) 
+     {
+        EINA_LOG_ERR("Could not create a module log domain.");
+        return 0;
+     }
+
+   func = pfunc;
+
+#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
+   ORD(info);
+   ORD(info_free);
+   ORD(setup);
+   ORD(canvas_alpha_get);
+   ORD(output_free);
+   ORD(output_resize);
+   ORD(output_tile_size_set);
+   ORD(output_redraws_rect_add);
+   ORD(output_redraws_rect_del);
+   ORD(output_redraws_clear);
+   ORD(output_redraws_next_update_get);
+   ORD(output_redraws_next_update_push);
+   ORD(output_flush);
+   ORD(output_idle_flush);
+
+   em->functions = (void *)(&func);
+   return 1;
+}
+
+static void 
+module_close(Evas_Module *em __UNUSED__) 
+{
+   eina_log_domain_unregister(_evas_engine_way_shm_log_dom);
+}
+
+static Evas_Module_Api evas_modapi = 
+{
+   EVAS_MODULE_API_VERSION, "wayland_shm", "none", {module_open, module_close}
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, wayland_shm);
+
+#ifndef EVAS_STATIC_BUILD_WAYLAND_SHM
+EVAS_EINA_MODULE_DEFINE(engine, wayland_shm);
+#endif
diff --git a/src/modules/engines/wayland_shm/evas_engine.h b/src/modules/engines/wayland_shm/evas_engine.h
new file mode 100644 (file)
index 0000000..878851a
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef _EVAS_ENGINE_H
+# define _EVAS_ENGINE_H
+
+//# define LOGFNS 1
+
+# ifdef LOGFNS
+#  include <stdio.h>
+#  define LOGFN(fl, ln, fn) printf("-EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
+# else
+#  define LOGFN(fl, ln, fn)
+# endif
+
+extern int _evas_engine_way_shm_log_dom;
+
+# ifdef ERR
+#  undef ERR
+# endif
+# define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_way_shm_log_dom, __VA_ARGS__)
+
+# ifdef DBG
+#  undef DBG
+# endif
+# define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_way_shm_log_dom, __VA_ARGS__)
+
+# ifdef INF
+#  undef INF
+# endif
+# define INF(...) EINA_LOG_DOM_INFO(_evas_engine_way_shm_log_dom, __VA_ARGS__)
+
+# ifdef WRN
+#  undef WRN
+# endif
+# define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_way_shm_log_dom, __VA_ARGS__)
+
+# ifdef CRIT
+#  undef CRIT
+# endif
+# define CRIT(...) EINA_LOG_DOM_CRIT(_evas_engine_way_shm_log_dom, __VA_ARGS__)
+
+typedef struct _Outbuf Outbuf;
+struct _Outbuf 
+{
+   int w, h;
+   int rotation;
+
+   struct 
+     {
+        void *dest;
+        RGBA_Image *buffer;
+     } priv;
+};
+
+void evas_outbuf_free(Outbuf *ob);
+void evas_outbuf_resize(Outbuf *ob, int w, int h);
+Outbuf *evas_outbuf_setup(int w, int h, int rot, void *dest);
+RGBA_Image *evas_outbuf_new_region_for_update(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
+void evas_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update, int x __UNUSED__, int y, int w, int h);
+void evas_outbuf_free_region_for_update(Outbuf *ob, RGBA_Image *update);
+
+#endif
diff --git a/src/modules/engines/wayland_shm/evas_outbuf.c b/src/modules/engines/wayland_shm/evas_outbuf.c
new file mode 100644 (file)
index 0000000..635cb37
--- /dev/null
@@ -0,0 +1,97 @@
+#include "evas_common.h"
+#include "evas_engine.h"
+
+void 
+evas_outbuf_free(Outbuf *ob) 
+{
+   if (!ob) return;
+   if (ob->priv.buffer) evas_cache_image_drop(&ob->priv.buffer->cache_entry);
+   free(ob);
+}
+
+void 
+evas_outbuf_resize(Outbuf *ob, int w, int h) 
+{
+   if (!ob) return;
+   if ((ob->w == w) && (ob->h == h)) return;
+   ob->w = w;
+   ob->h = h;
+   if (ob->priv.buffer) evas_cache_image_drop(&ob->priv.buffer->cache_entry);
+   ob->priv.buffer = NULL;
+}
+
+Outbuf *
+evas_outbuf_setup(int w, int h, int rot, void *dest) 
+{
+   Outbuf *ob = NULL;
+
+   if (!(ob = calloc(1, sizeof(Outbuf)))) return NULL;
+
+   ob->w = w;
+   ob->h = h;
+   ob->rotation = rot;
+   ob->priv.dest = dest;
+
+   ob->priv.buffer = 
+     (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), 
+                                         w, h, ob->priv.dest, 
+                                         1, EVAS_COLORSPACE_ARGB8888);
+
+   return ob;
+}
+
+RGBA_Image *
+evas_outbuf_new_region_for_update(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) 
+{
+   if (ob->priv.buffer)
+     {
+       *cx = x; *cy = y; *cw = w; *ch = h;
+       return ob->priv.buffer;
+     }
+   else
+     {
+       RGBA_Image *im;
+
+       *cx = 0; *cy = 0; *cw = w; *ch = h;
+       im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
+        im->cache_entry.flags.alpha = 1;
+        im = (RGBA_Image *)evas_cache_image_size_set(&im->cache_entry, w, h);
+
+        return im;
+     }
+
+   return NULL;
+}
+
+void 
+evas_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update, int x __UNUSED__, int y, int w, int h) 
+{
+   if (!ob->priv.dest) return;
+   if (!ob->priv.buffer) 
+     {
+        Gfx_Func_Copy func;
+
+        func = evas_common_draw_func_copy_get(w, 0);
+        if (func) 
+          {
+             DATA32 *dst, *src;
+             int yy = 0, bytes = 0;
+
+             bytes = (h * (w * sizeof(DATA32)));
+             for (yy = 0; yy < h; yy++) 
+               {
+                  src = update->image.data + (yy * update->cache_entry.w);
+                  dst = (DATA32 *)((DATA8 *)(ob->priv.dest) + 
+                                   ((y + yy) * bytes));
+                  func(src, dst, w);
+               }
+          }
+     }
+}
+
+void 
+evas_outbuf_free_region_for_update(Outbuf *ob, RGBA_Image *update) 
+{
+   if (!ob) return;
+   if (update != ob->priv.buffer) evas_cache_image_drop(&update->cache_entry);
+}