From fc92a1c0f6380021dfb8d0199b44252463d536db Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Mon, 3 Apr 2017 21:24:07 +0900 Subject: [PATCH] evas filters: Enable down scaling with GL blur 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 | 41 ++++++++++--------- .../gl_generic/filters/gl_filter_blur.c | 22 +++++++++- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 270c79f948..e5391f2a19 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -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 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 8c78f8c196..98faa3aeaf 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 @@ -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;