Evas filters: Use Ector.Buffer instead of RGBA_Image
authorJean-Philippe Andre <jp.andre@samsung.com>
Wed, 9 Dec 2015 01:45:53 +0000 (10:45 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Tue, 5 Jan 2016 06:43:44 +0000 (15:43 +0900)
This is a major refactoring of the evas filters submodule.

Use Ector.Buffer and the map/unmap methods instead of directly
accessing image buffers with RGBA_Image. RGBA_Image is still
used under the hood, for two reasons:
 - Required for the final output (blend onto Evas itself)
 - Required for the scaling routines

FIXME:
 - Breaks proxy support (ie. all kind of texturing).
 - This breaks filters support for the GL engine.

17 files changed:
src/lib/evas/canvas/evas_filter_mixin.c
src/lib/evas/filters/evas_filter.c
src/lib/evas/filters/evas_filter_blend.c
src/lib/evas/filters/evas_filter_blur.c
src/lib/evas/filters/evas_filter_bump.c
src/lib/evas/filters/evas_filter_curve.c
src/lib/evas/filters/evas_filter_displace.c
src/lib/evas/filters/evas_filter_fill.c
src/lib/evas/filters/evas_filter_mask.c
src/lib/evas/filters/evas_filter_private.h
src/lib/evas/filters/evas_filter_transform.c
src/lib/evas/filters/evas_filter_utils.c
src/lib/evas/include/evas_filter.h
src/lib/evas/include/evas_private.h
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/engines/software_generic/evas_ector_software_buffer.c
src/modules/evas/engines/software_generic/evas_engine.c

index e93fa70..8c5c8ae 100644 (file)
@@ -242,7 +242,8 @@ evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
 
         // Request rendering from the object itself (child class)
         evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b);
-        eo_do(eo_obj, evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
+        eo_do(eo_obj, ok = evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
+        if (!ok) ERR("Filter input render failed.");
 
         ENFN->context_free(ENDT, drawctx);
 
index 6aa1890..148a032 100644 (file)
 #endif
 
 #include "evas_filter_private.h"
+#include <Ector.h>
+#include <software/Ector_Software.h>
+#include "evas_ector_buffer.eo.h"
 
 #define _assert(a) if (!(a)) CRI("Failed on %s", #a);
 
 static void _buffer_free(Evas_Filter_Buffer *fb);
 static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
-static RGBA_Image *_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data);
+static Ector_Buffer* _ector_buffer_create(Evas_Filter_Buffer const *fb, void *data);
 
 #define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0)
 #define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0)
 #define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0)
 
-typedef struct _Evas_Filter_Thread_Command Evas_Filter_Thread_Command;
-struct _Evas_Filter_Thread_Command
+static inline void *
+_evas_image_get(Ector_Buffer *buf)
 {
-   Evas_Filter_Context *ctx;
-   RGBA_Image *src, *mask, *dst;
-   Evas_Filter_Apply_Func func;
-};
-
+   void *image = NULL;
+   if (!buf) return NULL;
+   eo_do(buf, evas_ector_buffer_engine_image_get(NULL, &image));
+   return image;
+}
 
 /* Main functions */
 
@@ -67,6 +70,11 @@ evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async)
     * better and implement filters direcly with shaders.
     */
    ctx->gl_engine = (evas->engine.func->gl_surface_read_pixels != NULL);
+   if (ctx->gl_engine)
+     {
+        // FIXME!!!
+        CRI("gl support not implemented");
+     }
    return ctx;
 }
 
@@ -93,44 +101,21 @@ evas_filter_context_clear(Evas_Filter_Context *ctx)
 }
 
 static void
-_backing_free(Evas_Filter_Context *ctx, RGBA_Image *im)
-{
-   if (!im) return;
-
-   if (!ctx->gl_engine)
-     {
-        if (!ctx->async)
-          ENFN->image_free(ENDT, im);
-        else
-          evas_unref_queue_image_put(ctx->evas, &im->cache_entry);
-     }
-   else
-     {
-#ifdef EVAS_CSERVE2
-        if (evas_cserve2_use_get())
-          evas_cache2_image_close(&im->cache_entry);
-        else
-#endif
-          evas_cache_image_drop(&im->cache_entry);
-     }
-}
-
-static void
 _filter_buffer_backing_free(Evas_Filter_Buffer *fb)
 {
-   if (!fb) return;
-
-   _backing_free(fb->ctx, fb->backing);
-   if (fb->glimage)
-     fb->ENFN->image_free(fb->ENDT, fb->glimage);
-   fb->backing = NULL;
-   fb->glimage = NULL;
+   if (!fb || !fb->buffer) return;
+   eo_del(fb->buffer);
+   fb->buffer = NULL;
 }
 
 /* GL engine stuff: read-back from texture */
 static Eina_Bool
-_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
+_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb EINA_UNUSED, void *glimage EINA_UNUSED)
 {
+   CRI("not implemented");
+   return 0;
+
+#if 0
    Eina_Bool ok;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
@@ -143,8 +128,8 @@ _filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
    EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_read_pixels, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_unlock, EINA_FALSE);
 
-   fb->backing = _rgba_image_alloc(fb, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(fb->backing, EINA_FALSE);
+   fb->buffer = _ector_buffer_create(fb, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb->buffer, EINA_FALSE);
 
    ok = fb->ENFN->gl_surface_lock(fb->ENDT, glimage);
    if (!ok)
@@ -163,13 +148,18 @@ _filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
 
    ok &= fb->ENFN->gl_surface_unlock(fb->ENDT, glimage);
    return ok;
+#endif
 }
 
 /** @hidden private render proxy objects */
 void
-evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
-                                     Eina_Bool do_async)
+evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx EINA_UNUSED, Eo *eo_obj EINA_UNUSED,
+                                     Eina_Bool do_async EINA_UNUSED)
 {
+   CRI("not implemented");
+   return;
+
+#if 0
    Evas_Object_Protected_Data *source;
    Evas_Object_Protected_Data *obj;
    Evas_Filter_Buffer *fb;
@@ -208,6 +198,7 @@ evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
           fb->alpha_only = EINA_FALSE;
           XDBG("Source has dimensions %dx%d (buffer %d)", fb->w, fb->h, fb->id);
        }
+#endif
 }
 
 void
@@ -257,63 +248,43 @@ _buffer_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only)
    return fb;
 }
 
-static RGBA_Image *
-_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data)
+static Ector_Buffer *
+_ector_buffer_create(Evas_Filter_Buffer const *fb, void *data)
 {
    Evas_Colorspace cspace;
-   RGBA_Image *image;
-   size_t sz;
+   Image_Entry *ie;
+
+   // FIXME: We still rely on evas image structs (scaling and target render)
+   // This should be fixed by implementing full support in ector
+   // Note: dropped support for cserve2, that was not needed anyway
+
+   cspace = fb->alpha_only ? E_ALPHA : E_ARGB;
+#if 0
+   // ideal code
+   return fb->ENFN->ector_buffer_new(fb->ENDT, fb->ctx->evas->evas,
+                                     data, fb->w, fb->h, 0,
+                                     cspace, EINA_TRUE, 0, 0, 0, 0,
+                                     ECTOR_BUFFER_FLAG_CPU_READABLE |
+                                     ECTOR_BUFFER_FLAG_CPU_WRITABLE);
+#endif
 
-   cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888;
-   if (!fb->ctx->gl_engine)
+   if (data)
      {
-        if (!data)
-          {
-             image = fb->ENFN->image_new_from_copied_data
-                   (fb->ENDT, fb->w, fb->h, NULL, EINA_TRUE, cspace);
-          }
-        else
-          {
-             image = fb->ENFN->image_new_from_data
-                   (fb->ENDT, fb->w, fb->h, data, EINA_TRUE, cspace);
-          }
+        // no copy
+        ie = evas_cache_image_data(evas_common_image_cache_get(), fb->w, fb->h,
+                                   data, EINA_TRUE, cspace);
+        if (!ie) return NULL;
      }
    else
      {
-        // FIXME: Directly calling the alloc functions since we want to use sw surfaces.
-
-        if (!data)
-          {
-#ifdef EVAS_CSERVE2
-             if (evas_cserve2_use_get())
-               image = (RGBA_Image *) evas_cache2_image_copied_data
-                     (evas_common_image_cache2_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
-             else
-#endif
-               image = (RGBA_Image *) evas_cache_image_copied_data
-                     (evas_common_image_cache_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
-          }
-        else
-          {
-#ifdef EVAS_CSERVE2
-             if (evas_cserve2_use_get())
-               image = (RGBA_Image *) evas_cache2_image_data
-                     (evas_common_image_cache2_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
-             else
-#endif
-               image = (RGBA_Image *) evas_cache_image_data
-                     (evas_common_image_cache_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
-          }
+         // alloc buffer
+        ie = evas_cache_image_copied_data(evas_common_image_cache_get(), fb->w, fb->h,
+                                          NULL, EINA_TRUE, cspace);
+        if (!ie) return NULL;
+        data = ((RGBA_Image *) ie)->image.data;
+        memset(data, 0, fb->w * fb->h * (fb->alpha_only ? 1 : 4));
      }
-   if (!image) return NULL;
-
-   if (fb->alpha_only)
-     sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA8);
-   else
-     sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA32);
-   if (!data) memset(image->image.data, 0, sz);
-
-   return image;
+   return fb->ENFN->ector_buffer_wrap(fb->ENDT, fb->ctx->evas->evas, ie);
 }
 
 Eina_Bool
@@ -404,7 +375,7 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
 
    EINA_LIST_FOREACH(ctx->buffers, li, fb)
      {
-        if (fb->backing || fb->source || fb->glimage)
+        if (fb->buffer || fb->source || fb->glimage)
           continue;
 
         if (!fb->w && !fb->h)
@@ -413,10 +384,10 @@ evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx)
              continue;
           }
 
-        fb->backing = _rgba_image_alloc(fb, NULL);
-        XDBG("Allocating buffer #%d of size %ux%u %s",
-             fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba");
-        if (!fb->backing) goto alloc_fail;
+        fb->buffer = _ector_buffer_create(fb, NULL);
+        XDBG("Allocated buffer #%d of size %ux%u %s: %p",
+             fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba", fb->buffer);
+        if (!fb->buffer) goto alloc_fail;
      }
 
    return EINA_TRUE;
@@ -457,35 +428,29 @@ _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data,
    if (w <= 0 || h <= 0)
      return EINA_FALSE;
 
-   EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->backing == NULL, EINA_FALSE);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->buffer == NULL, EINA_FALSE);
    // TODO: Check input parameters?
    fb->alpha_only = alpha_only;
    fb->w = w;
    fb->h = h;
 
-   fb->backing = _rgba_image_alloc(fb, data);
-   return (fb->backing != NULL);
+   fb->buffer = _ector_buffer_create(fb, data);
+   return (fb->buffer != NULL);
 }
 
-int
-evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image)
+static int
+_filter_buffer_new_from_evas_surface(Evas_Filter_Context *ctx, void *image)
 {
    Evas_Filter_Buffer *fb;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
 
-   image = ENFN->image_ref(ENDT, image);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(image, -1);
-
    fb = calloc(1, sizeof(Evas_Filter_Buffer));
    if (!fb) return -1;
 
    fb->id = ++(ctx->last_buffer_id);
    fb->ctx = ctx;
-   if (!ctx->gl_engine)
-     fb->backing = image;
-   else
-     fb->glimage = image;
+   fb->buffer = ENFN->ector_buffer_wrap(ENDT, ctx->evas->evas, image);
    ENFN->image_size_get(ENDT, image, &fb->w, &fb->h);
    fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image)
                      == EVAS_COLORSPACE_GRY8);
@@ -544,12 +509,12 @@ _filter_buffer_get(Evas_Filter_Context *ctx, int bufid)
 void *
 evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid)
 {
-   Evas_Filter_Buffer *buffer;
+   Evas_Filter_Buffer *fb;
 
-   buffer = _filter_buffer_get(ctx, bufid);
-   if (!buffer) return NULL;
+   fb = _filter_buffer_get(ctx, bufid);
+   if (!fb) return NULL;
 
-   return buffer->backing;
+   return _evas_image_get(fb->buffer);
 }
 
 void *
@@ -557,15 +522,10 @@ evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
 {
    Evas_Filter_Buffer *fb;
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
-
    fb = _filter_buffer_get(ctx, bufid);
    if (!fb) return NULL;
 
-   if (ctx->gl_engine)
-     return fb->ENFN->image_ref(fb->ENDT, fb->glimage);
-   else
-     return fb->ENFN->image_ref(fb->ENDT, fb->backing);
+   return fb->ENFN->image_ref(fb->ENDT, _evas_image_get(fb->buffer));
 }
 
 Eina_Bool
@@ -577,11 +537,11 @@ evas_filter_buffer_backing_release(Evas_Filter_Context *ctx,
 
    if (ctx->async)
      evas_unref_queue_image_put(ctx->evas, stolen_buffer);
-   else if (ctx->gl_engine)
-     ctx->post_run.buffers_to_free =
-       eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer);
    else
-     _backing_free(ctx, stolen_buffer);
+     {
+        ctx->post_run.buffers_to_free =
+              eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer);
+     }
 
    return EINA_TRUE;
 }
@@ -1345,12 +1305,6 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx,
         return -1;
      }
 
-   if (in->alpha_only != out->alpha_only)
-     {
-        CRI("Incompatible buffer formats");
-        return -1;
-     }
-
    cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out);
    if (!cmd) return -1;
 
@@ -1372,7 +1326,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
 
-   ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface);
+   ctx->target.bufid = _filter_buffer_new_from_evas_surface(ctx, surface);
    ctx->target.x = x;
    ctx->target.y = y;
    ctx->target.clip_use = ENFN->context_clip_get
@@ -1391,6 +1345,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
      ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask);
    ctx->target.mask = mask;
 
+#if 0
    if (ctx->gl_engine)
      {
         // Since GL has sync rendering, draw_context is safe to keep around
@@ -1410,6 +1365,7 @@ evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context,
         XDBG("Set target as #%d (%p) and output #%d (%p, gl %p)",
             ctx->target.bufid, surface, fb->id, fb->backing, fb->glimage);
      }
+#endif
 
    return EINA_TRUE;
 }
@@ -1418,7 +1374,7 @@ static Eina_Bool
 _filter_target_render(Evas_Filter_Context *ctx)
 {
    Evas_Filter_Buffer *src, *dst;
-   void *drawctx, *image, *surface;
+   void *drawctx, *image = NULL, *surface = NULL;
    int cx, cy, cw, ch;
    Eina_Bool use_clip = EINA_FALSE;
 
@@ -1429,13 +1385,8 @@ _filter_target_render(Evas_Filter_Context *ctx)
    EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
 
-   if (!ctx->gl_engine)
-     {
-        drawctx = ENFN->context_new(ENDT);
-        surface = dst->backing;
-        image = src->backing;
-     }
-   else
+#if 0
+   if (ctx->gl_engine)
      {
         drawctx = ctx->target.context;
         surface = dst->glimage;
@@ -1456,9 +1407,18 @@ _filter_target_render(Evas_Filter_Context *ctx)
           }
         image = src->glimage;
      }
+   else
+#endif
+     {
+        drawctx = ENFN->context_new(ENDT);
+        image = _evas_image_get(src->buffer);
+        surface = _evas_image_get(dst->buffer);
+     }
    EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
 
+   // FIXME: Use ector buffer RENDERER here
+
    if (ctx->target.clip_use)
      {
         use_clip = ENFN->context_clip_get(ENDT, drawctx, &cx, &cy, &cw, &ch);
@@ -1511,12 +1471,10 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
 {
    Eina_Bool async_unref;
    Evas_Filter_Buffer *fb;
-   void *surface;
+   void *surface = NULL;
 
    fb = _filter_buffer_get(ctx, bufid);
-   if (!fb) return EINA_FALSE;
-
-   surface = fb->backing;
+   surface = _evas_image_get(fb->buffer);
    if (!surface) return EINA_FALSE;
 
    if (!ctx->gl_engine)
@@ -1771,10 +1729,7 @@ end:
    DEBUG_TIME_END();
 
    EINA_LIST_FREE(ctx->post_run.buffers_to_free, buffer)
-     {
-        if (ctx->gl_engine)
-          ENFN->image_free(ENDT, buffer);
-     }
+     ENFN->image_free(ENDT, buffer);
 
    return ok;
 }
index 0c7c548..153e568 100644 (file)
@@ -1,33 +1,37 @@
 #include "evas_filter.h"
 #include "evas_filter_private.h"
 #include "evas_blend_private.h"
+#include "ector_buffer.h"
 #include "draw.h"
 
+// FIXME: This should all be based on ector renderer
+
 // Use a better formula than R+G+B for rgba to alpha conversion (RGB to YCbCr)
 #define RGBA2ALPHA_WEIGHTED 1
 
-typedef Eina_Bool (*image_draw_func) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async);
-static Eina_Bool _mapped_blend(void *data, void *drawctx, void *in, void *out, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, image_draw_func image_draw);
+typedef Eina_Bool (*draw_func) (void *data, void *context, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async);
+static Eina_Bool _mapped_blend(void *data, void *drawctx, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, draw_func image_draw);
 
 struct Filter_Blend_Draw_Context
 {
    Efl_Gfx_Render_Op rop;
-   DATA32 color;
+   uint32_t color;
 };
 
+#define LINELEN(stride, ptr) (stride / (sizeof(*ptr)))
+
 static Eina_Bool
 _image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
-                            void *surface, void *image,
+                            const void *src_map, unsigned int src_stride,
+                            void *dst_map, unsigned int dst_stride,
                             int src_x, int src_y, int src_w, int src_h,
                             int dst_x, int dst_y, int dst_w, int dst_h,
                             int smooth EINA_UNUSED,
                             Eina_Bool do_async EINA_UNUSED)
 {
    struct Filter_Blend_Draw_Context *dc = context;
-   RGBA_Image *src = image;
-   RGBA_Image *dst = surface;
-   DATA8* srcdata = src->image.data8;
-   DATA8* dstdata = dst->image.data8;
+   const uint8_t *srcdata = src_map;
+   uint8_t *dstdata = dst_map;
    Alpha_Gfx_Func func;
    int y, sw, dw;
 
@@ -36,8 +40,8 @@ _image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
    func = efl_draw_alpha_func_get(dc->rop, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
 
-   sw = src->cache_entry.w;
-   dw = dst->cache_entry.w;
+   sw = LINELEN(src_stride, srcdata);
+   dw = LINELEN(dst_stride, dstdata);
 
    srcdata += src_y * sw;
    dstdata += dst_y * dw;
@@ -53,28 +57,26 @@ _image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
 
 static Eina_Bool
 _image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context,
-                           void *surface, void *image,
+                           const void *src_map, unsigned int src_stride,
+                           void *dst_map, unsigned int dst_stride,
                            int src_x, int src_y, int src_w, int src_h,
                            int dst_x, int dst_y, int dst_w, int dst_h,
                            int smooth EINA_UNUSED,
                            Eina_Bool do_async EINA_UNUSED)
 {
    struct Filter_Blend_Draw_Context *dc = context;
-   RGBA_Image *src = image;
-   RGBA_Image *dst = surface;
-   DATA8* srcdata = src->image.data8;
-   DATA32* dstdata = dst->image.data;
+   uint8_t *srcdata = (uint8_t *) src_map;
+   uint32_t *dstdata = dst_map;
    RGBA_Gfx_Func func;
    int y, sw, dw;
 
    EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
 
-   func = evas_common_gfx_func_composite_mask_color_span_get
-     (dc->color, dst->cache_entry.flags.alpha, 1, dc->rop);
+   func = evas_common_gfx_func_composite_mask_color_span_get(dc->color, 1, 1, _gfx_to_evas_render_op(dc->rop));
    EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
 
-   sw = src->cache_entry.w;
-   dw = dst->cache_entry.w;
+   sw = LINELEN(src_stride, srcdata);
+   dw = LINELEN(dst_stride, dstdata);
 
    srcdata += src_y * sw;
    dstdata += dst_y * dw;
@@ -89,76 +91,56 @@ _image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context,
 }
 
 static Eina_Bool
-_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd,
-                             image_draw_func image_draw)
+_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context,
+                          const void *src_map, unsigned int src_stride,
+                          void *dst_map, unsigned int dst_stride,
+                          int src_x, int src_y, int src_w, int src_h,
+                          int dst_x, int dst_y, int dst_w, int dst_h,
+                          int smooth EINA_UNUSED,
+                          Eina_Bool do_async EINA_UNUSED)
 {
-   RGBA_Image *in, *out;
-   int sw, sh, dx, dy, dw, dh, sx, sy;
-   struct Filter_Blend_Draw_Context dc;
-
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
-
-   sx = 0;
-   sy = 0;
-   sw = in->cache_entry.w;
-   sh = in->cache_entry.h;
+   struct Filter_Blend_Draw_Context *dc = context;
+   uint32_t *srcdata = (uint32_t *) src_map;
+   uint32_t *dstdata = dst_map;
+   RGBA_Gfx_Func func;
+   int y, sw, dw;
 
-   dx = cmd->draw.ox;
-   dy = cmd->draw.oy;
-   dw = out->cache_entry.w;
-   dh = out->cache_entry.h;
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
 
-   if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
+   if (!dc->color)
      return EINA_TRUE;
+   else if (dc->color == 0xFFFFFFFF)
+     func = evas_common_gfx_func_composite_pixel_span_get(1, 0, 1, 1, _gfx_to_evas_render_op(dc->rop));
+   else
+     func = evas_common_gfx_func_composite_pixel_color_span_get(1, 0, dc->color, 1, 1, _gfx_to_evas_render_op(dc->rop));
+   EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
 
-   // Stretch if necessary.
-
-   /* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
-    * only proxy sources may be scaled. So, we don't need an alpha scaling
-    * algorithm just now.
-    */
+   sw = LINELEN(src_stride, srcdata);
+   dw = LINELEN(dst_stride, dstdata);
 
-   if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
+   srcdata += src_y * sw;
+   dstdata += dst_y * dw;
+   for (y = src_h; y; y--)
      {
-        Evas_Filter_Buffer *fb;
-
-        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
-          sw = dw;
-        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
-          sh = dh;
-
-        BUFFERS_LOCK();
-        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
-        BUFFERS_UNLOCK();
-
-        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
-        fb->locked = EINA_FALSE;
-        in = fb->backing;
+        func(srcdata + src_x, NULL, dc->color, dstdata + dst_x, src_w);
+        srcdata += sw;
+        dstdata += dw;
      }
 
-   dc.rop = cmd->draw.rop;
-   dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
-   return _mapped_blend(cmd->ENDT, &dc, in, out, cmd->draw.fillmode,
-                        sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
+   return EINA_TRUE;
 }
 
 static Eina_Bool
 _image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
-                           void *surface, void *image,
+                           const void *src_map, unsigned int src_stride,
+                           void *dst_map, unsigned int dst_stride,
                            int src_x, int src_y, int src_w, int src_h,
                            int dst_x, int dst_y, int dst_w, int dst_h,
                            int smooth EINA_UNUSED,
                            Eina_Bool do_async EINA_UNUSED)
 {
-   RGBA_Image *src = image;
-   RGBA_Image *dst = surface;
-   DATA32* srcdata = src->image.data;
-   DATA8* dstdata = dst->image.data8;
+   uint32_t *srcdata = (uint32_t *) src_map;
+   uint8_t *dstdata = dst_map;
    int x, y, sw, dw;
 #if RGBA2ALPHA_WEIGHTED
    const int WR = 299;
@@ -173,15 +155,15 @@ _image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
 
    EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
 
-   sw = src->cache_entry.w;
-   dw = dst->cache_entry.w;
+   sw = LINELEN(src_stride, srcdata);
+   dw = LINELEN(dst_stride, dstdata);
 
    srcdata += src_y * sw;
    dstdata += dst_y * dw;
    for (y = src_h; y; y--)
      {
-        DATA32 *s = srcdata + src_x;
-        DATA8 *d = dstdata + dst_x;
+        uint32_t *s = srcdata + src_x;
+        uint8_t *d = dstdata + dst_x;
         for (x = src_w; x; x--, d++, s++)
           *d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB));
         srcdata += sw;
@@ -192,44 +174,63 @@ _image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
 }
 
 static Eina_Bool
-_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context,
-                          void *surface, void *image,
-                          int src_x, int src_y, int src_w, int src_h,
-                          int dst_x, int dst_y, int dst_w, int dst_h,
-                          int smooth EINA_UNUSED,
-                          Eina_Bool do_async EINA_UNUSED)
+_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw)
 {
-   struct Filter_Blend_Draw_Context *dc = context;
-   RGBA_Image *src = image;
-   RGBA_Image *dst = surface;
-   DATA32* srcdata = src->image.data;
-   DATA32* dstdata = dst->image.data;
-   RGBA_Gfx_Func func;
-   int y, sw, dw;
+   unsigned int src_len, src_stride, dst_len, dst_stride;
+   int sw, sh, dx, dy, dw, dh, sx, sy;
+   struct Filter_Blend_Draw_Context dc;
+   Eina_Bool ret = EINA_FALSE;
+   Evas_Filter_Buffer *src_fb;
+   void *src, *dst;
 
-   EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
+   sx = 0;
+   sy = 0;
+   eo_do(cmd->input->buffer, ector_buffer_size_get(&sw, &sh));
 
-   if (!dc->color)
+   dx = cmd->draw.ox;
+   dy = cmd->draw.oy;
+   eo_do(cmd->output->buffer, ector_buffer_size_get(&dw, &dh));
+
+   if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
      return EINA_TRUE;
-   else if (dc->color == 0xFFFFFFFF)
-     func = evas_common_gfx_func_composite_pixel_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dst->cache_entry.flags.alpha, 1, dc->rop);
-   else
-     func = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dc->color, dst->cache_entry.flags.alpha, 1, dc->rop);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
 
-   sw = src->cache_entry.w;
-   dw = dst->cache_entry.w;
+   // Stretch if necessary.
 
-   srcdata += src_y * sw;
-   dstdata += dst_y * dw;
-   for (y = src_h; y; y--)
+   /* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
+    * only proxy sources may be scaled. So, we don't need an alpha scaling
+    * algorithm just now.
+    */
+
+   if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
      {
-        func(srcdata + src_x, NULL, dc->color, dstdata + dst_x, src_w);
-        srcdata += sw;
-        dstdata += dw;
+
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+          sw = dw;
+        if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+          sh = dh;
+
+        BUFFERS_LOCK();
+        src_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
+        BUFFERS_UNLOCK();
+
+        EINA_SAFETY_ON_NULL_GOTO(src_fb, end);
+        src_fb->locked = EINA_FALSE;
      }
+   else src_fb = cmd->input;
 
-   return EINA_TRUE;
+   src = _buffer_map_all(src_fb->buffer, &src_len, E_READ, src_fb->alpha_only ? E_ALPHA : E_ARGB, &src_stride);
+   dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &dst_stride);
+
+   dc.rop = cmd->draw.rop;
+   dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+
+   ret = _mapped_blend(cmd->ENDT, &dc, src, src_stride, dst, dst_stride, cmd->draw.fillmode,
+                        sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
+
+end:
+   eo_do(src_fb->buffer, ector_buffer_unmap(src, src_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
+   return ret;
 }
 
 static Eina_Bool
@@ -239,7 +240,7 @@ _filter_blend_cpu_alpha(Evas_Filter_Command *cmd)
 }
 
 static Eina_Bool
-_filter_blend_cpu_mask_rgba(Evas_Filter_Command *cmd)
+_filter_blend_cpu_alpha2rgba(Evas_Filter_Command *cmd)
 {
    return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha2rgba);
 }
@@ -253,73 +254,19 @@ _filter_blend_cpu_rgba2alpha(Evas_Filter_Command *cmd)
 static Eina_Bool
 _filter_blend_cpu_rgba(Evas_Filter_Command *cmd)
 {
-   RGBA_Image *in, *out;
-   RGBA_Draw_Context *drawctx;
-   int sw, sh, dx, dy, dw, dh, sx, sy;
-   Eina_Bool ret;
-
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
-   if (cmd->ctx->gl_engine)
-     return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba);
-
-   sx = 0;
-   sy = 0;
-   sw = in->cache_entry.w;
-   sh = in->cache_entry.h;
-
-   dx = cmd->draw.ox;
-   dy = cmd->draw.oy;
-   dw = out->cache_entry.w;
-   dh = out->cache_entry.h;
-
-   if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
-     return EINA_TRUE;
-
-   drawctx = cmd->ENFN->context_new(cmd->ENDT);
-   cmd->ENFN->context_color_set(cmd->ENDT, drawctx, 255, 255, 255, 255);
-   if ((cmd->draw.R != 255) || (cmd->draw.G != 255) || (cmd->draw.B != 255) || (cmd->draw.A != 255))
-     cmd->ENFN->context_multiplier_set(cmd->ENDT, drawctx, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
-   else
-     cmd->ENFN->context_multiplier_unset(cmd->ENDT, drawctx);
-   cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, _gfx_to_evas_render_op(cmd->draw.rop));
-
-   if (cmd->draw.clip_use)
-     {
-        cmd->ENFN->context_clip_set(cmd->ENDT, drawctx,
-                                    cmd->draw.clip.x, cmd->draw.clip.y,
-                                    cmd->draw.clip.w, cmd->draw.clip.h);
-        cmd->ENFN->context_clip_clip(cmd->ENDT, drawctx, 0, 0,
-                                     out->cache_entry.w, out->cache_entry.h);
-     }
-   else
-     {
-        cmd->ENFN->context_clip_set(cmd->ENDT, drawctx, 0, 0,
-                                    out->cache_entry.w, out->cache_entry.h);
-     }
-
-   ret = _mapped_blend(cmd->ENDT, drawctx, in, out, cmd->draw.fillmode,
-                       sx, sy, sw, sh, dx, dy, dw, dh,
-                       cmd->ENFN->image_draw);
-
-   cmd->ENFN->context_free(cmd->ENDT, drawctx);
-   return ret;
+   return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba);
 }
 
 static Eina_Bool
 _mapped_blend(void *data, void *drawctx,
-              void *in, void *out,
+              const void *src_map, unsigned int src_stride,
+              void *dst_map, unsigned int dst_stride,
               Evas_Filter_Fill_Mode fillmode,
               int sx, int sy,
               int sw, int sh,
               int dx, int dy,
               int dw, int dh,
-              image_draw_func image_draw)
+              draw_func image_draw)
 {
    int right = 0, bottom = 0, left = 0, top = 0;
    int row, col, rows, cols;
@@ -336,7 +283,8 @@ _mapped_blend(void *data, void *drawctx,
              XDBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d (from %dx%d to %dx%d +%d,%d)",
                   0, 0, sw, sh, dx, dy, cols, rows, sw, sh, dw, dh, dx, dy);
           }
-        image_draw(data, drawctx, out, in,
+        image_draw(data, drawctx,
+                   src_map, src_stride, dst_map, dst_stride,
                    sx, sy, cols, rows, // src
                    dx, dy, cols, rows, // dst
                    EINA_TRUE, // smooth
@@ -477,7 +425,8 @@ _mapped_blend(void *data, void *drawctx,
                        dst_x, dst_y, dst_w, dst_h,
                        sw, sh, dw, dh);
                }
-             image_draw(data, drawctx, out, in,
+             image_draw(data, drawctx,
+                        src_map, src_stride, dst_map, dst_stride,
                         src_x, src_y, src_w, src_h,
                         dst_x, dst_y, dst_w, dst_h,
                         EINA_TRUE, EINA_FALSE);
@@ -493,27 +442,18 @@ evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd)
    EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
 
-   if (!cmd->ctx->gl_engine || !cmd->output->glimage || cmd->output->backing)
+   if (cmd->input->alpha_only)
      {
-        if (cmd->input->alpha_only)
-          {
-             if (cmd->output->alpha_only)
-               return _filter_blend_cpu_alpha;
-             else
-               return _filter_blend_cpu_mask_rgba;
-          }
+        if (cmd->output->alpha_only)
+          return _filter_blend_cpu_alpha;
         else
-          {
-             if (cmd->output->alpha_only)
-               return _filter_blend_cpu_rgba2alpha;
-             else
-               return _filter_blend_cpu_rgba;
-          }
+          return _filter_blend_cpu_alpha2rgba;
      }
    else
      {
-        CRI("Can't render to GL image for the moment!");
-        //return _filter_blend_opengl_generic;
-        return NULL;
+        if (cmd->output->alpha_only)
+          return _filter_blend_cpu_rgba2alpha;
+        else
+          return _filter_blend_cpu_rgba;
      }
 }
index fd444cc..9cf851f 100644 (file)
@@ -4,6 +4,8 @@
 #include <math.h>
 #include <time.h>
 
+// FIXME: Add proper stride support
+
 static int
 _box_blur_auto_radius(int *radii, int r)
 {
@@ -45,7 +47,7 @@ _box_blur_auto_radius(int *radii, int r)
 #endif
 
 static void
-_box_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h)
+_box_blur_horiz_rgba(uint32_t *src, uint32_t *dst, int* radii, int w, int h)
 {
    DEBUG_TIME_BEGIN();
 
@@ -77,7 +79,7 @@ end:
 }
 
 static void
-_box_blur_vert_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h)
+_box_blur_vert_rgba(uint32_t *src, uint32_t *dst, int* radii, int w, int h)
 {
    DEBUG_TIME_BEGIN();
 
@@ -108,64 +110,6 @@ end:
    DEBUG_TIME_END();
 }
 
-static Eina_Bool
-_box_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
-{
-   RGBA_Image *in, *out;
-   int radii[7] = {0};
-   unsigned int r;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   r = abs(cmd->blur.dx);
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-
-   if (cmd->blur.auto_count)
-     _box_blur_auto_radius(radii, r);
-   else for (int k = 0; k < cmd->blur.count; k++)
-     radii[k] = r;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
-   _box_blur_horiz_rgba(in->image.data, out->image.data, radii,
-                        in->cache_entry.w, in->cache_entry.h);
-
-   return EINA_TRUE;
-}
-
-static Eina_Bool
-_box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
-{
-   RGBA_Image *in, *out;
-   int radii[7] = {0};
-   unsigned int r;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   r = abs(cmd->blur.dy);
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-
-   if (cmd->blur.auto_count)
-     _box_blur_auto_radius(radii, r);
-   else for (int k = 0; k < cmd->blur.count; k++)
-     radii[k] = r;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
-   _box_blur_vert_rgba(in->image.data, out->image.data, radii,
-                       in->cache_entry.w, in->cache_entry.h);
-
-   return EINA_TRUE;
-}
-
 #include "./blur/blur_box_alpha_.c"
 #ifdef BUILD_MMX
 #include "./blur/blur_box_alpha_i386.c"
@@ -178,7 +122,7 @@ _box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
 #endif
 
 static void
-_box_blur_horiz_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h)
+_box_blur_horiz_alpha(const DATA8 *src, DATA8 *dst, int* radii, int w, int h)
 {
    DEBUG_TIME_BEGIN();
 
@@ -210,7 +154,7 @@ end:
 }
 
 static void
-_box_blur_vert_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h)
+_box_blur_vert_alpha(const DATA8 *src, DATA8 *dst, int* radii, int w, int h)
 {
    DEBUG_TIME_BEGIN();
 
@@ -242,61 +186,70 @@ end:
 }
 
 static Eina_Bool
-_box_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
+_box_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
 {
-   RGBA_Image *in, *out;
+   unsigned int src_len, src_stride, dst_len, dst_stride;
+   Eina_Bool ret = EINA_TRUE;
    int radii[7] = {0};
    unsigned int r;
+   void *src, *dst;
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   r = abs(cmd->blur.dx);
-   in = cmd->input->backing;
-   out = cmd->output->backing;
+   r = abs(vert ? cmd->blur.dy : cmd->blur.dx);
+   src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
+   dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
 
    if (cmd->blur.auto_count)
      _box_blur_auto_radius(radii, r);
    else for (int k = 0; k < cmd->blur.count; k++)
      radii[k] = r;
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
+   if (src && dst)
+     {
+        if (rgba)
+          {
+             if (!vert)
+               _box_blur_horiz_rgba(src, dst, radii, cmd->input->w, cmd->input->h);
+             else
+                _box_blur_vert_rgba(src, dst, radii, cmd->input->w, cmd->input->h);
+          }
+        else
+          {
+             if (!vert)
+               _box_blur_horiz_alpha(src, dst, radii, cmd->input->w, cmd->input->h);
+             else
+                _box_blur_vert_alpha(src, dst, radii, cmd->input->w, cmd->input->h);
+          }
+     }
+   else ret = EINA_FALSE;
 
-   _box_blur_horiz_alpha(in->image.data8, out->image.data8, radii,
-                         in->cache_entry.w, in->cache_entry.h);
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
 
-   return EINA_TRUE;
+   return ret;
 }
 
 static Eina_Bool
-_box_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
+_box_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
 {
-   RGBA_Image *in, *out;
-   int radii[7] = {0};
-   unsigned int r;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   r = abs(cmd->blur.dy);
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-
-   if (cmd->blur.auto_count)
-     _box_blur_auto_radius(radii, r);
-   else for (int k = 0; k < cmd->blur.count; k++)
-     radii[k] = r;
+   return _box_blur_apply(cmd, 0, 0);
+}
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
+static Eina_Bool
+_box_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
+{
+   return _box_blur_apply(cmd, 1, 0);
+}
 
-   _box_blur_vert_alpha(in->image.data8, out->image.data8, radii,
-                        in->cache_entry.w, in->cache_entry.h);
+static Eina_Bool
+_box_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
+{
+   return _box_blur_apply(cmd, 0, 1);
+}
 
-   return EINA_TRUE;
+static Eina_Bool
+_box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
+{
+   return _box_blur_apply(cmd, 1, 1);
 }
 
 /* Gaussian blur */
@@ -342,165 +295,86 @@ _sin_blur_weights_get(int *weights, int *pow2_divider, int radius)
 #define STEP 1
 #include "./blur/blur_gaussian_alpha_.c"
 
-static void
-_gaussian_blur_horiz_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
-{
-   int *weights;
-   int pow2_div = 0;
-
-   weights = alloca((2 * radius + 1) * sizeof(int));
-   _sin_blur_weights_get(weights, &pow2_div, radius);
-
-   DEBUG_TIME_BEGIN();
-   _gaussian_blur_horiz_alpha_step(src, dst, radius, w, h, w, weights, pow2_div);
-   DEBUG_TIME_END();
-}
-
 // Step size is w (row by row), loops = w, so STEP = 'loops'
 #define FUNCTION_NAME _gaussian_blur_vert_alpha_step
 #define STEP loops
 #include "./blur/blur_gaussian_alpha_.c"
 
-static void
-_gaussian_blur_vert_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
-{
-   int *weights;
-   int pow2_div = 0;
-
-   weights = alloca((2 * radius + 1) * sizeof(int));
-   _sin_blur_weights_get(weights, &pow2_div, radius);
-
-   DEBUG_TIME_BEGIN();
-   _gaussian_blur_vert_alpha_step(src, dst, radius, h, w, 1, weights, pow2_div);
-   DEBUG_TIME_END();
-}
-
 #define FUNCTION_NAME _gaussian_blur_horiz_rgba_step
 #define STEP 1
 #include "./blur/blur_gaussian_rgba_.c"
 
-static void
-_gaussian_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h)
-{
-   int *weights;
-   int pow2_div = 0;
-
-   weights = alloca((2 * radius + 1) * sizeof(int));
-   _sin_blur_weights_get(weights, &pow2_div, radius);
-
-   DEBUG_TIME_BEGIN();
-   _gaussian_blur_horiz_rgba_step(src, dst, radius, w, h, w, weights, pow2_div);
-   DEBUG_TIME_END();
-}
-
 #define FUNCTION_NAME _gaussian_blur_vert_rgba_step
 #define STEP loops
 #include "./blur/blur_gaussian_rgba_.c"
 
-static void
-_gaussian_blur_vert_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h)
+static Eina_Bool
+_gaussian_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
 {
+   unsigned int src_len, src_stride, dst_len, dst_stride, radius;
+   Eina_Bool ret = EINA_TRUE;
+   int pow2_div = 0, w, h;
+   void *src, *dst;
    int *weights;
-   int pow2_div = 0;
+
+   radius = abs(vert ? cmd->blur.dy : cmd->blur.dx);
+   src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
+   dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
+   w = cmd->input->w;
+   h = cmd->input->h;
 
    weights = alloca((2 * radius + 1) * sizeof(int));
    _sin_blur_weights_get(weights, &pow2_div, radius);
 
-   DEBUG_TIME_BEGIN();
-   _gaussian_blur_vert_rgba_step(src, dst, radius, h, w, 1, weights, pow2_div);
-   DEBUG_TIME_END();
+   if (src && dst)
+     {
+        DEBUG_TIME_BEGIN();
+        if (rgba)
+          {
+             if (!vert)
+               _gaussian_blur_horiz_rgba_step(src, dst, radius, w, h, w, weights, pow2_div);
+             else
+               _gaussian_blur_vert_rgba_step(src, dst, radius, h, w, 1, weights, pow2_div);
+          }
+        else
+          {
+             if (!vert)
+               _gaussian_blur_horiz_alpha_step(src, dst, radius, w, h, w, weights, pow2_div);
+             else
+               _gaussian_blur_vert_alpha_step(src, dst, radius, h, w, 1, weights, pow2_div);
+          }
+        DEBUG_TIME_END();
+     }
+   else ret = EINA_FALSE;
+
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
+
+   return ret;
 }
 
 static Eina_Bool
 _gaussian_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
 {
-   RGBA_Image *in, *out;
-   unsigned int r;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   r = abs(cmd->blur.dx);
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
-
-   _gaussian_blur_horiz_alpha(in->image.data8, out->image.data8, r,
-                              in->cache_entry.w, in->cache_entry.h);
-
-   return EINA_TRUE;
+   return _gaussian_blur_apply(cmd, 0, 0);
 }
 
 static Eina_Bool
 _gaussian_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
 {
-   RGBA_Image *in, *out;
-   unsigned int r;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   r = abs(cmd->blur.dy);
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
-
-   _gaussian_blur_vert_alpha(in->image.data8, out->image.data8, r,
-                             in->cache_entry.w, in->cache_entry.h);
-
-   return EINA_TRUE;
+   return _gaussian_blur_apply(cmd, 1, 0);
 }
 
 static Eina_Bool
 _gaussian_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
 {
-   RGBA_Image *in, *out;
-   unsigned int r;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   r = abs(cmd->blur.dx);
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
-   _gaussian_blur_horiz_rgba(in->image.data, out->image.data, r,
-                             in->cache_entry.w, in->cache_entry.h);
-
-   return EINA_TRUE;
+   return _gaussian_blur_apply(cmd, 0, 1);
 }
 
 static Eina_Bool
 _gaussian_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
 {
-   RGBA_Image *in, *out;
-   unsigned int r;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   r = abs(cmd->blur.dy);
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
-   _gaussian_blur_vert_rgba(in->image.data, out->image.data, r,
-                            in->cache_entry.w, in->cache_entry.h);
-
-   return EINA_TRUE;
+   return _gaussian_blur_apply(cmd, 1, 1);
 }
 
 /* Main entry point */
index 6155e65..e93f1ad 100644 (file)
@@ -50,7 +50,7 @@ evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd)
 }
 
 static void
-_phong_alpha_generate(DATA8 *phong, DATA8 dark, DATA8 color, DATA8 white,
+_phong_alpha_generate(uint8_t *phong, uint8_t dark, uint8_t color, uint8_t white,
                       float sf)
 {
    int x, y;
@@ -100,22 +100,23 @@ _phong_alpha_generate(DATA8 *phong, DATA8 dark, DATA8 color, DATA8 white,
 static Eina_Bool
 _bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
 {
-   DATA8 *src, *map, *dst, *map_y1, *map_y2;
-   DATA8 dark, color, white;
-   DATA8 *phong;
+   uint8_t *src_map, *map_map, *dst_map;
+   uint8_t *src, *map, *dst, *map_y1, *map_y2;
+   uint8_t dark, color, white;
+   uint8_t *phong = NULL;
+   Eina_Bool ret = EINA_FALSE;
    int x, y, w, h, lx, ly;
+   unsigned int ss, ms, ds, slen, dlen, mlen;
    float xyangle, zangle, sf, lxy;
 
    w = cmd->input->w;
    h = cmd->input->h;
    EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
 
-   src = ((RGBA_Image *) cmd->input->backing)->image.data8;
-   map = ((RGBA_Image *) cmd->mask->backing)->image.data8;
-   dst = ((RGBA_Image *) cmd->output->backing)->image.data8;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+   src_map = src = _buffer_map_all(cmd->input->buffer, &slen, E_READ, E_ALPHA, &ss);
+   map_map = map = _buffer_map_all(cmd->mask->buffer, &mlen, E_READ, E_ALPHA, &ms);
+   dst_map = dst = _buffer_map_all(cmd->output->buffer, &dlen, E_WRITE, E_ALPHA, &ds);
+   EINA_SAFETY_ON_FALSE_GOTO(src && dst && map, end);
 
    xyangle = cmd->bump.xyangle;
    zangle = cmd->bump.zangle;
@@ -150,7 +151,7 @@ _bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
 
    // Generate light table
    phong = malloc(256 * 256 * sizeof(*phong));
-   EINA_SAFETY_ON_NULL_RETURN_VAL(phong, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_GOTO(phong, end);
    _phong_alpha_generate(phong, dark, color, white, sf);
 
    for (y = 0; y < h; y++)
@@ -228,31 +229,36 @@ _bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
         src++;
      }
 
+   ret = EINA_TRUE;
+
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, slen));
+   eo_do(cmd->mask->buffer, ector_buffer_unmap(map_map, mlen));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dlen));
    free(phong);
-   return EINA_TRUE;
+   return ret;
 }
 
 static Eina_Bool
 _bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd)
 {
-   DATA8 *src, *map, *map_y1, *map_y2;
-   DATA32 *dst;
-   DATA32 dark, color, white, col;
-   //DATA32 *phong;
-   Eina_Bool compensate;
+   uint8_t *src_map, *map_map;
+   uint8_t *src, *map, *map_y1, *map_y2;
+   uint32_t *dst, *dst_map;
+   uint32_t dark, color, white, col;
+   Eina_Bool compensate, ret = EINA_FALSE;
    int x, y, w, h, lx, ly, lz, gz, NL, diffusion, gzlz, gz2;
+   unsigned int ss, ms, ds, slen, dlen, mlen;
    double xyangle, zangle, sf, lxy, elevation;
 
    w = cmd->input->w;
    h = cmd->input->h;
    EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
 
-   src = ((RGBA_Image *) cmd->input->backing)->image.data8;
-   map = ((RGBA_Image *) cmd->mask->backing)->image.data8;
-   dst = ((RGBA_Image *) cmd->output->backing)->image.data;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+   src_map = src = _buffer_map_all(cmd->input->buffer, &slen, E_READ, E_ALPHA, &ss);
+   map_map = map = _buffer_map_all(cmd->mask->buffer, &mlen, E_READ, E_ALPHA, &ms);
+   dst_map = dst = (uint32_t *) _buffer_map_all(cmd->output->buffer, &dlen, E_WRITE, E_ARGB, &ds);
+   EINA_SAFETY_ON_FALSE_GOTO(src && dst && map, end);
 
    xyangle = cmd->bump.xyangle;
    zangle = cmd->bump.zangle;
@@ -403,7 +409,13 @@ _bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd)
           }
    }
 
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, slen));
+   eo_do(cmd->mask->buffer, ector_buffer_unmap(map_map, mlen));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dlen));
+   return ret;
 }
 
 static Eina_Bool
index 0a9d761..9950121 100644 (file)
@@ -5,23 +5,23 @@
 static Eina_Bool
 _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
 {
-   RGBA_Image *in, *out;
-   DATA32 *src, *dst, *d, *s;
-   DATA8 *curve;
+   unsigned int src_len, src_stride, dst_len, dst_stride;
+   void *src_map = NULL, *dst_map;
+   Eina_Bool ret = EINA_FALSE;
+   uint32_t *src, *dst, *d, *s;
+   uint8_t *curve;
    int k, offset = -1, len;
 
-#define C_VAL(p) (((DATA8 *)(p))[offset])
+#define C_VAL(p) (((uint8_t *)(p))[offset])
+
+   // FIXME: support src_stride != dst_stride
+   // Note: potentially mapping the same region twice (read then write)
+   src_map = src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride);
+   dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
+   EINA_SAFETY_ON_FALSE_GOTO(src && dst && (src_len == dst_len), end);
 
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
-   src = in->image.data;
-   dst = out->image.data;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
    curve = cmd->curve.data;
-   len = in->cache_entry.w * in->cache_entry.h;
+   len = dst_len / sizeof(uint32_t);
 
    switch (cmd->curve.channel)
      {
@@ -38,11 +38,11 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
       case EVAS_FILTER_CHANNEL_RGB: break;
       default:
         ERR("Invalid color channel %d", (int) cmd->curve.channel);
-        return EINA_FALSE;
+        goto end;
      }
 
    if (src != dst)
-     memcpy(dst, src, len * sizeof(DATA32));
+     memcpy(dst, src, dst_len);
    evas_data_argb_unpremul(dst, len);
 
    // One channel (R, G or B)
@@ -82,31 +82,39 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
 
 premul:
    evas_data_argb_premul(dst, len);
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+   return ret;
 }
 
 static Eina_Bool
 _filter_curve_cpu_alpha(Evas_Filter_Command *cmd)
 {
-   RGBA_Image *in, *out;
-   DATA8 *src, *dst;
-   DATA8 *curve;
+   unsigned int src_len, src_stride, dst_len, dst_stride;
+   uint8_t *src, *dst, *curve;
+   void *src_map, *dst_map;
+   Eina_Bool ret = EINA_FALSE;
    int k;
 
-   in = cmd->input->backing;
-   out = cmd->output->backing;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
-   src = in->image.data8;
-   dst = out->image.data8;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+   // FIXME: support src_stride != dst_stride
+   // Note: potentially mapping the same region twice (read then write)
+   src_map = src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
+   dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ALPHA, &dst_stride);
+   EINA_SAFETY_ON_FALSE_GOTO(src && dst && (src_len == dst_len), end);
    curve = cmd->curve.data;
 
-   for (k = in->cache_entry.w * in->cache_entry.h; k; k--)
+   for (k = src_len; k; k--)
      *dst++ = curve[*src++];
 
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+   return ret;
 }
 
 Evas_Filter_Apply_Func
@@ -124,6 +132,8 @@ evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd)
    if (cmd->input->alpha_only && cmd->output->alpha_only)
      return _filter_curve_cpu_alpha;
 
-   CRI("Incompatible image formats");
-   return NULL;
+   // Rely on ector buffer's implicit conversion. not great but the command
+   // doesn't make much sense (curve requires same channel count).
+   WRN("Incompatible image formats");
+   return _filter_curve_cpu_rgba;
 }
index 3a1829c..1513a91 100644 (file)
@@ -3,22 +3,24 @@
 
 static void
 _filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
-                              DATA8 *src, DATA8 *dst, DATA32 *map_start,
+                              uint8_t *src, uint8_t *dst, uint32_t *map_start,
                               Eina_Bool stretch, Eina_Bool smooth,
                               Eina_Bool blend)
 {
    int x, y, map_x, map_y;
    const int dx = RED;
    const int dy = GREEN;
-   DATA8 *map;
+   uint8_t *map;
+
+   // FIXME: Add stride support
 
    for (y = 0, map_y = 0; y < h; y++, map_y++)
      {
         if (map_y >= map_h) map_y = 0;
-        map = (DATA8 *) (map_start + map_y * map_w);
+        map = (uint8_t *) (map_start + map_y * map_w);
 
         for (x = 0, map_x = 0; x < w;
-             x++, dst++, src++, map_x++, map += sizeof(DATA32))
+             x++, dst++, src++, map_x++, map += sizeof(uint32_t))
           {
              int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
              Eina_Bool out = 0;
@@ -27,7 +29,7 @@ _filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
              if (map_x >= map_w)
                {
                   map_x = 0;
-                  map = (DATA8 *) (map_start + map_y * map_w);
+                  map = (uint8_t *) (map_start + map_y * map_w);
                }
 
              // x
@@ -76,7 +78,7 @@ _filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
 
 static void
 _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
-                             DATA32 *src, DATA32 *dst, DATA32 *map_start,
+                             uint32_t *src, uint32_t *dst, uint32_t *map_start,
                              Eina_Bool stretch, Eina_Bool smooth,
                              Eina_Bool blend)
 {
@@ -84,25 +86,25 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
    const int dx = RED;
    const int dy = GREEN;
    Eina_Bool unpremul = EINA_FALSE;
-   DATA8 *map;
+   uint8_t *map;
 
    for (y = 0, map_y = 0; y < h; y++, map_y++)
      {
         if (map_y >= map_h) map_y = 0;
-        map = (DATA8 *) (map_start + map_y * map_w);
+        map = (uint8_t *) (map_start + map_y * map_w);
 
         for (x = 0, map_x = 0; x < w;
-             x++, dst++, src++, map_x++, map += sizeof(DATA32))
+             x++, dst++, src++, map_x++, map += sizeof(uint32_t))
           {
              int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
-             DATA32 col = 0;
+             uint32_t col = 0;
              Eina_Bool out = 0;
 
              // wrap (x)
              if (map_x >= map_w)
                {
                   map_x = 0;
-                  map = (DATA8 *) (map_start + map_y * map_w);
+                  map = (uint8_t *) (map_start + map_y * map_w);
                }
 
              if (!map[ALPHA]) continue;
@@ -134,7 +136,7 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
              else
                {
                   int R, G, B, A;
-                  DATA32 s00, s01, s10, s11; // indexes represent x,y
+                  uint32_t s00, s01, s10, s11; // indexes represent x,y
                   int mul00, mul01, mul10, mul11;
 
                   mul00 = (128 - offx_dec) * (128 - offy_dec);
@@ -172,7 +174,7 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
 
              if (blend)
                {
-                  DATA32 a = 256 - ALPHA_OF(col);
+                  uint32_t a = 256 - ALPHA_OF(col);
                   *dst = col + MUL_256(a, *dst);
                }
              else
@@ -193,26 +195,21 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
 static Eina_Bool
 _filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
 {
+   unsigned int src_len, src_stride, map_len, map_stride, dst_len, dst_stride;
    int w, h, map_w, map_h, intensity;
-   DATA8 *dst, *src;
-   DATA32 *map_start;
+   uint8_t *dst, *src;
+   uint32_t *map_start;
    Eina_Bool stretch, smooth, blend;
+   Evas_Filter_Buffer *map_fb;
+   Eina_Bool ret = EINA_FALSE;
 
    w = cmd->input->w;
    h = cmd->input->h;
    EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   src = ((RGBA_Image *) cmd->input->backing)->image.data8;
-   map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
-   dst = ((RGBA_Image *) cmd->output->backing)->image.data8;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
 
+   src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
+   dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ALPHA, &dst_stride);
    stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
    smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
    map_w = cmd->mask->w;
@@ -223,26 +220,32 @@ _filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
    // Stretch if necessary.
    if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
      {
-        Evas_Filter_Buffer *fb;
-
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
           map_w = w;
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
           map_h = h;
 
         BUFFERS_LOCK();
-        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
+        map_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
         BUFFERS_UNLOCK();
 
-        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
-        fb->locked = EINA_FALSE;
-        map_start = ((RGBA_Image *) fb->backing)->image.data;
+        EINA_SAFETY_ON_NULL_RETURN_VAL(map_fb, EINA_FALSE);
+        map_fb->locked = EINA_FALSE;
      }
+   else map_fb = cmd->mask;
+
+   map_start = (uint32_t *) _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride);
+   EINA_SAFETY_ON_FALSE_GOTO(src && dst && map_start, end);
 
    _filter_displace_cpu_alpha_do(w, h, map_w, map_h, intensity,
                                  src, dst, map_start, stretch, smooth, blend);
 
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
+   eo_do(map_fb->buffer, ector_buffer_unmap(map_start, map_len));
+   return ret;
 }
 
 /**
@@ -254,25 +257,20 @@ _filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
 static Eina_Bool
 _filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
 {
+   unsigned int src_len, src_stride, map_len, map_stride, dst_len, dst_stride;
    int w, h, map_w, map_h, intensity;
-   DATA32 *dst, *src, *map_start;
+   uint32_t *dst, *src, *map_start;
    Eina_Bool stretch, smooth, blend;
+   Evas_Filter_Buffer *map_fb;
+   Eina_Bool ret = EINA_FALSE;
 
    w = cmd->input->w;
    h = cmd->input->h;
    EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
-   src = ((RGBA_Image *) cmd->input->backing)->image.data;
-   map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
-   dst = ((RGBA_Image *) cmd->output->backing)->image.data;
-   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
 
+   src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride);
+   dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ARGB, &dst_stride);
    stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
    smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
    map_w = cmd->mask->w;
@@ -283,26 +281,32 @@ _filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
    // Stretch if necessary.
    if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
      {
-        Evas_Filter_Buffer *fb;
-
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
           map_w = w;
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
           map_h = h;
 
         BUFFERS_LOCK();
-        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
+        map_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
         BUFFERS_UNLOCK();
 
-        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
-        fb->locked = EINA_FALSE;
-        map_start = ((RGBA_Image *) fb->backing)->image.data;
+        EINA_SAFETY_ON_NULL_RETURN_VAL(map_fb, EINA_FALSE);
+        map_fb->locked = EINA_FALSE;
      }
+   else map_fb = cmd->mask;
+
+   map_start = (uint32_t *) _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride);
+   EINA_SAFETY_ON_FALSE_GOTO(src && dst && map_start, end);
 
    _filter_displace_cpu_rgba_do(w, h, map_w, map_h, intensity,
                                 src, dst, map_start, stretch, smooth, blend);
 
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
+   eo_do(map_fb->buffer, ector_buffer_unmap(map_start, map_len));
+   return ret;
 }
 
 Evas_Filter_Apply_Func
index 5293233..e7090d9 100644 (file)
@@ -1,14 +1,17 @@
 #include "evas_filter_private.h"
+#include "draw.h"
 
 static Eina_Bool
 _fill_cpu(Evas_Filter_Command *cmd)
 {
    Evas_Filter_Buffer *fb = cmd->output;
-   int step = fb->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
+   int step = fb->alpha_only ? sizeof(uint8_t) : sizeof(uint32_t);
    int x = MAX(0, cmd->draw.clip.x);
    int y = MAX(0, cmd->draw.clip.y);
-   DATA8 *ptr = ((RGBA_Image *) fb->backing)->image.data8;
-   int w, h, k, j;
+   uint32_t color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+   unsigned int stride, len;
+   int w, h, k;
+   uint8_t *ptr;
 
    if (!cmd->draw.clip_mode_lrtb)
      {
@@ -29,30 +32,28 @@ _fill_cpu(Evas_Filter_Command *cmd)
         h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y);
      }
 
-   ptr += y * step * fb->w;
-   if ((fb->alpha_only)
-       || (!cmd->draw.R && !cmd->draw.G && !cmd->draw.B && !cmd->draw.A)
-       || ((cmd->draw.R == 0xff) && (cmd->draw.G == 0xff)
-           && (cmd->draw.B == 0xff) && (cmd->draw.A == 0xff)))
+   ptr = _buffer_map_all(fb->buffer, &len, E_WRITE, fb->alpha_only ? E_ALPHA : E_ARGB, &stride);
+   if (!ptr) return EINA_FALSE;
+
+   ptr += y * stride;
+   if (fb->alpha_only)
      {
         for (k = 0; k < h; k++)
           {
              memset(ptr + (x * step), cmd->draw.A, step * w);
-             ptr += step * fb->w;
+             ptr += stride;
           }
      }
    else
      {
-        DATA32 *dst = ((DATA32 *) ptr) + x;
-        DATA32 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
         for (k = 0; k < h; k++)
           {
-             for (j = 0; j < w; j++)
-               *dst++ = color;
-             dst += fb->w - w;
+             uint32_t *dst = ((uint32_t *) (ptr + (y + k) * stride)) + x;
+             draw_memset32(dst, color, w);
           }
      }
 
+   eo_do(fb->buffer, ector_buffer_unmap(ptr, len));
    return EINA_TRUE;
 }
 
index 135d0df..d8d6dda 100644 (file)
@@ -18,11 +18,11 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd)
    EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL);
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, NULL);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, NULL);
-
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->buffer, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->buffer, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->buffer, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->input->w > 0) && (cmd->input->h > 0), NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->mask->w > 0) && (cmd->mask->h > 0), NULL);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->w == cmd->output->w, NULL);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->h == cmd->output->h, NULL);
 
@@ -53,12 +53,14 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd)
 static Eina_Bool
 _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
 {
-   Alpha_Gfx_Func func;
-   RGBA_Image *in, *out, *mask;
-   DATA8 *src, *dst, *msk;
+   unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
    Efl_Gfx_Render_Op render_op = cmd->draw.rop;
+   Evas_Filter_Buffer *msk_fb;
+   Alpha_Gfx_Func func;
+   uint8_t *src_map = NULL, *dst, *dst_map = NULL, *msk, *msk_map = NULL;
    int w, h, mw, mh, x, y, my;
    int stepsize, stepcount, step;
+   Eina_Bool ret = EINA_FALSE;
 
    /* Mechanism:
     * 1. Stretch mask as requested in fillmode
@@ -68,56 +70,57 @@ _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
     * FIXME: Could probably be optimized into a single op :)
     */
 
-   in = (RGBA_Image *) cmd->input->backing;
-   out = (RGBA_Image *) cmd->output->backing;
-   mask = (RGBA_Image *) cmd->mask->backing;
-
    w = cmd->input->w;
    h = cmd->input->h;
    mw = cmd->mask->w;
    mh = cmd->mask->h;
-   src = in->image.data8;
-   dst = out->image.data8;
-
-   EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
-
    stepsize  = MIN(mw, w);
    stepcount = w / stepsize;
 
    // Stretch if necessary.
    if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
      {
-        Evas_Filter_Buffer *fb;
-
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
           mw = w;
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
           mh = h;
 
         BUFFERS_LOCK();
-        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+        msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
         BUFFERS_UNLOCK();
 
-        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
-        fb->locked = EINA_FALSE;
-        mask = fb->backing;
+        EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
+        msk_fb->locked = EINA_FALSE;
      }
+   else msk_fb = cmd->mask;
 
-   msk = mask->image.data8;
+   msk_map = msk = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ALPHA, &msk_stride);
+   dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ALPHA, &dst_stride);
+   EINA_SAFETY_ON_FALSE_GOTO(dst_map && msk_map, end);
 
    // First pass: copy to dest
-   if (src != dst)
-     memcpy(dst, src, w * h * sizeof(DATA8));
+   if (cmd->input->buffer != cmd->output->buffer)
+     {
+        src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
+        EINA_SAFETY_ON_FALSE_GOTO(src_map, end);
+        if (dst_stride == src_stride)
+          memcpy(dst_map, src_map, dst_stride * h * sizeof(uint8_t));
+        else
+          {
+             for (y = 0; y < h; y++)
+               memcpy(dst_map + (y * dst_stride), src_map + (y * src_stride),
+                      MIN(dst_stride, src_stride) * h * sizeof(uint8_t));
+          }
+     }
 
    // Second pass: apply render op
    func = efl_draw_alpha_func_get(render_op, EINA_FALSE);
-   for (y = 0, my = 0; y < h; y++, my++, msk += mw)
+   for (y = 0, my = 0; y < h; y++, my++)
      {
-        if (my >= mh)
-          {
-             my = 0;
-             msk = mask->image.data8;
-          }
+        if (my >= mh) my = 0;
+
+        msk = msk_map + (my * msk_stride);
+        dst = dst_map + (y * dst_stride);
 
         for (step = 0; step < stepcount; step++, dst += stepsize)
           func(msk, dst, stepsize);
@@ -126,11 +129,16 @@ _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
         if (x < w)
           {
              func(msk, dst, w - x);
-             dst += w - x;
           }
      }
 
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+   eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+   return ret;
 }
 
 static Eina_Bool
@@ -161,14 +169,16 @@ _mask_cpu_rgba_alpha_rgba(Evas_Filter_Command *cmd)
 static Eina_Bool
 _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd)
 {
-   RGBA_Gfx_Func func1, func2;
-   RGBA_Image *in, *out, *mask;
-   DATA8 *src;
-   DATA32 *dst, *msk, *span;
+   unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
    Efl_Gfx_Render_Op op = cmd->draw.rop;
-   int w, h, mw, mh, y, my, r;
+   Evas_Filter_Buffer *msk_fb;
+   RGBA_Gfx_Func func1, func2;
+   uint8_t *src, *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
+   uint32_t *dst, *msk, *span;
+   int w, h, mw, mh, x, y, my;
    int stepsize, stepcount, step;
-   DATA32 color2;
+   Eina_Bool ret = EINA_FALSE;
+   uint32_t color;
 
    /* Mechanism:
     * 1. Stretch mask as requested in fillmode
@@ -178,94 +188,88 @@ _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd)
     * FIXME: Could probably be optimized into a single op :)
     */
 
-   in = (RGBA_Image *) cmd->input->backing;
-   out = (RGBA_Image *) cmd->output->backing;
-   mask = (RGBA_Image *) cmd->mask->backing;
-
    w = cmd->input->w;
    h = cmd->input->h;
    mw = cmd->mask->w;
    mh = cmd->mask->h;
-   src = in->image.data8;
-   dst = out->image.data;
+   color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+   stepsize  = MIN(mw, w);
+   stepcount = w / stepsize;
+   span = alloca(stepsize * sizeof(uint32_t));
 
    // Stretch if necessary.
    if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
      {
-        Evas_Filter_Buffer *fb;
-
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
           mw = w;
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
           mh = h;
 
         BUFFERS_LOCK();
-        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+        msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
         BUFFERS_UNLOCK();
 
-        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
-        fb->locked = EINA_FALSE;
-        mask = fb->backing;
+        EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
+        msk_fb->locked = EINA_FALSE;
      }
+   else msk_fb = cmd->mask;
 
-   color2 = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
-   msk = mask->image.data;
+   src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ALPHA, &src_stride);
+   msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
+   dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
+   EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
 
-   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(msk, EINA_FALSE);
-   EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
-
-   stepsize  = MIN(mw, w);
-   stepcount = w / stepsize;
-   span = malloc(stepsize * sizeof(DATA32));
-
-   func1 = evas_common_gfx_func_composite_pixel_mask_span_get(mask->cache_entry.flags.alpha, mask->cache_entry.flags.alpha_sparse, out->cache_entry.flags.alpha, 1, EVAS_RENDER_COPY);
-   func2 = evas_common_gfx_func_composite_pixel_color_span_get(mask->cache_entry.flags.alpha, mask->cache_entry.flags.alpha_sparse, color2, out->cache_entry.flags.alpha, 1, _gfx_to_evas_render_op(op));
+   func1 = evas_common_gfx_func_composite_pixel_mask_span_get(1, 0, 1, 1, EVAS_RENDER_COPY);
+   func2 = evas_common_gfx_func_composite_pixel_color_span_get(1, 0, color, 1, 1, _gfx_to_evas_render_op(op));
 
    // Apply mask using Gfx functions
-   for (y = 0, my = 0; y < h; y++, my++, msk += mw)
+   for (y = 0, my = 0; y < h; y++, my++)
      {
-        if (my >= mh)
-          {
-             my = 0;
-             msk = mask->image.data;
-          }
+        if (my >= mh) my = 0;
+
+        src = src_map + (y * src_stride);
+        msk = (uint32_t *) (msk_map + (my * msk_stride));
+        dst = (uint32_t *) (dst_map + (y * dst_stride));
 
         for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
           {
-             memset(span, 0, stepsize * sizeof(DATA32));
+             memset(span, 0, stepsize * sizeof(uint32_t));
              func1(msk, src, 0, span, stepsize);
-             func2(span, NULL, color2, dst, stepsize);
+             func2(span, NULL, color, dst, stepsize);
           }
 
-        r = w - (stepsize * stepcount);
-        if (r > 0)
+        x = stepsize * stepcount;
+        if (x < w)
           {
-             memset(span, 0, r * sizeof(DATA32));
-             func1(msk, src, 0, span, r);
-             func2(span, NULL, color2, dst, r);
-             dst += r;
-             src += r;
+             memset(span, 0, (w - x) * sizeof(uint32_t));
+             func1(msk, src, 0, span, w - x);
+             func2(span, NULL, color, dst, w - x);
           }
      }
 
-   free(span);
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+   eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+   return ret;
 }
 
 static Eina_Bool
 _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
 {
+   unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
+   uint8_t *src, *msk, *span, *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
+   Evas_Filter_Buffer *msk_fb;
    RGBA_Gfx_Func func;
    Alpha_Gfx_Func span_func;
-   RGBA_Image *in, *out, *mask;
-   DATA8 *src, *msk, *span;
-   DATA32 *dst;
-   DATA32 color;
+   uint32_t *dst;
+   uint32_t color;
    Efl_Gfx_Render_Op op = cmd->draw.rop;
-   int w, h, mw, mh, y, my, r;
+   int w, h, mw, mh, x, y, my;
    int stepsize, stepcount, step;
+   Eina_Bool ret = EINA_FALSE;
 
    /* Mechanism:
     * 1. Copy mask to span buffer (1 line)
@@ -275,155 +279,147 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
     * FIXME: Could probably be optimized into a single op :)
     */
 
-   in = (RGBA_Image *) cmd->input->backing;
-   out = (RGBA_Image *) cmd->output->backing;
-   mask = (RGBA_Image *) cmd->mask->backing;
-
    w = cmd->input->w;
    h = cmd->input->h;
    mw = cmd->mask->w;
    mh = cmd->mask->h;
-   src = in->image.data8;
-   dst = out->image.data;
    color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
-
-   EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
+   stepsize  = MIN(mw, w);
+   stepcount = w / stepsize;
+   span = alloca(stepsize * sizeof(uint32_t));
 
    // Stretch if necessary.
    if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
      {
-        Evas_Filter_Buffer *fb;
-
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
           mw = w;
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
           mh = h;
 
         BUFFERS_LOCK();
-        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+        msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
         BUFFERS_UNLOCK();
 
-        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
-        fb->locked = EINA_FALSE;
-        mask = fb->backing;
+        EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
+        msk_fb->locked = EINA_FALSE;
      }
+   else msk_fb = cmd->mask;
 
-   msk = mask->image.data8;
-   stepsize  = MIN(mw, w);
-   stepcount = w / stepsize;
-   span = malloc(stepsize * sizeof(DATA8));
+   src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ALPHA, &src_stride);
+   msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
+   dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
+   EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
 
-   func = evas_common_gfx_func_composite_mask_color_span_get(color, out->cache_entry.flags.alpha, 1, _gfx_to_evas_render_op(op));
+   func = evas_common_gfx_func_composite_mask_color_span_get(color, 1, 1, _gfx_to_evas_render_op(op));
    span_func = efl_draw_alpha_func_get(cmd->draw.rop, EINA_TRUE);
 
    for (y = 0, my = 0; y < h; y++, my++, msk += mw)
      {
-        if (my >= mh)
-          {
-             my = 0;
-             msk = mask->image.data8;
-          }
+        if (my >= mh) my = 0;
+
+        src = src_map + (y * src_stride);
+        msk = msk_map + (my * msk_stride);
+        dst = (uint32_t *) (dst_map + (y * dst_stride));
 
         for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
           {
-             memcpy(span, msk, stepsize * sizeof(DATA8));
+             memcpy(span, msk, stepsize * sizeof(uint8_t));
              span_func(src, span, stepsize);
              func(NULL, span, color, dst, stepsize);
           }
 
-        r = w - (stepsize * stepcount);
-        if (r > 0)
+        x = stepsize * stepcount;
+        if (x < w)
           {
-             memcpy(span, msk, r * sizeof(DATA8));
-             span_func(src, span, r);
-             func(NULL, span, color, dst, r);
-             dst += r;
-             src += r;
+             memcpy(span, msk, (w - x) * sizeof(uint8_t));
+             span_func(src, span, w - x);
+             func(NULL, span, color, dst, w -x);
           }
      }
 
-   free(span);
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+   eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+   return ret;
 }
 
 static Eina_Bool
 _mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd)
 {
+   unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
+   uint8_t *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
    Draw_Func_ARGB_Mix3 func;
-   RGBA_Image *in, *out, *mask;
-   DATA32 *dst, *msk, *src;
-   int w, h, mw, mh, y, my, r;
+   Evas_Filter_Buffer *msk_fb;
+   uint32_t *dst, *msk, *src;
+   int w, h, mw, mh, x, y, my;
    int stepsize, stepcount, step;
-   DATA32 color;
+   Eina_Bool ret = EINA_FALSE;
+   uint32_t color;
 
    /* Mechanism:
     * 1. Stretch mask as requested in fillmode
     * 2. Mix 3 colors
     */
 
-   in = (RGBA_Image *) cmd->input->backing;
-   out = (RGBA_Image *) cmd->output->backing;
-   mask = (RGBA_Image *) cmd->mask->backing;
-
    w = cmd->input->w;
    h = cmd->input->h;
    mw = cmd->mask->w;
    mh = cmd->mask->h;
-   src = in->image.data;
-   dst = out->image.data;
+   color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+   stepsize  = MIN(mw, w);
+   stepcount = w / stepsize;
 
    // Stretch if necessary.
    if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
      {
-        Evas_Filter_Buffer *fb;
-
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
           mw = w;
         if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
           mh = h;
 
         BUFFERS_LOCK();
-        fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+        msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
         BUFFERS_UNLOCK();
 
-        EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
-        fb->locked = EINA_FALSE;
-        mask = fb->backing;
+        EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
+        msk_fb->locked = EINA_FALSE;
      }
+   else msk_fb = cmd->mask;
 
-   color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
-   msk = mask->image.data;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(msk, EINA_FALSE);
-   EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
-
-   stepsize  = MIN(mw, w);
-   stepcount = w / stepsize;
+   src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ARGB, &src_stride);
+   msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
+   dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
+   EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
 
    func = efl_draw_func_argb_mix3_get(cmd->draw.rop, color);
 
    // Apply mask using Gfx functions
-   for (y = 0, my = 0; y < h; y++, my++, msk += mw)
+   for (y = 0, my = 0; y < h; y++, my++)
      {
-        if (my >= mh)
-          {
-             my = 0;
-             msk = mask->image.data;
-          }
+        if (my >= mh) my = 0;
+
+        src = (uint32_t *) (src_map + (y * src_stride));
+        msk = (uint32_t *) (msk_map + (my * msk_stride));
+        dst = (uint32_t *) (dst_map + (y * dst_stride));
 
         for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
           func(dst, src, msk, stepsize, color);
 
-        r = w - (stepsize * stepcount);
-        if (r > 0)
+        x = stepsize * stepcount;
+        if (x < w)
           {
-             func(dst, src, msk, r, color);
-             dst += r;
-             src += r;
+             func(dst, src, msk, w - x, color);
           }
      }
 
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+   eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
+   eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+   return ret;
 }
index 02dd977..f3d7118 100644 (file)
@@ -230,7 +230,7 @@ struct _Evas_Filter_Buffer
 
    Evas_Object *source;
    Eina_Stringshare *source_name;
-   RGBA_Image *backing;
+   Ector_Generic_Buffer *buffer;
    void *glimage;
    int w, h;
 
@@ -275,4 +275,20 @@ int evas_filter_smallest_pow2_larger_than(int val);
 
 void evas_filter_parser_shutdown(void);
 
+#define E_READ  ECTOR_BUFFER_ACCESS_FLAG_READ
+#define E_WRITE ECTOR_BUFFER_ACCESS_FLAG_WRITE
+#define E_ALPHA EFL_GFX_COLORSPACE_GRY8
+#define E_ARGB  EFL_GFX_COLORSPACE_ARGB8888
+
+static inline void *
+_buffer_map_all(Ector_Buffer *buf, unsigned int *len, Ector_Buffer_Access_Flag mode, Efl_Gfx_Colorspace cspace, unsigned int *stride)
+{
+   void *ret = NULL;
+   int w, h;
+   if (!buf) return NULL;
+   eo_do(buf, ector_buffer_size_get(&w, &h);
+         ret = ector_buffer_map(len, mode, 0, 0, w, h, cspace, stride));
+   return ret;
+}
+
 #endif // EVAS_FILTER_PRIVATE_H
index 3deda12..fd05d5c 100644 (file)
 static Eina_Bool
 _vflip_cpu(Evas_Filter_Command *cmd)
 {
-   size_t datasize, stride;
-   DATA8 *in, *out, *span = NULL;
+   unsigned int src_len, src_stride, dst_len, dst_stride;
+   uint8_t *in, *out = NULL, *span = NULL;
    int w, h, sy, dy, oy, center, t, b, objh;
    int s0, s1, d0, d1;
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+   Eina_Bool ret = 0;
 
    w = cmd->input->w;
    h = cmd->input->h;
-   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->w == w, EINA_FALSE);
-   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->h == h, EINA_FALSE);
-   EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->alpha_only == cmd->input->alpha_only, EINA_FALSE);
+   in = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &src_stride);
+   if (cmd->input->buffer != cmd->output->buffer)
+     out = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &dst_stride);
 
-   in = ((RGBA_Image *) cmd->input->backing)->image.data8;
-   out = ((RGBA_Image *) cmd->output->backing)->image.data8;
-   datasize = cmd->input->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
-   stride = w * datasize;
+   EINA_SAFETY_ON_FALSE_GOTO(cmd->output->w == w, end);
+   EINA_SAFETY_ON_FALSE_GOTO(cmd->output->h == h, end);
+   EINA_SAFETY_ON_FALSE_GOTO(src_stride <= dst_stride, end);
+   EINA_SAFETY_ON_FALSE_GOTO(cmd->output->alpha_only == cmd->input->alpha_only, end);
 
    oy = cmd->draw.oy;
    t = cmd->ctx->padt;
@@ -53,28 +48,32 @@ _vflip_cpu(Evas_Filter_Command *cmd)
 
    if (in == out)
      {
-        span = malloc(stride);
-        if (!span) return EINA_FALSE;
+        span = alloca(src_stride);
+        if (!span) goto end;
      }
 
    for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
      {
-        DATA8* src = in + stride * sy;
-        DATA8* dst = out + stride * dy;
+        uint8_t* src = in + src_stride * sy;
+        uint8_t* dst = out + dst_stride * dy;
 
         if (in == out)
           {
              if (src == dst) break;
-             memcpy(span, dst, stride);
-             memcpy(dst, src, stride);
-             memcpy(src, span, stride);
+             memcpy(span, dst, src_stride);
+             memcpy(dst, src, src_stride);
+             memcpy(src, span, src_stride);
              if (sy >= center) break;
           }
         else
-          memcpy(dst, src, stride);
+          memcpy(dst, src, src_stride);
      }
-   free(span);
-   return EINA_TRUE;
+   ret = EINA_TRUE;
+
+end:
+   eo_do(cmd->input->buffer, ector_buffer_unmap(in, src_len));
+   if (in != out) eo_do(cmd->output->buffer, ector_buffer_unmap(out, dst_len));
+   return ret;
 }
 
 Evas_Filter_Apply_Func
index c643c67..8bb98d5 100644 (file)
@@ -8,76 +8,35 @@ evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx,
                               unsigned w, unsigned h)
 {
    Evas_Filter_Buffer *fb;
-   Image_Entry *dstdata = NULL;
-   Image_Entry *srcdata;
-   void *drawctx;
+   RGBA_Image *dstim, *srcim;
+   RGBA_Draw_Context dc;
+   Eina_Bool ok;
 
-   srcdata = evas_filter_buffer_backing_get(ctx, src->id);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(srcdata, NULL);
+   // only for RGBA
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(!src->alpha_only, NULL);
 
-   if (src->alpha_only)
-     {
-        // There is no supporting function in Evas for alpha scaling...
-        // but guess what? There is also no use case in the filters :)
-        CRI("Alpha buffer scaling is not supported");
-        return NULL;
-     }
+   srcim = evas_filter_buffer_backing_get(ctx, src->id);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(srcim, NULL);
 
    fb = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only);
-   if (!fb) return NULL;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fb, NULL);
 
-   dstdata = evas_filter_buffer_backing_get(ctx, fb->id);
-   if (!dstdata)
-     {
-        CRI("No backing found for buffer %d", fb->id);
-        return NULL;
-     }
+   dstim = evas_filter_buffer_backing_get(ctx, fb->id);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dstim, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((dstim->cache_entry.w == w) &&
+                                   (dstim->cache_entry.h == h), NULL);
 
-   if ((dstdata->w != w) || (dstdata->h != h))
-     {
-        CRI("Buffer size mismatch: got %dx%d requested %dx%d",
-            dstdata->w, dstdata->h, w, h);
-        return NULL;
-     }
+   memset(&dc, 0, sizeof(dc));
+   dc.sli.h = 1;
+   dc.render_op = EVAS_RENDER_COPY;
 
-   if (ctx->gl_engine)
-     {
-        RGBA_Image *s = (RGBA_Image *) srcdata;
-        RGBA_Image *d = (RGBA_Image *) dstdata;
-        EINA_SAFETY_ON_NULL_RETURN_VAL(s->image.data, NULL);
-        EINA_SAFETY_ON_NULL_RETURN_VAL(d->image.data, NULL);
+   ok = evas_common_scale_rgba_in_to_out_clip_smooth
+         (srcim, dstim, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
 
-        if (src->w == (int) w && src->h == (int) h)
-          memcpy(d->image.data, s->image.data, w * h * 4);
-        else
-          {
-             Eina_Bool ok;
-             RGBA_Draw_Context dc;
-
-             memset(&dc, 0, sizeof(dc));
-             dc.sli.h = 1;
-             dc.render_op = EVAS_RENDER_COPY;
-
-             ok = evas_common_scale_rgba_in_to_out_clip_smooth
-                   (s, d, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
-             if (!ok)
-               {
-                  ERR("RGBA Image scaling failed.");
-                  return NULL;
-               }
-          }
-     }
-   else
+   if (!ok)
      {
-        drawctx = ENFN->context_new(ENDT);
-        ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
-        ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
-        ENFN->image_draw(ENDT, drawctx, dstdata, srcdata,
-                         0, 0, src->w, src->h, // src
-                         0, 0, w, h, // dst
-                         EINA_TRUE, // smooth
-                         EINA_FALSE); // Not async
-        ENFN->context_free(ENDT, drawctx);
+       ERR("RGBA Image scaling failed.");
+       return NULL;
      }
 
    return fb;
index f1cbffb..bb7a32d 100644 (file)
@@ -143,7 +143,6 @@ void                     evas_filter_context_post_run_callback_set(Evas_Filter_C
 Eina_Bool                evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx);
 
 int                      evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
-int                      evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image);
 void                    *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid);
 void                    *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid);
 Eina_Bool                evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer);
index 854d99d..8ca3c2b 100644 (file)
@@ -1450,7 +1450,8 @@ struct _Evas_Func
 
    Ector_Surface *(*ector_create)        (void *data);
    void  (*ector_destroy)                (void *data, Ector_Surface *surface);
-   Ector_Buffer *(*ector_buffer_new)     (void *data, Evas *e, void *engine_image); // free it with eo_del
+   Ector_Buffer *(*ector_buffer_wrap)    (void *data, Evas *e, void *engine_image);
+   Ector_Buffer *(*ector_buffer_new)     (void *data, Evas *e, void *pixels, int width, int height, int stride, Efl_Gfx_Colorspace cspace, Eina_Bool writeable, int l, int r, int t, int b, Ector_Buffer_Flag flags);
    void  (*ector_begin)                  (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async);
    void  (*ector_renderer_draw)          (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
    void  (*ector_end)                    (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async);
index 0a9e0bc..78a73f4 100644 (file)
@@ -2465,17 +2465,20 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector)
 }
 
 static Ector_Buffer *
-eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image)
+eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image)
 {
-   Evas_GL_Image *im = engine_image;
-   Ector_Buffer *buf = NULL;
-
-   if (!im) return NULL;
-
 #warning FIXME: implement me
-   (void) e;
+   return NULL;
+}
 
-   return buf;
+static Ector_Buffer *
+eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *pixels,
+                     int width, int height, int stride,
+                     Efl_Gfx_Colorspace cspace, Eina_Bool writeable,
+                     int l, int r, int t, int b, Ector_Buffer_Flag flags)
+{
+#warning FIXME: implement me
+   return NULL;
 }
 
 static Efl_Gfx_Render_Op
@@ -2836,6 +2839,7 @@ module_open(Evas_Module *em)
 
    ORD(ector_create);
    ORD(ector_destroy);
+   ORD(ector_buffer_wrap);
    ORD(ector_buffer_new);
    ORD(ector_begin);
    ORD(ector_renderer_draw);
index 3d45862..44ebf8f 100644 (file)
@@ -49,7 +49,7 @@ _evas_ector_software_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ect
 
    eo_do(obj, ector_buffer_pixels_set(im->image.data,
                                       im->cache_entry.w, im->cache_entry.h, 0,
-                                      _evas_to_gfx_render_op(im->cache_entry.space),
+                                      im->cache_entry.space,
                                       EINA_TRUE, 0, 0, 0, 0));
 }
 
index 22967ad..a32c7e6 100644 (file)
@@ -3758,7 +3758,7 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector)
 }
 
 static Ector_Buffer *
-eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image)
+eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image)
 {
    Image_Entry *ie = engine_image;
    Ector_Buffer *buf = NULL;
@@ -3771,6 +3771,22 @@ eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image)
    return buf;
 }
 
+static Ector_Buffer *
+eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *pixels,
+                     int width, int height, int stride,
+                     Efl_Gfx_Colorspace cspace, Eina_Bool writeable,
+                     int l, int r, int t, int b,
+                     Ector_Buffer_Flag flags EINA_UNUSED)
+{
+   Ector_Buffer *buf = NULL;
+
+   buf = eo_add(ECTOR_SOFTWARE_BUFFER_CLASS, e,
+                ector_buffer_pixels_set(pixels, width, height, stride, cspace,
+                                        writeable, l, r, t, b));
+
+   return buf;
+}
+
 static Efl_Gfx_Render_Op
 _evas_render_op_to_ector_rop(Evas_Render_Op op)
 {
@@ -4182,6 +4198,7 @@ static Evas_Func func =
      NULL, // eng_texture_image_get
      eng_ector_create,
      eng_ector_destroy,
+     eng_ector_buffer_wrap,
      eng_ector_buffer_new,
      eng_ector_begin,
      eng_ector_renderer_draw,