Masking: Push a bit more arbitrary clipping

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.

SVN revision: 58373
This commit is contained in:
Brett Nash 2011-04-06 05:38:38 +00:00
parent a5d83e3cbe
commit b96d227334
12 changed files with 522 additions and 10 deletions

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

View 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

View File

@ -152,6 +152,26 @@ evas_common_draw_context_unset_multiplier(RGBA_Draw_Context *dc)
dc->mul.use = 0;
}
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)
{

View 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

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

View 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 {
@ -788,6 +791,11 @@ struct _RGBA_Image
Eina_Bool no_free : 1;
} image;
struct {
DATA8 *mask;
Eina_Bool dirty: 1;
} mask;
struct {
LK(lock);
Eina_List *list;

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

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

View 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,

View 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
@ -1543,6 +1590,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,
@ -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;

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

View File

@ -96,6 +96,24 @@ eng_context_multiplier_get(void *data __UNUSED__, void *context, int *r, int *g,
return ((RGBA_Draw_Context *)context)->mul.use;
}
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)
{
@ -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 */