evas filters: Fix blur logic and GL buffer handling
authorJean-Philippe Andre <jp.andre@samsung.com>
Mon, 23 Jan 2017 08:55:17 +0000 (17:55 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Fri, 14 Apr 2017 02:26:43 +0000 (11:26 +0900)
This corrects two things:
- the blur filter high-level logic, that lead to reusing some
  temporary buffers which contained garbage;
- the versatile gl buffer implementation so that it now properly
  switches between the RGBA_Image and the FBO content (yes, this
  is insanely slow and inefficient... but it works and that was
  the only point).

16 files changed:
src/lib/evas/filters/evas_filter.c
src/lib/evas/filters/evas_filter_parser.c
src/lib/evas/filters/evas_filter_private.h
src/lib/evas/filters/evas_filter_utils.c
src/lib/evas/include/evas_ector_buffer.eo
src/lib/evas/include/evas_filter.h
src/modules/evas/engines/gl_common/evas_gl_common.h
src/modules/evas/engines/gl_common/evas_gl_image.c
src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/engines/gl_generic/filters/gl_engine_filter.h
src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c
src/modules/evas/engines/software_generic/evas_ector_software_buffer.c
src/modules/evas/engines/software_generic/filters/evas_filter_displace.c
src/modules/evas/engines/software_generic/filters/evas_filter_mask.c

index 98a1cb8..f76a8a3 100644 (file)
@@ -341,7 +341,6 @@ evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only)
    fb = _buffer_empty_new(ctx, 0, 0, alpha_only, EINA_FALSE);
    if (!fb) return -1;
 
-   XDBG("Created context buffer %d %s", fb->id, alpha_only ? "alpha" : "rgba");
    return fb->id;
 }
 
@@ -403,7 +402,7 @@ evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid)
    fb = _filter_buffer_get(ctx, bufid);
    if (!fb) return NULL;
 
-   return evas_ector_buffer_drawable_image_get(fb->buffer, EINA_TRUE);
+   return evas_ector_buffer_drawable_image_get(fb->buffer);
 }
 
 Eina_Bool
@@ -434,6 +433,7 @@ _command_new(Evas_Filter_Context *ctx, Evas_Filter_Mode mode,
    cmd->input = input;
    cmd->mask = mask;
    cmd->output = output;
+   if (output) output->dirty = EINA_TRUE;
 
    ctx->commands = eina_inlist_append(ctx->commands, EINA_INLIST_GET(cmd));
    return cmd;
@@ -454,19 +454,20 @@ _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd)
 
 Evas_Filter_Buffer *
 evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
-                                 Eina_Bool alpha_only)
+                                 Eina_Bool alpha_only, Eina_Bool clean)
 {
-   Evas_Filter_Buffer *buf = NULL;
+   Evas_Filter_Buffer *fb = NULL;
    Eina_List *l;
 
-   EINA_LIST_FOREACH(ctx->buffers, l, buf)
+   EINA_LIST_FOREACH(ctx->buffers, l, fb)
      {
-        if (buf->transient && !buf->locked && (buf->alpha_only == alpha_only))
+        if (fb->transient && !fb->locked && (fb->alpha_only == alpha_only)
+            && (!clean || !fb->dirty))
           {
-             if ((!w || (w == buf->w)) && (!h || (h == buf->h)))
+             if ((!w || (w == fb->w)) && (!h || (h == fb->h)))
                {
-                  buf->locked = EINA_TRUE;
-                  return buf;
+                  fb->locked = EINA_TRUE;
+                  return fb;
                }
           }
      }
@@ -477,10 +478,11 @@ evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h,
         return NULL;
      }
 
-   buf = _buffer_empty_new(ctx, w, h, alpha_only, EINA_TRUE);
-   buf->locked = EINA_TRUE;
+   fb = _buffer_empty_new(ctx, w, h, alpha_only, EINA_TRUE);
+   fb->locked = EINA_TRUE;
+   XDBG("Created temporary buffer %d %s", fb->id, alpha_only ? "alpha" : "rgba");
 
-   return buf;
+   return fb;
 }
 
 static void
@@ -522,7 +524,9 @@ evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context,
 
    XDBG("Add fill %d with color(%d,%d,%d,%d)", buf->id, R, G, B, A);
 
-   buf->dirty = EINA_TRUE;
+   if (!R && !G && !B && !A)
+     buf->dirty = EINA_FALSE;
+
    return cmd;
 }
 
@@ -533,10 +537,16 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
 {
    Evas_Filter_Buffer *in = NULL, *out = NULL, *tmp = NULL, *in_dy = NULL;
    Evas_Filter_Buffer *out_dy = NULL, *out_dx = NULL;
-   Evas_Filter_Buffer *copybuf = NULL, *blur_out = NULL;
-   Eina_Bool copy_back = EINA_FALSE, blend = EINA_FALSE;
+   Evas_Filter_Buffer *copybuf = NULL, *blendbuf = NULL;
    Evas_Filter_Command *cmd = NULL;
-   int R, G, B, A; DATA32 color;
+   int R, G, B, A, render_op;
+   Eina_Bool override;
+   DATA32 color;
+
+   // Note (SW engine):
+   // The basic blur operation overrides the pixels in the target buffer,
+   // only supports one direction (X or Y) and no offset. As a consequence
+   // most cases require intermediate work buffers.
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
    EINA_SAFETY_ON_NULL_RETURN_VAL(drawctx, NULL);
@@ -555,20 +565,19 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
    out = _filter_buffer_get(ctx, outbuf);
    EINA_SAFETY_ON_FALSE_GOTO(out, fail);
 
-   if (!in->alpha_only && out->alpha_only)
-     DBG("Different color formats, implicit conversion may be slow");
-
    if (in == out) out->dirty = EINA_FALSE;
-   blend = (out->dirty && !out->transient);
 
    ENFN->context_color_get(ENDT, drawctx, &R, &G, &B, &A);
    color = ARGB_JOIN(A, R, G, B);
    if (!color)
      {
         DBG("Blur with transparent color. Nothing to do.");
-        /* FIXME: return skip; */
+        return _command_new(ctx, EVAS_FILTER_MODE_SKIP, NULL, NULL, NULL);
      }
 
+   render_op = ENFN->context_render_op_get(ENDT, drawctx);
+   override = (render_op == EVAS_RENDER_COPY);
+
    switch (type)
      {
       case EVAS_FILTER_BLUR_GAUSSIAN:
@@ -580,48 +589,47 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
         break;
 
       case EVAS_FILTER_BLUR_DEFAULT:
-
-        /* In DEFAULT mode we cheat, depending on the size of the kernel:
-         * For 1px to 2px, use true Gaussian blur.
-         * For 3px to 6px, use two Box blurs.
-         * For more than 6px, use three Box blurs.
-         * This will give both nicer and MUCH faster results than Gaussian.
-         *
-         * NOTE: When implementing blur with GL shaders, other tricks will be
-         * needed, of course!
-         */
         {
-           const Eina_Bool alpha = in->alpha_only;
+           /* In DEFAULT mode we cheat, depending on the size of the kernel:
+            * For 1px to 2px, use true Gaussian blur.
+            * For 3px to 6px, use two Box blurs.
+            * For more than 6px, use three Box blurs.
+            * This will give both nicer and MUCH faster results than Gaussian.
+            *
+            * NOTE: This step should be avoided in GL.
+            */
+
            int tmp_out = outbuf;
            int tmp_in = inbuf;
            int tmp_ox = ox;
            int tmp_oy = oy;
 
+           // For 2D blur: create intermediate buffer
            if (dx && dy)
              {
-                tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, alpha);
+                tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 1);
                 if (!tmp) goto fail;
                 tmp_in = tmp_out = tmp->id;
                 tmp_ox = tmp_oy = 0;
              }
 
+           // X box blur
            if (dx)
              {
                 if (dx <= 2)
                   type = EVAS_FILTER_BLUR_GAUSSIAN;
                 else
-                   type = EVAS_FILTER_BLUR_BOX;
+                  type = EVAS_FILTER_BLUR_BOX;
 
-                if (dy && (color != 0xFFFFFFFF))
-                  ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
+                if (dy) ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
                 cmd = evas_filter_command_blur_add(ctx, drawctx, inbuf, tmp_out,
                                                    type, dx, 0, tmp_ox, tmp_oy, 0);
                 if (!cmd) goto fail;
                 cmd->blur.auto_count = EINA_TRUE;
-                if (dy && (color != 0xFFFFFFFF))
-                  ENFN->context_color_set(ENDT, drawctx, R, G, B, A);
+                if (dy) ENFN->context_color_set(ENDT, drawctx, R, G, B, A);
              }
 
+           // Y box blur
            if (dy)
              {
                 if (dy <= 2)
@@ -629,51 +637,39 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
                 else
                   type = EVAS_FILTER_BLUR_BOX;
 
+                if (dx && (inbuf == outbuf))
+                  ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
                 cmd = evas_filter_command_blur_add(ctx, drawctx, tmp_in, outbuf,
                                                    type, 0, dy, ox, oy, 0);
+                if (dx && (inbuf == outbuf))
+                  ENFN->context_render_op_set(ENDT, drawctx, render_op);
                 if (!cmd) goto fail;
                 cmd->blur.auto_count = EINA_TRUE;
              }
 
            return cmd;
         }
-        break;
 
       default:
         CRI("Not implemented yet!");
         goto fail;
      }
 
-   if ((blend || (in->alpha_only && !out->alpha_only)) ||
-            (!blend && !in->alpha_only && !out->alpha_only && (color != 0xFFFFFFFF)) ||
-            (!in->alpha_only && out->alpha_only))
-     {
-        XDBG("Adding extra blending step %d --> %d (%s --> %s)", in->id, out->id,
-            in->alpha_only ? "Alpha" : "RGBA",
-            out->alpha_only ? "Alpha" : "RGBA");
-        Eina_Bool wasl = in->locked;
-        in->locked = 1;
-        blur_out = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
-        in->locked = wasl;
-        if (!blur_out) goto fail;
-        blend = EINA_TRUE;
-     }
-   else
-     blur_out = out;
-
+   // For 2D blur: create intermediate buffer between X and Y passes
    if (dx && dy)
      {
-        tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
-        if (!tmp) goto fail;
-
-        if (!blend && (ox || oy))
+        // If there's an offset: create intermediate buffer before offset blend
+        if (ox || oy)
           {
-             copybuf = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
+             copybuf = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
              if (!copybuf) goto fail;
-             copy_back = EINA_TRUE;
           }
 
-        if (in == blur_out)
+        // Intermediate buffer between X and Y passes
+        tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
+        if (!tmp) goto fail;
+
+        if (in == out)
           {
              // IN = OUT and 2-D blur. IN -blur-> TMP -blur-> IN.
              out_dx = tmp;
@@ -685,43 +681,80 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
              // IN != OUT and 2-D blur. IN -blur-> TMP -blur-> OUT.
              out_dx = tmp;
              in_dy = tmp;
-             out_dy = copybuf ? copybuf : blur_out;
+             out_dy = copybuf ? copybuf : out;
           }
      }
    else if (dx)
      {
-        if ((in == blur_out) || ox || oy)
+        // X blur only
+        if (in == out)
           {
              // IN = OUT and 1-D blur. IN -blur-> TMP -copy-> IN.
-             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
+             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
              if (!tmp) goto fail;
-             copy_back = EINA_TRUE;
              copybuf = tmp;
              out_dx = tmp;
           }
+        else if (ox || oy || (color != 0xFFFFFFFF))
+          {
+             // IN != OUT and 1-D blur. IN -blur-> TMP -blend-> OUT.
+             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
+             if (!tmp) goto fail;
+             blendbuf = tmp;
+             out_dx = tmp;
+          }
+        else if (out->dirty)
+          {
+             // IN != OUT and 1-D blur. IN -blur-> TMP -blend-> OUT.
+             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
+             if (!tmp) goto fail;
+             blendbuf = tmp;
+             out_dx = tmp;
+          }
         else
           {
              // IN != OUT and 1-D blur. IN -blur-> OUT.
-             out_dx = blur_out;
+             out_dx = out;
           }
      }
    else
      {
-        if ((in == blur_out) || ox || oy)
+        // Y blur only
+        if (in == out)
           {
              // IN = OUT and 1-D blur. IN -blur-> TMP -copy-> IN.
-             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only);
+             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
              if (!tmp) goto fail;
-             copy_back = EINA_TRUE;
              copybuf = tmp;
              in_dy = in;
              out_dy = tmp;
           }
+        else if (ox || oy || (color != 0xFFFFFFFF))
+          {
+             // IN != OUT and 1-D blur. IN -blur-> TMP -blend-> IN.
+             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
+             if (!tmp) goto fail;
+             if (override)
+               copybuf = tmp;
+             else
+               blendbuf = tmp;
+             in_dy = in;
+             out_dy = tmp;
+          }
+        else if (out->dirty && !override)
+          {
+             // IN != OUT and 1-D blur. IN -blur-> TMP -blend-> OUT.
+             tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 0);
+             if (!tmp) goto fail;
+             blendbuf = tmp;
+             in_dy = in;
+             out_dy = tmp;
+          }
         else
           {
              // IN != OUT and 1-D blur. IN -blur-> OUT.
              in_dy = in;
-             out_dy = blur_out;
+             out_dy = out;
           }
      }
 
@@ -734,8 +767,7 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
         cmd->blur.dx = dx;
         cmd->blur.dy = 0;
         cmd->blur.count = count;
-        if (!dy && !blend)
-          DRAW_COLOR_SET(R, G, B, A);
+        if (!dy) DRAW_COLOR_SET(R, G, B, A);
      }
 
    if (dy)
@@ -747,38 +779,36 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
         cmd->blur.dx = 0;
         cmd->blur.dy = dy;
         cmd->blur.count = count;
-        if (!blend)
-          DRAW_COLOR_SET(R, G, B, A);
+        DRAW_COLOR_SET(R, G, B, A);
      }
 
-   if (copy_back)
+   if (blendbuf)
+     {
+        Evas_Filter_Command *blendcmd;
+
+        XDBG("Add extra blend %d -> %d", blendbuf->id, out->id);
+        blendcmd = evas_filter_command_blend_add(ctx, drawctx,
+                                                 blendbuf->id, out->id, ox, oy,
+                                                 EVAS_FILTER_FILL_MODE_NONE);
+        if (!blendcmd) goto fail;
+        ox = oy = 0;
+     }
+   else if (copybuf)
      {
         Evas_Filter_Command *copycmd;
-        int render_op;
 
-        if (!cmd) goto fail;
-        XDBG("Add copy %d -> %d", copybuf->id, blur_out->id);
+        XDBG("Add extra copy %d -> %d: offset: %d,%d", copybuf->id, out->id, ox, oy);
         ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
-        render_op = ENFN->context_render_op_get(ENDT, drawctx);
         ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
-        copycmd = evas_filter_command_blend_add(ctx, drawctx, copybuf->id, blur_out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE);
+        copycmd = evas_filter_command_blend_add(ctx, drawctx,
+                                                copybuf->id, out->id, ox, oy,
+                                                EVAS_FILTER_FILL_MODE_NONE);
         ENFN->context_color_set(ENDT, drawctx, R, G, B, A);
         ENFN->context_render_op_set(ENDT, drawctx, render_op);
         if (!copycmd) goto fail;
         ox = oy = 0;
      }
 
-   if (blend)
-     {
-        Evas_Filter_Command *blendcmd;
-
-        XDBG("Add blend %d (%s) -> %d (%s)",
-            blur_out->id, blur_out->alpha_only ? "Alpha" : "RGBA",
-            out->id, out->alpha_only ? "Alpha" : "RGBA");
-        blendcmd = evas_filter_command_blend_add(ctx, drawctx, blur_out->id, out->id, ox, oy, EVAS_FILTER_FILL_MODE_NONE);
-        if (!blendcmd) goto fail;
-     }
-
    out->dirty = EINA_TRUE;
    _filter_buffer_unlock_all(ctx);
    return cmd;
@@ -796,6 +826,7 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
 {
    Evas_Filter_Command *cmd;
    Evas_Filter_Buffer *in, *out;
+   Eina_Bool copy;
    int R, G, B, A;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
@@ -823,18 +854,24 @@ evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *drawctx,
    cmd = _command_new(ctx, EVAS_FILTER_MODE_BLEND, in, NULL, out);
    if (!cmd) return NULL;
 
+   if (ENFN->context_render_op_get(ENDT, drawctx) == EVAS_RENDER_COPY)
+     copy = EINA_TRUE;
+   else
+     copy = EINA_FALSE;
+
    ENFN->context_color_get(ENDT, drawctx, &R, &G, &B, &A);
    DRAW_COLOR_SET(R, G, B, A);
    DRAW_FILL_SET(fillmode);
    cmd->draw.ox = ox;
    cmd->draw.oy = oy;
-   cmd->draw.rop = _evas_to_gfx_render_op(ENFN->context_render_op_get(ENDT, drawctx));
+   cmd->draw.rop = copy ? EFL_GFX_RENDER_OP_COPY : EFL_GFX_RENDER_OP_BLEND;
    cmd->draw.clip_use =
          ENFN->context_clip_get(ENDT, drawctx,
                                 &cmd->draw.clip.x, &cmd->draw.clip.y,
                                 &cmd->draw.clip.w, &cmd->draw.clip.h);
 
-   XDBG("Add blend %d -> %d", in->id, out->id);
+   XDBG("Add %s %d -> %d: offset %d,%d, color: %d,%d,%d,%d",
+        copy ? "copy" : "blend", in->id, out->id, ox, oy, R, G, B, A);
    if (cmd->draw.clip_use)
      XDBG("Draw clip: %d,%d,%d,%d", cmd->draw.clip.x, cmd->draw.clip.y,
          cmd->draw.clip.w, cmd->draw.clip.h);
@@ -864,9 +901,12 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
    in = _filter_buffer_get(ctx, inbuf);
    EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
 
-   if (inbuf != outbuf)
+   out = _filter_buffer_get(ctx, outbuf);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
+
+   if ((inbuf != outbuf) && out->dirty)
      {
-        tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only);
+        tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
         EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, NULL);
         growbuf = tmp->id;
      }
@@ -901,16 +941,6 @@ evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context,
           memset(curve + end, 255, 256 - end);
      }
 
-   out = _filter_buffer_get(ctx, growbuf);
-   if (!out) return NULL;
-   out->dirty = EINA_TRUE;
-   if (growbuf != outbuf)
-     {
-        out = _filter_buffer_get(ctx, growbuf);
-        if (!out) return NULL;
-        out->dirty = EINA_TRUE;
-     }
-
    threshcmd = evas_filter_command_curve_add(ctx, draw_context, growbuf, growbuf,
                                              curve, EVAS_FILTER_CHANNEL_ALPHA);
    if (!threshcmd)
@@ -973,7 +1003,6 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx,
    cmd->curve.data = copy;
    cmd->curve.channel = channel;
 
-   out->dirty = EINA_TRUE;
    return cmd;
 }
 
@@ -1009,7 +1038,7 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
 
    if (in == out)
      {
-        tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only);
+        tmp = evas_filter_temporary_buffer_get(ctx, in->w, in->h, in->alpha_only, 1);
         if (!tmp) return NULL;
         disp_out = tmp;
      }
@@ -1033,8 +1062,6 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx,
         if (!fillcmd) goto fail;
      }
 
-   out->dirty = EINA_TRUE;
-
    _filter_buffer_unlock_all(ctx);
    return cmd;
 
@@ -1072,7 +1099,6 @@ evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context,
    cmd->draw.rop = render_op;
    DRAW_COLOR_SET(R, G, B, A);
    DRAW_FILL_SET(fillmode);
-   out->dirty = EINA_TRUE;
 
    return cmd;
 }
@@ -1122,7 +1148,6 @@ evas_filter_command_bump_map_add(Evas_Filter_Context *ctx,
    cmd->bump.white = white;
    cmd->bump.elevation = elevation;
    cmd->bump.compensate = !!(flags & EVAS_FILTER_BUMP_COMPENSATE);
-   out->dirty = EINA_TRUE;
 
    return cmd;
 }
@@ -1160,8 +1185,6 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx,
    else
      cmd->draw.rop = EFL_GFX_RENDER_OP_BLEND;
 
-   out->dirty = EINA_TRUE;
-
    return cmd;
 }
 
@@ -1211,7 +1234,7 @@ _filter_target_render(Evas_Filter_Context *ctx)
    src = _filter_buffer_get(ctx, EVAS_FILTER_BUFFER_OUTPUT_ID);
    EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
 
-   image = evas_ector_buffer_drawable_image_get(src->buffer, EINA_FALSE);
+   image = evas_ector_buffer_drawable_image_get(src->buffer);
    EINA_SAFETY_ON_NULL_GOTO(image, fail);
 
    // FIXME: Use ector buffer RENDERER here
@@ -1272,7 +1295,7 @@ evas_filter_font_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
    fb = _filter_buffer_get(ctx, bufid);
    EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
 
-   surface = evas_ector_buffer_render_image_get(fb->buffer, EINA_FALSE);
+   surface = evas_ector_buffer_render_image_get(fb->buffer);
    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
 
    // Copied from evas_font_draw_async_check
@@ -1306,7 +1329,7 @@ evas_filter_image_draw(Evas_Filter_Context *ctx, void *draw_context, int bufid,
    fb = _filter_buffer_get(ctx, bufid);
    if (!fb) return EINA_FALSE;
 
-   surface = evas_ector_buffer_render_image_get(fb->buffer, EINA_FALSE);
+   surface = evas_ector_buffer_render_image_get(fb->buffer);
    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
 
    ENFN->image_size_get(ENDT, image, &dw, &dh);
@@ -1391,6 +1414,7 @@ _filter_name_get(int mode)
 #define FNAME(a) case EVAS_FILTER_MODE_ ## a: return "EVAS_FILTER_MODE_" #a
    switch (mode)
      {
+      FNAME(SKIP);
       FNAME(BLEND);
       FNAME(BLUR);
       FNAME(CURVE);
@@ -1409,6 +1433,9 @@ _filter_command_run(Evas_Filter_Command *cmd)
 {
    Evas_Filter_Support support = EVAS_FILTER_SUPPORT_NONE;
 
+   if (cmd->mode == EVAS_FILTER_MODE_SKIP)
+     return EINA_TRUE;
+
    EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
 
index e3346e0..143d065 100644 (file)
@@ -2861,6 +2861,8 @@ _buffers_update(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm)
                pgm->changed = EINA_TRUE;
              buf->w = fb->w = source->cur->geometry.w;
              buf->h = fb->h = source->cur->geometry.h;
+             XDBG("Created proxy buffer %d %s '%s'", fb->id,
+                  buf->alpha ? "alpha" : "rgba", buf->name);
           }
         else
           {
@@ -2870,6 +2872,8 @@ _buffers_update(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm)
              fb = _filter_buffer_get(ctx, buf->cid);
              fb->w = buf->w = pgm->state.w;
              fb->h = buf->h = pgm->state.h;
+             XDBG("Created context buffer %d %s '%s'", fb->id,
+                  buf->alpha ? "alpha" : "rgba", buf->name);
           }
      }
 }
index d982e6b..4c487c5 100644 (file)
@@ -266,7 +266,7 @@ void                     evas_filter_context_source_set(Evas_Filter_Context *ctx
 void _clip_to_target(int *sx, int *sy, int sw, int sh, int ox, int oy, int dw, int dh, int *dx, int *dy, int *rows, int *cols);
 Eina_Bool evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h);
 Evas_Filter_Buffer *_filter_buffer_get(Evas_Filter_Context *ctx, int bufid);
-Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only);
+Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only, Eina_Bool clean);
 Evas_Filter_Buffer *evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h);
 Eina_Bool           evas_filter_interpolate(DATA8* output /* 256 values */, int *points /* 256 values */, Evas_Filter_Interpolation_Mode mode);
 int evas_filter_smallest_pow2_larger_than(int val);
index 1f08698..48d813a 100644 (file)
@@ -19,7 +19,7 @@ evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx,
    DEBUG_TIME_BEGIN();
 
    // Get destination buffer
-   dst = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only);
+   dst = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only, 0);
    EINA_SAFETY_ON_NULL_RETURN_VAL(dst, NULL);
 
    // Map input and output
index d70d971..f65012e 100644 (file)
@@ -19,16 +19,10 @@ interface Evas.Ector.Buffer
       }
       drawable_image_get {
          [[Fetch an engine image from this ector buffer as a drawable.]]
-         params {
-            @in update: bool; [[$true to update the data to the remote image.]]
-         }
          return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]]
       }
       render_image_get {
          [[Fetch an engine image from this ector buffer as a render target.]]
-         params {
-            @in update: bool; [[$true to update the data to the remote image.]]
-         }
          return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]]
       }
       engine_image_release {
index 0736b5b..533bc24 100644 (file)
@@ -55,6 +55,7 @@ typedef void (* Evas_Filter_Cb) (Evas_Filter_Context *ctx, void *data, Eina_Bool
 /** @internal */
 enum _Evas_Filter_Mode
 {
+   EVAS_FILTER_MODE_SKIP,         /**< No operation */
    EVAS_FILTER_MODE_BLEND,        /**< Blend with current context render_op */
    EVAS_FILTER_MODE_BLUR,         /**< @see Evas_Filter_Blur_Type */
    EVAS_FILTER_MODE_CURVE,        /**< Apply color curve */
index 38474bb..74d456e 100644 (file)
@@ -689,6 +689,7 @@ void              evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_G
 void              evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int npoints, RGBA_Map_Point *p, int smooth, int level);
 void              evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth);
 Evas_GL_Image    *evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
+Evas_GL_Image    *evas_gl_common_image_surface_detach(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
 
 void             *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg);
 void              evas_gl_font_texture_free(void *);
index de907be..e422031 100644 (file)
@@ -1100,6 +1100,17 @@ fail:
    return NULL;
 }
 
+Evas_GL_Image *
+evas_gl_common_image_surface_detach(Evas_Engine_GL_Context *gc EINA_UNUSED, Evas_GL_Image *im)
+{
+   if (!im || !im->im) return im;
+
+   evas_cache_image_drop(&im->im->cache_entry);
+   im->im = NULL;
+
+   return im;
+}
+
 void
 evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
                               int npoints, RGBA_Map_Point *p, int smooth, int level EINA_UNUSED)
index ef8999e..d4657b9 100644 (file)
@@ -23,6 +23,8 @@
 typedef struct _Ector_GL_Buffer_Map Ector_GL_Buffer_Map;
 typedef struct _Evas_Ector_GL_Buffer_Data Evas_Ector_GL_Buffer_Data;
 
+static int _map_id = 0;
+
 struct _Ector_GL_Buffer_Map
 {
    EINA_INLIST;
@@ -30,6 +32,7 @@ struct _Ector_GL_Buffer_Map
    unsigned int base_size; // in bytes
    unsigned int x, y, w, h;
    void *image_data, *base_data;
+   int map_id;
    size_t length;
    Efl_Gfx_Colorspace cspace;
    Evas_GL_Image *im;
@@ -41,7 +44,7 @@ struct _Evas_Ector_GL_Buffer_Data
 {
    Evas_Public_Data *evas;
    Evas_GL_Image *glim;
-   Eina_Bool alpha_only;
+   Eina_Bool alpha_only, was_render;
    Ector_GL_Buffer_Map *maps;
 };
 
@@ -55,6 +58,20 @@ struct _Evas_Ector_GL_Buffer_Data
 
 #define fail(fmt, ...) do { ERR(fmt, ##__VA_ARGS__); goto on_fail; } while (0)
 
+#if 0
+static inline void
+_mapped_image_dump(Eo *buf, Evas_GL_Image *im, const char *fmt, int id)
+{
+   if (!im || !im->im) return;
+   evas_common_save_image_to_file(im->im, eina_slstr_printf("/tmp/dump/%s_%02d_buf_%p_im_%p.png", fmt, id, buf, im),
+                                  NULL, 100, 9, NULL);
+}
+
+#define MAP_DUMP(_im, _fmt) _mapped_image_dump(obj, _im, _fmt, map->map_id)
+#else
+#define MAP_DUMP(...)
+#endif
+
 /* FIXME: Conversion routines don't belong here */
 static inline void
 _pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len)
@@ -120,23 +137,14 @@ on_fail:
    pd->glim = NULL;
 }
 
-EOLIAN static void *
-_evas_ector_gl_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
-                                                           Evas_Ector_GL_Buffer_Data *pd,
-                                                           Eina_Bool update)
+static inline void *
+_image_get(Evas_Ector_GL_Buffer_Data *pd, Eina_Bool render)
 {
-   Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
-   Evas_Engine_GL_Context *gc;
-
    if (pd->maps != NULL)
      fail("Image is currently mapped!");
 
    evas_gl_common_image_ref(pd->glim);
-   if (!update) return pd->glim;
-
-   gc = re->window_gl_context_get(re->software.ob);
-   evas_gl_common_image_update(gc, pd->glim);
-
+   if (render) pd->was_render = EINA_TRUE;
    return pd->glim;
 
 on_fail:
@@ -144,26 +152,17 @@ on_fail:
 }
 
 EOLIAN static void *
-_evas_ector_gl_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED,
-                                                         Evas_Ector_GL_Buffer_Data *pd,
-                                                         Eina_Bool update)
+_evas_ector_gl_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
+                                                           Evas_Ector_GL_Buffer_Data *pd)
 {
-   Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
-   Evas_Engine_GL_Context *gc;
-
-   if (pd->maps != NULL)
-     fail("Image is currently mapped!");
-
-   evas_gl_common_image_ref(pd->glim);
-   if (!update) return pd->glim;
-
-   gc = re->window_gl_context_get(re->software.ob);
-   evas_gl_common_image_update(gc, pd->glim);
-
-   return pd->glim;
+   return _image_get(pd, EINA_FALSE);
+}
 
-on_fail:
-   return NULL;
+EOLIAN static void *
+_evas_ector_gl_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED,
+                                                         Evas_Ector_GL_Buffer_Data *pd)
+{
+   return _image_get(pd, EINA_TRUE);
 }
 
 EOLIAN static Eina_Bool
@@ -174,6 +173,14 @@ _evas_ector_gl_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED
    EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
    EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->glim == image, EINA_FALSE);
 
+   if (pd->was_render)
+     {
+        Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
+        Evas_Engine_GL_Context *gc;
+
+        gc = re->window_gl_context_get(re->software.ob);
+        pd->glim = evas_gl_common_image_surface_detach(gc, pd->glim);
+     }
    evas_gl_common_image_free(pd->glim);
 
    return EINA_TRUE;
@@ -270,12 +277,15 @@ _evas_ector_gl_buffer_ector_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buffer
         pxs = 4;
      }
 
+   map->map_id = ++_map_id;
    map->base_size = len * pxs;
    map->length = (W * h + w - W) * pxs;
    if (stride) *stride = W * pxs;
    if (length) *length = map->length;
 
-   EINA_INLIST_PREPEND(pd->maps, map);;
+   MAP_DUMP(im, "in");
+
+   EINA_INLIST_PREPEND(pd->maps, map);
    return map->ptr;
 
 on_fail:
@@ -311,20 +321,28 @@ _evas_ector_gl_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buff
 
                   if (map->im)
                     {
+                       MAP_DUMP(map->im, "out_w_free");
                        pd->glim = evas_gl_common_image_surface_update(gc, map->im);
                        evas_gl_common_image_free(old_glim);
                     }
                   else
                     {
+                       MAP_DUMP(old_glim, "out_w_nofree");
                        pd->glim = evas_gl_common_image_surface_update(gc, old_glim);
                     }
                }
              else
                {
                   if (map->im)
-                    ENFN->image_free(ENDT, map->im);
+                    {
+                       MAP_DUMP(map->im, "out_ro_free");
+                       ENFN->image_free(ENDT, map->im);
+                    }
                   else
-                    ENFN->image_data_put(ENDT, pd->glim, map->image_data);
+                    {
+                       MAP_DUMP(pd->glim, "out_ro_nofree");
+                       ENFN->image_data_put(ENDT, pd->glim, map->image_data);
+                    }
                }
              if (map->allocated)
                free(map->base_data);
index 647f7cc..6e1666c 100644 (file)
@@ -82,8 +82,7 @@ _evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ect
 
 EOLIAN static void *
 _evas_ector_gl_image_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
-                                                                 Evas_Ector_GL_Image_Buffer_Data *pd,
-                                                                 Eina_Bool update EINA_UNUSED)
+                                                                 Evas_Ector_GL_Image_Buffer_Data *pd)
 {
    evas_gl_common_image_ref(pd->glim);
    return pd->glim;
index fe127d4..296da98 100644 (file)
@@ -28,7 +28,7 @@
 
 #define EVAS_GL_UPDATE_TILE_SIZE 16
 
-static int _evas_engine_GL_log_dom = -1;
+int _evas_engine_GL_log_dom = -1;
 
 #undef ERR
 #undef DBG
index 061ea5f..9cbf4f1 100644 (file)
@@ -6,6 +6,8 @@
 #include "evas_ector_buffer.eo.h"
 #include "../Evas_Engine_GL_Generic.h"
 
+extern int _evas_engine_GL_log_dom;
+
 typedef Eina_Bool (* GL_Filter_Apply_Func) (Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
 GL_Filter_Apply_Func gl_filter_blend_func_get(Evas_Filter_Command *cmd);
 //Software_Filter_Func gl_filter_blur_func_get(Evas_Filter_Command *cmd);
@@ -16,4 +18,15 @@ GL_Filter_Apply_Func gl_filter_blend_func_get(Evas_Filter_Command *cmd);
 //Software_Filter_Func gl_filter_mask_func_get(Evas_Filter_Command *cmd);
 //Software_Filter_Func gl_filter_transform_func_get(Evas_Filter_Command *cmd);
 
+#undef DBG
+#undef INF
+#undef WRN
+#undef ERR
+#undef CRI
+#define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_GL_log_dom, __VA_ARGS__)
+#define INF(...) EINA_LOG_DOM_INFO(_evas_engine_GL_log_dom, __VA_ARGS__)
+#define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_GL_log_dom, __VA_ARGS__)
+#define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_GL_log_dom, __VA_ARGS__)
+#define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_GL_log_dom, __VA_ARGS__)
+
 #endif // GL_ENGINE_FILTER_H
index 5e48883..d9977bf 100644 (file)
@@ -1,5 +1,162 @@
 #include "gl_engine_filter.h"
 
+// Copied logic from SW engine
+static Eina_Bool
+_mapped_blend(Evas_Engine_GL_Context *gc,
+              Evas_GL_Image *image,
+              Evas_Filter_Fill_Mode fillmode,
+              int sx, int sy, int sw, int sh,
+              int dx, int dy, int dw, int dh)
+{
+   int right = 0, bottom = 0, left = 0, top = 0;
+   int row, col, rows, cols;
+   Eina_Bool ret = EINA_TRUE;
+
+   EINA_SAFETY_ON_FALSE_RETURN_VAL((sx == 0) && (sy == 0), EINA_FALSE);
+
+   if (fillmode == EVAS_FILTER_FILL_MODE_NONE)
+     {
+        DBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d", sx, sy, sw, sh, dx, dy, sw, sh);
+        evas_gl_common_image_draw(gc, image, sx, sy, sw, sh, dx, dy, sw, sh, EINA_TRUE);
+        return EINA_TRUE;
+     }
+
+   if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_X)
+     {
+        if (dx > 0) left = dx % sw;
+        else if (dx < 0) left = sw + (dx % sw);
+        cols = (dw  /*- left*/) / sw;
+        if (left > 0)
+          right = dw - (sw * (cols - 1)) - left;
+        else
+          right = dw - (sw * cols);
+        dx = 0;
+     }
+   else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+     {
+        cols = 0;
+        dx = 0;
+     }
+   else
+     {
+        // FIXME: Probably wrong if dx != 0
+        cols = 0;
+        dw -= dx;
+     }
+
+   if (fillmode & EVAS_FILTER_FILL_MODE_REPEAT_Y)
+     {
+        if (dy > 0) top = dy % sh;
+        else if (dy < 0) top = sh + (dy % sh);
+        rows = (dh /*- top*/) / sh;
+        if (top > 0)
+          bottom = dh - (sh * (rows - 1)) - top;
+        else
+          bottom = dh - (sh * rows);
+        dy = 0;
+     }
+   else if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+     {
+        rows = 0;
+        dy = 0;
+     }
+   else
+     {
+        // FIXME: Probably wrong if dy != 0
+        rows = 0;
+        dh -= dy;
+     }
+
+   if (top > 0) row = -1;
+   else row = 0;
+   for (; row <= rows; row++)
+     {
+        int src_x, src_y, src_w, src_h;
+        int dst_x, dst_y, dst_w, dst_h;
+
+        if (row == -1 && top > 0)
+          {
+             // repeat only
+             src_h = top;
+             src_y = sh - top;
+             dst_y = dy;
+             dst_h = src_h;
+          }
+        else if (row == rows && bottom > 0)
+          {
+             // repeat only
+             src_h = bottom;
+             src_y = 0;
+             dst_y = top + dy + row * sh;
+             dst_h = src_h;
+          }
+        else
+          {
+             src_y = 0;
+             if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+               {
+                  src_h = sh;
+                  dst_h = dh;
+                  dst_y = 0;
+               }
+             else
+               {
+                  dst_y = top + dy + row * sh;
+                  src_h = MIN(dh - dst_y, sh);
+                  dst_h = src_h;
+               }
+          }
+        if (src_h <= 0 || dst_h <= 0) break;
+
+        if (left > 0) col = -1;
+        else col = 0;
+        for (; col <= cols; col++)
+          {
+             if (col == -1 && left > 0)
+               {
+                  // repeat only
+                  src_w = left;
+                  src_x = sw - left;
+                  dst_x = dx;
+                  dst_w = src_w;
+               }
+             else if (col == cols && right > 0)
+               {
+                  // repeat only
+                  src_w = right;
+                  src_x = 0;
+                  dst_x = left + dx + col * sw;
+                  dst_w = src_w;
+               }
+             else
+               {
+                  src_x = 0;
+                  if (fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+                    {
+                       src_w = sw;
+                       dst_w = dw;
+                       dst_x = 0;
+                    }
+                  else
+                    {
+                       dst_x = left + dx + col * sw;
+                       src_w = MIN(dw - dst_x, sw);
+                       dst_w = src_w;
+                    }
+               }
+             if (src_w <= 0 || dst_w <= 0) break;
+
+             DBG("blend: [%d,%d] %d,%d,%dx%d --> %d,%d,%dx%d "
+                 "(src %dx%d, dst %dx%d)",
+                 col, row, src_x, src_y, src_w, src_h,
+                 dst_x, dst_y, dst_w, dst_h, sw, sh, dw, dh);
+             evas_gl_common_image_draw(gc, image, src_x, src_y, src_w, src_h,
+                                       dst_x, dst_y, dst_w, dst_h, EINA_TRUE);
+          }
+     }
+   return ret;
+}
+
 static Eina_Bool
 _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
 {
@@ -10,12 +167,12 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
    re->window_use(re->software.ob);
    gc = re->window_gl_context_get(re->software.ob);
 
-   image = evas_ector_buffer_drawable_image_get(cmd->input->buffer, EINA_TRUE);
+   image = evas_ector_buffer_drawable_image_get(cmd->input->buffer);
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(image->tex, EINA_FALSE);
 
-   surface = evas_ector_buffer_render_image_get(cmd->output->buffer, EINA_FALSE);
+   surface = evas_ector_buffer_render_image_get(cmd->output->buffer);
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
    EINA_SAFETY_ON_NULL_RETURN_VAL(surface->tex, EINA_FALSE);
@@ -23,15 +180,15 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
    EINA_SAFETY_ON_FALSE_RETURN_VAL(surface->tex->pt->fb != 0, EINA_FALSE);
    evas_gl_common_context_target_surface_set(gc, surface);
 
-   // TODO: mapped render iteration
-
    dc_save = gc->dc;
    gc->dc = evas_common_draw_context_new();
    evas_common_draw_context_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
+   gc->dc->render_op = _gfx_to_evas_render_op(cmd->draw.rop);
 
-   evas_gl_common_image_draw(gc, image, 0, 0, image->w, image->h,
-                             cmd->draw.ox, cmd->draw.oy, image->w, image->h,
-                             EINA_TRUE);
+   DBG("blend %d @%p -> %d @%p", cmd->input->id, cmd->input->buffer,
+       cmd->output->id, cmd->output->buffer);
+   _mapped_blend(gc, image, cmd->draw.fillmode, 0, 0, image->w, image->h,
+                 cmd->draw.ox, cmd->draw.oy, cmd->output->w, cmd->output->h);
 
    evas_common_draw_context_free(gc->dc);
    gc->dc = dc_save;
index d312974..262c405 100644 (file)
@@ -39,8 +39,7 @@ _evas_ector_software_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ect
 
 EOLIAN static void *
 _evas_ector_software_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
-                                                                 Evas_Ector_Software_Buffer_Data *pd,
-                                                                 Eina_Bool update EINA_UNUSED)
+                                                                 Evas_Ector_Software_Buffer_Data *pd)
 {
    evas_cache_image_ref(&pd->image->cache_entry);
    return pd->image;
@@ -48,8 +47,7 @@ _evas_ector_software_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UN
 
 EOLIAN static void *
 _evas_ector_software_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED,
-                                                               Evas_Ector_Software_Buffer_Data *pd,
-                                                               Eina_Bool update EINA_UNUSED)
+                                                               Evas_Ector_Software_Buffer_Data *pd)
 {
    evas_cache_image_ref(&pd->image->cache_entry);
    return pd->image;
index cc459a0..6fdf054 100644 (file)
@@ -208,7 +208,7 @@ _filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
    EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, 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);
+   dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ | E_WRITE, 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;
index a138b43..a3d5dd1 100644 (file)
@@ -16,9 +16,6 @@ eng_filter_mask_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->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);