--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+//#include <sys/mman.h>
+
+#ifdef EVAS_CSERVE2
+# include "evas_cs2_private.h"
+#endif
+
+#include "evas_common.h"
+#include "evas_macros.h"
+#include "evas_engine.h"
+#include "evas_swapbuf.h"
+#include "evas_swapper.h"
+
+#define RED_MASK 0x00ff0000
+#define GREEN_MASK 0x0000ff00
+#define BLUE_MASK 0xff000000
+
+/* local function prototypes */
+
+Outbuf *
+evas_swapbuf_setup(int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha, struct wl_shm *wl_shm, struct wl_surface *wl_surface)
+{
+ Outbuf *ob = NULL;
+
+ /* try to allocate a new Outbuf */
+ if (!(ob = calloc(1, sizeof(Outbuf))))
+ return NULL;
+
+ /* set some properties */
+ ob->w = w;
+ ob->h = h;
+ ob->rotation = rotation;
+ ob->depth = depth;
+ ob->priv.destination_alpha = alpha;
+ ob->priv.wl.shm = wl_shm;
+ ob->priv.wl.surface = wl_surface;
+
+ if ((ob->rotation == 0) || (ob->rotation == 180))
+ {
+ ob->priv.swapper =
+ evas_swapper_setup(w, h, depth, alpha, ob->priv.wl.shm,
+ ob->priv.wl.surface);
+ }
+ else if ((ob->rotation == 90) || (ob->rotation == 270))
+ {
+ ob->priv.swapper =
+ evas_swapper_setup(h, w, depth, alpha, ob->priv.wl.shm,
+ ob->priv.wl.surface);
+ }
+
+ /* check that a swapper was created */
+ if (!ob->priv.swapper)
+ {
+ /* free the Outbuf structure allocation */
+ free(ob);
+
+ return NULL;
+ }
+
+ /* set step size of regions array */
+ eina_array_step_set(&ob->priv.onebuf_regions, sizeof(Eina_Array), 8);
+
+ /* return allocated Outbuf */
+ return ob;
+}
+
+void
+evas_swapbuf_free(Outbuf *ob)
+{
+ /* check for valid output buffer */
+ if (!ob) return;
+
+ /* flush the output buffer */
+ evas_swapbuf_flush(ob);
+ evas_swapbuf_idle_flush(ob);
+ eina_array_flush(&ob->priv.onebuf_regions);
+
+ /* destroy the wayland shm pool */
+ /* _evas_swapbuf_pool_destroy(ob); */
+
+ /* free the allocated structure */
+ free(ob);
+}
+
+void
+evas_swapbuf_reconfigure(Outbuf *ob, int w, int h, unsigned int rotation, Outbuf_Depth depth, Eina_Bool alpha)
+{
+ /* check for valid output buffer */
+ if (!ob) return;
+
+ /* check that something was actually changed */
+ if ((ob->w == w) && (ob->h == h) && (ob->rotation == rotation) &&
+ (ob->depth == depth) && (ob->priv.destination_alpha == alpha))
+ return;
+
+ /* set some properties */
+ ob->w = w;
+ ob->h = h;
+ ob->rotation = rotation;
+ ob->depth = depth;
+ ob->priv.destination_alpha = alpha;
+
+ /* check for valid swapper */
+ if (ob->priv.swapper)
+ {
+ /* free existing swapper */
+ evas_swapper_free(ob->priv.swapper);
+ }
+
+ /* create new swapper */
+ if ((ob->rotation == 0) || (ob->rotation == 180))
+ {
+ ob->priv.swapper =
+ evas_swapper_setup(w, h, depth, alpha, ob->priv.wl.shm,
+ ob->priv.wl.surface);
+ }
+ else if ((ob->rotation == 90) || (ob->rotation == 270))
+ {
+ ob->priv.swapper =
+ evas_swapper_setup(h, w, depth, alpha, ob->priv.wl.shm,
+ ob->priv.wl.surface);
+ }
+}
+
+RGBA_Image *
+evas_swapbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
+{
+ RGBA_Image *img;
+ Eina_Rectangle *rect;
+
+ RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h);
+ if ((w <= 0) || (h <= 0)) return NULL;
+
+ if (ob->rotation == 0)
+ {
+ if (!(img = ob->priv.onebuf))
+ {
+ void *data;
+
+ data = evas_swapper_buffer_map(ob->priv.swapper);
+
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ img = (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(),
+ ob->w, ob->h, data,
+ ob->priv.destination_alpha,
+ EVAS_COLORSPACE_ARGB8888);
+ else
+#endif
+ img = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
+ ob->w, ob->h, data,
+ ob->priv.destination_alpha,
+ EVAS_COLORSPACE_ARGB8888);
+
+ ob->priv.onebuf = img;
+ if (!img) return NULL;
+ }
+
+ if (!(rect = eina_rectangle_new(x, y, w, h)))
+ return NULL;
+
+ if (!eina_array_push(&ob->priv.onebuf_regions, rect))
+ {
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_close(&img->cache_entry);
+ else
+#endif
+ evas_cache_image_drop(&img->cache_entry);
+
+ free(rect);
+
+ return NULL;
+ }
+
+ /* clip the region to the onebuf region */
+ if (cx) *cx = x;
+ if (cy) *cy = y;
+ }
+ else
+ {
+ if (!(rect = eina_rectangle_new(x, y, w, h)))
+ return NULL;
+
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ img = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
+ else
+#endif
+ img = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
+
+ if (!img)
+ {
+ free(rect);
+ return NULL;
+ }
+
+ img->cache_entry.flags.alpha |= ob->priv.destination_alpha;
+
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_surface_alloc(&img->cache_entry, w, h);
+ else
+#endif
+ evas_cache_image_surface_alloc(&img->cache_entry, w, h);
+
+ img->extended_info = rect;
+
+ ob->priv.pending_writes =
+ eina_list_append(ob->priv.pending_writes, img);
+
+ if (cx) *cx = 0;
+ if (cy) *cy = 0;
+ }
+
+ if (cw) *cw = w;
+ if (ch) *ch = h;
+
+ return img;
+}
+
+void
+evas_swapbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h)
+{
+ Gfx_Func_Convert func = NULL;
+ Eina_Rectangle rect = {0, 0, 0, 0};
+ DATA32 *src;
+ DATA8 *dst;
+ int depth = 32, bpp = 0, bpl = 0, wid = 0;
+
+ /* check for valid output buffer */
+ if (!ob) return;
+
+ /* check for pending writes */
+ if (!ob->priv.pending_writes) return;
+
+ if ((ob->rotation == 0) || (ob->rotation == 180))
+ {
+ func =
+ evas_common_convert_func_get(0, w, h, depth,
+ RED_MASK, GREEN_MASK, BLUE_MASK,
+ PAL_MODE_NONE, ob->rotation);
+ }
+ else if ((ob->rotation == 90) || (ob->rotation == 270))
+ {
+ func =
+ evas_common_convert_func_get(0, h, w, depth,
+ RED_MASK, GREEN_MASK, BLUE_MASK,
+ PAL_MODE_NONE, ob->rotation);
+ }
+
+ /* make sure we have a valid convert function */
+ if (!func) return;
+
+ /* based on rotation, set rectangle position */
+ if (ob->rotation == 0)
+ {
+ rect.x = x;
+ rect.y = y;
+ }
+ else if (ob->rotation == 90)
+ {
+ rect.x = y;
+ rect.y = (ob->w - x - w);
+ }
+ else if (ob->rotation == 180)
+ {
+ rect.x = (ob->w - x - w);
+ rect.y = (ob->h - y - h);
+ }
+ else if (ob->rotation == 270)
+ {
+ rect.x = (ob->h - y - h);
+ rect.y = x;
+ }
+
+ /* based on rotation, set rectangle size */
+ if ((ob->rotation == 0) || (ob->rotation == 180))
+ {
+ rect.w = w;
+ rect.h = h;
+ }
+ else if ((ob->rotation == 90) || (ob->rotation == 270))
+ {
+ rect.w = h;
+ rect.h = w;
+ }
+
+ /* check for valid update image data */
+ if (!(src = update->image.data)) return;
+
+ /* check for valid desination data */
+ if (!(dst = evas_swapper_buffer_map(ob->priv.swapper))) return;
+
+ bpp = depth / 8;
+ if (bpp <= 0) return;
+
+ bpl = (ob->w * sizeof(int));
+ wid = bpl / bpp;
+
+ dst += (bpl * rect.y) + (rect.x * bpp);
+
+ func(src, dst, (update->cache_entry.w - w), (wid - rect.w),
+ rect.w, rect.h, x, y, NULL);
+}
+
+void
+evas_swapbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
+{
+ /* NB: nothing to do, they are cleaned up on flush */
+}
+
+void
+evas_swapbuf_flush(Outbuf *ob)
+{
+ Eina_Rectangle *rects;
+ RGBA_Image *img;
+ unsigned int n = 0, i = 0;
+
+ /* check for valid output buffer */
+ if (!ob) return;
+
+ /* check for pending writes */
+ if (!ob->priv.pending_writes)
+ {
+ Eina_Rectangle *rect;
+ Eina_Array_Iterator it;
+
+ /* get number of buffer regions */
+ n = eina_array_count_get(&ob->priv.onebuf_regions);
+ if (n == 0) return;
+
+ /* allocate rectangles */
+ if (!(rects = alloca(n * sizeof(Eina_Rectangle)))) return;
+
+ /* loop the buffer regions and assign to rects */
+ EINA_ARRAY_ITER_NEXT(&ob->priv.onebuf_regions, i, rect, it)
+ rects[i] = *rect;
+
+ /* unmap the buffer */
+ evas_swapper_buffer_unmap(ob->priv.swapper);
+
+ /* force a buffer swap */
+ evas_swapper_swap(ob->priv.swapper, rects, n);
+
+ /* clean array */
+ eina_array_clean(&ob->priv.onebuf_regions);
+
+ img = ob->priv.onebuf;
+ ob->priv.onebuf = NULL;
+ if (img)
+ {
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_close(&img->cache_entry);
+ else
+#endif
+ evas_cache_image_drop(&img->cache_entry);
+ }
+ }
+ else
+ {
+ /* get number of pending writes */
+ n = eina_list_count(ob->priv.pending_writes);
+ if (n == 0) return;
+
+ /* allocate rectangles */
+ if (!(rects = alloca(n * sizeof(Eina_Rectangle)))) return;
+
+ /* loop the pending writes */
+ EINA_LIST_FREE(ob->priv.pending_writes, img)
+ {
+ Eina_Rectangle *rect;
+ int x = 0, y = 0, w = 0, h = 0;
+
+ if (!(rect = img->extended_info)) continue;
+
+ x = rect->x; y = rect->y; w = rect->w; h = rect->h;
+ rects[i] = *rect;
+
+ /* based on rotation, set rectangle position */
+ if (ob->rotation == 0)
+ {
+ rects[i].x = x;
+ rects[i].y = y;
+ }
+ else if (ob->rotation == 90)
+ {
+ rects[i].x = y;
+ rects[i].y = (ob->w - x - w);
+ }
+ else if (ob->rotation == 180)
+ {
+ rects[i].x = (ob->w - x - w);
+ rects[i].y = (ob->h - y - h);
+ }
+ else if (ob->rotation == 270)
+ {
+ rects[i].x = (ob->h - y - h);
+ rects[i].y = x;
+ }
+
+ /* based on rotation, set rectangle size */
+ if ((ob->rotation == 0) || (ob->rotation == 180))
+ {
+ rects[i].w = w;
+ rects[i].h = h;
+ }
+ else if ((ob->rotation == 90) || (ob->rotation == 270))
+ {
+ rects[i].w = h;
+ rects[i].h = w;
+ }
+
+ free(rect);
+#ifdef EVAS_CSERVE2
+ if (evas_cserve2_use_get())
+ evas_cache2_image_close(&img->cache_entry);
+ else
+#endif
+ evas_cache_image_drop(&img->cache_entry);
+ }
+
+ /* unmap the buffer */
+ evas_swapper_buffer_unmap(ob->priv.swapper);
+
+ /* force a buffer swap */
+ evas_swapper_swap(ob->priv.swapper, rects, n);
+ }
+}
+
+void
+evas_swapbuf_idle_flush(Outbuf *ob EINA_UNUSED)
+{
+
+}
+
+int
+evas_swapbuf_state_get(Outbuf *ob)
+{
+ int mode = 0;
+
+ if (!ob->priv.swapper) return MODE_FULL;
+ mode = evas_swapper_buffer_state_get(ob->priv.swapper);
+ return mode;
+}
+
+/* local functions */