evas filters: Implement mask filter in pure GL
authorJean-Philippe Andre <jp.andre@samsung.com>
Tue, 24 Jan 2017 05:23:03 +0000 (14:23 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Fri, 14 Apr 2017 02:26:43 +0000 (11:26 +0900)
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 :)

20 files changed:
src/Makefile_Evas.am
src/lib/evas/canvas/evas_render.c
src/lib/evas/include/evas_common_private.h
src/lib/evas/include/evas_private.h
src/modules/evas/engines/gl_common/evas_gl_common.h
src/modules/evas/engines/gl_common/evas_gl_context.c
src/modules/evas/engines/gl_common/evas_gl_font.c
src/modules/evas/engines/gl_common/evas_gl_image.c
src/modules/evas/engines/gl_common/evas_gl_line.c
src/modules/evas/engines/gl_common/evas_gl_polygon.c
src/modules/evas/engines/gl_common/evas_gl_rectangle.c
src/modules/evas/engines/gl_common/evas_gl_shader.c
src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x
src/modules/evas/engines/gl_common/shader/fragment.glsl
src/modules/evas/engines/gl_generic/evas_ector_gl_buffer.c
src/modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/engines/gl_generic/filters/gl_engine_filter.h
src/modules/evas/engines/gl_generic/filters/gl_filter_blend.c
src/modules/evas/engines/gl_generic/filters/gl_filter_mask.c [new file with mode: 0644]

index 83557df..aa2da76 100644 (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 = \
index a348f6e..5de9847 100644 (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;
index a3558f6..829c510 100644 (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
index 98c68a0..f3d74d2 100644 (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);
index 74d456e..537361c 100644 (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 *);
index b0ddb5e..df6af10 100644 (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);
index 5a5fdeb..1b3e35b 100644 (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);
index e422031..4a89ff6 100644 (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);
 }
index 1b7def1..892be20 100644 (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);
 }
index 4552d66..839dc61 100644 (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);
                               }
                          }
                     }
index 04bdc1a..a188467 100644 (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);
index cc22155..f4a8e69 100644 (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)
index 195ed19..8cae148 100644 (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"
index c20dc71..7de74a2 100644 (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
 
index d4657b9..d948634 100644 (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
index 6e1666c..3d3bb2e 100644 (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
index 296da98..6c840f6 100644 (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;
      }
index 9cbf4f1..6b6e45b 100644 (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
index d9977bf..4af89f1 100644 (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;
 }
 
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 (file)
index 0000000..37f534d
--- /dev/null
@@ -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;
+}