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.
This commit is contained in:
Jean-Philippe Andre 2017-04-03 21:24:07 +09:00
parent 293438111c
commit fc92a1c0f6
2 changed files with 43 additions and 20 deletions

View 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

View 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;