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 :)
This commit is contained in:
Jean-Philippe Andre 2017-01-24 14:23:03 +09:00
parent 92dfe1831c
commit 3d2f1a3d9b
20 changed files with 391 additions and 187 deletions

View File

@ -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_mask.c \
$(NULL)
evas_gl_generic_eolian_files = \

View File

@ -2470,7 +2470,7 @@ evas_render_mask_subrender(Evas_Public_Data *evas,
Eina_Bool smooth = evas_object_image_smooth_scale_get(mask->object);
void *original = mask->func->engine_data_get(mask->object);
void *scaled = ENFN->image_scaled_update
(ENDT, mdata->surface, original, w, h, smooth, EINA_TRUE, EVAS_COLORSPACE_GRY8);
(ENDT, mdata->surface, original, w, h, smooth, EVAS_COLORSPACE_GRY8);
if (scaled)
{
done = EINA_TRUE;

View File

@ -766,6 +766,7 @@ struct _RGBA_Draw_Context
int mask_x, mask_y;
Eina_Bool use : 1;
Eina_Bool async : 1;
Eina_Bool mask_color : 1; // true if masking with color (eg. filters)
} clip;
struct {
#ifdef HAVE_PIXMAN

View File

@ -1491,7 +1491,7 @@ struct _Evas_Func
Eina_Bool (*image_map_draw) (void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level, Eina_Bool do_async);
void *(*image_map_surface_new) (void *data, int w, int h, int alpha);
void (*image_map_clean) (void *data, RGBA_Map *m);
void *(*image_scaled_update) (void *data, void *scaled, void *image, int dst_w, int dst_h, Eina_Bool smooth, Eina_Bool alpha, Evas_Colorspace cspace);
void *(*image_scaled_update) (void *data, void *scaled, void *image, int dst_w, int dst_h, Eina_Bool smooth, Evas_Colorspace cspace);
void (*image_content_hint_set) (void *data, void *surface, int hint);
int (*image_content_hint_get) (void *data, void *surface);

View File

@ -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 *);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}