forked from enlightenment/efl
evas filters: Pass gaussian values to GL blur shader
This commit is contained in:
parent
a9ddeeb4fb
commit
6af3c20aeb
|
@ -548,7 +548,7 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
|
|||
{
|
||||
Evas_Filter_Command *cmd;
|
||||
Evas_Filter_Buffer *dx_in, *dx_out, *dy_in, *tmp = NULL;
|
||||
int down_x, down_y, dx, dy;
|
||||
int dx, dy;
|
||||
|
||||
/* GL blur implementation:
|
||||
* - Create intermediate buffer T (variable size)
|
||||
|
@ -567,8 +567,13 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
|
|||
|
||||
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);
|
||||
*/
|
||||
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, ctx->w / down_x, ctx->h / down_y,
|
||||
in->alpha_only, EINA_TRUE);
|
||||
|
|
|
@ -651,7 +651,9 @@ 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, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh, 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, GLfloat *values, GLfloat *offsets, int count,
|
||||
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);
|
||||
|
|
|
@ -3432,7 +3432,8 @@ 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)
|
||||
GLfloat *values, GLfloat *offsets, int count,
|
||||
Eina_Bool horiz)
|
||||
{
|
||||
double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4, pw, ph;
|
||||
GLfloat tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;
|
||||
|
@ -3443,6 +3444,8 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
|
|||
Eina_Bool blend = EINA_TRUE;
|
||||
Eina_Bool smooth = EINA_TRUE;
|
||||
Shader_Type type = horiz ? SHD_FILTER_BLUR_X : SHD_FILTER_BLUR_Y;
|
||||
GLuint map_tex;
|
||||
double sum;
|
||||
|
||||
r = R_VAL(&gc->dc->mul.col);
|
||||
g = G_VAL(&gc->dc->mul.col);
|
||||
|
@ -3489,11 +3492,34 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
|
|||
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);
|
||||
sum = values[0];
|
||||
for (int k = 1; k < count; k++)
|
||||
sum += 2.0 * values[k];
|
||||
|
||||
// Synchronous upload of Nx1 RGBA texture (FIXME: no reuse)
|
||||
glGenTextures(1, &map_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, map_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
// FIXME: GLES2 requires extensions here!!!
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, count, 1, 0, GL_RED, GL_FLOAT, values);
|
||||
// FIXME: double values don't work??
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, count, 1, 0, GL_RED, GL_DOUBLE, values);
|
||||
|
||||
// Set curve properties (no need for filter_data)
|
||||
gc->pipe[pn].shader.filter.map_tex = map_tex;
|
||||
gc->pipe[pn].shader.filter.map_nearest = EINA_TRUE;
|
||||
gc->pipe[pn].shader.filter.map_delete = EINA_TRUE;
|
||||
|
||||
// Set blur properties... WIP
|
||||
_filter_data_prepare(gc, pn, prog, 2);
|
||||
filter_data = gc->pipe[pn].array.filter_data;
|
||||
filter_data[0] = radius;
|
||||
filter_data[0] = count;
|
||||
filter_data[1] = horiz ? sw : sh;
|
||||
filter_data[2] = sum;
|
||||
filter_data[3] = 0.0; // unused
|
||||
|
||||
pw = tex->pt->w;
|
||||
ph = tex->pt->h;
|
||||
|
|
|
@ -903,7 +903,8 @@ evas_gl_common_shader_textures_bind(Evas_GL_Program *p)
|
|||
hastex = 1;
|
||||
}
|
||||
if ((p->flags & SHADER_FLAG_FILTER_DISPLACE) ||
|
||||
(p->flags & SHADER_FLAG_FILTER_CURVE))
|
||||
(p->flags & SHADER_FLAG_FILTER_CURVE) ||
|
||||
(p->flags & SHADER_FLAG_FILTER_BLUR))
|
||||
{
|
||||
textures[6].enabled = 1;
|
||||
hastex = 1;
|
||||
|
|
|
@ -92,7 +92,8 @@ static const char fragment_glsl[] =
|
|||
"uniform sampler2D tex_filter;\n"
|
||||
"#endif\n"
|
||||
"#ifdef SHD_FILTER_BLUR\n"
|
||||
"varying vec2 blur_data;\n"
|
||||
"uniform sampler2D tex_filter;\n"
|
||||
"varying vec3 blur_data;\n"
|
||||
"#endif\n"
|
||||
"// ----------------------------------------------------------------------------\n"
|
||||
"#ifndef SHD_FILTER_BLUR\n"
|
||||
|
@ -225,26 +226,39 @@ static const char fragment_glsl[] =
|
|||
"#else // SHD_FILTER_BLUR\n"
|
||||
" return c;\n"
|
||||
"}\n"
|
||||
"#ifndef SHD_FILTER_DIR_Y\n"
|
||||
"# define FETCH_PIXEL(x) fetch_pixel((x), 0.0)\n"
|
||||
"#else\n"
|
||||
"# define FETCH_PIXEL(x) fetch_pixel(0.0, (x))\n"
|
||||
"#endif\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" float u, u_div, radius, diam;\n"
|
||||
" vec4 acc = vec4(0.,0.,0.,0.);\n"
|
||||
" float div = 0.0;\n"
|
||||
" radius = blur_data.x;\n"
|
||||
" float u, u_div, count, div, w;\n"
|
||||
" vec4 acc, px;\n"
|
||||
" count = blur_data.x;\n"
|
||||
" u_div = blur_data.y;\n"
|
||||
" diam = radius * 2.0 + 1.0;\n"
|
||||
" for (u = -radius; u <= radius; u += 1.0)\n"
|
||||
" //div = blur_data.z;\n"
|
||||
" // Center pixel\n"
|
||||
" w = texture2D(tex_filter, vec2(0.0, 0.0)).r;\n"
|
||||
" px = FETCH_PIXEL(u / u_div);\n"
|
||||
" acc = px * w;\n"
|
||||
" div = w;\n"
|
||||
" // Left & right\n"
|
||||
" for (u = 1; u <= count; u += 1.0)\n"
|
||||
"#if 0\n"
|
||||
" div = 0.0;\n"
|
||||
" for (u = -count; u <= count; u += 1.0)\n"
|
||||
" {\n"
|
||||
" float w = (u + radius) / (diam - 1.0) * 6.0 - 3.0;\n"
|
||||
" w = (sin(w + M_PI_2) + 1.0) / 2.0;\n"
|
||||
" w = texture2D(tex_filter, vec2(abs(u) / count, 0.0)).r;\n"
|
||||
"#ifndef SHD_FILTER_DIR_Y\n"
|
||||
" vec4 px = fetch_pixel(u / u_div, 0.0);\n"
|
||||
" px = fetch_pixel(u / u_div, 0.0);\n"
|
||||
"#else\n"
|
||||
" vec4 px = fetch_pixel(0.0, u / u_div);\n"
|
||||
" px = fetch_pixel(0.0, u / u_div);\n"
|
||||
"#endif\n"
|
||||
" acc += px * w;\n"
|
||||
" div += w;\n"
|
||||
" }\n"
|
||||
"#endif\n"
|
||||
"#ifndef SHD_NOMUL\n"
|
||||
" gl_FragColor = (acc / div) * col;\n"
|
||||
"#else\n"
|
||||
|
@ -327,7 +341,8 @@ static const char vertex_glsl[] =
|
|||
"/* Gfx Filters: blur */\n"
|
||||
"#ifdef SHD_FILTER_BLUR\n"
|
||||
"attribute vec2 filter_data_0;\n"
|
||||
"varying vec2 blur_data;\n"
|
||||
"attribute vec2 filter_data_1;\n"
|
||||
"varying vec3 blur_data;\n"
|
||||
"#endif\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
|
@ -398,7 +413,7 @@ static const char vertex_glsl[] =
|
|||
" displace_max = filter_data_2;\n"
|
||||
"#endif\n"
|
||||
"#ifdef SHD_FILTER_BLUR\n"
|
||||
" blur_data = filter_data_0;\n"
|
||||
" blur_data = vec3(filter_data_0.xy, filter_data_1.x);\n"
|
||||
"#endif\n"
|
||||
"}\n";
|
||||
|
||||
|
|
|
@ -89,7 +89,8 @@ uniform sampler2D tex_filter;
|
|||
#endif
|
||||
|
||||
#ifdef SHD_FILTER_BLUR
|
||||
varying vec2 blur_data;
|
||||
uniform sampler2D tex_filter;
|
||||
varying vec3 blur_data;
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -244,30 +245,46 @@ vec4 fetch_pixel(float ox, float oy)
|
|||
return c;
|
||||
}
|
||||
|
||||
#ifndef SHD_FILTER_DIR_Y
|
||||
# define FETCH_PIXEL(x) fetch_pixel((x), 0.0)
|
||||
#else
|
||||
# define FETCH_PIXEL(x) fetch_pixel(0.0, (x))
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
float u, u_div, radius, diam;
|
||||
vec4 acc = vec4(0.,0.,0.,0.);
|
||||
float div = 0.0;
|
||||
float u, u_div, count, div, w;
|
||||
vec4 acc, px;
|
||||
|
||||
radius = blur_data.x;
|
||||
count = blur_data.x;
|
||||
u_div = blur_data.y;
|
||||
diam = radius * 2.0 + 1.0;
|
||||
//div = blur_data.z;
|
||||
|
||||
for (u = -radius; u <= radius; u += 1.0)
|
||||
// Center pixel
|
||||
w = texture2D(tex_filter, vec2(0.0, 0.0)).r;
|
||||
px = FETCH_PIXEL(u / u_div);
|
||||
acc = px * w;
|
||||
div = w;
|
||||
|
||||
// Left & right
|
||||
for (u = 1; u <= count; u += 1.0)
|
||||
|
||||
#if 0
|
||||
div = 0.0;
|
||||
for (u = -count; u <= count; u += 1.0)
|
||||
{
|
||||
float w = (u + radius) / (diam - 1.0) * 6.0 - 3.0;
|
||||
w = (sin(w + M_PI_2) + 1.0) / 2.0;
|
||||
w = texture2D(tex_filter, vec2(abs(u) / count, 0.0)).r;
|
||||
|
||||
#ifndef SHD_FILTER_DIR_Y
|
||||
vec4 px = fetch_pixel(u / u_div, 0.0);
|
||||
px = fetch_pixel(u / u_div, 0.0);
|
||||
#else
|
||||
vec4 px = fetch_pixel(0.0, u / u_div);
|
||||
px = fetch_pixel(0.0, u / u_div);
|
||||
#endif
|
||||
|
||||
acc += px * w;
|
||||
div += w;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SHD_NOMUL
|
||||
gl_FragColor = (acc / div) * col;
|
||||
|
|
|
@ -81,7 +81,8 @@ varying vec2 displace_max;
|
|||
/* Gfx Filters: blur */
|
||||
#ifdef SHD_FILTER_BLUR
|
||||
attribute vec2 filter_data_0;
|
||||
varying vec2 blur_data;
|
||||
attribute vec2 filter_data_1;
|
||||
varying vec3 blur_data;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -165,6 +166,6 @@ void main()
|
|||
#endif
|
||||
|
||||
#ifdef SHD_FILTER_BLUR
|
||||
blur_data = filter_data_0;
|
||||
blur_data = vec3(filter_data_0.xy, filter_data_1.x);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -3022,20 +3022,20 @@ eng_image_surface_noscale_region_get(void *engdata EINA_UNUSED, void *image, int
|
|||
//------------------------------------------------//
|
||||
|
||||
static GL_Filter_Apply_Func
|
||||
_gfx_filter_func_get(Evas_Filter_Command *cmd)
|
||||
_gfx_filter_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
||||
{
|
||||
GL_Filter_Apply_Func funcptr = NULL;
|
||||
|
||||
switch (cmd->mode)
|
||||
{
|
||||
case EVAS_FILTER_MODE_BLEND: funcptr = gl_filter_blend_func_get(cmd); break;
|
||||
case EVAS_FILTER_MODE_BLUR: funcptr = gl_filter_blur_func_get(cmd); break;
|
||||
//case EVAS_FILTER_MODE_BUMP: funcptr = gl_filter_bump_func_get(cmd); break;
|
||||
case EVAS_FILTER_MODE_CURVE: funcptr = gl_filter_curve_func_get(cmd); break;
|
||||
case EVAS_FILTER_MODE_DISPLACE: funcptr = gl_filter_displace_func_get(cmd); break;
|
||||
case EVAS_FILTER_MODE_FILL: funcptr = gl_filter_fill_func_get(cmd); break;
|
||||
case EVAS_FILTER_MODE_MASK: funcptr = gl_filter_mask_func_get(cmd); break;
|
||||
//case EVAS_FILTER_MODE_TRANSFORM: funcptr = gl_filter_transform_func_get(cmd); break;
|
||||
case EVAS_FILTER_MODE_BLEND: funcptr = gl_filter_blend_func_get(re, cmd); break;
|
||||
case EVAS_FILTER_MODE_BLUR: funcptr = gl_filter_blur_func_get(re, cmd); break;
|
||||
//case EVAS_FILTER_MODE_BUMP: funcptr = gl_filter_bump_func_get(re, cmd); break;
|
||||
case EVAS_FILTER_MODE_CURVE: funcptr = gl_filter_curve_func_get(re, cmd); break;
|
||||
case EVAS_FILTER_MODE_DISPLACE: funcptr = gl_filter_displace_func_get(re, cmd); break;
|
||||
case EVAS_FILTER_MODE_FILL: funcptr = gl_filter_fill_func_get(re, cmd); break;
|
||||
case EVAS_FILTER_MODE_MASK: funcptr = gl_filter_mask_func_get(re, cmd); break;
|
||||
//case EVAS_FILTER_MODE_TRANSFORM: funcptr = gl_filter_transform_func_get(re, cmd); break;
|
||||
default: return NULL;
|
||||
}
|
||||
|
||||
|
@ -3047,7 +3047,7 @@ eng_gfx_filter_supports(void *data, Evas_Filter_Command *cmd)
|
|||
{
|
||||
Render_Engine_GL_Generic *re = data;
|
||||
|
||||
if (!_gfx_filter_func_get(cmd))
|
||||
if (!_gfx_filter_func_get(re, cmd))
|
||||
return pfunc.gfx_filter_supports(&re->software, cmd);
|
||||
|
||||
return EVAS_FILTER_SUPPORT_GL;
|
||||
|
@ -3059,7 +3059,7 @@ eng_gfx_filter_process(void *data, Evas_Filter_Command *cmd)
|
|||
Render_Engine_GL_Generic *re = data;
|
||||
GL_Filter_Apply_Func funcptr;
|
||||
|
||||
funcptr = _gfx_filter_func_get(cmd);
|
||||
funcptr = _gfx_filter_func_get(re, cmd);
|
||||
if (funcptr)
|
||||
return funcptr(re, cmd);
|
||||
else
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
extern int _evas_engine_GL_log_dom;
|
||||
|
||||
typedef Eina_Bool (* GL_Filter_Apply_Func) (Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_blend_func_get(Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_blur_func_get(Evas_Filter_Command *cmd);
|
||||
//GL_Filter_Apply_Func gl_filter_bump_func_get(Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_curve_func_get(Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_displace_func_get(Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_fill_func_get(Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_mask_func_get(Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_blend_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_blur_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
//GL_Filter_Apply_Func gl_filter_bump_func_get(Render_Engine_GL_Generic *reEvas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_curve_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_displace_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_fill_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_mask_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
//GL_Filter_Apply_Func gl_filter_transform_func_get(Evas_Filter_Command *cmd);
|
||||
|
||||
#undef DBG
|
||||
|
|
|
@ -201,7 +201,7 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
}
|
||||
|
||||
GL_Filter_Apply_Func
|
||||
gl_filter_blend_func_get(Evas_Filter_Command *cmd)
|
||||
gl_filter_blend_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);
|
||||
|
|
|
@ -1,5 +1,84 @@
|
|||
#include "gl_engine_filter.h"
|
||||
|
||||
// sqrt(2 * M_PI)
|
||||
#define SQRT_2_PI 2.506628274631
|
||||
|
||||
static inline double
|
||||
_radius_to_sigma(double radius)
|
||||
{
|
||||
// FIXME: This was supposed to be sqrt(r/3) ~ or something close
|
||||
return /*sqrt*/ (radius / 3.0);
|
||||
}
|
||||
|
||||
static inline double
|
||||
_gaussian_val(double a, double b, double x)
|
||||
{
|
||||
return a * exp(-(x*x/b));
|
||||
}
|
||||
|
||||
static void
|
||||
_gaussian_calc(double *values, int count, double radius)
|
||||
{
|
||||
// f(x) = a * exp(-(x^2 / b))
|
||||
// sigma is such that variance v = sigma^2
|
||||
// v is such that after 3 v the value is almost 0 (ressembles a radius)
|
||||
// a = 1 / (sigma * sqrt (2 * pi))
|
||||
// b = 2 * sigma^2
|
||||
|
||||
// FIXME: Some of this math doesn't fit right (values too small too fast)
|
||||
|
||||
double a, b, sigma;
|
||||
int k;
|
||||
|
||||
sigma = _radius_to_sigma(radius);
|
||||
a = 1.0 / (sigma * SQRT_2_PI);
|
||||
b = 2.0 * sigma * sigma;
|
||||
|
||||
for (k = 0; k <= count; k++)
|
||||
{
|
||||
values[k] = _gaussian_val(a, b, k);
|
||||
ERR("Gauss %d: %f", k, values[k]);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_gaussian_interpolate(GLfloat **weights, GLfloat **offsets, double radius)
|
||||
{
|
||||
int k, num, count;
|
||||
GLfloat *w, *o;
|
||||
double *values;
|
||||
|
||||
count = (int) ceil(radius);
|
||||
if (count & 0x1) count++;
|
||||
values = alloca((count + 1) * sizeof(*values));
|
||||
_gaussian_calc(values, count, radius);
|
||||
|
||||
num = (count / 2) + 1;
|
||||
*offsets = o = calloc(1, num * sizeof(*o));
|
||||
*weights = w = calloc(1, num * sizeof(*w));
|
||||
|
||||
// Center pixel's weight
|
||||
k = 0;
|
||||
o[k] = 0.0;
|
||||
w[k] = values[0];
|
||||
ERR("Interpolating weights %d: w %f o %f", k, w[k], o[k]);
|
||||
|
||||
// Left & right pixels' interpolated weights
|
||||
for (k = 1; k < num; k++)
|
||||
{
|
||||
double w1, w2;
|
||||
|
||||
w1 = values[(k - 1) * 2 + 1];
|
||||
w2 = values[(k - 1) * 2 + 2];
|
||||
w[k] = w1 + w2;
|
||||
if (EINA_DBL_EQ(w[k], 0.0)) continue;
|
||||
o[k] = (w2 / w[k]) + (k - 1.0) * 2.0;
|
||||
ERR("Interpolating weights %d: %f %f -> w %f o %f", k, w1, w2, w[k], o[k]);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
||||
{
|
||||
|
@ -8,7 +87,8 @@ _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;
|
||||
int nx, ny, nw, nh;
|
||||
int nx, ny, nw, nh, count = 0;
|
||||
GLfloat *weights, *offsets;
|
||||
|
||||
DEBUG_TIME_BEGIN();
|
||||
|
||||
|
@ -23,15 +103,6 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
|
||||
evas_gl_common_context_target_surface_set(gc, surface);
|
||||
|
||||
dc_save = gc->dc;
|
||||
gc->dc = evas_common_draw_context_new();
|
||||
evas_common_draw_context_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
|
||||
|
||||
if (cmd->input == cmd->output)
|
||||
gc->dc->render_op = EVAS_RENDER_COPY;
|
||||
else
|
||||
gc->dc->render_op = _gfx_to_evas_render_op(cmd->draw.rop);
|
||||
|
||||
if (cmd->blur.dx)
|
||||
{
|
||||
horiz = EINA_TRUE;
|
||||
|
@ -44,7 +115,8 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
}
|
||||
|
||||
DBG("blur %d @%p -> %d @%p (%.0fpx %s)",
|
||||
cmd->input->id, cmd->input->buffer, cmd->output->id, cmd->output->buffer,
|
||||
cmd->input->id, cmd->input->buffer,
|
||||
cmd->output->id, cmd->output->buffer,
|
||||
radius, horiz ? "X" : "Y");
|
||||
|
||||
sx = 0;
|
||||
|
@ -63,7 +135,21 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
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);
|
||||
dc_save = gc->dc;
|
||||
gc->dc = evas_common_draw_context_new();
|
||||
evas_common_draw_context_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
|
||||
|
||||
// FIXME: Don't render to same FBO as input! This is not supposed to work!
|
||||
if (cmd->input == cmd->output)
|
||||
gc->dc->render_op = EVAS_RENDER_COPY;
|
||||
else
|
||||
gc->dc->render_op = _gfx_to_evas_render_op(cmd->draw.rop);
|
||||
|
||||
count = _gaussian_interpolate(&weights, &offsets, radius);
|
||||
evas_gl_common_filter_blur_push(gc, image->tex, ssx, ssy, ssw, ssh, dx, dy, dw, dh,
|
||||
weights, offsets, count, horiz);
|
||||
free(weights);
|
||||
free(offsets);
|
||||
|
||||
evas_common_draw_context_free(gc->dc);
|
||||
gc->dc = dc_save;
|
||||
|
@ -77,11 +163,13 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
}
|
||||
|
||||
GL_Filter_Apply_Func
|
||||
gl_filter_blur_func_get(Evas_Filter_Command *cmd)
|
||||
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);
|
||||
|
||||
// 1D blurs only, radius != 0
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL((!cmd->blur.dx) ^ (!cmd->blur.dy), NULL);
|
||||
|
||||
return _gl_filter_blur;
|
||||
|
|
|
@ -56,7 +56,7 @@ _gl_filter_curve(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
}
|
||||
|
||||
GL_Filter_Apply_Func
|
||||
gl_filter_curve_func_get(Evas_Filter_Command *cmd)
|
||||
gl_filter_curve_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->input, NULL);
|
||||
|
|
|
@ -74,7 +74,7 @@ _gl_filter_displace(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
}
|
||||
|
||||
GL_Filter_Apply_Func
|
||||
gl_filter_displace_func_get(Evas_Filter_Command *cmd)
|
||||
gl_filter_displace_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->input, NULL);
|
||||
|
|
|
@ -63,7 +63,7 @@ _gl_filter_fill(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
}
|
||||
|
||||
GL_Filter_Apply_Func
|
||||
gl_filter_fill_func_get(Evas_Filter_Command *cmd)
|
||||
gl_filter_fill_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);
|
||||
|
|
|
@ -68,7 +68,7 @@ _gl_filter_mask(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
}
|
||||
|
||||
GL_Filter_Apply_Func
|
||||
gl_filter_mask_func_get(Evas_Filter_Command *cmd)
|
||||
gl_filter_mask_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->input, NULL);
|
||||
|
|
Loading…
Reference in New Issue