aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules/evas
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-01-24 14:23:03 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-04-14 11:26:43 +0900
commit3d2f1a3d9b04d4067ebe6008d2662c46ec694d7b (patch)
treeadcdba47ffe0813684dc6379d1328102736adc67 /src/modules/evas
parentevas filters: Fix blur logic and GL buffer handling (diff)
downloadefl-3d2f1a3d9b04d4067ebe6008d2662c46ec694d7b.tar.gz
evas filters: Implement mask filter in pure GL
This reuses the existing mask infrastructure, but adds a color flag to use the whole RGBA range, rather than just the Alpha channel. Filters are still very slow (glReadPixels and non-optimized use of GL buffers...), but this is progress :)
Diffstat (limited to 'src/modules/evas')
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_common.h37
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_context.c49
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_font.c12
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_image.c117
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_line.c4
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_polygon.c8
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_rectangle.c10
-rw-r--r--src/modules/evas/engines/gl_common/evas_gl_shader.c38
-rw-r--r--src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x25
-rw-r--r--src/modules/evas/engines/gl_common/shader/fragment.glsl25
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c24
-rw-r--r--src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c30
-rw-r--r--src/modules/evas/engines/gl_generic/evas_engine.c83
-rw-r--r--src/modules/evas/engines/gl_generic/filters/gl_engine_filter.h14
-rw-r--r--src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c13
-rw-r--r--src/modules/evas/engines/gl_generic/filters/gl_filter_mask.c83
16 files changed, 387 insertions, 185 deletions
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 74d456e008..537361ca45 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_common.h
+++ b/src/modules/evas/engines/gl_common/evas_gl_common.h
@@ -556,58 +556,67 @@ void evas_gl_common_context_target_surface_set(Evas_Engine_GL_Conte
void evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
int x1, int y1, int x2, int y2,
int clip, int cx, int cy, int cw, int ch,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a);
void evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
int x, int y, int w, int h,
int r, int g, int b, int a,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth);
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color);
void evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool tex_only);
void evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a);
void evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_yuv_709_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth);
void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
@@ -615,7 +624,8 @@ void evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *g
int npoints,
RGBA_Map_Point *p,
int clip, int cx, int cy, int cw, int ch,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth,
Eina_Bool tex_only,
@@ -632,7 +642,7 @@ Evas_GL_Program *evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
int sw, int sh, int w, int h, Eina_Bool smooth,
Evas_GL_Texture *tex, Eina_Bool tex_only,
Evas_GL_Texture *mtex, Eina_Bool mask_smooth,
- int mw, int mh,
+ Eina_Bool mask_color, int mw, int mh,
Shader_Sampling *psam, int *pnomul,
Shader_Sampling *pmasksam);
void evas_gl_common_shader_textures_bind(Evas_GL_Program *p);
@@ -688,8 +698,9 @@ void evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x,
void evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
void evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int npoints, RGBA_Map_Point *p, int smooth, int level);
void evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth);
-Evas_GL_Image *evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
-Evas_GL_Image *evas_gl_common_image_surface_detach(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
+Evas_GL_Image *evas_gl_common_image_surface_update(Evas_GL_Image *im);
+Evas_GL_Image *evas_gl_common_image_surface_detach(Evas_GL_Image *im);
+Evas_GL_Image *evas_gl_common_image_virtual_scaled_get(Evas_GL_Image *scaled, Evas_GL_Image *image, int dst_w, int dst_h, Eina_Bool smooth);
void *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg);
void evas_gl_font_texture_free(void *);
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 b0ddb5e0ba..df6af106f8 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_context.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_context.c
@@ -1889,7 +1889,8 @@ void
evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
int x1, int y1, int x2, int y2,
int clip, int cx, int cy, int cw, int ch,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a)
{
Eina_Bool blend = EINA_FALSE;
@@ -1907,7 +1908,7 @@ evas_gl_common_context_line_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_LINE, NULL, 0, r, g, b, a,
0, 0, 0, 0, EINA_FALSE, NULL, EINA_FALSE,
- mtex, mask_smooth, mw, mh, NULL, NULL, &masksam);
+ mtex, mask_smooth, mask_color, mw, mh, NULL, NULL, &masksam);
pn = _evas_gl_common_context_push(SHD_LINE,
gc, NULL, mtex,
@@ -1958,7 +1959,7 @@ evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
int r, int g, int b, int a,
Evas_GL_Texture *mtex,
int mx, int my, int mw, int mh,
- Eina_Bool mask_smooth)
+ Eina_Bool mask_smooth, Eina_Bool mask_color)
{
Eina_Bool blend = EINA_FALSE;
Shader_Sampling masksam = SHD_SAM11;
@@ -1971,7 +1972,7 @@ evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_RECT, NULL, 0, r, g, b, a,
0, 0, 0, 0, EINA_FALSE, NULL, EINA_FALSE,
- mtex, mask_smooth, mw, mh, NULL, NULL, &masksam);
+ mtex, mask_smooth, mask_color, mw, mh, NULL, NULL, &masksam);
pn = _evas_gl_common_context_push(SHD_RECT,
@@ -2130,7 +2131,8 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool tex_only)
{
@@ -2167,7 +2169,7 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, shd_in, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, tex_only,
- mtex, mask_smooth, mw, mh,
+ mtex, mask_smooth, mask_color, mw, mh,
&sam, &nomul, &masksam);
if (tex->ptt)
@@ -2378,7 +2380,8 @@ evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a)
{
GLfloat tx1, tx2, ty1, ty2;
@@ -2388,7 +2391,7 @@ evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_FONT, NULL, 0, r, g, b, a,
sw, sh, w, h, EINA_FALSE, tex, EINA_FALSE,
- mtex, mask_smooth, mw, mh,
+ mtex, mask_smooth, mask_color, mw, mh,
NULL, NULL, &masksam);
pn = _evas_gl_common_context_push(SHD_FONT,
@@ -2452,7 +2455,8 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth)
{
@@ -2467,7 +2471,7 @@ evas_gl_common_context_yuv_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_YUV, NULL, 0, r, g, b, a,
w, h, w, h, smooth, tex, 0,
- mtex, mask_smooth, mw, mh,
+ mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_YUV,
@@ -2531,7 +2535,8 @@ evas_gl_common_context_yuv_709_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth)
{
@@ -2546,7 +2551,7 @@ evas_gl_common_context_yuv_709_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_YUV_709, NULL, 0, r, g, b, a,
w, h, w, h, smooth, tex, 0,
- mtex, mask_smooth, mw, mh,
+ mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_YUV_709,
@@ -2610,7 +2615,8 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth)
{
@@ -2625,7 +2631,7 @@ evas_gl_common_context_yuy2_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_YUY2, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, 0,
- mtex, mask_smooth, mw, mh,
+ mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_YUY2,
@@ -2687,7 +2693,8 @@ evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
Evas_GL_Texture *tex,
double sx, double sy, double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth)
{
@@ -2702,7 +2709,7 @@ evas_gl_common_context_nv12_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_NV12, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, 0,
- mtex, mask_smooth, mw, mh,
+ mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_NV12,
@@ -2767,7 +2774,8 @@ evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
double sx, double sy,
double sw, double sh,
int x, int y, int w, int h,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth)
@@ -2786,7 +2794,7 @@ evas_gl_common_context_rgb_a_pair_push(Evas_Engine_GL_Context *gc,
prog = evas_gl_common_shader_program_get(gc, SHD_RGB_A_PAIR, NULL, 0, r, g, b, a,
sw, sh, w, h, smooth, tex, 0,
- mtex, mask_smooth, mw, mh,
+ mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
pn = _evas_gl_common_context_push(SHD_RGB_A_PAIR,
@@ -2851,7 +2859,8 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
int npoints,
RGBA_Map_Point *p,
int clip, int cx, int cy, int cw, int ch,
- Evas_GL_Texture *mtex, int mx, int my, int mw, int mh, Eina_Bool mask_smooth,
+ Evas_GL_Texture *mtex, int mx, int my, int mw, int mh,
+ Eina_Bool mask_smooth, Eina_Bool mask_color,
int r, int g, int b, int a,
Eina_Bool smooth, Eina_Bool tex_only,
Evas_Colorspace cspace)
@@ -2916,7 +2925,7 @@ evas_gl_common_context_image_map_push(Evas_Engine_GL_Context *gc,
}
prog = evas_gl_common_shader_program_get(gc, type, p, npoints, r, g, b, a,
w, h, w, h, smooth, tex, tex_only,
- mtex, mask_smooth, mw, mh,
+ mtex, mask_smooth, mask_color, mw, mh,
NULL, &nomul, &masksam);
x = w = (p[0].x >> FP);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_font.c b/src/modules/evas/engines/gl_common/evas_gl_font.c
index 5a5fdeb730..1b3e35b607 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_font.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_font.c
@@ -71,6 +71,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
int sx, sy, sw, sh;
double mx = 0.0, my = 0.0, mw = 0.0, mh = 0.0;
Eina_Bool mask_smooth = EINA_FALSE;
+ Eina_Bool mask_color = EINA_FALSE;
if (dc != gc->dc) return;
tex = fg->ext_dat;
@@ -94,6 +95,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
mw = mask->w;
mh = mask->h;
mask_smooth = mask->scaled.smooth;
+ mask_color = gc->dc->clip.mask_color;
}
else mtex = NULL;
}
@@ -117,7 +119,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
0.0, 0.0, 0.0, 0.0,
// sx, sy, sw, sh,
x, y, tex->w, tex->h,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a);
return;
}
@@ -128,7 +130,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
evas_gl_common_context_font_push(gc, tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a);
}
else
@@ -137,7 +139,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
0.0, 0.0, 0.0, 0.0,
// sx, sy, sw, sh,
x, y, tex->w, tex->h,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a);
}
return;
@@ -167,7 +169,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
0.0, 0.0, 0.0, 0.0,
// sx, sy, sw, sh,
x, y, tex->w, tex->h,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a);
continue;
}
@@ -178,7 +180,7 @@ evas_gl_font_texture_draw(void *context, void *surface EINA_UNUSED, void *draw_c
evas_gl_common_context_font_push(gc, tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a);
}
evas_common_draw_context_cutouts_free(_evas_gl_common_cutout_rects);
diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c
index e42203151a..4a89ff62d8 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_image.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_image.c
@@ -1042,13 +1042,14 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
}
Evas_GL_Image *
-evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
+evas_gl_common_image_surface_update(Evas_GL_Image *im)
{
+ Evas_Engine_GL_Context *gc;
Evas_GL_Image *glim = NULL;
Eina_Bool alpha;
int w, h;
- if (!gc || !im || !im->im || !im->im->image.data)
+ if (!im || !im->gc || !im->im || !im->im->image.data)
goto fail;
if (im->im->cache_entry.space == EFL_GFX_COLORSPACE_ARGB8888)
@@ -1057,6 +1058,7 @@ evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *i
alpha = EINA_TRUE;
else goto fail;
+ gc = im->gc;
w = im->im->cache_entry.w;
h = im->im->cache_entry.h;
glim = evas_gl_common_image_surface_new(gc, w, h, EINA_TRUE, EINA_FALSE);
@@ -1101,7 +1103,7 @@ fail:
}
Evas_GL_Image *
-evas_gl_common_image_surface_detach(Evas_Engine_GL_Context *gc EINA_UNUSED, Evas_GL_Image *im)
+evas_gl_common_image_surface_detach(Evas_GL_Image *im)
{
if (!im || !im->im) return im;
@@ -1111,6 +1113,85 @@ evas_gl_common_image_surface_detach(Evas_Engine_GL_Context *gc EINA_UNUSED, Evas
return im;
}
+Evas_GL_Image *
+evas_gl_common_image_virtual_scaled_get(Evas_GL_Image *scaled, Evas_GL_Image *image,
+ int dst_w, int dst_h, Eina_Bool smooth)
+{
+ Evas_GL_Image *dst = scaled, *newdst;
+ Evas_GL_Image *src = image;
+ Evas_Engine_GL_Context *gc;
+ Eina_Bool reffed = EINA_FALSE;
+
+ if (!src) return NULL;
+
+ // masking will work only with single texture images
+ switch (src->cs.space)
+ {
+ case EVAS_COLORSPACE_AGRY88:
+ case EVAS_COLORSPACE_ARGB8888:
+ case EVAS_COLORSPACE_GRY8:
+ case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
+ case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
+ case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
+ case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
+ case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
+ case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
+ break;
+ default:
+ DBG("cspace %d can't be used for masking's fast path", src->cs.space);
+ return NULL;
+ }
+
+ gc = src->gc;
+ if (dst && (dst->scaled.origin == src) &&
+ (dst->w == dst_w) && (dst->h == dst_h))
+ return dst;
+
+ evas_gl_common_image_update(gc, src);
+ if (!src->tex)
+ {
+ ERR("No source texture.");
+ return NULL;
+ }
+
+ newdst = calloc(1, sizeof(Evas_GL_Image));
+ if (!newdst) return NULL;
+
+ if (dst)
+ {
+ if (dst->scaled.origin == src)
+ {
+ if (dst->references == 1)
+ {
+ dst->w = dst_w;
+ dst->h = dst_h;
+ dst->scaled.smooth = smooth;
+ free(newdst);
+ return dst;
+ }
+ src->references++;
+ reffed = EINA_TRUE;
+ }
+ evas_gl_common_image_free(dst);
+ }
+
+ newdst->references = 1;
+ newdst->gc = gc;
+ newdst->cs.space = src->cs.space;
+ newdst->alpha = src->alpha;
+ newdst->w = dst_w;
+ newdst->h = dst_h;
+ newdst->tex = src->tex;
+ newdst->tex->references++;
+ newdst->tex_only = 1;
+
+ if (!reffed) src->references++;
+ newdst->scaled.origin = src;
+ newdst->scaled.smooth = smooth;
+
+ return newdst;
+}
+
void
evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
int npoints, RGBA_Map_Point *p, int smooth, int level EINA_UNUSED)
@@ -1120,6 +1201,7 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
Eina_Bool mask_smooth = EINA_FALSE;
Evas_GL_Image *mask = dc->clip.mask;
Evas_GL_Texture *mtex = NULL;
+ Eina_Bool mask_color = EINA_FALSE;
int r, g, b, a;
int c, cx, cy, cw, ch;
@@ -1155,13 +1237,14 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
mw = mask->w;
mh = mask->h;
mask_smooth = mask->scaled.smooth;
+ mask_color = dc->clip.mask_color;
}
else mtex = NULL;
}
evas_gl_common_context_image_map_push(gc, im->tex, npoints, p,
c, cx, cy, cw, ch,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a, smooth, im->tex_only,
im->cs.space);
}
@@ -1182,6 +1265,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
double ssx, ssy, ssw, ssh;
Evas_GL_Texture *mtex = NULL;
Eina_Bool mask_smooth = EINA_FALSE;
+ Eina_Bool mask_color = EINA_FALSE;
int nx, ny, nw, nh;
nx = dx; ny = dy; nw = dw; nh = dh;
@@ -1202,6 +1286,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
mw = mask->w;
mh = mask->h;
mask_smooth = mask->scaled.smooth;
+ mask_color = gc->dc->clip.mask_color;
}
else mtex = NULL;
}
@@ -1213,7 +1298,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else if (yuv_709)
@@ -1221,7 +1306,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else if (yuy2)
@@ -1229,7 +1314,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else if (nv12)
@@ -1237,7 +1322,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else if (rgb_a_pair)
@@ -1245,7 +1330,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else
@@ -1253,7 +1338,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
sx, sy, sw, sh,
dx, dy, dw, dh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth, im->tex_only);
return;
@@ -1269,7 +1354,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else if (yuv_709)
@@ -1277,7 +1362,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else if (yuy2)
@@ -1285,7 +1370,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else if (nv12)
@@ -1293,7 +1378,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else if (rgb_a_pair)
@@ -1301,7 +1386,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth);
else
@@ -1309,7 +1394,7 @@ _evas_gl_common_image_push(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
im->tex,
ssx, ssy, ssw, ssh,
nx, ny, nw, nh,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a,
smooth, im->tex_only);
}
diff --git a/src/modules/evas/engines/gl_common/evas_gl_line.c b/src/modules/evas/engines/gl_common/evas_gl_line.c
index 1b7def125f..892be20260 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_line.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_line.c
@@ -12,6 +12,7 @@ evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, int y1, int x2, int
const int OFFSET_HACK_ARM = 2;
Evas_GL_Texture *mtex = NULL;
Eina_Bool mask_smooth = EINA_FALSE;
+ Eina_Bool mask_color = EINA_FALSE;
int mx = 0, my = 0, mw = 0, mh = 0;
Evas_GL_Image *mask;
@@ -48,6 +49,7 @@ evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, int y1, int x2, int
mw = mask->w;
mh = mask->h;
mask_smooth = mask->scaled.smooth;
+ mask_color = gc->dc->clip.mask_color;
}
else mtex = NULL;
}
@@ -97,6 +99,6 @@ evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, int y1, int x2, int
evas_gl_common_context_line_push(gc, x1, y1, x2, y2,
c, cx, cy, cw, ch,
- mtex, mx, my, mw, mh, mask_smooth,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color,
r, g, b, a);
}
diff --git a/src/modules/evas/engines/gl_common/evas_gl_polygon.c b/src/modules/evas/engines/gl_common/evas_gl_polygon.c
index 4552d663a3..839dc61339 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_polygon.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_polygon.c
@@ -133,6 +133,7 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
int x = 0, y = 0, w = 0, h = 0;
Evas_GL_Texture *mtex = NULL;
Eina_Bool mask_smooth = EINA_FALSE;
+ Eina_Bool mask_color = EINA_FALSE;
int mx = 0, my = 0, mw = 0, mh = 0;
Evas_GL_Image *mask;
@@ -165,6 +166,7 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
mw = mask->w;
mh = mask->h;
mask_smooth = mask->scaled.smooth;
+ mask_color = gc->dc->clip.mask_color;
}
else mtex = NULL;
}
@@ -291,7 +293,8 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
h = 1;
evas_gl_common_context_rectangle_push(gc, x, y, w, h,
cr, cg, cb, ca,
- mtex, mx, my, mw, mh, mask_smooth);
+ mtex, mx, my, mw, mh,
+ mask_smooth, mask_color);
}
}
else
@@ -315,7 +318,8 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
if ((w > 0) && (h > 0))
evas_gl_common_context_rectangle_push(gc, x, y, w, h,
cr, cg, cb, ca,
- mtex, mx, my, mw, mh, mask_smooth);
+ mtex, mx, my, mw, mh,
+ mask_smooth, mask_color);
}
}
}
diff --git a/src/modules/evas/engines/gl_common/evas_gl_rectangle.c b/src/modules/evas/engines/gl_common/evas_gl_rectangle.c
index 04bdc1ae48..a188467b58 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_rectangle.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_rectangle.c
@@ -8,6 +8,7 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
int mx = 0, my = 0, mw = 0, mh = 0;
Eina_Bool mask_smooth = EINA_FALSE;
Evas_GL_Image *mask = gc->dc->clip.mask;
+ Eina_Bool mask_color = EINA_FALSE;
Evas_GL_Texture *mtex = NULL;
if ((w <= 0) || (h <= 0)) return;
@@ -42,6 +43,7 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
mw = mask->w;
mh = mask->h;
mask_smooth = mask->scaled.smooth;
+ mask_color = gc->dc->clip.mask_color;
}
else mtex = NULL;
}
@@ -50,7 +52,9 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
((gc->shared->info.tune.cutout.max > 0) &&
(gc->dc->cutout.active > gc->shared->info.tune.cutout.max)))
{
- evas_gl_common_context_rectangle_push(gc, x, y, w, h, cr, cg, cb, ca, mtex, mx, my, mw, mh, mask_smooth);
+ evas_gl_common_context_rectangle_push
+ (gc, x, y, w, h, cr, cg, cb, ca,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color);
}
else
{
@@ -64,7 +68,9 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
r = _evas_gl_common_cutout_rects->rects + i;
if ((r->w > 0) && (r->h > 0))
{
- evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca, mtex, mx, my, mw, mh, mask_smooth);
+ evas_gl_common_context_rectangle_push
+ (gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca,
+ mtex, mx, my, mw, mh, mask_smooth, mask_color);
}
}
evas_common_draw_context_cutouts_free(_evas_gl_common_cutout_rects);
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 cc22155dce..f4a8e6980c 100644
--- a/src/modules/evas/engines/gl_common/evas_gl_shader.c
+++ b/src/modules/evas/engines/gl_common/evas_gl_shader.c
@@ -28,19 +28,20 @@ typedef enum {
SHADER_FLAG_MASKSAM12 = (1 << (SHADER_FLAG_MASKSAM_BITSHIFT + 0)),
SHADER_FLAG_MASKSAM21 = (1 << (SHADER_FLAG_MASKSAM_BITSHIFT + 1)),
SHADER_FLAG_MASKSAM22 = (1 << (SHADER_FLAG_MASKSAM_BITSHIFT + 2)),
- SHADER_FLAG_IMG = (1 << 9),
- SHADER_FLAG_BIGENDIAN = (1 << 10),
- SHADER_FLAG_YUV = (1 << 11),
- SHADER_FLAG_YUY2 = (1 << 12),
- SHADER_FLAG_NV12 = (1 << 13),
- SHADER_FLAG_YUV_709 = (1 << 14),
- SHADER_FLAG_EXTERNAL = (1 << 15),
- SHADER_FLAG_AFILL = (1 << 16),
- SHADER_FLAG_NOMUL = (1 << 17),
- SHADER_FLAG_ALPHA = (1 << 18),
- SHADER_FLAG_RGB_A_PAIR = (1 << 19),
+ SHADER_FLAG_MASK_COLOR = (1 << 9),
+ SHADER_FLAG_IMG = (1 << 10),
+ SHADER_FLAG_BIGENDIAN = (1 << 11),
+ SHADER_FLAG_YUV = (1 << 12),
+ SHADER_FLAG_YUY2 = (1 << 13),
+ SHADER_FLAG_NV12 = (1 << 14),
+ SHADER_FLAG_YUV_709 = (1 << 15),
+ SHADER_FLAG_EXTERNAL = (1 << 16),
+ SHADER_FLAG_AFILL = (1 << 17),
+ SHADER_FLAG_NOMUL = (1 << 18),
+ SHADER_FLAG_ALPHA = (1 << 19),
+ SHADER_FLAG_RGB_A_PAIR = (1 << 20),
} Shader_Flag;
-#define SHADER_FLAG_COUNT 20
+#define SHADER_FLAG_COUNT 21
static const char *_shader_flags[SHADER_FLAG_COUNT] = {
"TEX",
@@ -52,6 +53,7 @@ static const char *_shader_flags[SHADER_FLAG_COUNT] = {
"MASKSAM12",
"MASKSAM21",
"MASKSAM22",
+ "MASK_COLOR",
"IMG",
"BIGENDIAN",
"YUV",
@@ -707,7 +709,7 @@ evas_gl_common_shader_flags_get(Evas_GL_Shared *shared, Shader_Type type,
int sw, int sh, int w, int h, Eina_Bool smooth,
Evas_GL_Texture *tex, Eina_Bool tex_only,
Evas_GL_Texture *mtex, Eina_Bool mask_smooth,
- int mw, int mh,
+ Eina_Bool mask_color, int mw, int mh,
Shader_Sampling *psam, int *pnomul, Shader_Sampling *pmasksam)
{
Shader_Sampling sam = SHD_SAM11, masksam = SHD_SAM11;
@@ -740,6 +742,12 @@ evas_gl_common_shader_flags_get(Evas_GL_Shared *shared, Shader_Type type,
flags |= (1 << (SHADER_FLAG_MASKSAM_BITSHIFT + masksam - 1));
}
+ // mask color mode
+ if (mtex && mask_color)
+ {
+ flags |= SHADER_FLAG_MASK_COLOR;
+ }
+
switch (type)
{
case SHD_RECT:
@@ -899,7 +907,7 @@ evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
int sw, int sh, int w, int h, Eina_Bool smooth,
Evas_GL_Texture *tex, Eina_Bool tex_only,
Evas_GL_Texture *mtex, Eina_Bool mask_smooth,
- int mw, int mh,
+ Eina_Bool mask_color, int mw, int mh,
Shader_Sampling *psam, int *pnomul,
Shader_Sampling *pmasksam)
{
@@ -908,7 +916,7 @@ evas_gl_common_shader_program_get(Evas_Engine_GL_Context *gc,
flags = evas_gl_common_shader_flags_get(gc->shared, type, map_points, npoints, r, g, b, a,
sw, sh, w, h, smooth, tex, tex_only,
- mtex, mask_smooth, mw, mh,
+ mtex, mask_smooth, mask_color, mw, mh,
psam, pnomul, pmasksam);
p = eina_hash_find(gc->shared->shaders_hash, &flags);
if (!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 195ed19bb6..8cae1481b5 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
@@ -131,19 +131,38 @@ static const char fragment_glsl[] =
" c = vec4(1, 1, 1, 1);\n"
"#endif\n"
"#ifdef SHD_MASK\n"
+ "# ifndef SHD_MASK_COLOR\n"
+ " // Classic mask: alpha only\n"
" float ma;\n"
- "# if defined(SHD_MASKSAM12) || defined(SHD_MASKSAM21)\n"
+ "# if defined(SHD_MASKSAM12) || defined(SHD_MASKSAM21)\n"
" float ma00 = texture2D(texm, tex_m + masktex_s[0]).a;\n"
" float ma01 = texture2D(texm, tex_m + masktex_s[1]).a;\n"
" ma = (ma00 + ma01) / maskdiv_s;\n"
- "# elif defined(SHD_MASKSAM22)\n"
+ "# elif defined(SHD_MASKSAM22)\n"
" float ma00 = texture2D(texm, tex_m + masktex_s[0]).a;\n"
" float ma01 = texture2D(texm, tex_m + masktex_s[1]).a;\n"
" float ma10 = texture2D(texm, tex_m + masktex_s[2]).a;\n"
" float ma11 = texture2D(texm, tex_m + masktex_s[3]).a;\n"
" ma = (ma00 + ma01 + ma10 + ma11) / maskdiv_s;\n"
- "# else\n"
+ "# else\n"
" ma = texture2D(texm, tex_m).a;\n"
+ "# endif\n"
+ "# else\n"
+ " // Full color mask\n"
+ " vec4 ma;\n"
+ "# if defined(SHD_MASKSAM12) || defined(SHD_MASKSAM21)\n"
+ " vec4 ma00 = texture2D(texm, tex_m + masktex_s[0]);\n"
+ " vec4 ma01 = texture2D(texm, tex_m + masktex_s[1]);\n"
+ " ma = (ma00 + ma01) / maskdiv_s;\n"
+ "# elif defined(SHD_MASKSAM22)\n"
+ " vec4 ma00 = texture2D(texm, tex_m + masktex_s[0]);\n"
+ " vec4 ma01 = texture2D(texm, tex_m + masktex_s[1]);\n"
+ " vec4 ma10 = texture2D(texm, tex_m + masktex_s[2]);\n"
+ " vec4 ma11 = texture2D(texm, tex_m + masktex_s[3]);\n"
+ " ma = (ma00 + ma01 + ma10 + ma11) / maskdiv_s;\n"
+ "# else\n"
+ " ma = texture2D(texm, tex_m);\n"
+ "# endif\n"
"# endif\n"
"#endif\n"
"#ifdef SHD_AFILL\n"
diff --git a/src/modules/evas/engines/gl_common/shader/fragment.glsl b/src/modules/evas/engines/gl_common/shader/fragment.glsl
index c20dc71fc7..7de74a2e80 100644
--- a/src/modules/evas/engines/gl_common/shader/fragment.glsl
+++ b/src/modules/evas/engines/gl_common/shader/fragment.glsl
@@ -132,19 +132,38 @@ void main()
#endif
#ifdef SHD_MASK
+# ifndef SHD_MASK_COLOR
+ // Classic mask: alpha only
float ma;
-# if defined(SHD_MASKSAM12) || defined(SHD_MASKSAM21)
+# if defined(SHD_MASKSAM12) || defined(SHD_MASKSAM21)
float ma00 = texture2D(texm, tex_m + masktex_s[0]).a;
float ma01 = texture2D(texm, tex_m + masktex_s[1]).a;
ma = (ma00 + ma01) / maskdiv_s;
-# elif defined(SHD_MASKSAM22)
+# elif defined(SHD_MASKSAM22)
float ma00 = texture2D(texm, tex_m + masktex_s[0]).a;
float ma01 = texture2D(texm, tex_m + masktex_s[1]).a;
float ma10 = texture2D(texm, tex_m + masktex_s[2]).a;
float ma11 = texture2D(texm, tex_m + masktex_s[3]).a;
ma = (ma00 + ma01 + ma10 + ma11) / maskdiv_s;
-# else
+# else
ma = texture2D(texm, tex_m).a;
+# endif
+# else
+ // Full color mask
+ vec4 ma;
+# if defined(SHD_MASKSAM12) || defined(SHD_MASKSAM21)
+ vec4 ma00 = texture2D(texm, tex_m + masktex_s[0]);
+ vec4 ma01 = texture2D(texm, tex_m + masktex_s[1]);
+ ma = (ma00 + ma01) / maskdiv_s;
+# elif defined(SHD_MASKSAM22)
+ vec4 ma00 = texture2D(texm, tex_m + masktex_s[0]);
+ vec4 ma01 = texture2D(texm, tex_m + masktex_s[1]);
+ vec4 ma10 = texture2D(texm, tex_m + masktex_s[2]);
+ vec4 ma11 = texture2D(texm, tex_m + masktex_s[3]);
+ ma = (ma00 + ma01 + ma10 + ma11) / maskdiv_s;
+# else
+ ma = texture2D(texm, tex_m);
+# endif
# endif
#endif
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
index d4657b9dd4..d948634bc6 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
@@ -143,8 +143,16 @@ _image_get(Evas_Ector_GL_Buffer_Data *pd, Eina_Bool render)
if (pd->maps != NULL)
fail("Image is currently mapped!");
+ if (!pd->glim || !pd->glim->tex || !pd->glim->tex->pt)
+ fail("Image has no texture!");
+
evas_gl_common_image_ref(pd->glim);
- if (render) pd->was_render = EINA_TRUE;
+ if (render)
+ {
+ if (!pd->glim->tex->pt->fb)
+ fail("Image has no FBO!");
+ pd->was_render = EINA_TRUE;
+ }
return pd->glim;
on_fail:
@@ -174,13 +182,8 @@ _evas_ector_gl_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED
EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->glim == image, EINA_FALSE);
if (pd->was_render)
- {
- Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
- Evas_Engine_GL_Context *gc;
+ pd->glim = evas_gl_common_image_surface_detach(pd->glim);
- gc = re->window_gl_context_get(re->software.ob);
- pd->glim = evas_gl_common_image_surface_detach(gc, pd->glim);
- }
evas_gl_common_image_free(pd->glim);
return EINA_TRUE;
@@ -307,14 +310,11 @@ _evas_ector_gl_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buff
EINA_INLIST_REMOVE(pd->maps, map);
if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE)
{
- Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
Evas_GL_Image *old_glim = pd->glim;
- Evas_Engine_GL_Context *gc;
int W, H;
W = pd->glim->w;
H = pd->glim->h;
- gc = re->window_gl_context_get(re->software.ob);
if (map->cspace == EFL_GFX_COLORSPACE_GRY8)
_pixels_gry8_to_argb_convert(map->image_data, map->base_data, W * H);
@@ -322,13 +322,13 @@ _evas_ector_gl_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buff
if (map->im)
{
MAP_DUMP(map->im, "out_w_free");
- pd->glim = evas_gl_common_image_surface_update(gc, map->im);
+ pd->glim = evas_gl_common_image_surface_update(map->im);
evas_gl_common_image_free(old_glim);
}
else
{
MAP_DUMP(old_glim, "out_w_nofree");
- pd->glim = evas_gl_common_image_surface_update(gc, old_glim);
+ pd->glim = evas_gl_common_image_surface_update(old_glim);
}
}
else
diff --git a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
index 6e1666cf74..3d3bb2eb66 100644
--- a/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
+++ b/src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
@@ -54,6 +54,8 @@ struct _Evas_Ector_GL_Image_Buffer_Data
#define EINA_INLIST_REMOVE(l,i) do { l = (__typeof__(l)) eina_inlist_remove(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
#define EINA_INLIST_APPEND(l,i) do { l = (__typeof__(l)) eina_inlist_append(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
+#define fail(fmt, ...) do { ERR(fmt, ##__VA_ARGS__); goto on_fail; } while (0)
+
/* FIXME: Conversion routines don't belong here */
static inline void
_pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len)
@@ -68,24 +70,48 @@ _pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len)
EOLIAN static void
_evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd,
- Evas *evas, void *image)
+ Evas *eo_evas, void *image)
{
Evas_GL_Image *im = image;
+ Evas_Public_Data *evas;
EINA_SAFETY_ON_FALSE_RETURN(!pd->glim);
EINA_SAFETY_ON_NULL_RETURN(im);
- pd->evas = efl_data_xref(evas, EVAS_CANVAS_CLASS, obj);
+ evas = efl_data_xref(eo_evas, EVAS_CANVAS_CLASS, obj);
+ if (!im->tex)
+ {
+ Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
+ Evas_Engine_GL_Context *gc;
+
+ gc = re->window_gl_context_get(re->software.ob);
+ evas_gl_common_image_update(gc, im);
+
+ if (!im->tex)
+ fail("Image has no texture!");
+ }
+
+ pd->evas = evas;
evas_gl_common_image_ref(im);
pd->glim = im;
+
+on_fail:
+ efl_data_xunref(eo_evas, evas, obj);
+ return;
}
EOLIAN static void *
_evas_ector_gl_image_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Image_Buffer_Data *pd)
{
+ if (!pd->glim->tex)
+ fail("Image has no texture!");
+
evas_gl_common_image_ref(pd->glim);
return pd->glim;
+
+on_fail:
+ return NULL;
}
EOLIAN static Eina_Bool
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c
index 296da981a2..6c840f65d7 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -1284,93 +1284,20 @@ eng_image_map_clean(void *data EINA_UNUSED, RGBA_Map *m EINA_UNUSED)
static void *
eng_image_map_surface_new(void *data, int w, int h, int alpha)
{
- Evas_Engine_GL_Context *gl_context;
Render_Engine_GL_Generic *re = data;
+ Evas_Engine_GL_Context *gl_context;
re->window_use(re->software.ob);
gl_context = re->window_gl_context_get(re->software.ob);
return evas_gl_common_image_surface_new(gl_context, w, h, alpha, EINA_FALSE);
}
-static void *
+void *
eng_image_scaled_update(void *data EINA_UNUSED, void *scaled, void *image,
- int dst_w, int dst_h,
- Eina_Bool smooth, Eina_Bool alpha,
+ int dst_w, int dst_h, Eina_Bool smooth,
Evas_Colorspace cspace EINA_UNUSED)
{
- Evas_GL_Image *dst = scaled, *newdst;
- Evas_GL_Image *src = image;
- Evas_Engine_GL_Context *gc;
- Eina_Bool reffed = EINA_FALSE;
-
- if (!src) return NULL;
-
- // masking will work only with single texture images
- switch (src->cs.space)
- {
- case EVAS_COLORSPACE_AGRY88:
- case EVAS_COLORSPACE_ARGB8888:
- case EVAS_COLORSPACE_GRY8:
- case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
- case EVAS_COLORSPACE_RGBA_S3TC_DXT1:
- case EVAS_COLORSPACE_RGBA_S3TC_DXT2:
- case EVAS_COLORSPACE_RGBA_S3TC_DXT3:
- case EVAS_COLORSPACE_RGBA_S3TC_DXT4:
- case EVAS_COLORSPACE_RGBA_S3TC_DXT5:
- break;
- default:
- DBG("cspace %d can't be used for masking's fast path", src->cs.space);
- return NULL;
- }
-
- gc = src->gc;
- if (dst && (dst->scaled.origin == src) &&
- (dst->w == dst_w) && (dst->h == dst_h))
- return dst;
-
- evas_gl_common_image_update(gc, src);
- if (!src->tex)
- {
- ERR("No source texture.");
- return NULL;
- }
-
- newdst = calloc(1, sizeof(Evas_GL_Image));
- if (!newdst) return NULL;
-
- if (dst)
- {
- if (dst->scaled.origin == src)
- {
- if (dst->references == 1)
- {
- dst->w = dst_w;
- dst->h = dst_h;
- dst->scaled.smooth = smooth;
- free(newdst);
- return dst;
- }
- src->references++;
- reffed = EINA_TRUE;
- }
- evas_gl_common_image_free(dst);
- }
-
- newdst->references = 1;
- newdst->gc = gc;
- newdst->cs.space = src->cs.space;
- newdst->alpha = alpha;
- newdst->w = dst_w;
- newdst->h = dst_h;
- newdst->tex = src->tex;
- newdst->tex->references++;
- newdst->tex_only = 1;
-
- if (!reffed) src->references++;
- newdst->scaled.origin = src;
- newdst->scaled.smooth = smooth;
-
- return newdst;
+ return evas_gl_common_image_virtual_scaled_get(scaled, image, dst_w, dst_h, smooth);
}
static void
@@ -3107,7 +3034,7 @@ _gfx_filter_func_get(Evas_Filter_Command *cmd)
//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_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 9cbf4f1766..6b6e45b2f1 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
@@ -10,13 +10,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);
-//Software_Filter_Func gl_filter_blur_func_get(Evas_Filter_Command *cmd);
-//Software_Filter_Func gl_filter_bump_func_get(Evas_Filter_Command *cmd);
-//Software_Filter_Func gl_filter_curve_func_get(Evas_Filter_Command *cmd);
-//Software_Filter_Func gl_filter_displace_func_get(Evas_Filter_Command *cmd);
-//Software_Filter_Func gl_filter_fill_func_get(Evas_Filter_Command *cmd);
-//Software_Filter_Func gl_filter_mask_func_get(Evas_Filter_Command *cmd);
-//Software_Filter_Func gl_filter_transform_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_transform_func_get(Evas_Filter_Command *cmd);
#undef DBG
#undef INF
diff --git a/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c b/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c
index d9977bf8bd..4af89f1087 100644
--- a/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c
+++ b/src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c
@@ -164,20 +164,17 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
Evas_GL_Image *image, *surface;
RGBA_Draw_Context *dc_save;
+ DEBUG_TIME_BEGIN();
+
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);
- EINA_SAFETY_ON_NULL_RETURN_VAL(image->tex, EINA_FALSE);
surface = evas_ector_buffer_render_image_get(cmd->output->buffer);
-
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(surface->tex, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(surface->tex->pt, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(surface->tex->pt->fb != 0, EINA_FALSE);
+
evas_gl_common_context_target_surface_set(gc, surface);
dc_save = gc->dc;
@@ -185,6 +182,8 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
evas_common_draw_context_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
gc->dc->render_op = _gfx_to_evas_render_op(cmd->draw.rop);
+ // FIXME: Maybe need to clear buffer in case of COPY mode?
+
DBG("blend %d @%p -> %d @%p", cmd->input->id, cmd->input->buffer,
cmd->output->id, cmd->output->buffer);
_mapped_blend(gc, image, cmd->draw.fillmode, 0, 0, image->w, image->h,
@@ -196,6 +195,8 @@ _gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
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;
}
diff --git a/src/modules/evas/engines/gl_generic/filters/gl_filter_mask.c b/src/modules/evas/engines/gl_generic/filters/gl_filter_mask.c
new file mode 100644
index 0000000000..37f534d791
--- /dev/null
+++ b/src/modules/evas/engines/gl_generic/filters/gl_filter_mask.c
@@ -0,0 +1,83 @@
+#include "gl_engine_filter.h"
+
+static Eina_Bool
+_gl_filter_mask(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
+{
+ Evas_Engine_GL_Context *gc;
+ Evas_GL_Image *image, *surface, *orig_mask, *use_mask = NULL;
+ RGBA_Draw_Context *dc_save;
+ int x, y, w, h, mask_w, mask_h;
+
+ DEBUG_TIME_BEGIN();
+
+ w = cmd->input->w;
+ h = cmd->input->h;
+
+ image = evas_ector_buffer_drawable_image_get(cmd->input->buffer);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
+
+ orig_mask = evas_ector_buffer_drawable_image_get(cmd->mask->buffer);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(orig_mask, EINA_FALSE);
+
+ surface = evas_ector_buffer_render_image_get(cmd->output->buffer);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
+
+ DBG("mask %d @%p + %d %p -> %d @%p", cmd->input->id, cmd->input->buffer,
+ cmd->mask->id, cmd->mask->buffer, cmd->output->id, cmd->output->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_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
+ evas_common_draw_context_clip_clip(gc->dc, 0, 0, w, h);
+
+ mask_w = (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X) ? w : cmd->mask->w;
+ mask_h = (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y) ? h : cmd->mask->h;
+ use_mask = evas_gl_common_image_virtual_scaled_get(NULL, orig_mask, mask_w, mask_h, EINA_TRUE);
+
+ gc->dc->clip.mask = use_mask;
+ gc->dc->clip.mask_color = !cmd->mask->alpha_only;
+
+ for (y = 0; y < h; y += mask_h)
+ for (x = 0; x < w; x += mask_w)
+ {
+ int sw, sh;
+
+ sw = MIN(mask_w, w - x);
+ sh = MIN(mask_h, h - y);
+ gc->dc->clip.mask_x = x;
+ gc->dc->clip.mask_y = y;
+
+ evas_gl_common_image_draw(gc, image, x, y, sw, sh, x, y, sw, sh, EINA_TRUE);
+ }
+
+ evas_gl_common_image_free(use_mask);
+ 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->mask->buffer, orig_mask);
+ evas_ector_buffer_engine_image_release(cmd->output->buffer, surface);
+
+ DEBUG_TIME_END();
+
+ return EINA_TRUE;
+}
+
+GL_Filter_Apply_Func
+gl_filter_mask_func_get(Evas_Filter_Command *cmd)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->input->w > 0) && (cmd->input->h > 0), NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->mask->w > 0) && (cmd->mask->h > 0), NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->w == cmd->output->w, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->h == cmd->output->h, NULL);
+
+ return _gl_filter_mask;
+}