summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShinwoo Kim <cinoo.kim@samsung.com>2019-09-27 15:30:36 +0900
committerShinwoo Kim <cinoo.kim@samsung.com>2019-09-27 15:35:03 +0900
commit081e318d90646c8b9c4e750c08224223120cb3bc (patch)
tree923dd2780934cb975e1a453a066ebb64a6c4ea4e
parent29beda7f4f365425656e3340ea2da592d00fb52c (diff)
evas filter: Implement grayscale filter in pure GL
Summary: Initial version implementing grayscale filter in pure GL. This patch needs a logt of love as 5bce712 did. Grasyscale formula: https://www.tutorialspoint.com/dip/grayscale_to_rgb_conversion.htm Test Plan: 1. Create filter_example with following . efl_gfx_filter_program_set(image, "grayscale ()", "grayscale"); 2. Run. ELM_ACCEL=gl ./filter_example Reviewers: Hermet, jsuya Subscribers: ali.alzyod, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9858
-rw-r--r--src/lib/evas/filters/evas_filter.c22
-rw-r--r--src/lib/evas/filters/evas_filter_parser.c39
-rw-r--r--src/lib/evas/include/evas_filter.h12
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h4
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_context.c92
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_shader.c7
-rw-r--r--src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x3
-rw-r--r--src/modules/evas/engines/gl_common/shader/fragment.glsl4
-rw-r--r--src/modules/evas/engines/gl_generic/evas_engine.c1
-rw-r--r--src/modules/evas/engines/gl_generic/filters/gl_engine_filter.h1
-rw-r--r--src/modules/evas/engines/gl_generic/filters/gl_filter_grayscale.c53
-rw-r--r--src/modules/evas/engines/gl_generic/meson.build1
12 files changed, 237 insertions, 2 deletions
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 332f6dbb27..36c9c5d2b1 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -1597,6 +1597,28 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx,
1597 return cmd; 1597 return cmd;
1598} 1598}
1599 1599
1600Evas_Filter_Command *
1601evas_filter_command_grayscale_add(Evas_Filter_Context *ctx,
1602 void *draw_context EINA_UNUSED,
1603 int inbuf, int outbuf)
1604{
1605 Evas_Filter_Command *cmd;
1606 Evas_Filter_Buffer *in, *out;
1607
1608 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
1609
1610 in = _filter_buffer_get(ctx, inbuf);
1611 EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
1612
1613 out = _filter_buffer_get(ctx, outbuf);
1614 EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
1615
1616 cmd = _command_new(ctx, EVAS_FILTER_MODE_GRAYSCALE, in, NULL, out);
1617 EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
1618
1619 return cmd;
1620}
1621
1600void 1622void
1601evas_filter_context_obscured_region_set(Evas_Filter_Context *ctx, Eina_Rectangle rect) 1623evas_filter_context_obscured_region_set(Evas_Filter_Context *ctx, Eina_Rectangle rect)
1602{ 1624{
diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c
index 72308d2a9e..6d89a3518f 100644
--- a/src/lib/evas/filters/evas_filter_parser.c
+++ b/src/lib/evas/filters/evas_filter_parser.c
@@ -1789,6 +1789,26 @@ _transform_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction
1789 return EINA_TRUE; 1789 return EINA_TRUE;
1790} 1790}
1791 1791
1792/**
1793 @page evasfiltersref
1794 Remove color information from buffer's contents and leave only grayscale
1795 TODO: write down more information
1796 */
1797
1798static Eina_Bool
1799_grayscale_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr)
1800{
1801 EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
1802 EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
1803 EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "grayscale"), EINA_FALSE);
1804
1805 instr->type = EVAS_FILTER_MODE_GRAYSCALE;
1806 _instruction_param_seq_add(instr, "src", VT_BUFFER, _buffer_get(pgm, "input"));
1807 _instruction_param_seq_add(instr, "dst", VT_BUFFER, _buffer_get(pgm, "output"));
1808
1809 return EINA_TRUE;
1810}
1811
1792static int 1812static int
1793_padding_set_padding_update(Evas_Filter_Program *pgm, 1813_padding_set_padding_update(Evas_Filter_Program *pgm,
1794 Evas_Filter_Instruction *instr, 1814 Evas_Filter_Instruction *instr,
@@ -2249,6 +2269,7 @@ LUA_GENERIC_FUNCTION(grow)
2249LUA_GENERIC_FUNCTION(mask) 2269LUA_GENERIC_FUNCTION(mask)
2250LUA_GENERIC_FUNCTION(padding_set) 2270LUA_GENERIC_FUNCTION(padding_set)
2251LUA_GENERIC_FUNCTION(transform) 2271LUA_GENERIC_FUNCTION(transform)
2272LUA_GENERIC_FUNCTION(grayscale)
2252 2273
2253static const luaL_Reg _lua_buffer_metamethods[] = { 2274static const luaL_Reg _lua_buffer_metamethods[] = {
2254 { "__call", _lua_buffer_new }, 2275 { "__call", _lua_buffer_new },
@@ -2485,6 +2506,7 @@ _lua_state_create(Evas_Filter_Program *pgm)
2485 PUSH_LUA_FUNCTION(mask) 2506 PUSH_LUA_FUNCTION(mask)
2486 PUSH_LUA_FUNCTION(padding_set) 2507 PUSH_LUA_FUNCTION(padding_set)
2487 PUSH_LUA_FUNCTION(transform) 2508 PUSH_LUA_FUNCTION(transform)
2509 PUSH_LUA_FUNCTION(grayscale)
2488 2510
2489 for (unsigned k = 0; k < (sizeof(fill_modes) / sizeof(fill_modes[0])); k++) 2511 for (unsigned k = 0; k < (sizeof(fill_modes) / sizeof(fill_modes[0])); k++)
2490 { 2512 {
@@ -3403,6 +3425,20 @@ _instr2cmd_transform(Evas_Filter_Context *ctx,
3403 return evas_filter_command_transform_add(ctx, dc, src->cid, dst->cid, flags, ox, oy); 3425 return evas_filter_command_transform_add(ctx, dc, src->cid, dst->cid, flags, ox, oy);
3404} 3426}
3405 3427
3428static Evas_Filter_Command *
3429_instr2cmd_grayscale(Evas_Filter_Context *ctx,
3430 Evas_Filter_Instruction *instr, void *dc)
3431{
3432 Buffer *src, *dst;
3433
3434 src = _instruction_param_getbuf(instr, "src", NULL);
3435 dst = _instruction_param_getbuf(instr, "dst", NULL);
3436 INSTR_PARAM_CHECK(src);
3437 INSTR_PARAM_CHECK(dst);
3438
3439 return evas_filter_command_grayscale_add(ctx, dc, src->cid, dst->cid);
3440}
3441
3406static Eina_Bool 3442static Eina_Bool
3407_command_from_instruction(Evas_Filter_Context *ctx, 3443_command_from_instruction(Evas_Filter_Context *ctx,
3408 Evas_Filter_Instruction *instr, void *dc) 3444 Evas_Filter_Instruction *instr, void *dc)
@@ -3439,6 +3475,9 @@ _command_from_instruction(Evas_Filter_Context *ctx,
3439 case EVAS_FILTER_MODE_TRANSFORM: 3475 case EVAS_FILTER_MODE_TRANSFORM:
3440 instr2cmd = _instr2cmd_transform; 3476 instr2cmd = _instr2cmd_transform;
3441 break; 3477 break;
3478 case EVAS_FILTER_MODE_GRAYSCALE:
3479 instr2cmd = _instr2cmd_grayscale;
3480 break;
3442 case EVAS_FILTER_MODE_PADDING_SET: 3481 case EVAS_FILTER_MODE_PADDING_SET:
3443 case EVAS_FILTER_MODE_BUFFER: 3482 case EVAS_FILTER_MODE_BUFFER:
3444 return EINA_TRUE; 3483 return EINA_TRUE;
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h
index ffbe797a6d..8dab0a9a34 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -69,6 +69,7 @@ enum _Evas_Filter_Mode
69 EVAS_FILTER_MODE_BUMP, /**< Apply bump mapping (light effect) */ 69 EVAS_FILTER_MODE_BUMP, /**< Apply bump mapping (light effect) */
70 EVAS_FILTER_MODE_TRANSFORM, /**< Apply a simple geometrical transformation */ 70 EVAS_FILTER_MODE_TRANSFORM, /**< Apply a simple geometrical transformation */
71 EVAS_FILTER_MODE_PADDING_SET, /**< Special padding_set instruction to force a specific padding value */ 71 EVAS_FILTER_MODE_PADDING_SET, /**< Special padding_set instruction to force a specific padding value */
72 EVAS_FILTER_MODE_GRAYSCALE, /**< Leave only grayscale information */
72 EVAS_FILTER_MODE_LAST 73 EVAS_FILTER_MODE_LAST
73}; 74};
74 75
@@ -306,6 +307,17 @@ Evas_Filter_Command *evas_filter_command_bump_map_add(Evas_Filter_Context *c
306 */ 307 */
307Evas_Filter_Command *evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags, int ox, int oy); 308Evas_Filter_Command *evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags, int ox, int oy);
308 309
310/**
311 * @brief Remove color information from the buffer
312 * @param ctx Current filter chain
313 * @param draw_context Current Evas draw context (ignored)
314 * @param inbuf Input buffer (Alpha or RGBA)
315 * @param outbuf Output buffer (Alpha or RGBA), same size as inbuf
316 * @return Filter command or NULL in case of error
317 * @internal
318 */
319Evas_Filter_Command *evas_filter_command_grayscale_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf);
320
309/* Simple binding between a filter object and its sources */ 321/* Simple binding between a filter object and its sources */
310struct _Evas_Filter_Proxy_Binding 322struct _Evas_Filter_Proxy_Binding
311{ 323{
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 2c74423f26..b2cf74bee5 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 {
265 SHD_FILTER_DISPLACE, 265 SHD_FILTER_DISPLACE,
266 SHD_FILTER_CURVE, 266 SHD_FILTER_CURVE,
267 SHD_FILTER_BLUR_X, 267 SHD_FILTER_BLUR_X,
268 SHD_FILTER_BLUR_Y 268 SHD_FILTER_BLUR_Y,
269 SHD_FILTER_GRAYSCALE
269}; 270};
270 271
271#define ARRAY_BUFFER_USE 500 272#define ARRAY_BUFFER_USE 500
@@ -680,6 +681,7 @@ void evas_gl_common_filter_curve_push(Evas_Engine_GL_Context *gc, E
680void evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, double sx, double sy, double sw, double sh, 681void evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, double sx, double sy, double sw, double sh,
681 double dx, double dy, double dw, double dh, const double * const values, const double * const offsets, int count, double radius, 682 double dx, double dy, double dw, double dh, const double * const values, const double * const offsets, int count, double radius,
682 Eina_Bool horiz, Eina_Bool alphaonly); 683 Eina_Bool horiz, Eina_Bool alphaonly);
684void evas_gl_common_filter_grayscale_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, int x, int y, int w, int h);
683 685
684int evas_gl_common_shader_program_init(Evas_GL_Shared *shared); 686int evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
685void evas_gl_common_shader_program_shutdown(Evas_GL_Shared *shared); 687void evas_gl_common_shader_program_shutdown(Evas_GL_Shared *shared);
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 bf7e5c1524..9178d3f6b8 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -3679,6 +3679,98 @@ evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc,
3679 PUSH_6_COLORS(pn, r, g, b, a); 3679 PUSH_6_COLORS(pn, r, g, b, a);
3680} 3680}
3681 3681
3682void
3683evas_gl_common_filter_grayscale_push(Evas_Engine_GL_Context *gc,
3684 Evas_GL_Texture *tex,
3685 int x, int y, int w, int h)
3686{
3687 double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4, pw, ph;
3688 GLfloat tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;
3689 GLfloat offsetx, offsety;
3690 int r, g, b, a, nomul = 0, pn;
3691 Evas_GL_Program *prog;
3692 Eina_Bool blend = EINA_TRUE;
3693 Eina_Bool smooth = EINA_TRUE;
3694 Shader_Type type = SHD_FILTER_GRAYSCALE;
3695
3696 r = R_VAL(&gc->dc->mul.col);
3697 g = G_VAL(&gc->dc->mul.col);
3698 b = B_VAL(&gc->dc->mul.col);
3699 a = A_VAL(&gc->dc->mul.col);
3700 if (gc->dc->render_op == EVAS_RENDER_COPY)
3701 blend = EINA_FALSE;
3702
3703 prog = evas_gl_common_shader_program_get(gc, type, NULL, 0, r, g, b, a,
3704 w, h, w, h, smooth, tex, EINA_FALSE,
3705 NULL, EINA_FALSE, EINA_FALSE, 0, 0,
3706 EINA_FALSE, NULL, &nomul, NULL);
3707
3708 _filter_data_flush(gc, prog);
3709 EINA_SAFETY_ON_NULL_RETURN(prog);
3710
3711 pn = _evas_gl_common_context_push(type, gc, tex, NULL, prog,
3712 x, y, w, h, blend, smooth,
3713 0, 0, 0, 0, 0, EINA_FALSE);
3714
3715 gc->pipe[pn].region.type = type;
3716 gc->pipe[pn].shader.prog = prog;
3717 gc->pipe[pn].shader.cur_tex = tex->pt->texture;
3718 gc->pipe[pn].shader.cur_texm = 0;
3719 gc->pipe[pn].shader.tex_target = GL_TEXTURE_2D;
3720 gc->pipe[pn].shader.smooth = smooth;
3721 gc->pipe[pn].shader.mask_smooth = 0;
3722 gc->pipe[pn].shader.blend = blend;
3723 gc->pipe[pn].shader.render_op = gc->dc->render_op;
3724 gc->pipe[pn].shader.clip = 0;
3725 gc->pipe[pn].shader.cx = 0;
3726 gc->pipe[pn].shader.cy = 0;
3727 gc->pipe[pn].shader.cw = 0;
3728 gc->pipe[pn].shader.ch = 0;
3729 gc->pipe[pn].array.line = 0;
3730 gc->pipe[pn].array.use_vertex = 1;
3731 gc->pipe[pn].array.use_color = !nomul;
3732 gc->pipe[pn].array.use_texuv = 1;
3733 gc->pipe[pn].array.use_texuv2 = 0;
3734 gc->pipe[pn].array.use_texuv3 = 0;
3735 gc->pipe[pn].array.use_texsam = 0;
3736 gc->pipe[pn].array.use_mask = 0;
3737 gc->pipe[pn].array.use_masksam = 0;
3738
3739 pipe_region_expand(gc, pn, x, y, w, h);
3740 PIPE_GROW(gc, pn, 6);
3741
3742 _filter_data_alloc(gc, pn, 0);
3743
3744 pw = tex->pt->w;
3745 ph = tex->pt->h;
3746
3747 ox1 = x;
3748 oy1 = y;
3749 ox2 = x + w;
3750 oy2 = y;
3751 ox3 = x + w;
3752 oy3 = y + h;
3753 ox4 = x;
3754 oy4 = y + h;
3755
3756 offsetx = tex->x;
3757 offsety = tex->y;
3758
3759 tx1 = ((double)(offsetx) + ox1) / pw;
3760 ty1 = ((double)(offsety) + oy1) / ph;
3761 tx2 = ((double)(offsetx) + ox2) / pw;
3762 ty2 = ((double)(offsety) + oy2) / ph;
3763 tx3 = ((double)(offsetx) + ox3) / pw;
3764 ty3 = ((double)(offsety) + oy3) / ph;
3765 tx4 = ((double)(offsetx) + ox4) / pw;
3766 ty4 = ((double)(offsety) + oy4) / ph;
3767
3768 PUSH_6_VERTICES(pn, x, y, w, h);
3769 PUSH_6_QUAD(pn, tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);
3770
3771 if (!nomul)
3772 PUSH_6_COLORS(pn, r, g, b, a);
3773}
3682// ---------------------------------------------------------------------------- 3774// ----------------------------------------------------------------------------
3683 3775
3684EAPI void 3776EAPI 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 a4dd632896..7c338674ec 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_shader.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c
@@ -45,8 +45,9 @@ typedef enum {
45 SHADER_FLAG_FILTER_BLUR = (1 << 23), 45 SHADER_FLAG_FILTER_BLUR = (1 << 23),
46 SHADER_FLAG_FILTER_DIR_Y = (1 << 24), 46 SHADER_FLAG_FILTER_DIR_Y = (1 << 24),
47 SHADER_FLAG_FILTER_ALPHA_ONLY = (1 << 25), 47 SHADER_FLAG_FILTER_ALPHA_ONLY = (1 << 25),
48 SHADER_FLAG_FILTER_GRAYSCALE = (1 << 26),
48} Shader_Flag; 49} Shader_Flag;
49#define SHADER_FLAG_COUNT 26 50#define SHADER_FLAG_COUNT 27
50 51
51static const char *_shader_flags[SHADER_FLAG_COUNT] = { 52static const char *_shader_flags[SHADER_FLAG_COUNT] = {
52 "TEX", 53 "TEX",
@@ -75,6 +76,7 @@ static const char *_shader_flags[SHADER_FLAG_COUNT] = {
75 "FILTER_BLUR", 76 "FILTER_BLUR",
76 "FILTER_DIR_Y", 77 "FILTER_DIR_Y",
77 "ALPHA_ONLY", 78 "ALPHA_ONLY",
79 "FILTER_GRAYSCALE",
78}; 80};
79 81
80static Eina_Bool compiler_released = EINA_FALSE; 82static Eina_Bool compiler_released = EINA_FALSE;
@@ -824,6 +826,9 @@ evas_gl_common_shader_flags_get(Evas_GL_Shared *shared, Shader_Type type,
824 flags |= SHADER_FLAG_FILTER_BLUR; 826 flags |= SHADER_FLAG_FILTER_BLUR;
825 flags |= SHADER_FLAG_FILTER_DIR_Y; 827 flags |= SHADER_FLAG_FILTER_DIR_Y;
826 break; 828 break;
829 case SHD_FILTER_GRAYSCALE:
830 flags |= SHADER_FLAG_FILTER_GRAYSCALE;
831 break;
827 default: 832 default:
828 CRI("Impossible shader type."); 833 CRI("Impossible shader type.");
829 return 0; 834 return 0;
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 2b071f2316..73ca4bef11 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
@@ -214,6 +214,9 @@ static const char fragment_glsl[] =
214 "#ifdef SHD_ALPHA_ONLY\n" 214 "#ifdef SHD_ALPHA_ONLY\n"
215 " c = vec4(c.a, c.a, c.a, c.a);\n" 215 " c = vec4(c.a, c.a, c.a, c.a);\n"
216 "#endif\n" 216 "#endif\n"
217 "#ifdef SHD_FILTER_GRAYSCALE\n"
218 " c.rgb = 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;\n"
219 "#endif\n"
217 "#ifndef SHD_FILTER_BLUR\n" 220 "#ifndef SHD_FILTER_BLUR\n"
218 " gl_FragColor =\n" 221 " gl_FragColor =\n"
219 " c\n" 222 " c\n"
diff --git a/src/modules/evas/engines/gl_common/shader/fragment.glsl b/src/modules/evas/engines/gl_common/shader/fragment.glsl
index 89f306062a..39fccf1119 100644
--- a/src/modules/evas/engines/gl_common/shader/fragment.glsl
+++ b/src/modules/evas/engines/gl_common/shader/fragment.glsl
@@ -230,6 +230,10 @@ vec4 fetch_pixel(float ox, float oy)
230 c = vec4(c.a, c.a, c.a, c.a); 230 c = vec4(c.a, c.a, c.a, c.a);
231#endif 231#endif
232 232
233#ifdef SHD_FILTER_GRAYSCALE
234 c.rgb = 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
235#endif
236
233#ifndef SHD_FILTER_BLUR 237#ifndef SHD_FILTER_BLUR
234 238
235 gl_FragColor = 239 gl_FragColor =
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c
index 4b0a6c735b..3428cf5620 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -3127,6 +3127,7 @@ _gfx_filter_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
3127 case EVAS_FILTER_MODE_FILL: funcptr = gl_filter_fill_func_get(re, cmd); break; 3127 case EVAS_FILTER_MODE_FILL: funcptr = gl_filter_fill_func_get(re, cmd); break;
3128 case EVAS_FILTER_MODE_MASK: funcptr = gl_filter_mask_func_get(re, cmd); break; 3128 case EVAS_FILTER_MODE_MASK: funcptr = gl_filter_mask_func_get(re, cmd); break;
3129 //case EVAS_FILTER_MODE_TRANSFORM: funcptr = gl_filter_transform_func_get(re, cmd); break; 3129 //case EVAS_FILTER_MODE_TRANSFORM: funcptr = gl_filter_transform_func_get(re, cmd); break;
3130 case EVAS_FILTER_MODE_GRAYSCALE: funcptr = gl_filter_grayscale_func_get(re, cmd); break;
3130 default: return NULL; 3131 default: return NULL;
3131 } 3132 }
3132 3133
diff --git a/src/modules/evas/engines/gl_generic/filters/gl_engine_filter.h b/src/modules/evas/engines/gl_generic/filters/gl_engine_filter.h
index 9cb59d1969..b1045d019e 100644
--- a/src/modules/evas/engines/gl_generic/filters/gl_engine_filter.h
+++ b/src/modules/evas/engines/gl_generic/filters/gl_engine_filter.h
@@ -17,6 +17,7 @@ GL_Filter_Apply_Func gl_filter_displace_func_get(Render_Engine_GL_Generic *re, E
17GL_Filter_Apply_Func gl_filter_fill_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd); 17GL_Filter_Apply_Func gl_filter_fill_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
18GL_Filter_Apply_Func gl_filter_mask_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd); 18GL_Filter_Apply_Func gl_filter_mask_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
19//GL_Filter_Apply_Func gl_filter_transform_func_get(Evas_Filter_Command *cmd); 19//GL_Filter_Apply_Func gl_filter_transform_func_get(Evas_Filter_Command *cmd);
20GL_Filter_Apply_Func gl_filter_grayscale_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
20 21
21#undef DBG 22#undef DBG
22#undef INF 23#undef INF
diff --git a/src/modules/evas/engines/gl_generic/filters/gl_filter_grayscale.c b/src/modules/evas/engines/gl_generic/filters/gl_filter_grayscale.c
new file mode 100644
index 0000000000..3e8ef1e5e0
--- /dev/null
+++ b/src/modules/evas/engines/gl_generic/filters/gl_filter_grayscale.c
@@ -0,0 +1,53 @@
1#include "gl_engine_filter.h"
2
3static Eina_Bool
4_gl_filter_grayscale(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
5{
6 Evas_Engine_GL_Context *gc;
7 Evas_GL_Image *image, *surface;
8 RGBA_Draw_Context *dc_save;
9 int w, h;
10
11 w = cmd->input->w;
12 h = cmd->input->h;
13 EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
14 EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
15
16 image = evas_ector_buffer_drawable_image_get(cmd->input->buffer);
17 EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
18
19 surface = evas_ector_buffer_render_image_get(cmd->output->buffer);
20 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
21
22 gc = gl_generic_context_find(re, 1);
23 evas_gl_common_context_target_surface_set(gc, surface);
24
25 dc_save = gc->dc;
26 gc->dc = evas_common_draw_context_new();
27 evas_common_draw_context_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
28
29 if (cmd->input == cmd->output)
30 gc->dc->render_op = EVAS_RENDER_COPY;
31 else
32 gc->dc->render_op = _gfx_to_evas_render_op(cmd->draw.rop);
33
34 evas_gl_common_filter_grayscale_push(gc, image->tex, 0, 0, w, h);
35
36 evas_common_draw_context_free(gc->dc);
37 gc->dc = dc_save;
38
39 evas_ector_buffer_engine_image_release(cmd->input->buffer, image);
40 evas_ector_buffer_engine_image_release(cmd->output->buffer, surface);
41
42 return EINA_TRUE;
43}
44
45GL_Filter_Apply_Func
46gl_filter_grayscale_func_get(Render_Engine_GL_Generic *re EINA_UNUSED, Evas_Filter_Command *cmd)
47{
48 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
49 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
50 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
51
52 return _gl_filter_grayscale;
53}
diff --git a/src/modules/evas/engines/gl_generic/meson.build b/src/modules/evas/engines/gl_generic/meson.build
index d18e032f7a..86e5c8fedd 100644
--- a/src/modules/evas/engines/gl_generic/meson.build
+++ b/src/modules/evas/engines/gl_generic/meson.build
@@ -12,6 +12,7 @@ engine_src = files([
12 join_paths('filters','gl_filter_displace.c'), 12 join_paths('filters','gl_filter_displace.c'),
13 join_paths('filters','gl_filter_fill.c'), 13 join_paths('filters','gl_filter_fill.c'),
14 join_paths('filters','gl_filter_mask.c'), 14 join_paths('filters','gl_filter_mask.c'),
15 join_paths('filters','gl_filter_grayscale.c'),
15]) 16])
16common_engine_src = [ 17common_engine_src = [
17 'evas_gl_private.h', 18 'evas_gl_private.h',