summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-04-03 16:29:51 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-04-03 20:39:35 +0900
commit266ee07805be6cc238123b2580a62b7d6f54cd3a (patch)
tree3f9ddeb699d09f542cb9b6332d6a920922dda82e
parentf8831b5b3e96955fe4ec2d60d5364b005371fd5d (diff)
downloadefl-devs/jpeg/filters_custom_shader.tar.gz
evas filters: Add custom fragment shaderdevs/jpeg/filters_custom_shader
The objective is to generate GLSL code from C and pass all the required constants directly. This will be used for highly specialized variants of GL blur.
-rw-r--r--src/lib/evas/filters/evas_filter.c61
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h6
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_context.c78
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_shader.c48
-rw-r--r--src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x23
-rw-r--r--src/modules/evas/engines/gl_common/shader/fragment.glsl32
-rw-r--r--src/modules/evas/engines/gl_generic/filters/gl_filter_blur.c128
7 files changed, 320 insertions, 56 deletions
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 270c79f948..7c51a0001a 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -684,6 +684,27 @@ evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context,
return cmd;
}
+static int
+_blur_support_gl(Evas_Filter_Context *ctx, Evas_Filter_Buffer *in, Evas_Filter_Buffer *out,
+ Evas_Filter_Blur_Type type, int count, int dx, int dy)
+{
+ Evas_Filter_Command cmd = {};
+
+ cmd.input = in;
+ cmd.output = out;
+ cmd.mode = EVAS_FILTER_MODE_BLUR;
+ cmd.ctx = ctx;
+ cmd.blur.count = count;
+ cmd.blur.type = type;
+ cmd.blur.dx = dx;
+ cmd.blur.dy = dy;
+
+ if (cmd.ENFN->gfx_filter_supports(cmd.ENDT, &cmd) != EVAS_FILTER_SUPPORT_GL)
+ return 0;
+
+ return cmd.draw.need_temp_buffer ? 2 : 1;
+}
+
static Evas_Filter_Command *
evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
Evas_Filter_Buffer *in, Evas_Filter_Buffer *out,
@@ -694,6 +715,7 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
Evas_Filter_Command *cmd;
Evas_Filter_Buffer *dx_in, *dx_out, *dy_in, *dy_out, *tmp = NULL;
double dx, dy;
+ int passes;
/* GL blur implementation:
* - Create intermediate buffer T (variable size)
@@ -712,15 +734,15 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
dy_out = out;
#if 0
- if (type == EVAS_FILTER_BLUR_DEFAULT)
+ if ((type == EVAS_FILTER_BLUR_DEFAULT) && (rx == ry) && (rx >= 8))
{
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 = 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 = down_y = 4;
tmp = evas_filter_temporary_buffer_get(ctx, ctx->w / down_x, ctx->h / down_y,
in->alpha_only, EINA_TRUE);
@@ -743,7 +765,19 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
}
#endif
- if (dx && dy)
+ passes = _blur_support_gl(ctx, in, out, type, count, dx, dy);
+ if (passes == 1)
+ {
+ XDBG("Add GL blur %d -> %d (%.2fx%.2f px)", dx_in->id, dy_out->id, dx, dy);
+ cmd = _command_new(ctx, EVAS_FILTER_MODE_BLUR, dx_in, NULL, dy_out);
+ if (!cmd) goto fail;
+ cmd->blur.type = type;
+ cmd->blur.dx = dx;
+ cmd->blur.dy = dy;
+ cmd->blur.count = count;
+ dx = dy = 0;
+ }
+ else if (dx && dy)
{
tmp = evas_filter_temporary_buffer_get(ctx, dx_in->w, dx_in->h, in->alpha_only, 1);
if (!tmp) goto fail;
@@ -798,21 +832,6 @@ fail:
return NULL;
}
-static Eina_Bool
-_blur_support_gl(Evas_Filter_Context *ctx, Evas_Filter_Buffer *in, Evas_Filter_Buffer *out)
-{
- Evas_Filter_Command cmd = {};
-
- cmd.input = in;
- cmd.output = out;
- cmd.mode = EVAS_FILTER_MODE_BLUR;
- cmd.ctx = ctx;
- cmd.blur.type = EVAS_FILTER_BLUR_GAUSSIAN;
- cmd.blur.dx = 5;
-
- return cmd.ENFN->gfx_filter_supports(cmd.ENDT, &cmd) == EVAS_FILTER_SUPPORT_GL;
-}
-
Evas_Filter_Command *
evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
int inbuf, int outbuf, Evas_Filter_Blur_Type type,
@@ -851,7 +870,7 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx,
return _command_new(ctx, EVAS_FILTER_MODE_SKIP, NULL, NULL, NULL);
}
- if (_blur_support_gl(ctx, in, out))
+ if (_blur_support_gl(ctx, in, out, type, count, dx, dy))
return evas_filter_command_blur_add_gl(ctx, in, out, type, dx, dy, ox, oy, count, R, G, B, A);
// Note (SW engine):
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 ad5835d1ba..258b0d9485 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -265,7 +265,8 @@ enum _Shader_Type {
SHD_FILTER_DISPLACE,
SHD_FILTER_CURVE,
SHD_FILTER_BLUR_X,
- SHD_FILTER_BLUR_Y
+ SHD_FILTER_BLUR_Y,
+ SHD_FILTER_CUSTOM,
};
#define ARRAY_BUFFER_USE 500
@@ -674,6 +675,8 @@ void evas_gl_common_filter_curve_push(Evas_Engine_GL_Context *gc, E
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, const double * const values, const double * const offsets, int count, double radius,
Eina_Bool horiz);
+void evas_gl_common_filter_custom_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, const char *fragment_main);
int evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
void evas_gl_common_shader_program_shutdown(Evas_GL_Shared *shared);
@@ -689,6 +692,7 @@ Evas_GL_Program *evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
Eina_Bool mask_color, int mw, int mh,
Shader_Sampling *psam, int *pnomul,
Shader_Sampling *pmasksam);
+Evas_GL_Program *evas_gl_common_shader_program_custom_get(Evas_Engine_GL_Context *gc, const char *fragment_main);
void evas_gl_common_shader_textures_bind(Evas_GL_Program *p);
Eina_Bool evas_gl_common_file_cache_is_dir(const char *file);
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 b61cc6aa9f..66ae821ecf 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -3616,6 +3616,84 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
PUSH_6_COLORS(pn, r, g, b, a);
}
+void
+evas_gl_common_filter_custom_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,
+ const char *fragment_main)
+{
+ double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4, pw, ph;
+ GLfloat tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;
+ GLfloat offsetx, offsety;
+ Evas_GL_Program *prog;
+ Eina_Bool blend = EINA_TRUE;
+ Eina_Bool smooth = EINA_TRUE;
+ Shader_Type type = SHD_FILTER_CUSTOM;
+ int pn;
+
+ if (gc->dc->render_op == EVAS_RENDER_COPY)
+ blend = EINA_FALSE;
+
+ prog = evas_gl_common_shader_program_custom_get(gc, fragment_main);
+
+ pw = tex->pt->w;
+ ph = tex->pt->h;
+ pn = _evas_gl_common_context_push(type, gc, tex, NULL, prog,
+ sx, sy, dw, dh, blend, smooth,
+ 0, 0, 0, 0, 0, EINA_FALSE);
+
+ gc->pipe[pn].region.type = type;
+ gc->pipe[pn].shader.prog = prog;
+ gc->pipe[pn].shader.cur_tex = tex->pt->texture;
+ gc->pipe[pn].shader.cur_texm = 0;
+ gc->pipe[pn].shader.tex_target = GL_TEXTURE_2D;
+ gc->pipe[pn].shader.smooth = smooth;
+ gc->pipe[pn].shader.mask_smooth = 0;
+ gc->pipe[pn].shader.blend = blend;
+ gc->pipe[pn].shader.render_op = gc->dc->render_op;
+ gc->pipe[pn].shader.clip = 0;
+ gc->pipe[pn].shader.cx = 0;
+ gc->pipe[pn].shader.cy = 0;
+ gc->pipe[pn].shader.cw = 0;
+ gc->pipe[pn].shader.ch = 0;
+ gc->pipe[pn].array.line = 0;
+ gc->pipe[pn].array.use_vertex = 1;
+ gc->pipe[pn].array.use_color = 0;
+ gc->pipe[pn].array.use_texuv = 1;
+ gc->pipe[pn].array.use_texuv2 = 0;
+ gc->pipe[pn].array.use_texuv3 = 0;
+ gc->pipe[pn].array.use_texsam = 0;
+ gc->pipe[pn].array.use_mask = 0;
+ gc->pipe[pn].array.use_masksam = 0;
+
+ pipe_region_expand(gc, pn, dx, dy, dw, dh);
+ PIPE_GROW(gc, pn, 6);
+
+ ox1 = sx;
+ oy1 = sy;
+ ox2 = sx + sw;
+ oy2 = sy;
+ ox3 = sx + sw;
+ oy3 = sy + sh;
+ ox4 = sx;
+ oy4 = sy + sh;
+
+ offsetx = tex->x;
+ offsety = tex->y;
+
+ tx1 = ((double)(offsetx) + ox1) / pw;
+ ty1 = ((double)(offsety) + oy1) / ph;
+ tx2 = ((double)(offsetx) + ox2) / pw;
+ ty2 = ((double)(offsety) + oy2) / ph;
+ tx3 = ((double)(offsetx) + ox3) / pw;
+ ty3 = ((double)(offsety) + oy3) / ph;
+ tx4 = ((double)(offsetx) + ox4) / pw;
+ ty4 = ((double)(offsety) + oy4) / ph;
+
+ PUSH_6_VERTICES(pn, dx, dy, dw, dh);
+ PUSH_6_QUAD(pn, tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);
+}
+
// ----------------------------------------------------------------------------
EAPI void
diff --git a/src/modules/evas/engines/gl_common/evas_gl_shader.c b/src/modules/evas/engines/gl_common/evas_gl_shader.c
index 29c68ddb21..58f246b34c 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_shader.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c
@@ -417,13 +417,16 @@ _shaders_hash_free_cb(void *data)
}
static char *
-evas_gl_common_shader_glsl_get(unsigned int flags, const char *base)
+evas_gl_common_shader_glsl_get(unsigned int flags, const char *base,
+ const char *custom_header)
{
Eina_Strbuf *s = eina_strbuf_new();
unsigned int k;
char *str;
- //eina_strbuf_append_printf(s, "#version 300 es\n");
+ if (custom_header)
+ eina_strbuf_append_printf(s, "%s\n", custom_header);
+
for (k = 0; k < SHADER_FLAG_COUNT; k++)
{
if (flags & (1 << k))
@@ -576,8 +579,8 @@ evas_gl_common_shader_generate_and_compile(Evas_GL_Shared *shared, unsigned int
if (eina_hash_find(shared->shaders_hash, &flags))
return NULL;
- vertex = evas_gl_common_shader_glsl_get(flags, vertex_glsl);
- fragment = evas_gl_common_shader_glsl_get(flags, fragment_glsl);
+ vertex = evas_gl_common_shader_glsl_get(flags, vertex_glsl, NULL);
+ fragment = evas_gl_common_shader_glsl_get(flags, fragment_glsl, NULL);
p = evas_gl_common_shader_compile(flags, vertex, fragment);
if (p)
@@ -976,3 +979,40 @@ end:
p->hitcount++;
return p;
}
+
+Evas_GL_Program *
+evas_gl_common_shader_program_custom_get(Evas_Engine_GL_Context *gc,
+ const char *fragment_main)
+{
+ char *vertex, *fragment;
+ unsigned int flags;
+ Evas_GL_Program *p;
+
+ // FIXME
+ static Eina_Hash *hash = 0;
+ if (!hash) hash = eina_hash_string_superfast_new(NULL);
+
+ p = eina_hash_find(hash, fragment_main);
+ if (p) return p;
+
+ flags = SHADER_FLAG_TEX | SHADER_FLAG_IMG | SHADER_FLAG_NOMUL;
+ if (gc->shared->info.bgra) flags |= SHADER_FLAG_BGRA;
+
+ vertex = evas_gl_common_shader_glsl_get(flags, vertex_glsl, NULL);
+ fragment = evas_gl_common_shader_glsl_get(flags, fragment_glsl, fragment_main);
+
+ p = evas_gl_common_shader_compile(flags, vertex, fragment);
+ if (p)
+ {
+ p->uniform.mvp = glGetUniformLocation(p->prog, "mvp");
+ p->uniform.rotation_id = glGetUniformLocation(p->prog, "rotation_id");
+ evas_gl_common_shader_textures_bind(p);
+ eina_hash_add(hash, fragment_main, p);
+ }
+ else WRN("Failed to compile custom shader (flags: %08x):\n%s", flags, fragment_main);
+
+ free(vertex);
+ free(fragment);
+
+ return p;
+}
diff --git a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x
index 879548b184..628a2d190f 100644
--- a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x
+++ b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x
@@ -98,17 +98,11 @@ static const char fragment_glsl[] =
"uniform float blur_div;\n"
"#endif\n"
"// ----------------------------------------------------------------------------\n"
- "#ifndef SHD_FILTER_BLUR\n"
- "void main()\n"
- "{\n"
- "#if defined(SHD_EXTERNAL) || defined(SHD_TEX)\n"
- " vec2 coord = tex_c;\n"
- "#endif\n"
- "#else // SHD_FILTER_BLUR\n"
"vec4 fetch_pixel(float ox, float oy)\n"
"{\n"
+ "#if defined(SHD_EXTERNAL) || defined(SHD_TEX)\n"
" vec2 coord = tex_c + vec2(ox, oy);\n"
- "#endif // SHD_FILTER_BLUR\n"
+ "#endif\n"
" vec4 c;\n"
"#ifdef SHD_FILTER_DISPLACE\n"
" vec2 dxy = texture2D(tex_filter, tex_c).rg * displace_vector;\n"
@@ -211,8 +205,7 @@ static const char fragment_glsl[] =
" texture2D(tex_filter, vec2(c.b / old_alpha, 0.0)).b * new_alpha,\n"
" new_alpha);\n"
"#endif\n"
- "#ifndef SHD_FILTER_BLUR\n"
- " gl_FragColor =\n"
+ " return\n"
" c\n"
"#ifndef SHD_NOMUL\n"
" * col\n"
@@ -225,9 +218,15 @@ static const char fragment_glsl[] =
"#endif\n"
" ;\n"
"}\n"
- "#else // SHD_FILTER_BLUR\n"
- " return c;\n"
+ "#if defined(FRAGMENT_MAIN)\n"
+ "FRAGMENT_MAIN\n"
+ "#elif !defined(SHD_FILTER_BLUR)\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = fetch_pixel(0.0, 0.0);\n"
"}\n"
+ "// ----------------------------------------------------------------------------\n"
+ "#else\n"
"#ifndef SHD_FILTER_DIR_Y\n"
"# define FETCH_PIXEL(x) fetch_pixel((x), 0.0)\n"
"#else\n"
diff --git a/src/modules/evas/engines/gl_common/shader/fragment.glsl b/src/modules/evas/engines/gl_common/shader/fragment.glsl
index 4a710f595c..b968ae14ad 100644
--- a/src/modules/evas/engines/gl_common/shader/fragment.glsl
+++ b/src/modules/evas/engines/gl_common/shader/fragment.glsl
@@ -97,20 +97,11 @@ uniform float blur_div;
// ----------------------------------------------------------------------------
-#ifndef SHD_FILTER_BLUR
-void main()
-{
-#if defined(SHD_EXTERNAL) || defined(SHD_TEX)
- vec2 coord = tex_c;
-#endif
-
-#else // SHD_FILTER_BLUR
-
vec4 fetch_pixel(float ox, float oy)
{
+#if defined(SHD_EXTERNAL) || defined(SHD_TEX)
vec2 coord = tex_c + vec2(ox, oy);
-
-#endif // SHD_FILTER_BLUR
+#endif
vec4 c;
@@ -226,9 +217,7 @@ vec4 fetch_pixel(float ox, float oy)
new_alpha);
#endif
-#ifndef SHD_FILTER_BLUR
-
- gl_FragColor =
+ return
c
#ifndef SHD_NOMUL
* col
@@ -242,11 +231,22 @@ vec4 fetch_pixel(float ox, float oy)
;
}
-#else // SHD_FILTER_BLUR
- return c;
+#if defined(FRAGMENT_MAIN)
+
+FRAGMENT_MAIN
+
+#elif !defined(SHD_FILTER_BLUR)
+
+void main()
+{
+ gl_FragColor = fetch_pixel(0.0, 0.0);
}
+
+// ----------------------------------------------------------------------------
+#else
+
#ifndef SHD_FILTER_DIR_Y
# define FETCH_PIXEL(x) fetch_pixel((x), 0.0)
#else
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..59eab4ba29 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
@@ -246,15 +246,139 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
return EINA_TRUE;
}
+static Eina_Bool
+_gl_filter_blur_2d_radius_2(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
+{
+ Evas_Engine_GL_Context *gc;
+ Evas_GL_Image *image, *surface;
+ RGBA_Draw_Context *dc_save;
+ double sx, sy, sw, sh, ssx, ssy, ssw, ssh, dx, dy, dw, dh;
+ double s_w, s_h, d_w, d_h;
+ Eina_Rectangle s_region[4], d_region[4];
+ int nx, ny, nw, nh, regions;
+ const char *fragment_main;
+ Eina_Strbuf *str;
+
+ static char *base_code = NULL;
+
+ if (!base_code)
+ {
+ const char *code;
+
+ code = "const float wei = 1.0;\n"
+ "const float off = 1.0/3.0;\n"
+ "\n"
+ "void main ()\n"
+ "{\n"
+ " vec4 px1, px2, px3, px4;\n"
+ " px1 = fetch_pixel(-off / W, -off / H);\n"
+ " px2 = fetch_pixel(-off / W, off / H);\n"
+ " px3 = fetch_pixel( off / W, -off / H);\n"
+ " px4 = fetch_pixel( off / W, off / H);\n"
+ " gl_FragColor = (px1 + px2 + px3 + px4) / 4.0;\n"
+ "}\n";
+
+ str = eina_strbuf_new();
+ eina_strbuf_append(str, "#define FRAGMENT_MAIN\n");
+ eina_strbuf_append(str, code);
+ eina_strbuf_replace_all(str, "\n", " \\\n");
+ base_code = eina_strbuf_string_steal(str);
+ eina_strbuf_free(str);
+ }
+
+ DEBUG_TIME_BEGIN();
+
+ s_w = cmd->input->w;
+ s_h = cmd->input->h;
+ d_w = cmd->output->w;
+ d_h = cmd->output->h;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(s_w && s_h && d_w && d_h, EINA_FALSE);
+
+ re->window_use(re->software.ob);
+ gc = re->window_gl_context_get(re->software.ob);
+
+ image = evas_ector_buffer_drawable_image_get(cmd->input->buffer);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
+
+ surface = evas_ector_buffer_render_image_get(cmd->output->buffer);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
+
+ evas_gl_common_context_target_surface_set(gc, surface);
+
+ DBG("blur %d @%p -> %d @%p (custom 2D)",
+ cmd->input->id, cmd->input->buffer,
+ cmd->output->id, cmd->output->buffer);
+
+ dc_save = gc->dc;
+ gc->dc = evas_common_draw_context_new();
+ gc->dc->render_op = _gfx_to_evas_render_op(cmd->draw.rop);
+
+ // Set constants in shader code
+ str = eina_strbuf_new();
+ eina_strbuf_append_printf(str, "const float W = %f;\n", (float) image->tex->pt->w);
+ eina_strbuf_append_printf(str, "const float H = %f;\n", (float) image->tex->pt->h);
+ eina_strbuf_append(str, base_code);
+ fragment_main = eina_strbuf_string_get(str);
+
+ // FIXME: Implement region support! (note: can't separate perfectly in 2d)
+ regions = 1;
+ s_region[0] = S_RECT(0, 0, s_w, s_h);
+ d_region[0] = D_RECT(0, 0, d_w, d_h);
+
+ for (int k = 0; k < regions; k++)
+ {
+ sx = s_region[k].x;
+ sy = s_region[k].y;
+ sw = s_region[k].w;
+ sh = s_region[k].h;
+
+ dx = d_region[k].x + cmd->draw.ox;
+ dy = d_region[k].y + cmd->draw.oy;
+ dw = d_region[k].w;
+ dh = d_region[k].h;
+
+ nx = dx; ny = dy; nw = dw; nh = dh;
+ RECTS_CLIP_TO_RECT(nx, ny, nw, nh, 0, 0, d_w, d_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_custom_push(gc, image->tex, ssx, ssy, ssw, ssh,
+ dx, dy, dw, dh, fragment_main);
+ }
+ eina_strbuf_free(str);
+
+ evas_common_draw_context_free(gc->dc);
+ gc->dc = dc_save;
+
+ evas_ector_buffer_engine_image_release(cmd->input->buffer, image);
+ evas_ector_buffer_engine_image_release(cmd->output->buffer, surface);
+
+ DEBUG_TIME_END();
+
+ return EINA_TRUE;
+}
+
GL_Filter_Apply_Func
gl_filter_blur_func_get(Render_Engine_GL_Generic *re EINA_UNUSED, Evas_Filter_Command *cmd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(!cmd->blur.dx && !cmd->blur.dy, NULL);
- // 1D blurs only, radius != 0
- EINA_SAFETY_ON_FALSE_RETURN_VAL((!cmd->blur.dx) ^ (!cmd->blur.dy), NULL);
+ // FIXME: Handle box blur, perfect gaussian, scaling and other special cases
+
+ if ((EINA_FLT_EQ(cmd->blur.dx, cmd->blur.dy)) && (cmd->output != cmd->input))
+ {
+ // Special cases for very fast blurs
+ double r = cmd->blur.dx;
+
+ if (EINA_FLT_EQ(r, 2.0))
+ return _gl_filter_blur_2d_radius_2;
+ }
+ cmd->draw.need_temp_buffer = EINA_TRUE;
return _gl_filter_blur;
}