jpeg pushed a commit to branch master.

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

commit a9ddeeb4fb3dc1fecc930d77dfa8721ac88a99b7
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Mon Mar 20 20:20:21 2017 +0900

    evas filters: Use GL downscaling for blur
    
    This will improve the performance a lot. Now remains to figure
    out the best values for downscaling and improve the actual blur
    shader as well.
---
 src/lib/evas/filters/evas_filter.c                 | 51 +++++++++++++++++-----
 .../evas/engines/gl_common/evas_gl_common.h        |  2 +-
 .../evas/engines/gl_common/evas_gl_context.c       | 21 ++++-----
 .../engines/gl_generic/filters/gl_filter_blur.c    | 27 ++++++++----
 4 files changed, 68 insertions(+), 33 deletions(-)

diff --git a/src/lib/evas/filters/evas_filter.c 
b/src/lib/evas/filters/evas_filter.c
index a37fe40..ef2710b 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -543,24 +543,53 @@ static Evas_Filter_Command *
 evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
                                 Evas_Filter_Buffer *in, Evas_Filter_Buffer 
*out,
                                 Evas_Filter_Blur_Type type,
-                                int dx, int dy, int ox, int oy, int count,
+                                int rx, int ry, int ox, int oy, int count,
                                 int R, int G, int B, int A)
 {
    Evas_Filter_Command *cmd;
-   Evas_Filter_Buffer *dx_out, *dy_in;
+   Evas_Filter_Buffer *dx_in, *dx_out, *dy_in, *tmp = NULL;
+   int down_x, down_y, dx, dy;
 
    /* GL blur implementation:
-    * - Always split X and Y passes (only one pass if 1D blur)
-    * - TODO: Repeat blur for large radius
-    * - TODO: Scale down & up for cheap blur
-    * - The rest is all up to the engine!
+    * - Create intermediate buffer T (variable size)
+    * - Downscale to buffer T
+    * - Apply X blur kernel
+    * - Apply Y blur kernel while scaling up
+    *
+    * - TODO: Fix distortion X vs. Y
+    * - TODO: Calculate best scaline and blur radius
+    * - TODO: Add post-processing? (2D single-pass)
     */
 
+   dx = rx;
+   dy = ry;
+   dx_in = in;
+
+   if (type == EVAS_FILTER_BLUR_DEFAULT)
+     {
+        down_x = MAX((1 << evas_filter_smallest_pow2_larger_than(dx / 2) / 2), 
1);
+        down_y = MAX((1 << evas_filter_smallest_pow2_larger_than(dy / 2) / 2), 
1);
+
+        tmp = evas_filter_temporary_buffer_get(ctx, ctx->w / down_x, ctx->h / 
down_y,
+                                               in->alpha_only, EINA_TRUE);
+        if (!tmp) goto fail;
+
+        // FIXME: Fix logic here. This is where the smarts are! Now it's dumb.
+        dx = rx / down_x;
+        dy = ry / down_y;
+
+        XDBG("Add GL downscale %d (%dx%d) -> %d (%dx%d)", in->id, in->w, 
in->h, tmp->id, tmp->w, tmp->h);
+        cmd = _command_new(ctx, EVAS_FILTER_MODE_BLEND, in, NULL, tmp);
+        if (!cmd) goto fail;
+        cmd->draw.fillmode = EVAS_FILTER_FILL_MODE_STRETCH_XY;
+        dx_in = tmp;
+     }
+
    if (dx && dy)
      {
-        dx_out = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 
1);
-        if (!dx_out) goto fail;
-        dy_in = dx_out;
+        tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 1);
+        if (!tmp) goto fail;
+        dy_in = dx_out = tmp;
      }
    else
      {
@@ -570,8 +599,8 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
 
    if (dx)
      {
-        XDBG("Add GL blur %d -> %d (%dx%d px)", in->id, dx_out->id, dx, 0);
-        cmd = _command_new(ctx, EVAS_FILTER_MODE_BLUR, in, NULL, dx_out);
+        XDBG("Add GL blur %d -> %d (%dx%d px)", dx_in->id, dx_out->id, dx, 0);
+        cmd = _command_new(ctx, EVAS_FILTER_MODE_BLUR, dx_in, NULL, dx_out);
         if (!cmd) goto fail;
         cmd->blur.type = type;
         cmd->blur.dx = dx;
diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h 
b/src/modules/evas/engines/gl_common/evas_gl_common.h
index 3e7548a..b48955e 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -651,7 +651,7 @@ void              
evas_gl_common_filter_displace_push(Evas_Engine_GL_Context *gc
                                                       int x, int y, int w, int 
h, double dx, double dy, Eina_Bool nearest);
 void              evas_gl_common_filter_curve_push(Evas_Engine_GL_Context *gc, 
Evas_GL_Texture *tex,
                                                    int x, int y, int w, int h, 
const uint8_t *points, int channel);
-void              evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc, 
Evas_GL_Texture *tex, int x, int y, int w, int h, double radius, Eina_Bool 
horiz);
+void              evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc, 
Evas_GL_Texture *tex, double sx, double sy, double sw, double sh, double dx, 
double dy, double dw, double dh, double radius, Eina_Bool horiz);
 
 int               evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
 void              evas_gl_common_shader_program_shutdown(Evas_GL_Shared 
*shared);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c 
b/src/modules/evas/engines/gl_common/evas_gl_context.c
index a2f7d68..48de69e 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -3430,11 +3430,11 @@ evas_gl_common_filter_curve_push(Evas_Engine_GL_Context 
*gc,
 void
 evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
                                 Evas_GL_Texture *tex,
-                                int x, int y, int w, int h,
+                                double sx, double sy, double sw, double sh,
+                                double dx, double dy, double dw, double dh,
                                 double radius, Eina_Bool horiz)
 {
-   double sx, sy, sw, sh, pw, ph;
-   double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4;
+   double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4, pw, ph;
    GLfloat tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;
    GLfloat offsetx, offsety;
    int r, g, b, a, nomul = 0, pn;
@@ -3452,14 +3452,14 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context 
*gc,
      blend = EINA_FALSE;
 
    prog = evas_gl_common_shader_program_get(gc, type, NULL, 0, r, g, b, a,
-                                            w, h, w, h, smooth, tex, 
EINA_FALSE,
+                                            sw, sh, dw, dh, smooth, tex, 
EINA_FALSE,
                                             NULL, EINA_FALSE, EINA_FALSE, 0, 0,
                                             NULL, &nomul, NULL);
    _filter_data_flush(gc, prog);
    EINA_SAFETY_ON_NULL_RETURN(prog);
 
    pn = _evas_gl_common_context_push(type, gc, tex, NULL, prog,
-                                     x, y, w, h, blend, smooth,
+                                     sx, sy, dw, dh, blend, smooth,
                                      0, 0, 0, 0, 0, EINA_FALSE);
 
    gc->pipe[pn].region.type = type;
@@ -3486,19 +3486,14 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context 
*gc,
    gc->pipe[pn].array.use_mask = 0;
    gc->pipe[pn].array.use_masksam = 0;
 
-   pipe_region_expand(gc, pn, x, y, w, h);
+   pipe_region_expand(gc, pn, dx, dy, dw, dh);
    PIPE_GROW(gc, pn, 6);
 
    // Set blur properties... TODO
    _filter_data_prepare(gc, pn, prog, 1);
    filter_data = gc->pipe[pn].array.filter_data;
    filter_data[0] = radius;
-   filter_data[1] = horiz ? w : h;
-
-   sx = 0;
-   sy = 0;
-   sw = w;
-   sh = h;
+   filter_data[1] = horiz ? sw : sh;
 
    pw = tex->pt->w;
    ph = tex->pt->h;
@@ -3524,7 +3519,7 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context 
*gc,
    tx4 = ((double)(offsetx) + ox4) / pw;
    ty4 = ((double)(offsety) + oy4) / ph;
 
-   PUSH_6_VERTICES(pn, x, y, w, h);
+   PUSH_6_VERTICES(pn, dx, dy, dw, dh);
    PUSH_6_QUAD(pn, tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);
 
    if (!nomul)
diff --git a/src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c 
b/src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c
index 636b9a7..66416dd 100644
--- a/src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c
+++ b/src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c
@@ -7,16 +7,11 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, 
Evas_Filter_Command *cmd)
    Evas_GL_Image *image, *surface;
    RGBA_Draw_Context *dc_save;
    Eina_Bool horiz;
-   double radius;
-   int x, y, w, h;
+   double sx, sy, sw, sh, ssx, ssy, ssw, ssh, dx, dy, dw, dh, radius;
+   int nx, ny, nw, nh;
 
    DEBUG_TIME_BEGIN();
 
-   x = cmd->draw.ox;
-   y = cmd->draw.oy;
-   w = cmd->input->w;
-   h = cmd->input->h;
-
    re->window_use(re->software.ob);
    gc = re->window_gl_context_get(re->software.ob);
 
@@ -52,7 +47,23 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, 
Evas_Filter_Command *cmd)
        cmd->input->id, cmd->input->buffer, cmd->output->id, 
cmd->output->buffer,
        radius, horiz ? "X" : "Y");
 
-   evas_gl_common_filter_blur_push(gc, image->tex, x, y, w, h, radius, horiz);
+   sx = 0;
+   sy = 0;
+   sw = cmd->input->w;
+   sh = cmd->input->h;
+   dx = cmd->draw.ox;
+   dy = cmd->draw.oy;
+   dw = cmd->output->w;
+   dh = cmd->output->h;
+
+   nx = dx; ny = dy; nw = dw; nh = dh;
+   RECTS_CLIP_TO_RECT(nx, ny, nw, nh, 0, 0, cmd->output->w, cmd->output->h);
+   ssx = (double)sx + ((double)(sw * (nx - dx)) / (double)(dw));
+   ssy = (double)sy + ((double)(sh * (ny - dy)) / (double)(dh));
+   ssw = ((double)sw * (double)(nw)) / (double)(dw);
+   ssh = ((double)sh * (double)(nh)) / (double)(dh);
+
+   evas_gl_common_filter_blur_push(gc, image->tex, ssx, ssy, ssw, ssh, dx, dy, 
dw, dh, radius, horiz);
 
    evas_common_draw_context_free(gc->dc);
    gc->dc = dc_save;

-- 


Reply via email to