forked from enlightenment/efl
evas filters: Switch to uniforms in GL blur
This was a poor attempt at improving the performance but obviously the root cause isn't fixed (too many texel fetches). Uniform should (theoretically) work better than an attribute the for loop. Just a guess here. This also makes GL blur use a float value as radius, allowing future extension to non-integer blur radii, as well as using linear scaling as a fast blur approximation.
This commit is contained in:
parent
408115cef6
commit
06a7beec52
|
@ -660,8 +660,8 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
|
|||
int R, int G, int B, int A)
|
||||
{
|
||||
Evas_Filter_Command *cmd;
|
||||
Evas_Filter_Buffer *dx_in, *dx_out, *dy_in, *tmp = NULL;
|
||||
int dx, dy;
|
||||
Evas_Filter_Buffer *dx_in, *dx_out, *dy_in, *dy_out, *tmp = NULL;
|
||||
double dx, dy;
|
||||
|
||||
/* GL blur implementation:
|
||||
* - Create intermediate buffer T (variable size)
|
||||
|
@ -677,16 +677,18 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
|
|||
dx = rx;
|
||||
dy = ry;
|
||||
dx_in = in;
|
||||
dy_out = out;
|
||||
|
||||
#if 0
|
||||
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:
|
||||
* 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);
|
||||
|
@ -701,11 +703,17 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
|
|||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dx && dy)
|
||||
{
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, 0, 0, in->alpha_only, 1);
|
||||
tmp = evas_filter_temporary_buffer_get(ctx, dx_in->w, dx_in->h, in->alpha_only, 1);
|
||||
if (!tmp) goto fail;
|
||||
dy_in = dx_out = tmp;
|
||||
}
|
||||
|
@ -717,7 +725,7 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
|
|||
|
||||
if (dx)
|
||||
{
|
||||
XDBG("Add GL blur %d -> %d (%dx%d px)", dx_in->id, dx_out->id, dx, 0);
|
||||
XDBG("Add GL blur %d -> %d (%.2fx%.2f px)", dx_in->id, dx_out->id, dx, 0.0);
|
||||
cmd = _command_new(ctx, EVAS_FILTER_MODE_BLUR, dx_in, NULL, dx_out);
|
||||
if (!cmd) goto fail;
|
||||
cmd->blur.type = type;
|
||||
|
@ -727,14 +735,23 @@ evas_filter_command_blur_add_gl(Evas_Filter_Context *ctx,
|
|||
|
||||
if (dy)
|
||||
{
|
||||
XDBG("Add GL blur %d -> %d (%dx%d px)", dy_in->id, out->id, 0, dy);
|
||||
cmd = _command_new(ctx, EVAS_FILTER_MODE_BLUR, dy_in, NULL, out);
|
||||
XDBG("Add GL blur %d -> %d (%.2fx%.2f px)", dy_in->id, dy_out->id, 0.0, dy);
|
||||
cmd = _command_new(ctx, EVAS_FILTER_MODE_BLUR, dy_in, NULL, dy_out);
|
||||
if (!cmd) goto fail;
|
||||
cmd->blur.type = type;
|
||||
cmd->blur.dy = dy;
|
||||
cmd->blur.count = count;
|
||||
}
|
||||
|
||||
if (cmd->output != out)
|
||||
{
|
||||
XDBG("Add GL upscale %d (%dx%d) -> %d (%dx%d)",
|
||||
cmd->output->id, cmd->output->w, cmd->output->h, out->id, out->w, out->h);
|
||||
cmd = _command_new(ctx, EVAS_FILTER_MODE_BLEND, cmd->output, NULL, out);
|
||||
if (!cmd) goto fail;
|
||||
cmd->draw.fillmode = EVAS_FILTER_FILL_MODE_STRETCH_XY;
|
||||
}
|
||||
|
||||
cmd->draw.ox = ox;
|
||||
cmd->draw.oy = oy;
|
||||
DRAW_COLOR_SET(R, G, B, A);
|
||||
|
|
|
@ -182,7 +182,7 @@ struct _Evas_Filter_Command
|
|||
{
|
||||
struct
|
||||
{
|
||||
int dx, dy;
|
||||
float dx, dy;
|
||||
int count;
|
||||
Evas_Filter_Blur_Type type;
|
||||
Eina_Bool auto_count : 1; // If true, BOX blur will be smooth using
|
||||
|
|
|
@ -70,6 +70,7 @@ typedef struct _Evas_GL_Polygon Evas_GL_Polygon;
|
|||
typedef struct _Evas_GL_Polygon_Point Evas_GL_Polygon_Point;
|
||||
typedef struct _Evas_GL_Texture_Async_Preload Evas_GL_Texture_Async_Preload;
|
||||
typedef struct _Evas_GL_Image_Data_Map Evas_GL_Image_Data_Map;
|
||||
typedef struct _Evas_GL_Filter Evas_GL_Filter;
|
||||
|
||||
typedef Eina_Bool (*evas_gl_make_current_cb)(void *engine_data, void *doit);
|
||||
|
||||
|
@ -101,16 +102,34 @@ typedef Eina_Bool (*evas_gl_make_current_cb)(void *engine_data, void *doit);
|
|||
|
||||
#define PROGRAM_HITCOUNT_MAX 0x1000000
|
||||
|
||||
struct _Evas_GL_Filter
|
||||
{
|
||||
struct {
|
||||
GLint loc[3];
|
||||
Eina_Bool known_locations;
|
||||
} attribute;
|
||||
struct {
|
||||
GLint blur_count_loc;
|
||||
GLint blur_count_value;
|
||||
GLint blur_texlen_loc;
|
||||
GLfloat blur_texlen_value;
|
||||
GLint blur_div_loc;
|
||||
GLfloat blur_div_value;
|
||||
Eina_Bool known_locations;
|
||||
} uniform;
|
||||
struct {
|
||||
GLuint tex_ids[1];
|
||||
} texture;
|
||||
double blur_radius;
|
||||
};
|
||||
|
||||
struct _Evas_GL_Program
|
||||
{
|
||||
unsigned int flags, hitcount, tex_count;
|
||||
struct {
|
||||
GLuint mvp, rotation_id;
|
||||
} uniform;
|
||||
struct {
|
||||
GLint loc_filter_data[3];
|
||||
Eina_Bool known_locations;
|
||||
} attribute;
|
||||
Evas_GL_Filter *filter;
|
||||
GLuint prog;
|
||||
|
||||
Eina_Bool reset : 1;
|
||||
|
@ -652,7 +671,7 @@ void evas_gl_common_filter_displace_push(Evas_Engine_GL_Context *gc
|
|||
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, const double * const values, const double * const offsets, int count,
|
||||
double dx, double dy, double dw, double dh, const double * const values, const double * const offsets, int count, double radius,
|
||||
Eina_Bool horiz);
|
||||
|
||||
int evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
|
||||
|
|
|
@ -3143,16 +3143,19 @@ _filter_data_prepare(Evas_Engine_GL_Context *gc, int pn,
|
|||
Evas_GL_Program *prog, int count)
|
||||
{
|
||||
gc->pipe[pn].array.filter_data_count = count;
|
||||
gc->pipe[pn].array.filter_data = malloc(count * 2 * sizeof(GLfloat));
|
||||
if (count) gc->pipe[pn].array.filter_data = malloc(count * 2 * sizeof(GLfloat));
|
||||
else gc->pipe[pn].array.filter_data = NULL;
|
||||
|
||||
if (!prog->attribute.known_locations)
|
||||
if (!prog->filter) prog->filter = calloc(1, sizeof(*prog->filter));
|
||||
if (!prog->filter->attribute.known_locations)
|
||||
{
|
||||
prog->filter->attribute.known_locations = EINA_TRUE;
|
||||
for (int k = 0; k < count; k++)
|
||||
{
|
||||
char name[32];
|
||||
|
||||
sprintf(name, "filter_data_%d", k);
|
||||
prog->attribute.loc_filter_data[k] = glGetAttribLocation(prog->prog, name);
|
||||
prog->filter->attribute.loc[k] = glGetAttribLocation(prog->prog, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3434,21 +3437,21 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
|
|||
double dx, double dy, double dw, double dh,
|
||||
const double * const weights,
|
||||
const double * const offsets, int count,
|
||||
Eina_Bool horiz)
|
||||
double radius, Eina_Bool horiz)
|
||||
{
|
||||
double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4, pw, ph;
|
||||
GLfloat tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;
|
||||
GLfloat offsetx, offsety;
|
||||
int r, g, b, a, nomul = 0, pn;
|
||||
Evas_GL_Program *prog;
|
||||
GLfloat *filter_data;
|
||||
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_data;
|
||||
GLuint map_tex;
|
||||
double sum;
|
||||
|
||||
//shader_array_flush(gc);
|
||||
|
||||
r = R_VAL(&gc->dc->mul.col);
|
||||
g = G_VAL(&gc->dc->mul.col);
|
||||
b = B_VAL(&gc->dc->mul.col);
|
||||
|
@ -3521,30 +3524,50 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
|
|||
map_tex_data[k + count] = val;
|
||||
}
|
||||
|
||||
// Synchronous upload of Nx2 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);
|
||||
if (tex->gc->shared->info.unpack_row_length)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, sizeof(*map_tex_data));
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, count, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, map_tex_data);
|
||||
// Prepare attributes & uniforms
|
||||
_filter_data_prepare(gc, pn, prog, 0);
|
||||
if (!prog->filter->uniform.known_locations)
|
||||
{
|
||||
prog->filter->uniform.known_locations = EINA_TRUE;
|
||||
prog->filter->uniform.blur_count_loc = glGetUniformLocation(prog->prog, "blur_count");
|
||||
prog->filter->uniform.blur_texlen_loc = glGetUniformLocation(prog->prog, "blur_texlen");
|
||||
prog->filter->uniform.blur_div_loc = glGetUniformLocation(prog->prog, "blur_div");
|
||||
}
|
||||
|
||||
// Set curve properties (no need for filter_data)
|
||||
gc->pipe[pn].shader.filter.map_tex = map_tex;
|
||||
// Synchronous upload of Nx2 RGBA texture
|
||||
if (!EINA_DBL_EQ(prog->filter->blur_radius, radius))
|
||||
{
|
||||
prog->filter->blur_radius = radius;
|
||||
|
||||
if (!prog->filter->texture.tex_ids[0])
|
||||
glGenTextures(1, prog->filter->texture.tex_ids);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, prog->filter->texture.tex_ids[0]);
|
||||
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);
|
||||
if (tex->gc->shared->info.unpack_row_length)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, sizeof(*map_tex_data));
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, count, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, map_tex_data);
|
||||
}
|
||||
|
||||
//if (update_uniforms)
|
||||
{
|
||||
prog->filter->uniform.blur_count_value = count - 1;
|
||||
prog->filter->uniform.blur_texlen_value = horiz ? sw : sh;
|
||||
prog->filter->uniform.blur_div_value = sum;
|
||||
glUseProgram(prog->prog);
|
||||
glUniform1i(prog->filter->uniform.blur_count_loc, prog->filter->uniform.blur_count_value);
|
||||
glUniform1f(prog->filter->uniform.blur_texlen_loc, prog->filter->uniform.blur_texlen_value);
|
||||
glUniform1f(prog->filter->uniform.blur_div_loc, prog->filter->uniform.blur_div_value);
|
||||
}
|
||||
|
||||
// Set shader properties
|
||||
gc->pipe[pn].shader.filter.map_tex = prog->filter->texture.tex_ids[0];
|
||||
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] = count - 1.0;
|
||||
filter_data[1] = horiz ? sw : sh;
|
||||
filter_data[2] = sum;
|
||||
filter_data[3] = 0.0; // unused
|
||||
gc->pipe[pn].shader.filter.map_delete = EINA_FALSE;
|
||||
|
||||
pw = tex->pt->w;
|
||||
ph = tex->pt->h;
|
||||
|
@ -4241,7 +4264,7 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
|
|||
if (gc->pipe[i].array.filter_data)
|
||||
{
|
||||
for (int k = 0; k < gc->pipe[i].array.filter_data_count; k++)
|
||||
glVertexAttrib2fv(prog->attribute.loc_filter_data[k], &gc->pipe[i].array.filter_data[k * 2]);
|
||||
glVertexAttrib2fv(prog->filter->attribute.loc[k], &gc->pipe[i].array.filter_data[k * 2]);
|
||||
}
|
||||
|
||||
/* Gfx filters: texture (or data array as texture) */
|
||||
|
|
|
@ -400,6 +400,12 @@ save:
|
|||
static inline void
|
||||
_program_del(Evas_GL_Program *p)
|
||||
{
|
||||
if (p->filter)
|
||||
{
|
||||
if (p->filter->texture.tex_ids[0])
|
||||
glDeleteTextures(1, p->filter->texture.tex_ids);
|
||||
free(p->filter);
|
||||
}
|
||||
if (p->prog) glDeleteProgram(p->prog);
|
||||
free(p);
|
||||
}
|
||||
|
|
|
@ -93,7 +93,9 @@ static const char fragment_glsl[] =
|
|||
"#endif\n"
|
||||
"#ifdef SHD_FILTER_BLUR\n"
|
||||
"uniform sampler2D tex_filter;\n"
|
||||
"varying vec3 blur_data;\n"
|
||||
"uniform int blur_count;\n"
|
||||
"uniform float blur_texlen;\n"
|
||||
"uniform float blur_div;\n"
|
||||
"#endif\n"
|
||||
"// ----------------------------------------------------------------------------\n"
|
||||
"#ifndef SHD_FILTER_BLUR\n"
|
||||
|
@ -109,7 +111,7 @@ static const char fragment_glsl[] =
|
|||
"#endif // SHD_FILTER_BLUR\n"
|
||||
" vec4 c;\n"
|
||||
"#ifdef SHD_FILTER_DISPLACE\n"
|
||||
" vec2 dxy = texture2D(tex_filter, tex_c).rg * displace_vector;\n"
|
||||
" vec2 dxy = (texture2D(tex_filter, tex_c).rg - vec2(0.5, 0.5)) * displace_vector;\n"
|
||||
" float fa = texture2D(tex_filter, tex_c).a;\n"
|
||||
" coord = clamp(tex_c + dxy, displace_min, displace_max);\n"
|
||||
"#endif\n"
|
||||
|
@ -234,40 +236,40 @@ static const char fragment_glsl[] =
|
|||
"float weight_get(float u, float count, float index)\n"
|
||||
"{\n"
|
||||
" vec4 val = texture2D(tex_filter, vec2(u / count, index)).bgra;\n"
|
||||
" return val.a*255.0 + (val.r*255.0/256.0) + (val.g*255.0/256.0/256.0) + (val.b*255.0/256.0/256.0/256.0);\n"
|
||||
" return val.a * 255.0 + val.r + val.g / 256.0 + val.b / 65536.0;\n"
|
||||
"}\n"
|
||||
"float offset_get(float u, float count, float index)\n"
|
||||
"{\n"
|
||||
" // val.a is always 0 here ~ discard\n"
|
||||
" vec4 val = texture2D(tex_filter, vec2(u / count, index)).bgra;\n"
|
||||
" return (val.r*255.0/256.0) + (val.g*255.0/256.0/256.0) + (val.b*255.0/256.0/256.0/256.0);\n"
|
||||
" return val.r + val.g / 256.0 + val.b / 65536.0;\n"
|
||||
"}\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" float u, texlen, count, div;\n"
|
||||
" float weight, offset;\n"
|
||||
" float weight, offset, count;\n"
|
||||
" vec4 acc, px;\n"
|
||||
" count = blur_data.x;\n"
|
||||
" texlen = blur_data.y;\n"
|
||||
" div = blur_data.z;\n"
|
||||
" int k;\n"
|
||||
" count = float(blur_count);\n"
|
||||
" // Center pixel, offset is 0.0\n"
|
||||
" weight = weight_get(0.0, count, 0.0);\n"
|
||||
" px = FETCH_PIXEL(0.0);\n"
|
||||
" acc = px * weight;\n"
|
||||
" for (u = 1.0; u <= count; u += 1.0)\n"
|
||||
" // Left & right pixels\n"
|
||||
" for (k = 1; k <= blur_count; k++)\n"
|
||||
" {\n"
|
||||
" float u = float(k);\n"
|
||||
" weight = weight_get(u, count, 0.0);\n"
|
||||
" offset = offset_get(u, count, 1.0);\n"
|
||||
" // Left\n"
|
||||
" vec4 px1 = FETCH_PIXEL(-((offset + (2.0 * u) - 1.0)) / texlen);\n"
|
||||
" vec4 px1 = FETCH_PIXEL(-((offset + (2.0 * u) - 1.0)) / blur_texlen);\n"
|
||||
" // Right\n"
|
||||
" vec4 px2 = FETCH_PIXEL((offset + (2.0 * u) - 1.0) / texlen);\n"
|
||||
" vec4 px2 = FETCH_PIXEL((offset + (2.0 * u) - 1.0) / blur_texlen);\n"
|
||||
" acc += (px1 + px2) * weight;\n"
|
||||
" }\n"
|
||||
"#ifndef SHD_NOMUL\n"
|
||||
" gl_FragColor = (acc / div) * col;\n"
|
||||
" gl_FragColor = (acc / blur_div) * col;\n"
|
||||
"#else\n"
|
||||
" gl_FragColor = (acc / div);\n"
|
||||
" gl_FragColor = (acc / blur_div);\n"
|
||||
"#endif\n"
|
||||
"}\n"
|
||||
"#endif // SHD_FILTER_BLUR\n";
|
||||
|
@ -343,12 +345,6 @@ static const char vertex_glsl[] =
|
|||
"varying vec2 displace_min;\n"
|
||||
"varying vec2 displace_max;\n"
|
||||
"#endif\n"
|
||||
"/* Gfx Filters: blur */\n"
|
||||
"#ifdef SHD_FILTER_BLUR\n"
|
||||
"attribute vec2 filter_data_0;\n"
|
||||
"attribute vec2 filter_data_1;\n"
|
||||
"varying vec3 blur_data;\n"
|
||||
"#endif\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = mvp * vertex;\n"
|
||||
|
@ -417,8 +413,5 @@ static const char vertex_glsl[] =
|
|||
" displace_min = filter_data_1;\n"
|
||||
" displace_max = filter_data_2;\n"
|
||||
"#endif\n"
|
||||
"#ifdef SHD_FILTER_BLUR\n"
|
||||
" blur_data = vec3(filter_data_0.xy, filter_data_1.x);\n"
|
||||
"#endif\n"
|
||||
"}\n";
|
||||
|
||||
|
|
|
@ -90,7 +90,9 @@ uniform sampler2D tex_filter;
|
|||
|
||||
#ifdef SHD_FILTER_BLUR
|
||||
uniform sampler2D tex_filter;
|
||||
varying vec3 blur_data;
|
||||
uniform int blur_count;
|
||||
uniform float blur_texlen;
|
||||
uniform float blur_div;
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -254,49 +256,51 @@ vec4 fetch_pixel(float ox, float oy)
|
|||
float weight_get(float u, float count, float index)
|
||||
{
|
||||
vec4 val = texture2D(tex_filter, vec2(u / count, index)).bgra;
|
||||
return val.a*255.0 + (val.r*255.0/256.0) + (val.g*255.0/256.0/256.0) + (val.b*255.0/256.0/256.0/256.0);
|
||||
return val.a * 255.0 + val.r + val.g / 256.0 + val.b / 65536.0;
|
||||
}
|
||||
|
||||
float offset_get(float u, float count, float index)
|
||||
{
|
||||
// val.a is always 0 here ~ discard
|
||||
vec4 val = texture2D(tex_filter, vec2(u / count, index)).bgra;
|
||||
return (val.r*255.0/256.0) + (val.g*255.0/256.0/256.0) + (val.b*255.0/256.0/256.0/256.0);
|
||||
return val.r + val.g / 256.0 + val.b / 65536.0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float u, texlen, count, div;
|
||||
float weight, offset;
|
||||
float weight, offset, count;
|
||||
vec4 acc, px;
|
||||
int k;
|
||||
|
||||
count = float(blur_count);
|
||||
|
||||
count = blur_data.x;
|
||||
texlen = blur_data.y;
|
||||
div = blur_data.z;
|
||||
|
||||
// Center pixel, offset is 0.0
|
||||
weight = weight_get(0.0, count, 0.0);
|
||||
px = FETCH_PIXEL(0.0);
|
||||
acc = px * weight;
|
||||
|
||||
for (u = 1.0; u <= count; u += 1.0)
|
||||
// Left & right pixels
|
||||
for (k = 1; k <= blur_count; k++)
|
||||
{
|
||||
float u = float(k);
|
||||
|
||||
weight = weight_get(u, count, 0.0);
|
||||
offset = offset_get(u, count, 1.0);
|
||||
|
||||
// Left
|
||||
vec4 px1 = FETCH_PIXEL(-((offset + (2.0 * u) - 1.0)) / texlen);
|
||||
vec4 px1 = FETCH_PIXEL(-((offset + (2.0 * u) - 1.0)) / blur_texlen);
|
||||
|
||||
// Right
|
||||
vec4 px2 = FETCH_PIXEL((offset + (2.0 * u) - 1.0) / texlen);
|
||||
vec4 px2 = FETCH_PIXEL((offset + (2.0 * u) - 1.0) / blur_texlen);
|
||||
|
||||
acc += (px1 + px2) * weight;
|
||||
}
|
||||
|
||||
#ifndef SHD_NOMUL
|
||||
gl_FragColor = (acc / div) * col;
|
||||
gl_FragColor = (acc / blur_div) * col;
|
||||
#else
|
||||
gl_FragColor = (acc / div);
|
||||
gl_FragColor = (acc / blur_div);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -78,13 +78,6 @@ varying vec2 displace_min;
|
|||
varying vec2 displace_max;
|
||||
#endif
|
||||
|
||||
/* Gfx Filters: blur */
|
||||
#ifdef SHD_FILTER_BLUR
|
||||
attribute vec2 filter_data_0;
|
||||
attribute vec2 filter_data_1;
|
||||
varying vec3 blur_data;
|
||||
#endif
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -164,8 +157,4 @@ void main()
|
|||
displace_min = filter_data_1;
|
||||
displace_max = filter_data_2;
|
||||
#endif
|
||||
|
||||
#ifdef SHD_FILTER_BLUR
|
||||
blur_data = vec3(filter_data_0.xy, filter_data_1.x);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ _gl_filter_blur(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
|
||||
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);
|
||||
weights, offsets, count, radius, horiz);
|
||||
free(weights);
|
||||
free(offsets);
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ _box_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
|
|||
int radius, regions, w, h;
|
||||
void *src, *dst;
|
||||
|
||||
radius = abs(vert ? cmd->blur.dy : cmd->blur.dx);
|
||||
radius = abs(vert ? (int) cmd->blur.dy : (int) cmd->blur.dx);
|
||||
src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
|
||||
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
|
||||
if (!src || !dst) goto unmap;
|
||||
|
@ -386,7 +386,7 @@ _gaussian_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
|
|||
void *src, *dst;
|
||||
int *weights;
|
||||
|
||||
radius = abs(vert ? cmd->blur.dy : cmd->blur.dx);
|
||||
radius = abs(vert ? (int) cmd->blur.dy : (int) cmd->blur.dx);
|
||||
src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
|
||||
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
|
||||
w = cmd->input->w;
|
||||
|
|
Loading…
Reference in New Issue