evas filters: Enable down scaling with GL blur
authorJean-Philippe Andre <jp.andre@samsung.com>
Mon, 3 Apr 2017 12:24:07 +0000 (21:24 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Fri, 14 Apr 2017 02:26:44 +0000 (11:26 +0900)
This dramatically improves the performance and now seems
to give acceptable results. Eventually we need a quality flag
in order to enable this or not. Alternatively, "gaussian" blur
mode would skip this optimization, while "default" would trigger
it.

src/lib/evas/filters/evas_filter.c
src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c

index 270c79f9487eff2b17575b2f144ff39b2aac5166..e5391f2a197e3dc1d341f511ad140c67e2b3146b 100644 (file)
@@ -711,35 +711,38 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
    dx_in = in;
    dy_out = out;
 
-#if 0
+#if 1
    if (type == EVAS_FILTER_BLUR_DEFAULT)
      {
         int down_x = 1, down_y = 1;
 
         /* For now, disable scaling - testing perfect gaussian blur until it's
          * ready: */
-        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);
+        down_x = 1 << evas_filter_smallest_pow2_larger_than(dx / 2) / 2;
+        down_y = 1 << evas_filter_smallest_pow2_larger_than(dy / 2) / 2;
+        if (down_x > 4) down_x = 4;
+        if (down_y > 4) down_y = 4;
 
+        if (down_x > 1 && down_y > 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;
 
-        tmp = evas_filter_temporary_buffer_get(ctx, ctx->w / down_x, ctx->h / down_y,
-                                               in->alpha_only, EINA_TRUE);
-        if (!tmp) goto fail;
+             dx = rx / down_x;
+             dy = ry / down_y;
 
-        // 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;
 
-        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;
-
-        tmp = evas_filter_temporary_buffer_get(ctx, ctx->w / down_x, ctx->h / down_y,
-                                               in->alpha_only, EINA_TRUE);
-        if (!tmp) goto fail;
-        dy_out = tmp;
+             tmp = evas_filter_temporary_buffer_get(ctx, ctx->w / down_x, ctx->h / down_y,
+                                                    in->alpha_only, EINA_TRUE);
+             if (!tmp) goto fail;
+             dy_out = tmp;
+          }
      }
 #endif
 
index 8c78f8c1965acb11d6873ad4c007d983586d60ae..98faa3aeaffeb402fc3ce6d5cef21befd170a3f5 100644 (file)
@@ -111,6 +111,21 @@ _rect(int x, int y, int w, int h, int maxw, int maxh)
 #define S_RECT(_x, _y, _w, _h) _rect(_x, _y, _w, _h, s_w, s_h)
 #define D_RECT(_x, _y, _w, _h) _rect(_x, _y, _w, _h, d_w, d_h)
 
+static inline void
+_output_scale_get(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd,
+                  double *scale_x, double *scale_y)
+{
+   Evas_Filter_Buffer *fb;
+   Eina_List *li;
+
+   EINA_LIST_FOREACH(ctx->buffers, li, fb)
+     if (fb->id == EVAS_FILTER_BUFFER_OUTPUT_ID)
+       {
+          *scale_x = (double) cmd->output->w / (double) fb->w;
+          *scale_y = (double) cmd->output->h / (double) fb->h;
+       }
+}
+
 static Eina_Bool
 _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
 {
@@ -119,7 +134,7 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
    RGBA_Draw_Context *dc_save;
    Eina_Bool horiz;
    double sx, sy, sw, sh, ssx, ssy, ssw, ssh, dx, dy, dw, dh, radius;
-   double s_w, s_h, d_w, d_h;
+   double s_w, s_h, d_w, d_h, scale_x, scale_y;
    Eina_Rectangle s_ob, d_ob, s_region[4], d_region[4];
    int nx, ny, nw, nh, regions, count = 0;
    double *weights, *offsets;
@@ -171,7 +186,12 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
 
    count = _gaussian_interpolate(&weights, &offsets, radius);
 
+   _output_scale_get(cmd->ctx, cmd, &scale_x, &scale_y);
    d_ob = cmd->ctx->obscured.effective;
+   d_ob.x *= scale_x;
+   d_ob.y *= scale_y;
+   d_ob.w *= scale_x;
+   d_ob.h *= scale_y;
    s_ob.x = d_ob.x * s_w / d_w;
    s_ob.y = d_ob.y * s_h / d_h;
    s_ob.w = d_ob.w * s_w / d_w;