From ac8812665b8659fe0c9132ef1ccdc8e8a058fc03 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 24 Jan 2017 15:39:29 +0900 Subject: [PATCH] evas filters: Implement fill filter in pure GL Now that one was trivial. Could also be done with glClear and glScissor instead, but the rectangle infrastructure works well enough. --- src/Makefile_Evas.am | 1 + src/lib/evas/filters/evas_filter_parser.c | 1 + .../evas/engines/gl_generic/evas_engine.c | 2 +- .../gl_generic/filters/gl_engine_filter.h | 2 +- .../gl_generic/filters/gl_filter_fill.c | 72 +++++++++++++++++++ 5 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 src/modules/evas/engines/gl_generic/filters/gl_filter_fill.c diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index aa2da76028..5bac2786d9 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -844,6 +844,7 @@ modules/evas/engines/gl_generic/evas_ector_gl_buffer.c \ modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c \ modules/evas/engines/gl_generic/filters/gl_engine_filter.h \ modules/evas/engines/gl_generic/filters/gl_filter_blend.c \ +modules/evas/engines/gl_generic/filters/gl_filter_fill.c \ modules/evas/engines/gl_generic/filters/gl_filter_mask.c \ $(NULL) diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c index 143d065bc1..9bebd19f3c 100644 --- a/src/lib/evas/filters/evas_filter_parser.c +++ b/src/lib/evas/filters/evas_filter_parser.c @@ -3210,6 +3210,7 @@ _instr2cmd_fill(Evas_Filter_Context *ctx, cmd->draw.clip.t = t; cmd->draw.clip.b = b; cmd->draw.clip_mode_lrtb = EINA_TRUE; + cmd->draw.rop = EFL_GFX_RENDER_OP_COPY; return cmd; } diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 6c840f65d7..f43cebd35b 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -3033,7 +3033,7 @@ _gfx_filter_func_get(Evas_Filter_Command *cmd) //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_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; default: return NULL; 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 6b6e45b2f1..80daf91dfb 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 @@ -14,7 +14,7 @@ GL_Filter_Apply_Func gl_filter_blend_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_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_transform_func_get(Evas_Filter_Command *cmd); diff --git a/src/modules/evas/engines/gl_generic/filters/gl_filter_fill.c b/src/modules/evas/engines/gl_generic/filters/gl_filter_fill.c new file mode 100644 index 0000000000..a15198d176 --- /dev/null +++ b/src/modules/evas/engines/gl_generic/filters/gl_filter_fill.c @@ -0,0 +1,72 @@ +#include "gl_engine_filter.h" + +static Eina_Bool +_gl_filter_fill(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd) +{ + Evas_Filter_Buffer *fb = cmd->output; + Evas_Engine_GL_Context *gc; + Evas_GL_Image *surface; + RGBA_Draw_Context *dc_save; + int x = MAX(0, cmd->draw.clip.x); + int y = MAX(0, cmd->draw.clip.y); + int w, h; + + DEBUG_TIME_BEGIN(); + + if (!cmd->draw.clip_mode_lrtb) + { + if (cmd->draw.clip.w) + w = MIN(cmd->draw.clip.w, fb->w - x); + else + w = fb->w - x; + if (cmd->draw.clip.h) + h = MIN(cmd->draw.clip.h, fb->h - y); + else + h = fb->h - y; + } + else + { + x = MAX(0, cmd->draw.clip.l); + y = MAX(0, cmd->draw.clip.t); + w = CLAMP(0, fb->w - x - cmd->draw.clip.r, fb->w - x); + h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y); + } + + surface = evas_ector_buffer_render_image_get(fb->buffer); + EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE); + + DBG("fill rgba(%d,%d,%d,%d) %d,%d %dx%d) -> %d @%p", + cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A, x, y, w, h, + fb->id, fb->buffer); + + re->window_use(re->software.ob); + gc = re->window_gl_context_get(re->software.ob); + evas_gl_common_context_target_surface_set(gc, surface); + + dc_save = gc->dc; + gc->dc = evas_common_draw_context_new(); + evas_common_draw_context_clip_clip(gc->dc, x, y, w, h); + evas_common_draw_context_set_render_op(gc->dc, _gfx_to_evas_render_op(cmd->draw.rop)); + + evas_gl_common_context_rectangle_push(gc, x, y, w, h, + cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A, + NULL, 0, 0, 0, 0, EINA_FALSE, EINA_FALSE); + + evas_common_draw_context_free(gc->dc); + gc->dc = dc_save; + + evas_ector_buffer_engine_image_release(fb->buffer, surface); + + DEBUG_TIME_END(); + + return EINA_TRUE; +} + +GL_Filter_Apply_Func +gl_filter_fill_func_get(Evas_Filter_Command *cmd) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL); + + return _gl_filter_fill; +}