Masking: Push a bit more arbitrary clipping
authornash <nash@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 6 Apr 2011 05:38:38 +0000 (05:38 +0000)
committernash <nash@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 6 Apr 2011 05:38:38 +0000 (05:38 +0000)
This seems to have got lost in my big messup before.  This pushes enough of
mask/arbitrary clip to be somewhat useful.  I need to push a little more soon
for it to be 100% happy, but this is useful level.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@58373 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

12 files changed:
src/lib/canvas/evas_clip.c
src/lib/canvas/evas_render.c
src/lib/engines/common/evas_draw_main.c
src/lib/engines/common/evas_scale_sample.c
src/lib/engines/common/evas_scale_smooth_scaler_noscale.c
src/lib/include/evas_common.h
src/lib/include/evas_inline.x
src/lib/include/evas_private.h
src/modules/engines/gl_common/evas_gl_common.h
src/modules/engines/gl_common/evas_gl_context.c
src/modules/engines/gl_x11/evas_engine.c
src/modules/engines/software_generic/evas_engine.c

index 08bd86e..d556cb1 100644 (file)
@@ -265,6 +265,21 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
    obj->cur.clipper = clip;
    clip->clip.clipees = eina_list_append(clip->clip.clipees, obj);
    if (clip->clip.clipees) clip->cur.have_clipees = 1;
+
+   /* If it's NOT a rectangle set the mask bits too */
+   /* FIXME: Optmz ths chck */
+   if (strcmp(evas_object_type_get(clip),"rectangle") == 0)
+      obj->cur.mask = NULL;
+   else
+     {
+       void *engdata;
+        obj->cur.mask = clip;
+       engdata = clip->func->engine_data_get(clip);
+       /* FIXME: Images only */
+       clip->layer->evas->engine.func->image_mask_create(
+                                     clip->layer->evas->engine.data.output,
+                                     engdata);
+     }
    evas_object_change(clip);
    evas_object_change(obj);
    evas_object_clip_dirty(obj);
index 56bfa9d..5d497a0 100644 (file)
@@ -1336,6 +1336,17 @@ evas_render_updates_internal(Evas *e,
                                                     obj->cur.cache.clip.w,
                                                     obj->cur.cache.clip.h);
                               }
+                            if (obj->cur.mask)
+                               e->engine.func->context_mask_set(e->engine.data.output,
+                                                                e->engine.data.context,
+                                                                obj->cur.mask->func->engine_data_get(obj->cur.mask),
+                                                                obj->cur.mask->cur.geometry.x,
+                                                                obj->cur.mask->cur.geometry.y,
+                                                                obj->cur.mask->cur.geometry.w,
+                                                                obj->cur.mask->cur.geometry.h);
+                            else
+                               e->engine.func->context_mask_unset(e->engine.data.output,
+                                                                e->engine.data.context);
                             if (obj->cur.clipper)
                                e->engine.func->context_clip_set(e->engine.data.output,
                                                                 e->engine.data.context,
@@ -1382,6 +1393,9 @@ evas_render_updates_internal(Evas *e,
                                    }
                              }
 #endif
+                            e->engine.func->context_clip_set(e->engine.data.output,
+                                                             e->engine.data.context,
+                                                             x, y, w, h);
                             clean_them |= evas_render_mapped(e, obj, e->engine.data.context,
                                                             surface, off_x, off_y, 0,
                                                              cx, cy, cw, ch
index 8b8511a..e2d4568 100644 (file)
@@ -153,6 +153,26 @@ evas_common_draw_context_unset_multiplier(RGBA_Draw_Context *dc)
 }
 
 EAPI void
+evas_common_draw_context_set_mask(RGBA_Draw_Context *dc, RGBA_Image *mask, int x, int y, int w, int h)
+{
+   dc->mask.mask = mask;
+   dc->mask.x = x;
+   dc->mask.y = y;
+   dc->mask.w = w;
+   dc->mask.h = h;
+}
+
+EAPI void
+evas_common_draw_context_unset_mask(RGBA_Draw_Context *dc)
+{
+   dc->mask.mask = NULL;
+}
+
+
+
+
+
+EAPI void
 evas_common_draw_context_add_cutout(RGBA_Draw_Context *dc, int x, int y, int w, int h)
 {
 //   if (dc->cutout.rects > 512) return;
index c6fa9f2..1ee1960 100644 (file)
@@ -94,6 +94,8 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
    int      dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h;
    int      src_w, src_h, dst_w, dst_h;
    RGBA_Gfx_Func func;
+   RGBA_Image *maskobj;
+   DATA8   *mask = NULL;
 
    if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
      return;
@@ -235,7 +237,20 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
    /* figure out dest start ptr */
    dst_ptr = dst_data + dst_clip_x + (dst_clip_y * dst_w);
 
-   if (dc->mul.use)
+   if (dc->mask.mask)
+     {
+       func = evas_common_gfx_func_composite_pixel_mask_span_get(src, dst, dst_clip_w, dc->render_op);
+       maskobj = dc->mask.mask;
+       mask = maskobj->mask.mask;
+       if (1 || dst_region_w > src_region_w || dst_region_h > src_region_h){
+              printf("Mask w/h: %d/%d\n",maskobj->cache_entry.w,
+                              maskobj->cache_entry.h);
+              printf("Warning: Unscaled mask (%d/%d) // (%d/%d)\n",
+                              dst_region_w,src_region_w,
+                              dst_region_h,src_region_h);
+       }
+     }
+   else if (dc->mul.use)
      func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
    else
      func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
@@ -246,14 +261,20 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
        for (y = 0; y < dst_clip_h; y++)
          {
            /* * blend here [clip_w *] ptr -> dst_ptr * */
+            if (mask)
+             {
+                 mask += dst_clip_x - dc->mask.x;
+                 mask += (dst_clip_y - dc->mask.y) * maskobj->cache_entry.w;
+             }
 #ifdef EVAS_SLI
             if (((y + dst_clip_y) % dc->sli.h) == dc->sli.y)
 #endif
               {
-                 func(ptr, NULL, dc->mul.col, dst_ptr, dst_clip_w);
+                 func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w);
               }
            ptr += src_w;
            dst_ptr += dst_w;
+           if (mask) mask += maskobj->cache_entry.w;
          }
      }
    else
index 957b6a3..3d9e4f6 100644 (file)
@@ -1,16 +1,46 @@
 {
    DATA32 *ptr;
    RGBA_Gfx_Func func;
+   RGBA_Image *maskobj;
+   DATA8 *mask = NULL;
 #ifdef EVAS_SLI
    int ysli = dst_clip_y;
 #endif
 
    ptr = src->image.data + ((dst_clip_y - dst_region_y + src_region_y) * src_w) + (dst_clip_x - dst_region_x) + src_region_x;
-   if (dc->mul.use)
+   if (dc->mask.mask)
+     {
+       func = evas_common_gfx_func_composite_pixel_mask_span_get(NULL, NULL, dst_clip_w, dc->render_op);
+       maskobj = dc->mask.mask;
+       mask = maskobj->mask.mask;
+     }
+   else if (dc->mul.use)
        func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op);
    else
        func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op);
-   while (dst_clip_h--)
+
+   if (mask)
+     {
+        mask += dst_clip_x - dc->mask.x;
+        mask += (dst_clip_y - dc->mask.y) * maskobj->cache_entry.w;
+        while (dst_clip_h--)
+          {
+
+#ifdef EVAS_SLI
+             if (((ysli) % dc->sli.h) == dc->sli.y)
+#endif
+               {
+                  func(ptr, mask, dc->mul.col, dst_ptr, dst_clip_w);
+               }
+#ifdef EVAS_SLI
+             ysli++;
+#endif
+             ptr += src_w;
+             dst_ptr += dst_w;
+             mask += maskobj->cache_entry.w;
+          }
+     }
+   else
      {
 #ifdef EVAS_SLI
        if (((ysli) % dc->sli.h) == dc->sli.y)
index 6ba910a..db8fbd8 100644 (file)
@@ -675,10 +675,13 @@ struct _RGBA_Draw_Context
       DATA32 col;
    } col;
    struct RGBA_Draw_Context_clip {
-      DATA8  *mask;
       int    x, y, w, h;
       Eina_Bool use : 1;
    } clip;
+   struct {
+      int x, y, w, h;
+      RGBA_Image *mask;
+   } mask;
    Cutout_Rects cutout;
    struct {
       struct {
@@ -789,6 +792,11 @@ struct _RGBA_Image
    } image;
 
    struct {
+      DATA8             *mask;
+      Eina_Bool          dirty: 1;
+   } mask;
+
+   struct {
       LK(lock);
       Eina_List *list;
       unsigned long long orig_usage;
index f1d131d..3137579 100644 (file)
@@ -57,6 +57,8 @@ static inline int
 evas_object_is_opaque(Evas_Object *obj)
 {
    if (obj->smart.smart) return 0;
+   /* If a mask: Assume alpha */
+   if (obj->cur.mask) return 0;
    if (obj->cur.cache.clip.a == 255)
      {
        if (obj->func->is_opaque)
index f5586e5..8f1dc16 100644 (file)
@@ -393,6 +393,7 @@ struct _Evas_Object
    struct {
       Evas_Map             *map;
       Evas_Object          *clipper;
+      Evas_Object          *mask;
       Evas_Object          *map_parent;
       double                scale;
       Evas_Coord_Rectangle  geometry;
@@ -593,6 +594,8 @@ struct _Evas_Func
    void (*context_clip_clip)               (void *data, void *context, int x, int y, int w, int h);
    void (*context_clip_unset)              (void *data, void *context);
    int  (*context_clip_get)                (void *data, void *context, int *x, int *y, int *w, int *h);
+   void (*context_mask_set)               (void *data, void *context, void *mask, int x, int y, int w, int h);
+   void (*context_mask_unset)             (void *data, void *context);
    void (*context_color_set)               (void *data, void *context, int r, int g, int b, int a);
    int  (*context_color_get)               (void *data, void *context, int *r, int *g, int *b, int *a);
    void (*context_multiplier_set)          (void *data, void *context, int r, int g, int b, int a);
@@ -636,6 +639,7 @@ struct _Evas_Func
    char *(*image_format_get)               (void *data, void *image);
    void (*image_colorspace_set)            (void *data, void *image, int cspace);
    int  (*image_colorspace_get)            (void *data, void *image);
+   void (*image_mask_create)               (void *data, void *image);
    void *(*image_native_set)               (void *data, void *image, void *native);
    void *(*image_native_get)               (void *data, void *image);
 
index 477bd7f..0318bcb 100644 (file)
@@ -93,6 +93,7 @@
 #define SHAD_TEXUV  2
 #define SHAD_TEXUV2 3
 #define SHAD_TEXUV3 4
+#define SHAD_TEXM   5
 
 typedef struct _Evas_GL_Program                      Evas_GL_Program;
 typedef struct _Evas_GL_Program_Source               Evas_GL_Program_Source;
@@ -192,6 +193,7 @@ struct _Evas_GL_Shared
       
       Evas_GL_Program  img,            img_nomul;
       Evas_GL_Program  img_bgra,       img_bgra_nomul;
+      Evas_GL_Program  img_mask;
       Evas_GL_Program  yuv,            yuv_nomul;
       Evas_GL_Program  tex,            tex_nomul;
    } shader;
@@ -209,6 +211,7 @@ struct _Evas_GL_Shared
 #define RTYPE_FONT  3
 #define RTYPE_YUV   4
 #define RTYPE_MAP   5 /* need to merge with image */ 
+#define RTYPE_IMASK 6
 
 
 
@@ -228,6 +231,7 @@ struct _Evas_Engine_GL_Context
       struct {
          GLuint          cur_prog;
          GLuint          cur_tex, cur_texu, cur_texv;
+         GLuint          cur_texm, cur_texmu, cur_texmv;
          int             render_op;
          int             cx, cy, cw, ch;
          int             smooth;
@@ -248,7 +252,7 @@ struct _Evas_Engine_GL_Context
       struct {
          Evas_GL_Image  *surface;
          GLuint          cur_prog;
-         GLuint          cur_tex, cur_texu, cur_texv;
+         GLuint          cur_tex, cur_texu, cur_texv, cur_texm;
          int             render_op;
          int             cx, cy, cw, ch;
          int             smooth;
@@ -262,12 +266,14 @@ struct _Evas_Engine_GL_Context
          GLfloat *texuv;
          GLfloat *texuv2;
          GLfloat *texuv3;
-         Eina_Bool line : 1;
+         GLfloat *texm;
+        Eina_Bool line: 1;
          Eina_Bool use_vertex : 1;
          Eina_Bool use_color : 1;
          Eina_Bool use_texuv : 1;
          Eina_Bool use_texuv2 : 1;
          Eina_Bool use_texuv3 : 1;
+         Eina_Bool use_texm : 1;
          Evas_GL_Image *im;
       } array;
    } pipe[MAX_PIPES];
@@ -386,6 +392,8 @@ extern Evas_GL_Program_Source shader_img_bgra_frag_src;
 extern Evas_GL_Program_Source shader_img_bgra_vert_src;
 extern Evas_GL_Program_Source shader_img_bgra_nomul_frag_src;
 extern Evas_GL_Program_Source shader_img_bgra_nomul_vert_src;
+extern Evas_GL_Program_Source shader_img_mask_frag_src;
+extern Evas_GL_Program_Source shader_img_mask_vert_src;
 
 extern Evas_GL_Program_Source shader_yuv_frag_src;
 extern Evas_GL_Program_Source shader_yuv_vert_src;
@@ -419,6 +427,16 @@ void              evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc,
                                                     int x, int y, int w, int h,
                                                     int r, int g, int b, int a,
                                                     Eina_Bool smooth, Eina_Bool tex_only);
+void              evas_gl_common_context_image_mask_push(Evas_Engine_GL_Context *gc,
+                                                    Evas_GL_Texture *tex,
+                                                    Evas_GL_Texture *texm,
+                                                    double sx, double sy, double sw, double sh,
+                                                    double sxm, double sym, double swm, double shm,
+                                                    int x, int y, int w, int h,
+                                                    int r, int g, int b, int a,
+                                                    Eina_Bool smooth);
+
+
 void              evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
                                                    Evas_GL_Texture *tex,
                                                    double sx, double sy, double sw, double sh,
index cf2fa1a..e87d317 100644 (file)
@@ -465,6 +465,13 @@ _evas_gl_common_viewport_set(Evas_Engine_GL_Context *gc)
    glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_bgra_nomul.prog, "mvp"), 1,
                       GL_FALSE, proj);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   glUseProgram(gc->shared->shader.img_mask.prog);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+   glUniformMatrix4fv(glGetUniformLocation(gc->shared->shader.img_mask.prog, "mvp"), 1,
+                      GL_FALSE, proj);
+   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+
 
    glUseProgram(gc->pipe[0].shader.cur_prog);
    GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -696,6 +703,10 @@ evas_gl_common_context_new(void)
                                                 &(shader_img_bgra_nomul_vert_src),
                                                 &(shader_img_bgra_nomul_frag_src),
                                                 "img_bgra_nomul")) goto error;
+        if (!evas_gl_common_shader_program_init(&(shared->shader.img_mask),
+                                                &(shader_img_mask_vert_src),
+                                                &(shader_img_mask_frag_src),
+                                                "img_mask")) goto error;
         if (!evas_gl_common_shader_program_init(&(shared->shader.tex),
                                                 &(shader_tex_vert_src), 
                                                 &(shader_tex_frag_src),
@@ -730,7 +741,16 @@ evas_gl_common_context_new(void)
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
         glUniform1i(glGetUniformLocation(shared->shader.yuv_nomul.prog, "texv"), 2);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-        
+
+       glUseProgram(shared->shader.img_mask.prog);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glUniform1i(glGetUniformLocation(shared->shader.img_mask.prog, "tex"), 0);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+        glUniform1i(glGetUniformLocation(shared->shader.img_mask.prog, "texm"), 1);
+        GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+
+
+
         glUseProgram(gc->pipe[0].shader.cur_prog);
         GLERR(__FUNCTION__, __FILE__, __LINE__, "");
         
@@ -777,6 +797,7 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
              if (gc->pipe[i].array.vertex) free(gc->pipe[i].array.vertex);
              if (gc->pipe[i].array.color) free(gc->pipe[i].array.color);
              if (gc->pipe[i].array.texuv) free(gc->pipe[i].array.texuv);
+             if (gc->pipe[i].array.texm) free(gc->pipe[i].array.texm);
              if (gc->pipe[i].array.texuv2) free(gc->pipe[i].array.texuv2);
              if (gc->pipe[i].array.texuv3) free(gc->pipe[i].array.texuv3);
           }
@@ -792,6 +813,7 @@ evas_gl_common_context_free(Evas_Engine_GL_Context *gc)
         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_nomul));
         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_bgra));
         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_bgra_nomul));
+        evas_gl_common_shader_program_shutdown(&(gc->shared->shader.img_mask));
         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv));
         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.yuv_nomul));
         evas_gl_common_shader_program_shutdown(&(gc->shared->shader.tex));
@@ -846,6 +868,9 @@ evas_gl_common_context_newframe(Evas_Engine_GL_Context *gc)
    gc->state.current.cur_tex = 0;
    gc->state.current.cur_texu = 0;
    gc->state.current.cur_texv = 0;
+   gc->state.current.cur_texm = 0;
+   gc->state.current.cur_texmu = 0;
+   gc->state.current.cur_texmv = 0;
    gc->state.current.render_op = 0;
    gc->state.current.smooth = 0;
    gc->state.current.blend = 0;
@@ -872,6 +897,7 @@ evas_gl_common_context_newframe(Evas_Engine_GL_Context *gc)
         gc->pipe[i].shader.cur_tex = 0;
         gc->pipe[i].shader.cur_texu = 0;
         gc->pipe[i].shader.cur_texv = 0;
+        gc->pipe[i].shader.cur_texm = 0;
         gc->pipe[i].shader.render_op = EVAS_RENDER_BLEND;
         gc->pipe[i].shader.smooth = 0;
         gc->pipe[i].shader.blend = 0;
@@ -1008,6 +1034,10 @@ evas_gl_common_context_target_surface_set(Evas_Engine_GL_Context *gc,
 #define PUSH_TEXUV3(n, u, v) \
    gc->pipe[n].array.texuv3[nu3++] = u; \
    gc->pipe[n].array.texuv3[nu3++] = v
+#define PUSH_TEXM(n, u, v) \
+   gc->pipe[n].array.texm[nm++] = u; \
+   gc->pipe[n].array.texm[nm++] = v
+
 
 static inline void
 array_alloc(Evas_Engine_GL_Context *gc, int n)
@@ -1024,6 +1054,9 @@ array_alloc(Evas_Engine_GL_Context *gc, int n)
    if (gc->pipe[n].array.use_texuv)
      gc->pipe[n].array.texuv  = realloc(gc->pipe[n].array.texuv,
                                 gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
+   if (gc->pipe[n].array.use_texm)
+     gc->pipe[n].array.texm  = realloc(gc->pipe[n].array.texm,
+                                gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
    if (gc->pipe[n].array.use_texuv2)
      gc->pipe[n].array.texuv2  = realloc(gc->pipe[n].array.texuv2,
                                gc->pipe[n].array.alloc * sizeof(GLfloat) * 2);
@@ -1177,7 +1210,20 @@ evas_gl_common_context_rectangle_push(Evas_Engine_GL_Context *gc,
    Eina_Bool blend = 0;
    GLuint prog = gc->shared->shader.rect.prog;
    int pn = 0;
-   
+
+   if (gc->dc->mask.mask)
+     {
+       RGBA_Draw_Context *dc;
+       dc = gc->dc;
+       Evas_GL_Image *im;
+       im = (void *)dc->mask.mask;
+       evas_gl_common_context_font_push(gc, im->tex,
+                               x - dc->mask.x,y - dc->mask.y,
+                               dc->mask.w,dc->mask.h,
+                               x,y,w,h,r,g,b,a);
+       return;
+     }
+
    if (a < 255) blend = 1;
    if (gc->dc->render_op == EVAS_RENDER_COPY) blend = 0;
    
@@ -1493,6 +1539,7 @@ again:
    // if nomul... dont need this
    gc->pipe[pn].array.use_color = 1;
    gc->pipe[pn].array.use_texuv = 1;
+   gc->pipe[pn].array.use_texuvm = 0;
    gc->pipe[pn].array.use_texuv2 = 0;
    gc->pipe[pn].array.use_texuv3 = 0;
 #endif
@@ -1544,6 +1591,253 @@ again:
 }
 
 void
+evas_gl_common_context_image_mask_push(Evas_Engine_GL_Context *gc,
+                                  Evas_GL_Texture *tex,
+                                  Evas_GL_Texture *texm,
+                                  double sx, double sy, double sw, double sh,
+                                  double sxm, double sym, double swm,double shm,
+                                  int x, int y, int w, int h,
+                                  int r, int g, int b, int a,
+                                  Eina_Bool smooth)
+{
+   int pnum, nv, nc, nu, nm, nt, i;
+   GLfloat tx1, tx2, ty1, ty2;
+   GLfloat txm1, txm2, tym1, tym2;
+   Eina_Bool blend = 1;
+   GLuint prog = gc->shared->shader.img_mask.prog;
+   int pn = 0;
+
+#if 0
+   if (tex->gc->shared->info.bgra)
+   {
+          prog = gc->shared->shader.img_mask.prog;
+   }
+   else
+   {
+#warning Nash: FIXME: Need two shaders?
+          printf("Not good: Need other texture\n");
+          prog = gc->shared->shader.img.prog;
+   }
+#endif
+
+again:
+   vertex_array_size_check(gc, gc->state.top_pipe, 6);
+   pn = gc->state.top_pipe;
+#ifdef GLPIPES
+   if ((pn == 0) && (gc->pipe[pn].array.num == 0))
+     {
+        gc->pipe[pn].region.type = RTYPE_IMASK;
+        gc->pipe[pn].shader.cur_tex = tex->pt->texture;
+        gc->pipe[pn].shader.cur_texm = texm->pt->texture;
+        gc->pipe[pn].shader.cur_prog = prog;
+        gc->pipe[pn].shader.smooth = smooth;
+        gc->pipe[pn].shader.blend = blend;
+        gc->pipe[pn].shader.render_op = gc->dc->render_op;
+        gc->pipe[pn].shader.clip = 0;
+        gc->pipe[pn].shader.cx = 0;
+        gc->pipe[pn].shader.cy = 0;
+        gc->pipe[pn].shader.cw = 0;
+        gc->pipe[pn].shader.ch = 0;
+        gc->pipe[pn].array.line = 0;
+        gc->pipe[pn].array.use_vertex = 1;
+        // if nomul... dont need this
+        gc->pipe[pn].array.use_color = 1;
+        gc->pipe[pn].array.use_texuv = 1;
+        gc->pipe[pn].array.use_texuv2 = 0;
+        gc->pipe[pn].array.use_texuv3 = 0;
+        gc->pipe[pn].array.use_texm = 1;
+     }
+   else
+     {
+        int found = 0;
+        
+        for (i = pn; i >= 0; i--)
+          {
+             if ((gc->pipe[i].region.type == RTYPE_IMASK)
+                 && (gc->pipe[i].shader.cur_tex == tex->pt->texture)
+                 && (gc->pipe[i].shader.cur_texm == texm->pt->texture)
+                 && (gc->pipe[i].shader.cur_prog == prog)
+                 && (gc->pipe[i].shader.smooth == smooth)
+                 && (gc->pipe[i].shader.blend == blend)
+                 && (gc->pipe[i].shader.render_op == gc->dc->render_op)
+                 && (gc->pipe[i].shader.clip == 0)
+                )
+               {
+                  found = 1;
+                  pn = i;
+                  break;
+               }
+             if (pipe_region_intersects(gc, i, x, y, w, h)) break;
+          }
+        if (!found)
+          {
+             pn = gc->state.top_pipe + 1;
+             if (pn >= gc->shared->info.tune.pipes.max)
+               {
+                  shader_array_flush(gc);
+                  goto again;
+               }
+             gc->state.top_pipe = pn;
+             gc->pipe[pn].region.type = RTYPE_IMASK;
+             gc->pipe[pn].shader.cur_tex = tex->pt->texture;
+             gc->pipe[pn].shader.cur_texm = texm->pt->texture;
+             gc->pipe[pn].shader.cur_prog = prog;
+             gc->pipe[pn].shader.smooth = smooth;
+             gc->pipe[pn].shader.blend = blend;
+             gc->pipe[pn].shader.render_op = gc->dc->render_op;
+             gc->pipe[pn].shader.clip = 0;
+             gc->pipe[pn].shader.cx = 0;
+             gc->pipe[pn].shader.cy = 0;
+             gc->pipe[pn].shader.cw = 0;
+             gc->pipe[pn].shader.ch = 0;
+             gc->pipe[pn].array.line = 0;
+             gc->pipe[pn].array.use_vertex = 1;
+             gc->pipe[pn].array.use_color = 1;
+             gc->pipe[pn].array.use_texuv = 1;
+             gc->pipe[pn].array.use_texuv2 = 0;
+             gc->pipe[pn].array.use_texuv3 = 0;
+            gc->pipe[pn].array.use_texm = 1;
+   
+         }
+     }
+   if ((tex->im) && (tex->im->native.data))
+     {
+        if (gc->pipe[pn].array.im != tex->im)
+          {
+             shader_array_flush(gc);
+             pn = gc->state.top_pipe;
+             gc->pipe[pn].array.im = tex->im;
+             goto again;
+          }
+     }
+   if (tex->pt->dyn.img)
+     {
+        if (gc->pipe[pn].array.im != tex->im)
+          {
+             shader_array_flush(gc);
+             pn = gc->state.top_pipe;
+             gc->pipe[pn].array.im = tex->im;
+             goto again;
+          }
+     }
+#else   
+   if ((gc->pipe[pn].shader.cur_tex != tex->pt->texture)
+       || (gc->pipe[pn].shader.cur_prog != prog)
+       || (gc->pipe[pn].shader.smooth != smooth)
+       || (gc->pipe[pn].shader.blend != blend)
+       || (gc->pipe[pn].shader.render_op != gc->dc->render_op)
+       || (gc->pipe[pn].shader.clip != 0)
+       )
+     {
+        shader_array_flush(gc);
+        gc->pipe[pn].shader.cur_tex = tex->pt->texture;
+        gc->pipe[pn].shader.cur_texm = texm->pt->texture;
+        gc->pipe[pn].shader.cur_prog = prog;
+        gc->pipe[pn].shader.smooth = smooth;
+        gc->pipe[pn].shader.blend = blend;
+        gc->pipe[pn].shader.render_op = gc->dc->render_op;
+        gc->pipe[pn].shader.clip = 0;
+        gc->pipe[pn].shader.cx = 0;
+        gc->pipe[pn].shader.cy = 0;
+        gc->pipe[pn].shader.cw = 0;
+        gc->pipe[pn].shader.ch = 0;
+     } 
+   if ((tex->im) && (tex->im->native.data))
+     {
+        if (gc->pipe[pn].array.im != tex->im)
+          {
+             shader_array_flush(gc);
+             gc->pipe[pn].array.im = tex->im;
+          }
+     }
+   if (tex->pt->dyn.img)
+     {
+        if (gc->pipe[pn].array.im != tex->im)
+          {
+             shader_array_flush(gc);
+             gc->pipe[pn].array.im = tex->im;
+          }
+     }
+
+   gc->pipe[pn].array.line = 0;
+   gc->pipe[pn].array.use_vertex = 1;
+   gc->pipe[pn].array.use_color = 1;
+   gc->pipe[pn].array.use_texuv = 1;
+   gc->pipe[pn].array.use_texuv2 = 0;
+   gc->pipe[pn].array.use_texuv3 = 0;
+   gc->pipe[pn].array.use_texm = 1;
+#endif
+
+   pipe_region_expand(gc, pn, x, y, w, h);
+  
+   pnum = gc->pipe[pn].array.num;
+   nv = pnum * 3; nc = pnum * 4; nm = pnum * 2; nu = pnum * 2;
+   nt = pnum * 4;
+   gc->pipe[pn].array.num += 6;
+   array_alloc(gc, pn);
+
+   if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert))
+     {
+        tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+        ty1 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+        tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+        ty2 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+
+       txm1 = ((double)(texm->x) + sxm) / (double)texm->pt->w;
+        tym1 = ((double)(texm->y) + sym + shm) / (double)texm->pt->h;
+        txm2 = ((double)(texm->x) + sxm + swm) / (double)texm->pt->w;
+        tym2 = ((double)(texm->y) + sym) / (double)texm->pt->h;
+     }
+   else
+     {
+        tx1 = ((double)(tex->x) + sx) / (double)tex->pt->w;
+        ty1 = ((double)(tex->y) + sy) / (double)tex->pt->h;
+        tx2 = ((double)(tex->x) + sx + sw) / (double)tex->pt->w;
+        ty2 = ((double)(tex->y) + sy + sh) / (double)tex->pt->h;
+
+        txm1 = (texm->x + sxm) / (double)texm->pt->w;
+        tym1 = (texm->y + sym) / (double)texm->pt->h;
+        txm2 = (texm->x + sxm + swm) / (double)texm->pt->w;
+        tym2 = (texm->y + sym + shm) / (double)texm->pt->h;
+     }
+ // printf(" %3.6lf %3.6lf %3.6lf %3.6lf\n",sx,sy,sw,sh);
+ //  printf("m%3.6lf %3.6lf %3.6lf %3.6lf\n",sxm,sym,swm,shm);
+ // printf(" %3f %3f %3f %3f\n",tx1,ty1,tx2,ty2);
+ // printf("m%3f %3f %3f %3f\n",txm1,tym1,txm2,tym2);
+
+   PUSH_VERTEX(pn, x    , y    , 0);
+   PUSH_VERTEX(pn, x + w, y    , 0);
+   PUSH_VERTEX(pn, x    , y + h, 0);
+   
+   PUSH_TEXUV(pn, tx1, ty1);
+   PUSH_TEXUV(pn, tx2, ty1);
+   PUSH_TEXUV(pn, tx1, ty2);
+
+   PUSH_TEXM(pn, txm1, tym1);
+   PUSH_TEXM(pn, txm2, tym1);
+   PUSH_TEXM(pn, txm1, tym2);
+
+   PUSH_VERTEX(pn, x + w, y    , 0);
+   PUSH_VERTEX(pn, x + w, y + h, 0);
+   PUSH_VERTEX(pn, x    , y + h, 0);
+   
+   PUSH_TEXUV(pn, tx2, ty1);
+   PUSH_TEXUV(pn, tx2, ty2);
+   PUSH_TEXUV(pn, tx1, ty2);
+
+   PUSH_TEXM(pn, txm2, tym1);
+   PUSH_TEXM(pn, txm2, tym2);
+   PUSH_TEXM(pn, txm1, tym2);
+
+   // if nomul... dont need this
+   for (i = 0; i < 6; i++)
+     {
+        PUSH_COLOR(pn, r, g, b, a);
+     }
+}
+
+
+void
 evas_gl_common_context_font_push(Evas_Engine_GL_Context *gc,
                                  Evas_GL_Texture *tex,
                                  double sx, double sy, double sw, double sh,
@@ -2492,7 +2786,7 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
           {
              glDisableVertexAttribArray(SHAD_TEXUV);
              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
-             glDisableVertexAttribArray(SHAD_TEXUV2); 
+             glDisableVertexAttribArray(SHAD_TEXUV2);
              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
              glDisableVertexAttribArray(SHAD_TEXUV3);
              GLERR(__FUNCTION__, __FILE__, __LINE__, "");
@@ -2501,6 +2795,24 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
           }
         else
           {
+            if (gc->pipe[i].array.use_texm)
+              {
+                      printf("using tex m (%d)\n",gc->pipe[i].shader.cur_texm);
+                 glEnableVertexAttribArray(SHAD_TEXM);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                  glVertexAttribPointer(SHAD_TEXM, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texm);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                  glActiveTexture(GL_TEXTURE1);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                  glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texm);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                  glActiveTexture(GL_TEXTURE0);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+              }
+            else
+              {
+                  glDisableVertexAttribArray(SHAD_TEXM);
+              }
              if ((gc->pipe[i].array.use_texuv2) && (gc->pipe[i].array.use_texuv3))
                {
                   glEnableVertexAttribArray(SHAD_TEXUV2);
@@ -2528,6 +2840,11 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                   glVertexAttribPointer(SHAD_TEXUV2, 2, GL_FLOAT, GL_FALSE, 0, gc->pipe[i].array.texuv2);
                   GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                  glActiveTexture(GL_TEXTURE1);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
+                  glBindTexture(GL_TEXTURE_2D, gc->pipe[i].shader.cur_texu);
+                  glActiveTexture(GL_TEXTURE0);
+                  GLERR(__FUNCTION__, __FILE__, __LINE__, "");
                }
              else
                {
@@ -2579,12 +2896,14 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
         if (gc->pipe[i].array.vertex) free(gc->pipe[i].array.vertex);
         if (gc->pipe[i].array.color) free(gc->pipe[i].array.color);
         if (gc->pipe[i].array.texuv) free(gc->pipe[i].array.texuv);
+        if (gc->pipe[i].array.texm) free(gc->pipe[i].array.texm);
         if (gc->pipe[i].array.texuv2) free(gc->pipe[i].array.texuv2);
         if (gc->pipe[i].array.texuv3) free(gc->pipe[i].array.texuv3);
         
         gc->pipe[i].array.vertex = NULL;
         gc->pipe[i].array.color = NULL;
         gc->pipe[i].array.texuv = NULL;
+        gc->pipe[i].array.texm = NULL;
         gc->pipe[i].array.texuv2 = NULL;
         gc->pipe[i].array.texuv3 = NULL;
 
index af48bf0..ae4c303 100644 (file)
@@ -906,6 +906,20 @@ eng_image_colorspace_get(void *data __UNUSED__, void *image)
    return im->cs.space;
 }
 
+static void
+eng_image_mask_create(void *data __UNUSED__, void *image)
+{
+   Evas_GL_Image *im;
+
+   if (!image) return;
+   im = image;
+   if (!im->im->image.data)
+      evas_cache_image_load_data(&im->im->cache_entry);
+   if (!im->tex)
+      im->tex = evas_gl_common_texture_new(im->gc, im->im);
+}
+
+
 static void *
 eng_image_alpha_set(void *data, void *image, int has_alpha)
 {
@@ -2574,6 +2588,7 @@ module_open(Evas_Module *em)
    ORD(image_format_get);
    ORD(image_colorspace_set);
    ORD(image_colorspace_get);
+   ORD(image_mask_create);
    ORD(image_native_set);
    ORD(image_native_get);
    
index e3c607b..772a237 100644 (file)
@@ -97,6 +97,24 @@ eng_context_multiplier_get(void *data __UNUSED__, void *context, int *r, int *g,
 }
 
 static void
+eng_context_mask_set(void *data __UNUSED__, void *context, void *mask, int x, int y, int w, int h)
+{
+   evas_common_draw_context_set_mask(context, mask, x, y, w, h);
+}
+
+static void
+eng_context_mask_unset(void *data __UNUSED__, void *context)
+{
+   evas_common_draw_context_unset_mask(context);
+}
+
+static void *
+eng_context_mask_get(void *data __UNUSED__, void *context)
+{
+   return ((RGBA_Draw_Context *)context)->mask.mask;
+}
+
+static void
 eng_context_cutout_add(void *data __UNUSED__, void *context, int x, int y, int w, int h)
 {
    evas_common_draw_context_add_cutout(context, x, y, w, h);
@@ -239,6 +257,31 @@ eng_image_colorspace_get(void *data __UNUSED__, void *image)
    return im->space;
 }
 
+static void
+eng_image_mask_create(void *data __UNUSED__, void *image)
+{
+   RGBA_Image *im;
+   int sz;
+   uint8_t *dst,*end;
+   uint32_t *src;
+
+   if (!image) return;
+   im = image;
+   if (im->mask.mask && !im->mask.dirty) return;
+
+   if (im->mask.mask) free(im->mask.mask);
+   sz = im->cache_entry.w * im->cache_entry.h;
+   im->mask.mask = malloc(sz);
+   dst = im->mask.mask;
+   if (!im->image.data)
+      evas_cache_image_load_data(&im->cache_entry);
+   src = im->image.data;
+   for (end = dst + sz ; dst < end ; dst ++, src ++)
+      *dst = *src >> 24;
+   im->mask.dirty = 0;
+}
+
+
 static void *
 eng_image_alpha_set(void *data __UNUSED__, void *image, int has_alpha)
 {
@@ -848,6 +891,8 @@ static Evas_Func func =
      eng_context_clip_clip,
      eng_context_clip_unset,
      eng_context_clip_get,
+     eng_context_mask_set,
+     eng_context_mask_unset,
      eng_context_color_set,
      eng_context_color_get,
      eng_context_multiplier_set,
@@ -891,6 +936,7 @@ static Evas_Func func =
      eng_image_format_get,
      eng_image_colorspace_set,
      eng_image_colorspace_get,
+     eng_image_mask_create,
      eng_image_native_set,
      eng_image_native_get,
      /* image cache funcs */