jpeg pushed a commit to branch master.

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

commit c1b4728487715c66120ed4c4d75065012bd42682
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Mon Jan 4 21:46:56 2016 +0900

    Evas filters: Final fix after the ector refactor
    
    This implements a generic way of scaling buffers, using fake
    RGBA_Image wrapping ector buffer maps. The underlying algo is
    still the good old linear sw scaler.
    
    Now the filters *should* be back to their previous level of
    usability. Performance will probably be even worse than it was
    before, for GL, as more glReadPixels may be involved. Optimization
    now consists in actually implementing the filters with GL shaders.
---
 src/Makefile_Evas.am                               |  2 +
 src/lib/evas/canvas/evas_filter_mixin.c            | 32 ++++++++---
 src/lib/evas/filters/evas_filter.c                 |  2 +
 src/lib/evas/filters/evas_filter_mask.c            | 10 ++--
 src/lib/evas/filters/evas_filter_utils.c           | 64 +++++++++++++++-------
 .../gl_generic/evas_ector_gl_image_buffer.c        | 16 +-----
 .../gl_generic/evas_ector_gl_rgbaimage_buffer.c    |  6 ++
 src/modules/evas/engines/gl_generic/evas_engine.c  |  2 +-
 .../evas/engines/software_generic/evas_engine.c    | 43 +++++++++++++--
 9 files changed, 126 insertions(+), 51 deletions(-)

diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 24e9929..d5b3167 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -778,6 +778,8 @@ CLEANFILES += \
               $(evas_gl_generic_eolian_c) \
               $(evas_gl_generic_eolian_h)
 
+EXTRA_DIST += $(evas_gl_generic_eolian_files)
+
 #evaseolianfilesdir = $(datadir)/eolian/include/evas-@VMAJ@
 #evaseolianfiles_DATA += $(evas_gl_generic_eolian_files)
 
diff --git a/src/lib/evas/canvas/evas_filter_mixin.c 
b/src/lib/evas/canvas/evas_filter_mixin.c
index 8c5c8ae..6cf205a 100644
--- a/src/lib/evas/canvas/evas_filter_mixin.c
+++ b/src/lib/evas/canvas/evas_filter_mixin.c
@@ -11,6 +11,9 @@
 #define ENFN obj->layer->evas->engine.func
 #define ENDT obj->layer->evas->engine.data.output
 
+#define FCOW_BEGIN(_pd) eina_cow_write(evas_object_filter_cow, (const 
Eina_Cow_Data**)&(_pd->data))
+#define FCOW_END(_fcow, _pd) eina_cow_done(evas_object_filter_cow, (const 
Eina_Cow_Data**)&(_pd->data), _fcow, EINA_TRUE)
+
 typedef struct _Evas_Filter_Data Evas_Filter_Data;
 struct _Evas_Filter_Data
 {
@@ -21,9 +24,9 @@ static void
 _filter_cb(Evas_Filter_Context *ctx, void *data, Eina_Bool success)
 {
    Eo *eo_obj = data;
+   Evas_Filter_Data *pd = eo_data_scope_get(eo_obj, MY_CLASS);
 
-   // Destroy context as we won't reuse it.
-   evas_filter_context_destroy(ctx);
+   // FIXME: This needs to run in the main loop
 
    // Redraw text with normal styles in case of failure
    if (!success)
@@ -39,6 +42,18 @@ _filter_cb(Evas_Filter_Context *ctx, void *data, Eina_Bool 
success)
         evas_object_coords_recalc(eo_obj, obj);
         evas_object_inform_call_resize(eo_obj);
      }
+   else
+     {
+        Evas_Object_Filter_Data *fcow;
+        void *output = evas_filter_buffer_backing_steal(ctx, 
EVAS_FILTER_BUFFER_OUTPUT_ID);
+
+        fcow = FCOW_BEGIN(pd);
+        fcow->output = output;
+        FCOW_END(fcow, pd);
+     }
+
+   // Destroy context as we won't reuse it.
+   evas_filter_context_destroy(ctx);
 }
 
 static void
@@ -76,9 +91,6 @@ _filter_source_hash_free_cb(void *data)
    free(pb);
 }
 
-#define FCOW_BEGIN(_pd) eina_cow_write(evas_object_filter_cow, (const 
Eina_Cow_Data**)&(_pd->data))
-#define FCOW_END(_fcow, _pd) eina_cow_done(evas_object_filter_cow, (const 
Eina_Cow_Data**)&(_pd->data), _fcow, EINA_TRUE)
-
 Eina_Bool
 evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
                           void *output, void *context, void *surface,
@@ -86,6 +98,10 @@ evas_filter_object_render(Eo *eo_obj, 
Evas_Object_Protected_Data *obj,
 {
    Evas_Filter_Data *pd = eo_data_scope_get(eo_obj, MY_CLASS);
 
+   // FIXME: Forcing sync render for all engines! (cb needs the main loop)
+   if (do_async) WRN("Disarding async render flag!");
+   do_async = EINA_FALSE;
+
    if (!pd->data->invalid && (pd->data->chain || pd->data->code))
      {
         int X, Y, W, H, l = 0, r = 0, t = 0, b = 0;
@@ -94,7 +110,6 @@ evas_filter_object_render(Eo *eo_obj, 
Evas_Object_Protected_Data *obj,
         Eina_Bool ok;
         void *previous = pd->data->output;
         Evas_Object_Filter_Data *fcow;
-        void *filter_output;
 
         /* NOTE: Filter rendering is now done ENTIRELY on CPU.
          * So we rely on cache/cache2 to allocate a real image buffer,
@@ -236,8 +251,7 @@ evas_filter_object_render(Eo *eo_obj, 
Evas_Object_Protected_Data *obj,
         evas_filter_context_buffers_allocate_all(filter);
         evas_filter_target_set(filter, context, surface, X + x, Y + y);
 
-        // Steal output and release previous
-        filter_output = evas_filter_buffer_backing_steal(filter, 
EVAS_FILTER_BUFFER_OUTPUT_ID);
+        // Release previous output
         evas_filter_buffer_backing_release(filter, previous);
 
         // Request rendering from the object itself (child class)
@@ -252,7 +266,7 @@ evas_filter_object_render(Eo *eo_obj, 
Evas_Object_Protected_Data *obj,
         ok = evas_filter_run(filter);
 
         fcow = FCOW_BEGIN(pd);
-        fcow->output = filter_output;
+        fcow->output = NULL;
         fcow->changed = EINA_FALSE;
         fcow->async = do_async;
         if (!ok) fcow->invalid = EINA_TRUE;
diff --git a/src/lib/evas/filters/evas_filter.c 
b/src/lib/evas/filters/evas_filter.c
index d632d9b..3b798f4 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -209,6 +209,8 @@ _ector_buffer_create(Evas_Filter_Buffer const *fb, void 
*data)
    flags = ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_CPU_WRITABLE;
    if (fb->id == EVAS_FILTER_BUFFER_INPUT_ID)
      flags |= ECTOR_BUFFER_FLAG_RENDERABLE;
+   else if (fb->id == EVAS_FILTER_BUFFER_OUTPUT_ID)
+     flags |= ECTOR_BUFFER_FLAG_DRAWABLE;
 
    cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888;
    return fb->ENFN->ector_buffer_new(fb->ENDT, fb->ctx->evas->evas,
diff --git a/src/lib/evas/filters/evas_filter_mask.c 
b/src/lib/evas/filters/evas_filter_mask.c
index 949caa9..9f5b683 100644
--- a/src/lib/evas/filters/evas_filter_mask.c
+++ b/src/lib/evas/filters/evas_filter_mask.c
@@ -64,7 +64,7 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd)
 static Eina_Bool
 _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
 {
-   unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
+   unsigned int src_len = 0, src_stride, msk_len = 0, msk_stride, dst_len = 0, 
dst_stride;
    Efl_Gfx_Render_Op render_op = cmd->draw.rop;
    Evas_Filter_Buffer *msk_fb;
    Alpha_Gfx_Func func;
@@ -225,7 +225,7 @@ _mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd)
      }
    else msk_fb = cmd->mask;
 
-   src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ALPHA, 
&src_stride);
+   src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, 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);
@@ -316,8 +316,8 @@ _mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
      }
    else msk_fb = cmd->mask;
 
-   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);
+   src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, 
&src_stride);
+   msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ALPHA, 
&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);
 
@@ -400,7 +400,7 @@ _mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd)
      }
    else msk_fb = cmd->mask;
 
-   src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ARGB, 
&src_stride);
+   src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, 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);
diff --git a/src/lib/evas/filters/evas_filter_utils.c 
b/src/lib/evas/filters/evas_filter_utils.c
index 8bb98d5..802f09a 100644
--- a/src/lib/evas/filters/evas_filter_utils.c
+++ b/src/lib/evas/filters/evas_filter_utils.c
@@ -7,39 +7,65 @@ evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx,
                               Evas_Filter_Buffer *src,
                               unsigned w, unsigned h)
 {
-   Evas_Filter_Buffer *fb;
-   RGBA_Image *dstim, *srcim;
+   unsigned int src_len = 0, src_stride, dst_len = 0, dst_stride;
+   uint8_t *src_map = NULL, *dst_map = NULL;
+   Evas_Filter_Buffer *dst;
+   RGBA_Image dstim, srcim;
    RGBA_Draw_Context dc;
    Eina_Bool ok;
 
-   // only for RGBA
-   EINA_SAFETY_ON_FALSE_RETURN_VAL(!src->alpha_only, 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);
-   EINA_SAFETY_ON_NULL_RETURN_VAL(fb, 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);
-
+   DBG("Scaling buffer from %dx%d to %dx%d, this is a slow operation!",
+       src->w, src->h, w, h);
+   DEBUG_TIME_BEGIN();
+
+   // Get destination buffer
+   dst = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(dst, NULL);
+
+   // Map input and output
+   src_map = _buffer_map_all(src->buffer, &src_len, E_READ, E_ARGB, 
&src_stride);
+   dst_map = _buffer_map_all(dst->buffer, &dst_len, E_WRITE, E_ARGB, 
&dst_stride);
+   EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map, end);
+   EINA_SAFETY_ON_FALSE_GOTO((src_stride == ((unsigned) src->w * 4)) &&
+                             (dst_stride == (w * 4)), end);
+
+   // Wrap as basic RGBA_Images
+   memset(&dstim, 0, sizeof(dstim));
+   dstim.cache_entry.w = w;
+   dstim.cache_entry.h = h;
+   dstim.cache_entry.flags.alpha = 1;
+   dstim.cache_entry.flags.alpha_sparse = 0;
+   dstim.cache_entry.space = EVAS_COLORSPACE_ARGB8888;
+   dstim.image.data8 = dst_map;
+
+   memset(&srcim, 0, sizeof(srcim));
+   srcim.cache_entry.w = src->w;
+   srcim.cache_entry.h = src->h;
+   srcim.cache_entry.flags.alpha = 1;
+   srcim.cache_entry.flags.alpha_sparse = 0;
+   srcim.cache_entry.space = EVAS_COLORSPACE_ARGB8888;
+   srcim.image.data8 = src_map;
+
+   // Basic draw context
    memset(&dc, 0, sizeof(dc));
    dc.sli.h = 1;
    dc.render_op = EVAS_RENDER_COPY;
 
+   // Do the scale
    ok = evas_common_scale_rgba_in_to_out_clip_smooth
-         (srcim, dstim, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
+         (&srcim, &dstim, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
 
    if (!ok)
      {
        ERR("RGBA Image scaling failed.");
-       return NULL;
+       dst = NULL;
      }
 
-   return fb;
+end:
+   if (src_map) eo_do(src->buffer, ector_buffer_unmap(src_map, src_len));
+   if (dst_map) eo_do(dst->buffer, ector_buffer_unmap(dst_map, dst_len));
+   DEBUG_TIME_END();
+   return dst;
 }
 
 static Eina_Bool
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c 
b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
index 2b5b644..dc68f1c 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
@@ -54,17 +54,6 @@ _pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t 
*src, int len)
      }
 }
 
-static inline void
-_pixels_gry8_to_argb_convert(uint32_t *dst, const uint8_t *src, int len)
-{
-   int k;
-   for (k = 0; k < len; k++)
-     {
-        uint8_t s = *src++;
-        *dst++ = ARGB_JOIN(s, s, s, s);
-     }
-}
-
 EOLIAN static void
 _evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_set(Eo *obj, 
Evas_Ector_GL_Image_Buffer_Data *pd,
                                                                Evas *evas, 
void *image)
@@ -175,7 +164,7 @@ _evas_ector_gl_image_buffer_ector_generic_buffer_map(Eo 
*obj EINA_UNUSED, Evas_E
    if (tofree)
      map->im = im;
    else
-     map->im = ENFN->image_ref(ENDT, im);
+     map->im = NULL;
 
    len = w * h;
    if (cspace == EFL_GFX_COLORSPACE_GRY8)
@@ -218,7 +207,8 @@ _evas_ector_gl_image_buffer_ector_generic_buffer_unmap(Eo 
*obj EINA_UNUSED, Evas
                {
                   CRI("Not implemented yet. Dropping pixel changes.");
                }
-             ENFN->image_free(ENDT, map->im);
+             if (map->im)
+               ENFN->image_free(ENDT, map->im);
              if (map->allocated)
                free(map->ptr);
              return;
diff --git 
a/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c 
b/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c
index 6b2e127..4fb6723 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c
@@ -73,6 +73,12 @@ 
_evas_ector_gl_rgbaimage_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_
      goto end;
 
    gc = re->window_gl_context_get(re->software.ob);
+#ifdef EVAS_CSERVE2
+   if (evas_cache2_image_cached(&pd->image->cache_entry))
+     evas_cache2_image_ref(&pd->image->cache_entry);
+   else
+#endif
+   evas_cache_image_ref(&pd->image->cache_entry);
    pd->glim = evas_gl_common_image_new_from_rgbaimage(gc, pd->image, NULL, 
&err);
    if ((err != EVAS_LOAD_ERROR_NONE) || !pd->glim)
      {
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c 
b/src/modules/evas/engines/gl_generic/evas_engine.c
index 6cc4b90..ddedadd 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -2502,7 +2502,7 @@ eng_ector_buffer_new(void *data, Evas *evas, void *pixels,
    Ector_Buffer *buf = NULL;
    int iw = width + l + r;
    int ih = height + t + b;
-   int pxs = (cspace = EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1;
+   int pxs = (cspace == EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1;
 
    if (stride && (stride != iw * pxs))
      WRN("stride support is not implemented for ector gl buffers at this 
point!");
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c 
b/src/modules/evas/engines/software_generic/evas_engine.c
index 06d2a5d..8a4429a 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -3772,17 +3772,52 @@ eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, 
void *engine_image, Eina_
 }
 
 static Ector_Buffer *
-eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *pixels,
+eng_ector_buffer_new(void *data EINA_UNUSED, Evas *evas, 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;
+   int pxs = (cspace == EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1;
+   int iw = width + l + r;
+   int ih = height + t + b;
 
-   buf = eo_add(ECTOR_SOFTWARE_BUFFER_CLASS, e,
-                ector_buffer_pixels_set(pixels, width, height, stride, cspace,
-                                        writeable, l, r, t, b));
+   if ((flags & (ECTOR_BUFFER_FLAG_RENDERABLE | ECTOR_BUFFER_FLAG_DRAWABLE)) 
== 0)
+     {
+        buf = eo_add(ECTOR_SOFTWARE_BUFFER_CLASS, evas,
+                     ector_buffer_pixels_set(pixels, width, height, stride, 
cspace,
+                                             writeable, l, r, t, b));
+     }
+   else
+     {
+        // Create an RGBA Image as backing
+        Image_Entry *ie;
+
+        if (pixels)
+          {
+             // no copy
+             ie = evas_cache_image_data(evas_common_image_cache_get(), iw, ih,
+                                        pixels, EINA_TRUE, (Evas_Colorspace) 
cspace);
+             if (!ie) return NULL;
+          }
+        else
+          {
+             // alloc buffer
+             ie = evas_cache_image_copied_data(evas_common_image_cache_get(), 
iw, ih,
+                                               NULL, EINA_TRUE, 
(Evas_Colorspace) cspace);
+             if (!ie) return NULL;
+             pixels = ((RGBA_Image *) ie)->image.data;
+             memset(pixels, 0, iw * ih * pxs);
+          }
+        ie->borders.l = l;
+        ie->borders.r = r;
+        ie->borders.t = t;
+        ie->borders.b = b;
+
+        buf = eng_ector_buffer_wrap(data, evas, ie, EINA_TRUE);
+        evas_cache_image_drop(ie);
+     }
 
    return buf;
 }

-- 


Reply via email to