evas: add more infrastructure to the prepare stage of pipe rendering.

NOTE: this improve some test by 10 to 15% some other are down by 5%.
Their is still more tunning and improvement possible now (Particularly
with Map), but it will do for now.


SVN revision: 73264
This commit is contained in:
Cedric BAIL 2012-07-04 09:39:23 +00:00
parent 5ef3b00eaf
commit 1d415b796b
42 changed files with 1245 additions and 271 deletions

View File

@ -842,7 +842,7 @@
* upstream merge
* Merge remote-tracking branch 'remotes/origin/upstream'
2012-07-03 Christopher Michael
2012-07-03 Christopher Michael
* Merge Tizen changes to upstream EFL.
* Support gif scaling in evas gif loader.
@ -852,3 +852,6 @@
* When freeing a gl_x11 window, make sure to call eglMakeCurrent with a null surface
to inform EGL that this window is no longer valid.
2012-07-04 Cedric Bail
* Make pipeline rendering use more extensively the prepare stage.

View File

@ -13,7 +13,8 @@ Improvements:
* Don't wake up prepare thread if there is nothing to prepare.
* Limit the updated region to fit in CPU cache for Pipe rendering.
* Cache convertion from Evas_Map to RGBA_Map.
* evas_object_smart_members_get() now returns NULL on non-smart objects
* evas_object_smart_members_get() now returns NULL on non-smart objects.
* Pipeline rendering use prepare stage more extensively.
Fixes:
* Add missing files in the tarball.

View File

@ -179,11 +179,11 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
if (obj == clip) return;
if (evas_object_intercept_call_clip_set(obj, clip)) return;
// illegal to set anything but a rect as a clip
if (clip->type != o_rect_type)
{
ERR("For now a clip on other object than a rectangle is disabled");
return;
}
/* if (clip->type != o_rect_type) */
/* { */
/* ERR("For now a clip on other object than a rectangle is disabled"); */
/* return; */
/* } */
if (obj->smart.smart)
{
if (obj->smart.smart->smart_class->clip_set)
@ -228,7 +228,7 @@ evas_object_clip_set(Evas_Object *obj, Evas_Object *clip)
/* If it's NOT a rectangle set the mask bits too */
/* FIXME: Optmz ths chck */
if (strcmp(evas_object_type_get(clip),"rectangle") == 0)
if (clip->type == o_rect_type)
obj->cur.mask = NULL;
else
{

View File

@ -144,7 +144,9 @@ _evas_map_copy(Evas_Map *dst, const Evas_Map *src)
ERR("cannot copy map of different sizes: dst=%i, src=%i", dst->count, src->count);
return EINA_FALSE;
}
memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point));
if (dst == src) return EINA_TRUE;
if (dst->points != src->points)
memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point));
dst->smooth = src->smooth;
dst->alpha = src->alpha;
dst->persp = src->persp;
@ -170,10 +172,10 @@ _evas_map_free(Evas_Object *obj, Evas_Map *m)
{
if (m->surface)
obj->layer->evas->engine.func->image_map_surface_free
(obj->layer->evas->engine.data.output, m->surface);
(obj->layer->evas->engine.data.output, m->surface);
if (obj->spans)
{
// FIXME: destroy engine side spans
obj->layer->evas->engine.func->image_map_clean(obj->layer->evas->engine.data.output, obj->spans);
free(obj->spans);
obj->spans = NULL;
}
@ -487,7 +489,7 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
_evas_map_copy(obj->cur.map, map);
else
{
if (obj->cur.map) evas_map_free(obj->cur.map);
if (obj->cur.map) _evas_map_free(obj, obj->cur.map);
obj->cur.map = _evas_map_dup(map);
if (obj->cur.usemap)
evas_object_mapped_clip_across_mark(obj);

View File

@ -2952,14 +2952,11 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
}
if ((obj->cur.map) && (obj->cur.map->count > 3) && (obj->cur.usemap))
{
RGBA_Map_Point *pts;
evas_object_map_update(obj, x, y, imagew, imageh, uvw, uvh);
pts = obj->spans->pts;
obj->layer->evas->engine.func->image_map_draw
(output, context, surface, pixels, obj->cur.map->count,
pts, o->cur.smooth_scale | obj->cur.map->smooth, 0);
(output, context, surface, pixels, obj->spans,
o->cur.smooth_scale | obj->cur.map->smooth, 0);
}
else
{

View File

@ -1008,19 +1008,74 @@ static void
evas_object_smart_render_pre(Evas_Object *obj)
{
if (obj->pre_render_done) return;
if (!obj->child_has_map)
if (!obj->child_has_map && !obj->cur.cached_surface)
{
#if 0
Evas_Object_Smart *o;
fprintf(stderr, "");
o = (Evas_Object_Smart *)(obj->object_data);
if (o->member_count > 1 &&
if (/* o->member_count > 1 && */
obj->cur.bounding_box.w == obj->prev.bounding_box.w &&
obj->cur.bounding_box.h == obj->prev.bounding_box.h &&
(obj->cur.bounding_box.x != obj->prev.bounding_box.x ||
obj->cur.bounding_box.y != obj->prev.bounding_box.y))
{
fprintf(stderr, "Wouhou, I can detect moving smart object (%s, %p < %p)\n", evas_object_type_get(obj), obj, obj->smart.parent);
Eina_Bool cache_map = EINA_FALSE;
/* Check parent speed */
/* - same speed => do not map this object */
/* - different speed => map this object */
/* - if parent is mapped then map this object */
if (!obj->smart.parent || obj->smart.parent->child_has_map)
{
cache_map = EINA_TRUE;
}
else
{
if (_evas_render_has_map(obj->smart.parent))
{
cache_map = EINA_TRUE;
}
else
{
int speed_x, speed_y;
int speed_px, speed_py;
speed_x = obj->cur.geometry.x - obj->prev.geometry.x;
speed_y = obj->cur.geometry.y - obj->prev.geometry.y;
speed_px = obj->smart.parent->cur.geometry.x - obj->smart.parent->prev.geometry.x;
speed_py = obj->smart.parent->cur.geometry.y - obj->smart.parent->prev.geometry.y;
/* speed_x = obj->cur.bounding_box.x - obj->prev.bounding_box.x; */
/* speed_y = obj->cur.bounding_box.y - obj->prev.bounding_box.y; */
/* speed_px = obj->smart.parent->cur.bounding_box.x - obj->smart.parent->prev.bounding_box.x; */
/* speed_py = obj->smart.parent->cur.bounding_box.y - obj->smart.parent->prev.bounding_box.y; */
fprintf(stderr, "speed: '%s',%p (%i, %i) vs '%s',%p (%i, %i)\n",
evas_object_type_get(obj), obj, speed_x, speed_y,
evas_object_type_get(obj->smart.parent), obj->smart.parent, speed_px, speed_py);
if (speed_x != speed_px || speed_y != speed_py)
cache_map = EINA_TRUE;
}
}
if (cache_map)
fprintf(stderr, "Wouhou, I can detect moving smart object (%s, %p [%i, %i, %i, %i] < %s, %p [%i, %i, %i, %i])\n",
evas_object_type_get(obj), obj,
obj->cur.bounding_box.x - obj->prev.bounding_box.x,
obj->cur.bounding_box.y - obj->prev.bounding_box.y,
obj->cur.bounding_box.w, obj->cur.bounding_box.h,
evas_object_type_get(obj->smart.parent), obj->smart.parent,
obj->smart.parent->cur.bounding_box.x - obj->smart.parent->prev.bounding_box.x,
obj->smart.parent->cur.bounding_box.y - obj->smart.parent->prev.bounding_box.y,
obj->smart.parent->cur.bounding_box.w, obj->smart.parent->cur.bounding_box.h);
obj->cur.cached_surface = cache_map;
}
#endif
}

View File

@ -822,7 +822,6 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
_evas_render_has_map(obj));
if (_evas_render_has_map(obj))
{
RGBA_Map_Point *pts;
int sw, sh;
Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE;
@ -840,7 +839,6 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
}
evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh);
pts = obj->spans->pts;
if (obj->cur.map->surface)
{
@ -1032,7 +1030,7 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
(e->engine.data.output, e->engine.data.context);
obj->layer->evas->engine.func->image_map_draw
(e->engine.data.output, e->engine.data.context, surface,
obj->cur.map->surface, obj->cur.map->count, pts,
obj->cur.map->surface, obj->spans,
obj->cur.map->smooth, 0);
}
// FIXME: needs to cache these maps and

View File

@ -24,7 +24,7 @@ EAPI void evas_common_draw_context_cutouts_free (Cutout
EAPI void evas_common_draw_context_cutouts_del (Cutout_Rects* rects, int idx);
EAPI void evas_common_draw_context_add_cutout (RGBA_Draw_Context *dc, int x, int y, int w, int h);
EAPI void evas_common_draw_context_clear_cutouts (RGBA_Draw_Context *dc);
EAPI Cutout_Rects *evas_common_draw_context_apply_cutouts (RGBA_Draw_Context *dc);
EAPI Cutout_Rects *evas_common_draw_context_apply_cutouts (RGBA_Draw_Context *dc, Cutout_Rects *recycle);
EAPI void evas_common_draw_context_apply_clear_cutouts (Cutout_Rects* rects);
EAPI void evas_common_draw_context_apply_clean_cutouts (Cutout_Rects* rects);
EAPI void evas_common_draw_context_set_anti_alias (RGBA_Draw_Context *dc, unsigned char aa);

View File

@ -14,6 +14,7 @@ evas_common_draw_context_cutouts_new(void)
EAPI void
evas_common_draw_context_cutouts_free(Cutout_Rects* rects)
{
if (!rects) return ;
rects->active = 0;
}
@ -90,7 +91,7 @@ evas_common_draw_context_free(RGBA_Draw_Context *dc)
EAPI void
evas_common_draw_context_clear_cutouts(RGBA_Draw_Context *dc)
{
evas_common_draw_context_apply_clean_cutouts(&dc->cutout);
evas_common_draw_context_cutouts_free(&dc->cutout);
}
EAPI void
@ -557,9 +558,9 @@ evas_common_draw_context_cutout_split(Cutout_Rects* res, int idx, Cutout_Rect *s
}
EAPI Cutout_Rects*
evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc)
evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc, Cutout_Rects *reuse)
{
Cutout_Rects* res, *res2;
Cutout_Rects* res = NULL;
int i;
int j;
@ -567,7 +568,15 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc)
if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) return NULL;
res = evas_common_draw_context_cutouts_new();
if (!reuse)
{
res = evas_common_draw_context_cutouts_new();
}
else
{
evas_common_draw_context_cutouts_free(reuse);
res = reuse;
}
evas_common_draw_context_cutouts_add(res, dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
for (i = 0; i < dc->cutout.active; ++i)
@ -636,15 +645,18 @@ evas_common_draw_context_apply_cutouts(RGBA_Draw_Context *dc)
}
}
}
res2 = evas_common_draw_context_cutouts_new();
/* Repack the cutout */
j = 0;
for (i = 0; i < res->active; i++)
{
if (RI.w == 0) continue;
evas_common_draw_context_cutouts_add(res2, RI.x, RI.y, RI.w, RI.h);
if (i != j)
RJ = RI;
j++;
}
free(res->rects);
free(res);
return res2;
res->active = j;
return res;
}
return res;
}

View File

@ -25,6 +25,8 @@ EAPI Eina_Bool evas_common_font_int_cache_glyph_render(RGBA_Font_Glyph *
EAPI FT_UInt evas_common_get_char_index (RGBA_Font_Int* fi, Eina_Unicode gl);
EAPI void evas_common_font_draw_init (void);
EAPI void evas_common_font_draw_prepare (Evas_Text_Props *text_props);
EAPI void evas_common_font_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Gfx_Func func, RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *text_props);
EAPI Eina_Bool evas_common_font_draw_prepare_cutout(Cutout_Rects *reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func);
/* load */
EAPI void evas_common_font_dpi_set (int dpi);

View File

@ -40,21 +40,22 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, in
im = dst->image.data;
if (!text_props->bin) return ;
if (!text_props->glyphs) return ;
glyphs = (void*) eina_binbuf_string_get(text_props->bin);
length = eina_binbuf_length_get(text_props->bin) / sizeof (Evas_Glyph);
for (it = 0; it < length; ++it)
glyphs = text_props->glyphs;
length = text_props->glyphs_length;
for (it = 0; it < length; ++it, ++glyphs)
{
RGBA_Font_Glyph *fg;
int chr_x, chr_y;
fg = glyphs[it].fg;
fg = glyphs->fg;
glyphs[it].coord.w = fg->glyph_out->bitmap.width;
glyphs[it].coord.h = fg->glyph_out->bitmap.rows;
glyphs[it].j = fg->glyph_out->bitmap.pitch;
glyphs[it].data = fg->glyph_out->bitmap.buffer;
/* FIXME: Why was that moved out of prepare ? This increase cache miss. */
glyphs->coord.w = fg->glyph_out->bitmap.width;
glyphs->coord.h = fg->glyph_out->bitmap.rows;
glyphs->j = fg->glyph_out->bitmap.pitch;
glyphs->data = fg->glyph_out->bitmap.buffer;
if (dc->font_ext.func.gl_new)
{
@ -63,19 +64,19 @@ evas_common_font_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, in
fg->ext_dat_free = dc->font_ext.func.gl_free;
}
chr_x = x + glyphs[it].coord.x/* EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR */;
chr_y = y + glyphs[it].coord.y/* EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR */;
chr_x = x + glyphs->coord.x/* EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR */;
chr_y = y + glyphs->coord.y/* EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR */;
if (chr_x < (ext_x + ext_w))
{
DATA8 *data;
int i, j, w, h;
data = glyphs[it].data;
j = glyphs[it].j;
w = glyphs[it].coord.w;
data = glyphs->data;
j = glyphs->j;
w = glyphs->coord.w;
if (j < w) j = w;
h = glyphs[it].coord.h;
h = glyphs->coord.h;
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_FONT
@ -230,16 +231,21 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
{
RGBA_Font_Int *fi;
RGBA_Font_Glyph *fg;
Evas_Glyph *glyphs;
int glyphs_length;
int glyphs_max;
EVAS_FONT_WALK_TEXT_INIT();
fi = text_props->font_instance;
if (!fi) return;
if (!text_props->changed && text_props->generation == fi->generation && text_props->bin)
if (!text_props->changed && text_props->generation == fi->generation && text_props->glyphs)
return ;
if (!text_props->bin) text_props->bin = eina_binbuf_new();
else eina_binbuf_reset(text_props->bin);
glyphs = text_props->glyphs;
glyphs_length = 0;
glyphs_max = text_props->glyphs_length;
text_props->glyphs_length = 0;
evas_common_font_int_reload(fi);
@ -254,7 +260,7 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
EVAS_FONT_WALK_TEXT_START()
{
Evas_Glyph glyph;
Evas_Glyph *glyph;
FT_UInt idx;
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
@ -264,15 +270,28 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
if (!fg) continue;
if (!fg->glyph_out) evas_common_font_int_cache_glyph_render(fg);
glyph.fg = fg;
glyph.coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
glyph.coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
glyph.idx = idx;
if (glyphs_length + 1 >= glyphs_max)
{
Evas_Glyph *tmp;
eina_binbuf_append_length(text_props->bin, (void*) &glyph, sizeof (Evas_Glyph));
glyphs_max += 8;
tmp = realloc(glyphs, glyphs_max * sizeof (Evas_Glyph));
if (!tmp) return ;
glyphs = tmp;
text_props->glyphs = glyphs;
}
glyph = glyphs + glyphs_length++;
glyph->fg = fg;
glyph->idx = idx;
glyph->coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
glyph->coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
}
EVAS_FONT_WALK_TEXT_END();
text_props->glyphs_length = glyphs_length;
text_props->glyphs = glyphs;
/* check if there's a request queue in fi, if so ask cserve2 to render
* those glyphs
*/
@ -283,10 +302,10 @@ evas_common_font_draw_prepare(Evas_Text_Props *text_props)
EAPI void
evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, const Evas_Text_Props *text_props)
{
static Cutout_Rects *rects = NULL;
int ext_x, ext_y, ext_w, ext_h;
int im_w, im_h;
RGBA_Gfx_Func func;
Cutout_Rects *rects;
Cutout_Rect *r;
int c, cx, cy, cw, ch;
int i;
@ -335,7 +354,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, cons
/* our clip is 0 size.. abort */
if ((dc->clip.w > 0) && (dc->clip.h > 0))
{
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
@ -344,8 +363,96 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, cons
func, r->x, r->y, r->w, r->h,
im_w, im_h);
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
}
}
EAPI void
evas_common_font_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Gfx_Func func,
RGBA_Image *dst, RGBA_Draw_Context *dc,
int x, int y, const Evas_Text_Props *text_props)
{
Eina_Rectangle area;
Cutout_Rect *r;
int i;
int im_w, im_h;
im_w = dst->cache_entry.w;
im_h = dst->cache_entry.h;
if (!reuse)
{
evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
evas_common_font_draw_internal(dst, dc, x, y, text_props,
func, clip->x, clip->y, clip->w, clip->h,
im_w, im_h);
return ;
}
for (i = 0; i < reuse->active; ++i)
{
r = reuse->rects + i;
EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
if (!eina_rectangle_intersection(&area, clip)) continue ;
evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
evas_common_font_draw_internal(dst, dc, x, y, text_props,
func, area.x, area.y, area.w, area.h,
im_w, im_h);
}
}
EAPI Eina_Bool
evas_common_font_draw_prepare_cutout(Cutout_Rects *reuse, RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Gfx_Func *func)
{
int ext_x, ext_y, ext_w, ext_h;
int im_w, im_h;
im_w = dst->cache_entry.w;
im_h = dst->cache_entry.h;
*func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op);
ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h;
if (dc->clip.use)
{
ext_x = dc->clip.x;
ext_y = dc->clip.y;
ext_w = dc->clip.w;
ext_h = dc->clip.h;
if (ext_x < 0)
{
ext_w += ext_x;
ext_x = 0;
}
if (ext_y < 0)
{
ext_h += ext_y;
ext_y = 0;
}
if ((ext_x + ext_w) > im_w)
ext_w = im_w - ext_x;
if ((ext_y + ext_h) > im_h)
ext_h = im_h - ext_y;
}
if (ext_w <= 0) return EINA_FALSE;
if (ext_h <= 0) return EINA_FALSE;
if (dc->cutout.rects)
{
evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
/* our clip is 0 size.. abort */
if ((dc->clip.w > 0) && (dc->clip.h > 0))
{
reuse = evas_common_draw_context_apply_cutouts(dc, reuse);
}
else
{
return EINA_FALSE;
}
}
return EINA_TRUE;
}

View File

@ -562,9 +562,14 @@ evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl)
// }
evas_common_font_int_reload(fi);
FTLOCK();
/*
* There is no point in locking FreeType at this point as all caller
* are running in the main loop at a time where there is zero chance
* that something else try to use it.
*/
/* FTLOCK(); */
result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
FTUNLOCK();
/* FTUNLOCK(); */
result.gl = gl;
// eina_hash_direct_add(fi->indexes, &result->gl, result);

View File

@ -221,8 +221,7 @@ _sci_find(RGBA_Image *im,
{
if (im->cache.list != l)
{
im->cache.list = eina_list_remove_list(im->cache.list, l);
im->cache.list = eina_list_prepend(im->cache.list, sci);
im->cache.list = eina_list_promote_list(im->cache.list, l);
}
return sci;
}

View File

@ -47,6 +47,8 @@ evas_common_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, in
int clx, cly, clw, clh;
int cuse, cx, cy, cw, ch;
/* No cutout ? FIXME ? */
if ((x0 == x1) && (y0 == y1))
{
_evas_draw_point(dst, dc, x0, y0);

View File

@ -1,4 +1,5 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_blend_private.h"
#ifdef EVAS_CSERVE2
#include "evas_cs2_private.h"
@ -33,7 +34,7 @@ struct _Line
Span span[2];
};
static FPc
static inline FPc
_interp(int x1, int x2, int p, FPc u1, FPc u2)
{
FPc u;
@ -46,7 +47,7 @@ _interp(int x1, int x2, int p, FPc u1, FPc u2)
return u1 + u;
}
static DATA32
static inline DATA32
_interp_col(int x1, int x2, int p, DATA32 col1, DATA32 col2)
{
x2 -= x1;
@ -56,7 +57,7 @@ _interp_col(int x1, int x2, int p, DATA32 col1, DATA32 col2)
return INTERP_256(p, col2, col1);
}
static void
static inline void
_limit(Span *s, int c1, int c2, int nocol)
{
if (s->x1 < c1)
@ -357,17 +358,293 @@ _calc_spans(RGBA_Map_Point *p, Line *spans, int ystart, int yend, int cx, int cy
}
}
/* FIXME: Account for 10% during pipe rendering, should be improved
* Could be computing the interpolation once somehow.
*/
static void
_clip_spans(Line *spans, int ystart, int yend,
int cx, int cw, Eina_Bool nocol)
{
int y, yp;
for (y = ystart, yp = 0; y <= yend; y++, yp++)
{
if (spans[yp].span[0].x1 > -1)
{
if ((spans[yp].span[0].x1 >= (cx + cw)) ||
(spans[yp].span[0].x2 < cx))
{
spans[yp].span[0].x1 = -1;
}
else
{
_limit(&(spans[yp].span[0]), cx, cx + cw, nocol);
if ((spans[yp].span[1].x1 >= (cx + cw)) ||
(spans[yp].span[1].x2 < cx))
{
spans[yp].span[1].x1 = -1;
}
else
{
_limit(&(spans[yp].span[1]),
spans[yp].span[0].x2,
cx + cw, nocol);
}
}
}
}
}
typedef struct _RGBA_Map_Spans RGBA_Map_Spans;
typedef struct _RGBA_Map_Cutout RGBA_Map_Cutout;
struct _RGBA_Map_Spans
{
Line *spans;
int size;
int ystart;
int yend;
int havecol;
Eina_Bool nocol;
Eina_Bool havea;
Eina_Bool direct;
};
struct _RGBA_Map_Cutout
{
int count;
Cutout_Rects *rects;
RGBA_Map_Spans spans[1];
};
EAPI void
evas_common_map_rgba_clean(RGBA_Map *m)
{
RGBA_Map_Cutout *spans = m->engine_data;
if (spans)
{
int i;
if (spans->rects)
evas_common_draw_context_apply_clear_cutouts(spans->rects);
for (i = 0; i < spans->count; i++)
free(spans->spans[i].spans);
free(spans);
}
m->engine_data = NULL;
}
static void
_rgba_map_cutout_resize(RGBA_Map *m, int count)
{
RGBA_Map_Cutout *old = m->engine_data;
RGBA_Map_Cutout *r;
int size;
int i;
if (count == 0)
goto empty;
if (old && old->count == count)
{
return ;
}
size = sizeof (RGBA_Map_Cutout) + sizeof (RGBA_Map_Spans) * (count - 1);
if (old)
{
for (i = 0; i < old->count; i++)
{
free(old->spans[i].spans);
old->spans[i].spans = NULL;
}
}
r = realloc(old, size);
if (!r)
goto empty;
memset(r, 0, size);
m->engine_data = r;
r->count = count;
return ;
empty:
evas_common_map_rgba_clean(m);
return ;
}
static void
_evas_common_map_rgba_span(RGBA_Map_Spans *span,
RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
RGBA_Map_Point *p,
int cx, int cy, int cw, int ch)
{
int ytop, ybottom, sw;
unsigned int i;
span->havecol = 4;
span->havea = 0;
span->direct = 0;
// find y yop line and y bottom line
ytop = p[0].y;
if ((p[0].col >> 24) < 0xff) span->havea = 1;
if (p[0].col == 0xffffffff) span->havecol--;
for (i = 1; i < 4; i++)
{
if (p[i].y < ytop) ytop = p[i].y;
if ((p[i].col >> 24) < 0xff) span->havea = 1;
if (p[i].col == 0xffffffff) span->havecol--;
}
ybottom = p[0].y;
for (i = 1; i < 4; i++)
{
if (p[i].y > ybottom) ybottom = p[i].y;
}
// convert to screen space from fixed point
ytop = ytop >> FP;
ybottom = ybottom >> FP;
// if its outside the clip vertical bounds - don't bother
if ((ytop >= (cy + ch)) || (ybottom < cy)) return;
// limit to the clip vertical bounds
if (ytop < cy) span->ystart = cy;
else span->ystart = ytop;
if (ybottom >= (cy + ch)) span->yend = (cy + ch) - 1;
else span->yend = ybottom;
// get some source image information
sw = src->cache_entry.w;
// limit u,v coords of points to be within the source image
for (i = 0; i < 4; i++)
{
if (p[i].u < 0) p[i].u = 0;
else if (p[i].u > (int)(sw << FP))
p[i].u = src->cache_entry.w << FP;
if (p[i].v < 0) p[i].v = 0;
else if (p[i].v > (int)(sw << FP))
p[i].v = src->cache_entry.h << FP;
}
// allocate some spans to hold out span list
if (span->size < (span->yend - span->ystart + 1))
{
free(span->spans);
span->size = (span->yend - span->ystart + 1);
span->spans = calloc(1, span->size * sizeof(Line));
}
if (!span->spans) return;
// calculate the spans list
_calc_spans(p, span->spans, span->ystart, span->yend, cx, cy, cw, ch);
// if operation is solid, bypass buf and draw func and draw direct to dst
if ((!src->cache_entry.flags.alpha) && (!dst->cache_entry.flags.alpha) &&
(!dc->mul.use) && (!span->havea))
{
span->direct = 1;
}
}
EAPI Eina_Bool
evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
RGBA_Map *m)
{
RGBA_Map_Cutout *spans;
Cutout_Rects *rects;
Cutout_Rect *r;
int i;
if ((!dc->cutout.rects) && (!dc->clip.use))
{
evas_common_draw_context_clip_clip(dc, 0, 0,
dst->cache_entry.w, dst->cache_entry.h);
if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
{
_rgba_map_cutout_resize(m, 0);
return EINA_FALSE;
}
_rgba_map_cutout_resize(m, 1);
if (!m->engine_data) return EINA_FALSE;
spans = m->engine_data;
_evas_common_map_rgba_span(&spans->spans[0], src, dst, dc, m->pts,
0, 0,
dst->cache_entry.w, dst->cache_entry.h);
return EINA_TRUE;
}
evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
/* our clip is 0 size.. abort */
if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
{
_rgba_map_cutout_resize(m, 0);
return EINA_FALSE;
}
spans = m->engine_data;
if (spans)
{
rects = spans->rects;
spans->rects = NULL;
}
else
{
rects = evas_common_draw_context_cutouts_new();
}
rects = evas_common_draw_context_apply_cutouts(dc, rects);
_rgba_map_cutout_resize(m, rects->active);
spans = m->engine_data;
if (!spans)
{
evas_common_draw_context_apply_clear_cutouts(rects);
return EINA_FALSE;
}
spans->rects = rects;
for (i = 0; i < spans->rects->active; ++i)
{
r = spans->rects->rects + i;
_evas_common_map_rgba_span(&spans->spans[i], src, dst, dc, m->pts,
r->x, r->y, r->w, r->h);
}
return EINA_TRUE;
}
#ifdef BUILD_SCALE_SMOOTH
# ifdef BUILD_MMX
# undef FUNC_NAME
# undef FUNC_NAME_DO
# define FUNC_NAME evas_common_map_rgba_internal_mmx
# define FUNC_NAME_DO evas_common_map_rgba_internal_mmx_do
# undef SCALE_USING_MMX
# define SCALE_USING_MMX
# include "evas_map_image_internal.c"
# endif
# ifdef BUILD_C
# undef FUNC_NAME
# undef FUNC_NAME_DO
# define FUNC_NAME evas_common_map_rgba_internal
# define FUNC_NAME_DO evas_common_map_rgba_internal_do
# undef SCALE_USING_MMX
# include "evas_map_image_internal.c"
# endif
@ -382,7 +659,7 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
#ifdef BUILD_MMX
int mmx, sse, sse2;
#endif
Cutout_Rects *rects;
static Cutout_Rects *rects = NULL;
Cutout_Rect *r;
int c, cx, cy, cw, ch;
int i;
@ -422,7 +699,7 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
@ -436,7 +713,65 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
evas_common_map_rgba_internal(src, dst, dc, p, smooth, level);
#endif
}
evas_common_draw_context_apply_clear_cutouts(rects);
/* restore clip info */
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
}
EAPI void
evas_common_map_rgba_do(const Eina_Rectangle *clip,
RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
const RGBA_Map *m,
int smooth, int level)
{
#ifdef BUILD_MMX
int mmx, sse, sse2;
#endif
const Cutout_Rects *rects;
const RGBA_Map_Cutout *spans;
Eina_Rectangle area;
Cutout_Rect *r;
int i;
#ifdef BUILD_MMX
evas_common_cpu_can_do(&mmx, &sse, &sse2);
#endif
spans = m->engine_data;
rects = spans->rects;
if (rects->active == 0 &&
spans->count == 1)
{
evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h);
#ifdef BUILD_MMX
if (mmx)
evas_common_map_rgba_internal_mmx_do(src, dst, dc,
&spans->spans[0], smooth, level);
else
#endif
#ifdef BUILD_C
evas_common_map_rgba_internal_do(src, dst, dc,
&spans->spans[0], smooth, level);
#endif
return ;
}
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
if (!eina_rectangle_intersection(&area, clip)) continue ;
evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
#ifdef BUILD_MMX
if (mmx)
evas_common_map_rgba_internal_mmx_do(src, dst, dc,
&spans->spans[i], smooth, level);
else
#endif
#ifdef BUILD_C
evas_common_map_rgba_internal_do(src, dst, dc,
&spans->spans[i], smooth, level);
#endif
}
}

View File

@ -7,4 +7,17 @@ evas_common_map_rgba(RGBA_Image *src, RGBA_Image *dst,
int npoints, RGBA_Map_Point *points,
int smooth, int level);
EAPI Eina_Bool
evas_common_map_rgba_prepare(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
RGBA_Map *m);
EAPI void
evas_common_map_rgba_do(const Eina_Rectangle *clip,
RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
const RGBA_Map *m,
int smooth, int level);
EAPI void
evas_common_map_rgba_clean(RGBA_Map *m);
#endif /* _EVAS_MAP_H */

View File

@ -74,7 +74,6 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
// allocate some spans to hold out span list
spans = alloca((yend - ystart + 1) * sizeof(Line));
if (!spans) return;
memset(spans, 0, (yend - ystart + 1) * sizeof(Line));
// calculate the spans list
@ -94,7 +93,6 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
int pa;
buf = alloca(cw * sizeof(DATA32));
if (!buf) return;
pa = src->cache_entry.flags.alpha;
if (havea) src->cache_entry.flags.alpha = 1;
if (dc->mul.use)
@ -115,3 +113,68 @@ FUNC_NAME(RGBA_Image *src, RGBA_Image *dst,
#include "evas_map_image_core.c"
}
}
static void
FUNC_NAME_DO(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
const RGBA_Map_Spans *ms,
int smooth, int level __UNUSED__) // level unused for now - for future use
{
Line *spans;
DATA32 *buf = NULL, *sp;
RGBA_Gfx_Func func = NULL;
int cx, cy, cw, ch;
int ystart, yend, y, sw, shp, swp, direct;
int havecol;
int i;
cx = dc->clip.x;
cy = dc->clip.y;
cw = dc->clip.w;
ch = dc->clip.h;
if (ms->ystart < cy) ystart = cy;
else ystart = ms->ystart;
if (ms->yend >= (cy + ch)) yend = (cy + ch) - 1;
else yend = ms->yend;
// get some source image information
sp = src->image.data;
sw = src->cache_entry.w;
swp = sw << (FP + FPI);
shp = src->cache_entry.h << (FP + FPI);
havecol = ms->havecol;
direct = ms->direct;
// allocate some s to hold out span list
spans = alloca((yend - ystart + 1) * sizeof(Line));
memcpy(spans, &ms->spans[ystart - ms->ystart],
(yend - ystart + 1) * sizeof(Line));
_clip_spans(spans, ystart, yend, cx, cw, ms->nocol);
// if operation is solid, bypass buf and draw func and draw direct to dst
if (!direct)
{
int pa;
buf = alloca(cw * sizeof(DATA32));
pa = src->cache_entry.flags.alpha;
if (ms->havea) src->cache_entry.flags.alpha = 1;
if (dc->mul.use)
func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, cw, dc->render_op);
else
func = evas_common_gfx_func_composite_pixel_span_get(src, dst, cw, dc->render_op);
src->cache_entry.flags.alpha = pa;
}
if (!havecol)
{
#undef COLMUL
#include "evas_map_image_core.c"
}
else
{
#define COLMUL 1
#include "evas_map_image_core.c"
}
}

View File

@ -1,5 +1,3 @@
// THIS IS DEPRECATED. WILL GO EVENTUALLTY. NO NEED TO SUPPORT ANYMORE
#include "evas_common.h"
#include <unistd.h>
@ -79,14 +77,14 @@ evas_common_pipe_thread(void *data)
EINA_INLIST_FOREACH(thinfo->tasks, info)
{
EINA_INLIST_FOREACH(EINA_INLIST_GET(info->im->cache_entry.pipe), p)
EINA_INLIST_FOREACH(EINA_INLIST_GET(thinfo->im->cache_entry.pipe), p)
{
int i;
for (i = 0; i < p->op_num; i++)
{
if (p->op[i].op_func)
p->op[i].op_func(info->im, &(p->op[i]), info);
if (p->op[i].op_func && p->op[i].render)
p->op[i].op_func(thinfo->im, &(p->op[i]), info);
}
}
}
@ -100,12 +98,58 @@ evas_common_pipe_thread(void *data)
#endif
#ifdef BUILD_PTHREAD
static Eina_List *im_task = NULL;
static Eina_List *text_task = NULL;
static Thinfo task_thinfo[TH_MAX];
static pthread_barrier_t task_thbarrier[2];
static LK(im_task_mutex);
static LK(text_task_mutex);
static int thread_num = 0;
static Thinfo thinfo[TH_MAX];
static pthread_barrier_t thbarrier[2];
static RGBA_Pipe_Thread_Info *buf = NULL;
static unsigned int buf_size = 0;
static Cutout_Rects *
evas_pipe_cutout_rects_pop(Thinfo *info)
{
Cutout_Rects *r;
r = eina_array_pop(&info->cutout_trash);
if (!r) r = evas_common_draw_context_cutouts_new();
return r;
}
static void
evas_pipe_cutout_rects_push(Thinfo *info, Cutout_Rects *r)
{
/* evas_common_draw_context_apply_clean_cutouts(r); */
evas_common_draw_context_cutouts_free(r);
eina_array_push(&info->cutout_trash, r);
}
static void
evas_pipe_cutout_rects_rotate(Cutout_Rects *r)
{
static int current = 0;
if (current >= thread_num) current = 0;
evas_pipe_cutout_rects_push(&task_thinfo[current], r);
current++;
}
static void
evas_pipe_prepare_push(RGBA_Pipe_Op *op)
{
static int current = 0;
if (current >= thread_num) current = 0;
eina_array_push(&task_thinfo[current].rects_task, op);
current++;
}
#endif
static void
@ -145,12 +189,11 @@ evas_common_pipe_begin(RGBA_Image *im)
for (y = 0; y < im->cache_entry.h; y += estimatey)
for (x = 0; x < im->cache_entry.w; x += estimatex)
{
info->im = im;
info->x = x;
info->y = y;
info->w = (x + estimatex > im->cache_entry.w) ? im->cache_entry.w - x : estimatex;
info->h = (y + estimatey > im->cache_entry.h) ? im->cache_entry.h - y : estimatey;
EINA_RECTANGLE_SET(&info->area, x, y,
(x + estimatex > im->cache_entry.w) ? im->cache_entry.w - x : estimatex,
(y + estimatey > im->cache_entry.h) ? im->cache_entry.h - y : estimatey);
thinfo[cpu].im = im;
thinfo[cpu].tasks = eina_inlist_prepend((void*) thinfo[cpu].tasks, EINA_INLIST_GET(info));
cpu++;
if (cpu >= (unsigned int) thread_num) cpu = 0;
@ -180,18 +223,14 @@ evas_common_pipe_flush(RGBA_Image *im)
RGBA_Pipe *p;
int i;
info.im = im;
info.x = 0;
info.y = 0;
info.w = im->cache_entry.w;
info.h = im->cache_entry.h;
EINA_RECTANGLE_SET(&info.area, 0, 0, im->cache_entry.w, im->cache_entry.h);
/* process pipe - 1 thead */
for (p = im->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next)
{
for (i = 0; i < p->op_num; i++)
{
if (p->op[i].op_func)
if (p->op[i].render && p->op[i].op_func)
{
p->op[i].op_func(im, &(p->op[i]), &info);
}
@ -223,6 +262,7 @@ evas_common_pipe_free(RGBA_Image *im)
{
p->op[i].free_func(&(p->op[i]));
}
if (p->op[i].rects) evas_pipe_cutout_rects_rotate(p->op[i].rects);
}
im->cache_entry.pipe = (RGBA_Pipe *)eina_inlist_remove(EINA_INLIST_GET(im->cache_entry.pipe), EINA_INLIST_GET(p));
free(p);
@ -239,10 +279,28 @@ evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, cons
RGBA_Draw_Context context;
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
evas_common_rectangle_draw(dst, &(context),
op->op.rect.x, op->op.rect.y,
op->op.rect.w, op->op.rect.h);
evas_common_rectangle_draw_do(op->rects, &info->area, dst, &(context),
op->op.rect.x, op->op.rect.y,
op->op.rect.w, op->op.rect.h);
}
static Eina_Bool
evas_common_pipe_rectangle_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
{
RGBA_Draw_Context context;
Cutout_Rects *recycle;
Thinfo *info = data;
Eina_Bool r;
recycle = evas_pipe_cutout_rects_pop(info);
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
r = evas_common_rectangle_draw_prepare(recycle, dst, &context,
op->op.rect.x, op->op.rect.y,
op->op.rect.w, op->op.rect.h);
if (recycle->active) op->rects = recycle;
else evas_pipe_cutout_rects_push(info, recycle);
return r;
}
EAPI void
@ -259,6 +317,8 @@ evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, i
op->op.rect.h = h;
op->op_func = evas_common_pipe_rectangle_draw_do;
op->free_func = evas_common_pipe_op_free;
op->prepare_func = evas_common_pipe_rectangle_prepare;
evas_pipe_prepare_push(op);
evas_common_pipe_draw_context_copy(dc, op);
}
@ -269,7 +329,7 @@ evas_common_pipe_line_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGB
RGBA_Draw_Context context;
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h);
evas_common_line_draw(dst, &(context),
op->op.line.x0, op->op.line.y0,
op->op.line.x1, op->op.line.y1);
@ -289,6 +349,7 @@ evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
op->op.line.y1 = y1;
op->op_func = evas_common_pipe_line_draw_do;
op->free_func = evas_common_pipe_op_free;
op->prepare_func = NULL;
evas_common_pipe_draw_context_copy(dc, op);
}
@ -298,6 +359,7 @@ evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op)
{
RGBA_Polygon_Point *p;
#if 0
while (op->op.poly.points)
{
p = op->op.poly.points;
@ -305,6 +367,7 @@ evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op)
EINA_INLIST_GET(p));
free(p);
}
#endif
evas_common_pipe_op_free(op);
}
@ -314,9 +377,9 @@ evas_common_pipe_poly_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGB
RGBA_Draw_Context context;
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h);
evas_common_polygon_draw(dst, &(context),
op->op.poly.points, 0, 0);
op->op.poly.points, op->op.poly.x, op->op.poly.y);
}
EAPI void
@ -324,12 +387,13 @@ evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
RGBA_Polygon_Point *points, int x, int y)
{
RGBA_Pipe_Op *op;
RGBA_Polygon_Point *pts = NULL, *p, *pp;
/* RGBA_Polygon_Point *pts = NULL, *p, *pp; */
if (!points) return;
dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
if (!dst->cache_entry.pipe) return;
/* FIXME: copy points - maybe we should refcount? */
#if 0
for (p = points; p; p = (RGBA_Polygon_Point *)(EINA_INLIST_GET(p))->next)
{
pp = calloc(1, sizeof(RGBA_Polygon_Point));
@ -340,9 +404,13 @@ evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
pts = (RGBA_Polygon_Point *)eina_inlist_append(EINA_INLIST_GET(pts), EINA_INLIST_GET(pp));
}
}
op->op.poly.points = pts;
#endif
op->op.poly.x = x;
op->op.poly.y = y;
op->op.poly.points = points/* pts */;
op->op_func = evas_common_pipe_poly_draw_do;
op->free_func = evas_common_pipe_op_poly_free;
op->prepare_func = NULL; /* FIXME: If we really want to improve it, we should prepare span for it here */
evas_common_pipe_draw_context_copy(dc, op);
}
@ -360,8 +428,24 @@ evas_common_pipe_text_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGB
RGBA_Draw_Context context;
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
evas_common_font_draw(dst, &(context), op->op.text.x, op->op.text.y, op->op.text.intl_props);
evas_common_font_draw_do(op->rects, &info->area, op->op.text.func, dst, &(context), op->op.text.x, op->op.text.y, op->op.text.intl_props);
}
static Eina_Bool
evas_common_pipe_text_draw_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
{
RGBA_Draw_Context context;
Cutout_Rects *recycle;
Thinfo *info = data;
Eina_Bool r;
recycle = evas_pipe_cutout_rects_pop(info);
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
r = evas_common_font_draw_prepare_cutout(recycle, dst, &context, &(op->op.text.func));
if (recycle->active) op->rects = recycle;
else evas_pipe_cutout_rects_push(info, recycle);
return r;
}
EAPI void
@ -378,6 +462,8 @@ evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
evas_common_text_props_content_ref(intl_props);
op->op_func = evas_common_pipe_text_draw_do;
op->free_func = evas_common_pipe_op_text_free;
op->prepare_func = evas_common_pipe_text_draw_prepare;
evas_pipe_prepare_push(op);
evas_common_pipe_draw_context_copy(dc, op);
evas_common_pipe_text_prepare(intl_props);
}
@ -394,15 +480,35 @@ evas_common_pipe_op_image_free(RGBA_Pipe_Op *op)
evas_common_pipe_op_free(op);
}
static Eina_Bool
evas_common_pipe_op_image_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
{
RGBA_Draw_Context context;
Cutout_Rects *recycle;
Thinfo *info = data;
Eina_Bool r;
recycle = evas_pipe_cutout_rects_pop(info);
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
r = evas_common_scale_rgba_in_to_out_clip_prepare(recycle, op->op.image.src, dst, &(context),
op->op.image.dx, op->op.image.dy,
op->op.image.dw, op->op.image.dh);
if (recycle->active) op->rects = recycle;
else evas_pipe_cutout_rects_push(info, recycle);
return r;
}
static void
evas_common_pipe_image_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
{
RGBA_Draw_Context context;
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
#ifdef SCALECACHE
/* FIXME: Make the scalecache path use the prepared Cutout ? */
evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h);
evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src),
dst, &(context),
op->op.image.smooth,
@ -417,29 +523,31 @@ evas_common_pipe_image_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RG
#else
if (op->op.image.smooth)
{
evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src,
dst, &(context),
op->op.image.sx,
op->op.image.sy,
op->op.image.sw,
op->op.image.sh,
op->op.image.dx,
op->op.image.dy,
op->op.image.dw,
op->op.image.dh);
evas_common_scale_rgba_in_to_out_clip_smooth_do(op->rects, &info->area,
op->op.image.src,
dst, &(context),
op->op.image.sx,
op->op.image.sy,
op->op.image.sw,
op->op.image.sh,
op->op.image.dx,
op->op.image.dy,
op->op.image.dw,
op->op.image.dh);
}
else
{
evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src,
dst, &(context),
op->op.image.sx,
op->op.image.sy,
op->op.image.sw,
op->op.image.sh,
op->op.image.dx,
op->op.image.dy,
op->op.image.dw,
op->op.image.dh);
evas_common_scale_rgba_in_to_out_clip_sample_do(op->rects, &info->area,
op->op.image.src,
dst, &(context),
op->op.image.sx,
op->op.image.sy,
op->op.image.sw,
op->op.image.sh,
op->op.image.dx,
op->op.image.dy,
op->op.image.dw,
op->op.image.dh);
}
#endif
}
@ -471,6 +579,8 @@ evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst,
op->op.image.src = src;
op->op_func = evas_common_pipe_image_draw_do;
op->free_func = evas_common_pipe_op_image_free;
op->prepare_func = evas_common_pipe_op_image_prepare;
evas_pipe_prepare_push(op);
evas_common_pipe_draw_context_copy(dc, op);
evas_common_pipe_image_load(src);
@ -482,7 +592,7 @@ evas_common_pipe_op_map_free(RGBA_Pipe_Op *op)
op->op.map.src->ref--;
if (op->op.map.src->ref == 0)
evas_cache_image_drop(&op->op.map.src->cache_entry);
free(op->op.map.p);
/* free(op->op.map.p); */
evas_common_pipe_op_free(op);
}
@ -492,43 +602,56 @@ evas_common_pipe_map_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA
RGBA_Draw_Context context;
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
evas_common_map_rgba_do(&info->area, op->op.map.src, dst,
&context, op->op.map.m,
op->op.map.smooth, op->op.map.level);
}
evas_common_map_rgba(op->op.map.src, dst,
&context, op->op.map.npoints, op->op.map.p,
op->op.map.smooth, op->op.map.level);
static Eina_Bool
evas_common_pipe_map_draw_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
{
RGBA_Draw_Context context;
Thinfo *info = data;
Eina_Bool r;
memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
r = evas_common_map_rgba_prepare(op->op.map.src, dst,
&context, op->op.map.m);
return r;
}
EAPI void
evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc, int npoints, RGBA_Map_Point *p,
RGBA_Draw_Context *dc, RGBA_Map *m,
int smooth, int level)
{
RGBA_Pipe_Op *op;
RGBA_Map_Point *pts_copy;
/* RGBA_Map_Point *pts_copy; */
int i;
if (!src) return;
pts_copy = malloc(sizeof (RGBA_Map_Point) * 4);
if (!pts_copy) return;
/* pts_copy = malloc(sizeof (RGBA_Map_Point) * 4); */
/* if (!pts_copy) return; */
dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
if (!dst->cache_entry.pipe)
{
free(pts_copy);
/* free(pts_copy); */
return;
}
for (i = 0; i < 4; ++i)
pts_copy[i] = p[i];
/* for (i = 0; i < 4; ++i) */
/* pts_copy[i] = p[i]; */
op->op.map.npoints = npoints;
op->op.map.smooth = smooth;
op->op.map.level = level;
src->ref++;
op->op.map.src = src;
op->op.map.p = pts_copy;
op->op.map.m = m;
op->op_func = evas_common_pipe_map_draw_do;
op->free_func = evas_common_pipe_op_map_free;
op->prepare_func = evas_common_pipe_map_draw_prepare;
evas_pipe_prepare_push(op);
evas_common_pipe_draw_context_copy(dc, op);
evas_common_pipe_image_load(src);
@ -562,15 +685,6 @@ evas_common_pipe_map_render(RGBA_Image *root)
evas_common_pipe_flush(root);
}
#ifdef BUILD_PTHREAD
static Eina_List *im_task = NULL;
static Eina_List *text_task = NULL;
static Thinfo task_thinfo[TH_MAX];
static pthread_barrier_t task_thbarrier[2];
static LK(im_task_mutex);
static LK(text_task_mutex);
#endif
#ifdef BUILD_PTHREAD
static void*
evas_common_pipe_load(void *data)
@ -580,6 +694,9 @@ evas_common_pipe_load(void *data)
tinfo = data;
for (;;)
{
RGBA_Pipe_Op *op;
Eina_Array_Iterator it;
unsigned int i;
/* wait for start signal */
pthread_barrier_wait(&(tinfo->barrier[0]));
@ -625,6 +742,10 @@ evas_common_pipe_load(void *data)
}
}
EINA_ARRAY_ITER_NEXT(&tinfo->rects_task, i, op, it)
op->render = op->prepare_func(tinfo, tinfo->im, op);
eina_array_clean(&tinfo->rects_task);
/* send finished signal */
pthread_barrier_wait(&(tinfo->barrier[1]));
}
@ -636,20 +757,23 @@ evas_common_pipe_load(void *data)
static volatile int bval = 0;
static void
evas_common_pipe_load_do(void)
evas_common_pipe_load_do(RGBA_Image *im)
{
#ifdef BUILD_PTHREAD
if (!im_task && !text_task) return ;
int i;
/* Notify worker thread. */
pthread_barrier_wait(&(task_thbarrier[0]));
for (i = 0; i < thread_num; i++)
task_thinfo[i].im = im;
/* sync worker threads */
pthread_barrier_wait(&(task_thbarrier[1]));
/* Notify worker thread. */
pthread_barrier_wait(&(task_thbarrier[0]));
/* sync worker threads */
pthread_barrier_wait(&(task_thbarrier[1]));
#endif
}
static Eina_Bool
EAPI Eina_Bool
evas_common_pipe_init(void)
{
#ifdef BUILD_PTHREAD
@ -703,6 +827,8 @@ evas_common_pipe_init(void)
task_thinfo[i].thread_num = i;
task_thinfo[i].tasks = NULL;
task_thinfo[i].barrier = task_thbarrier;
eina_array_step_set(&task_thinfo[i].cutout_trash, sizeof (Eina_Array), 8);
eina_array_step_set(&task_thinfo[i].rects_task, sizeof (Eina_Array), 8);
/* setup initial locks */
pthread_create(&(task_thinfo[i].thread_id), &attr,
evas_common_pipe_load, &(task_thinfo[i]));
@ -746,7 +872,7 @@ evas_common_pipe_text_prepare(Evas_Text_Props *text_props)
fi = text_props->font_instance;
if (!fi) return ;
if (!text_props->changed && text_props->generation == fi->generation && text_props->bin)
if (!text_props->changed && text_props->generation == fi->generation && text_props->glyphs)
return ;
LKL(fi->ft_mutex);
@ -783,7 +909,7 @@ evas_common_pipe_map_begin(RGBA_Image *root)
}
}
evas_common_pipe_load_do();
evas_common_pipe_load_do(root);
evas_common_pipe_map_render(root);
}

View File

@ -7,10 +7,13 @@
#ifdef BUILD_PTHREAD
typedef struct _Thinfo
{
RGBA_Image *im;
int thread_num;
pthread_t thread_id;
pthread_barrier_t *barrier;
const Eina_Inlist *tasks;
Eina_Array cutout_trash;
Eina_Array rects_task;
} Thinfo;
#endif
@ -18,6 +21,8 @@ typedef struct _Thinfo
* threadable
*/
EAPI Eina_Bool evas_common_pipe_init(void);
EAPI void evas_common_pipe_free(RGBA_Image *im);
EAPI void evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
EAPI void evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x0, int y0, int x1, int y1);
@ -28,8 +33,8 @@ EAPI void evas_common_pipe_image_load(RGBA_Image *im);
EAPI void evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int smooth, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
EAPI void evas_common_pipe_map_begin(RGBA_Image *root);
EAPI void evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc, int npoints, RGBA_Map_Point *p,
int smooth, int level);
RGBA_Draw_Context *dc, RGBA_Map *m,
int smooth, int level);
EAPI void evas_common_pipe_flush(RGBA_Image *im);
#endif /* _EVAS_PIPE_H */

View File

@ -6,6 +6,8 @@ EAPI void evas_common_rectangle_init (void);
EAPI void evas_common_rectangle_draw (RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
EAPI void evas_common_rectangle_draw_do(const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
EAPI Eina_Bool evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
#endif /* _EVAS_RECTANGLE_H */

View File

@ -1,4 +1,5 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_blend_private.h"
static void rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h);
@ -11,7 +12,7 @@ evas_common_rectangle_init(void)
EAPI void
evas_common_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
Cutout_Rects *rects;
static Cutout_Rects *rects = NULL;
Cutout_Rect *r;
int c, cx, cy, cw, ch;
int i;
@ -34,20 +35,67 @@ evas_common_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y,
/* our clip is 0 size.. abort */
if ((dc->clip.w > 0) && (dc->clip.h > 0))
{
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
rectangle_draw_internal(dst, dc, x, y, w, h);
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
}
/* restore clip info */
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
}
EAPI Eina_Bool
evas_common_rectangle_draw_prepare(Cutout_Rects *reuse, const RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
if ((w <= 0) || (h <= 0)) return EINA_FALSE;
if (!(RECTS_INTERSECT(x, y, w, h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
return EINA_FALSE;
/* save out clip info */
evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
/* no cutouts - cut right to the chase */
if (dc->cutout.rects)
{
evas_common_draw_context_clip_clip(dc, x, y, w, h);
/* our clip is 0 size.. abort */
if ((dc->clip.w > 0) && (dc->clip.h > 0))
reuse = evas_common_draw_context_apply_cutouts(dc, reuse);
}
return EINA_TRUE;
}
EAPI void
evas_common_rectangle_draw_do(const Cutout_Rects *reuse,
const Eina_Rectangle *clip,
RGBA_Image *dst, RGBA_Draw_Context *dc,
int x, int y, int w, int h)
{
Eina_Rectangle area;
Cutout_Rect *r;
int i;
if (!reuse)
{
evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h);
rectangle_draw_internal(dst, dc, x, y, w, h);
return ;
}
for (i = 0; i < reuse->active; ++i)
{
r = reuse->rects + i;
EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
if (!eina_rectangle_intersection(&area, clip)) continue ;
evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
rectangle_draw_internal(dst, dc, x, y, w, h);
}
}
static void
rectangle_draw_internal(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
{

View File

@ -1,6 +1,33 @@
#include "evas_common.h"
#include "evas_private.h"
EAPI void
evas_common_scale_init(void)
{
}
EAPI Eina_Bool
evas_common_scale_rgba_in_to_out_clip_prepare(Cutout_Rects *reuse, const RGBA_Image *src __UNUSED__,
const RGBA_Image *dst,
RGBA_Draw_Context *dc,
int dst_region_x, int dst_region_y,
int dst_region_w, int dst_region_h)
{
/* handle cutouts here! */
if ((dst_region_w <= 0) || (dst_region_h <= 0)) return EINA_FALSE;
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 EINA_FALSE;
/* no cutouts - cut right to the chase */
if (!dc->cutout.rects) return EINA_TRUE;
evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h);
/* our clip is 0 size.. abort */
if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
return EINA_FALSE;
reuse = evas_common_draw_context_apply_cutouts(dc, reuse);
return EINA_TRUE;
}

View File

@ -10,4 +10,9 @@ EAPI void evas_common_scale_rgba_in_to_out_clip_sample (RGBA_Image *src, RG
EAPI void evas_common_rgba_image_scalecache_dump(void);
EAPI void evas_common_scale_rgba_in_to_out_clip_sample_do (const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
EAPI void evas_common_scale_rgba_in_to_out_clip_smooth_do (const Cutout_Rects *reuse, const Eina_Rectangle *clip, RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
EAPI Eina_Bool evas_common_scale_rgba_in_to_out_clip_prepare (Cutout_Rects *reuse, const RGBA_Image *src, const RGBA_Image *dst, RGBA_Draw_Context *dc, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
#endif /* _EVAS_SCALE_MAIN_H */

View File

@ -1,10 +1,27 @@
#include "evas_common.h"
#include "evas_blend_private.h"
void scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
static void scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst, RGBA_Draw_Context *dc, int src_region_x, int src_region_y, int src_region_w, int src_region_h, int dst_region_x, int dst_region_y, int dst_region_w, int dst_region_h);
#ifndef BUILD_SCALE_SMOOTH
#ifdef BUILD_SCALE_SAMPLE
EAPI void
evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse,
const Eina_Rectangle *clip,
RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
int src_region_x, int src_region_y,
int src_region_w, int src_region_h,
int dst_region_x, int dst_region_y,
int dst_region_w, int dst_region_h)
{
evas_common_scale_rgba_in_to_out_clip_sample_do(reuse, clip, src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
}
EAPI void
evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
@ -31,7 +48,7 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
int dst_region_x, int dst_region_y,
int dst_region_w, int dst_region_h)
{
Cutout_Rects *rects;
static Cutout_Rects *rects = NULL;
Cutout_Rect *r;
int c, cx, cy, cw, ch;
int i;
@ -60,7 +77,7 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
@ -72,12 +89,51 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
dst_region_w, dst_region_h);
}
evas_common_draw_context_apply_clear_cutouts(rects);
/* restore clip info */
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
}
void
EAPI void
evas_common_scale_rgba_in_to_out_clip_sample_do(const Cutout_Rects *reuse,
const Eina_Rectangle *clip,
RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
int src_region_x, int src_region_y,
int src_region_w, int src_region_h,
int dst_region_x, int dst_region_y,
int dst_region_w, int dst_region_h)
{
Eina_Rectangle area;
Cutout_Rect *r;
int i;
if (!reuse)
{
evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h);
scale_rgba_in_to_out_clip_sample_internal(src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
return;
}
for (i = 0; i < reuse->active; ++i)
{
r = reuse->rects + i;
EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
if (!eina_rectangle_intersection(&area, clip)) continue ;
evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
scale_rgba_in_to_out_clip_sample_internal(src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
}
}
static void
scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
int src_region_x, int src_region_y,
@ -403,5 +459,22 @@ evas_common_scale_rgba_in_to_out_clip_sample(RGBA_Image *src, RGBA_Image *dst,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
}
EAPI void
evas_common_scale_rgba_in_to_out_clip_sample_do(const Cutout_Rects *reuse,
const Eina_Rectangle *clip,
RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
int src_region_x, int src_region_y,
int src_region_w, int src_region_h,
int dst_region_x, int dst_region_y,
int dst_region_w, int dst_region_h)
{
evas_common_scale_rgba_in_to_out_clip_smooth_do(reuse, clip, src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
}
#endif
#endif

View File

@ -460,7 +460,7 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
# ifdef BUILD_MMX
int mmx, sse, sse2;
# endif
Cutout_Rects *rects;
static Cutout_Rects *rects = NULL;
Cutout_Rect *r;
int c, cx, cy, cw, ch;
int i;
@ -503,7 +503,7 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
@ -525,8 +525,76 @@ evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
dst_region_w, dst_region_h);
# endif
}
evas_common_draw_context_apply_clear_cutouts(rects);
/* restore clip info */
dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
}
EAPI void
evas_common_scale_rgba_in_to_out_clip_smooth_do(const Cutout_Rects *reuse,
const Eina_Rectangle *clip,
RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc,
int src_region_x, int src_region_y,
int src_region_w, int src_region_h,
int dst_region_x, int dst_region_y,
int dst_region_w, int dst_region_h)
{
# ifdef BUILD_MMX
int mmx, sse, sse2;
# endif
Eina_Rectangle area;
Cutout_Rect *r;
int i;
# ifdef BUILD_MMX
evas_common_cpu_can_do(&mmx, &sse, &sse2);
# endif
if (!reuse)
{
evas_common_draw_context_set_clip(dc, clip->x, clip->y, clip->w, clip->h);
# ifdef BUILD_MMX
if (mmx)
evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
else
# endif
# ifdef BUILD_C
evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
# endif
return ;
}
for (i = 0; i < reuse->active; ++i)
{
r = reuse->rects + i;
EINA_RECTANGLE_SET(&area, r->x, r->y, r->w, r->h);
if (!eina_rectangle_intersection(&area, clip)) continue ;
evas_common_draw_context_set_clip(dc, area.x, area.y, area.w, area.h);
# ifdef BUILD_MMX
if (mmx)
evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
else
# endif
# ifdef BUILD_C
evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
src_region_x, src_region_y,
src_region_w, src_region_h,
dst_region_x, dst_region_y,
dst_region_w, dst_region_h);
# endif
}
}
#endif

View File

@ -36,6 +36,8 @@ evas_common_text_props_content_copy_and_ref(Evas_Text_Props *dst,
const Evas_Text_Props *src)
{
memcpy(dst, src, sizeof(Evas_Text_Props));
dst->glyphs = NULL;
dst->glyphs_length = 0;
evas_common_text_props_content_ref(dst);
}
@ -66,11 +68,9 @@ evas_common_text_props_content_unref(Evas_Text_Props *props)
if (--(props->info->refcount) == 0)
{
if (props->bin)
{
eina_binbuf_free(props->bin);
props->bin = NULL;
}
free(props->glyphs);
props->glyphs = NULL;
props->glyphs_length = 0;
if (props->info->glyph)
free(props->info->glyph);

View File

@ -18,6 +18,8 @@ typedef enum
/* Used for showing "malformed" or missing chars */
#define REPLACEMENT_CHAR 0xFFFD
typedef struct _Evas_Glyph Evas_Glyph;
struct _Evas_Text_Props
{
/* Start and len represent the start offset and the length in the
@ -31,7 +33,8 @@ struct _Evas_Text_Props
Evas_Text_Props_Info *info;
void *font_instance;
Eina_Binbuf *bin;
Evas_Glyph *glyphs;
int glyphs_length;
int generation;
Eina_Bool changed : 1;

View File

@ -474,8 +474,8 @@ evas_common_soft16_image_draw(Soft16_Image *src, Soft16_Image *dst,
int dst_region_w, int dst_region_h,
int smooth __UNUSED__)
{
static Cutout_Rects *rects = NULL;
Eina_Rectangle sr, dr;
Cutout_Rects *rects;
Cutout_Rect *r;
struct RGBA_Draw_Context_clip clip_bkp;
int i;
@ -510,14 +510,13 @@ evas_common_soft16_image_draw(Soft16_Image *src, Soft16_Image *dst,
dc->clip = clip_bkp;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; i++)
{
r = rects->rects + i;
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
_soft16_image_draw_sampled_int(src, dst, dc, sr, dr);
}
evas_common_draw_context_apply_clear_cutouts(rects);
dc->clip = clip_bkp;
}

View File

@ -78,8 +78,8 @@ void
evas_common_soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc,
int x, int y, int w, int h)
{
static Cutout_Rects *rects = NULL;
Eina_Rectangle dr;
Cutout_Rects *rects;
Cutout_Rect *r;
struct RGBA_Draw_Context_clip c_bkp;
int i;
@ -108,14 +108,13 @@ evas_common_soft16_rectangle_draw(Soft16_Image *dst, RGBA_Draw_Context *dc,
dc->clip = c_bkp;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
_soft16_rectangle_draw_int(dst, dc, dr);
}
evas_common_draw_context_apply_clear_cutouts(rects);
dc->clip = c_bkp;
}

View File

@ -523,8 +523,8 @@ evas_common_soft8_image_draw(Soft8_Image * src, Soft8_Image * dst,
int dst_region_w, int dst_region_h,
int smooth __UNUSED__)
{
static Cutout_Rects *rects = NULL;
Eina_Rectangle sr, dr;
Cutout_Rects *rects;
Cutout_Rect *r;
struct RGBA_Draw_Context_clip clip_bkp;
int i;
@ -569,14 +569,13 @@ evas_common_soft8_image_draw(Soft8_Image * src, Soft8_Image * dst,
dc->clip = clip_bkp;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; i++)
{
r = rects->rects + i;
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
_soft8_image_draw_sampled_int(src, dst, dc, sr, dr);
}
evas_common_draw_context_apply_clear_cutouts(rects);
dc->clip = clip_bkp;
}

View File

@ -79,8 +79,8 @@ void
evas_common_soft8_rectangle_draw(Soft8_Image * dst, RGBA_Draw_Context * dc,
int x, int y, int w, int h)
{
static Cutout_Rects *rects = NULL;
Eina_Rectangle dr;
Cutout_Rects *rects;
Cutout_Rect *r;
struct RGBA_Draw_Context_clip c_bkp;
int i;
@ -113,13 +113,12 @@ evas_common_soft8_rectangle_draw(Soft8_Image * dst, RGBA_Draw_Context * dc,
dc->clip = c_bkp;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
_soft8_rectangle_draw_int(dst, dc, dr);
}
evas_common_draw_context_apply_clear_cutouts(rects);
dc->clip = c_bkp;
}

View File

@ -728,8 +728,10 @@ struct _RGBA_Draw_Context
struct _RGBA_Pipe_Op
{
RGBA_Draw_Context context;
Eina_Bool (*prepare_func) (void *data, RGBA_Image *dst, RGBA_Pipe_Op *op);
void (*op_func) (RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info);
void (*free_func) (RGBA_Pipe_Op *op);
Cutout_Rects *rects;
union {
struct {
@ -739,11 +741,13 @@ struct _RGBA_Pipe_Op
int x0, y0, x1, y1;
} line;
struct {
int x, y;
RGBA_Polygon_Point *points;
} poly;
struct {
int x, y;
Evas_Text_Props *intl_props;
RGBA_Gfx_Func func;
} text;
struct {
RGBA_Image *src;
@ -753,12 +757,14 @@ struct _RGBA_Pipe_Op
} image;
struct {
RGBA_Image *src;
RGBA_Map_Point *p;
RGBA_Map *m;
int npoints;
int smooth;
int level;
} map;
} op;
Eina_Bool render : 1;
};
#define PIPE_LEN 256
@ -773,8 +779,7 @@ struct _RGBA_Pipe
struct _RGBA_Pipe_Thread_Info
{
EINA_INLIST;
RGBA_Image *im;
int x, y, w, h;
Eina_Rectangle area;
};
#endif

View File

@ -834,9 +834,10 @@ struct _Evas_Func
int (*image_scale_hint_get) (void *data, void *image);
int (*font_last_up_to_pos) (void *data, Evas_Font_Set *font, const Evas_Text_Props *intl_props, int x, int y);
void (*image_map_draw) (void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level);
void (*image_map_draw) (void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level);
void *(*image_map_surface_new) (void *data, int w, int h, int alpha);
void (*image_map_surface_free) (void *data, void *surface);
void (*image_map_clean) (void *data, RGBA_Map *m);
void (*image_content_hint_set) (void *data, void *surface, int hint);
int (*image_content_hint_get) (void *data, void *surface);

View File

@ -404,10 +404,10 @@ typedef void (*_cb_for_each_cutout_t)(IDirectFBSurface *surface, RGBA_Draw_Conte
static void
_dfb_surface_for_each_cutout(IDirectFBSurface *surface, RGBA_Draw_Context *dc, _cb_for_each_cutout_t cb, void *data)
{
Cutout_Rects *rects;
static Cutout_Rects *rects = NULL;
int i;
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
if (!rects)
{
DFBRegion cr;
@ -435,7 +435,6 @@ _dfb_surface_for_each_cutout(IDirectFBSurface *surface, RGBA_Draw_Context *dc, _
surface->SetClip(surface, &cr);
cb(surface, dc, &cr, data);
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
static void

View File

@ -103,7 +103,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
Evas_Engine_GL_Context *gc = context;
RGBA_Draw_Context *dc = draw_context;
Evas_GL_Texture *tex;
Cutout_Rects *rects;
static Cutout_Rects *rects = NULL;
Cutout_Rect *rct;
int r, g, b, a;
double ssx, ssy, ssw, ssh;
@ -171,7 +171,7 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; ++i)
{
int nx, ny, nw, nh;
@ -198,7 +198,6 @@ evas_gl_font_texture_draw(void *context, void *surface __UNUSED__, void *draw_co
nx, ny, nw, nh,
r, g, b, a);
}
evas_common_draw_context_apply_clear_cutouts(rects);
/* restore clip info */
gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
}

View File

@ -690,12 +690,12 @@ evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
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)
{
static Cutout_Rects *rects = NULL;
RGBA_Draw_Context *dc;
Evas_GL_Image *imm;
int r, g, b, a;
double ssx, ssy, ssw, ssh;
double mssx, mssy, mssw, mssh;
Cutout_Rects *rects;
Cutout_Rect *rct;
int c, cx, cy, cw, ch;
int i;
@ -888,7 +888,7 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
return;
}
rects = evas_common_draw_context_apply_cutouts(dc);
rects = evas_common_draw_context_apply_cutouts(dc, rects);
for (i = 0; i < rects->active; ++i)
{
int nx, ny, nw, nh;
@ -962,7 +962,6 @@ evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx,
r, g, b, a,
smooth, im->tex_only);
}
evas_common_draw_context_apply_clear_cutouts(rects);
/* restore clip info */
gc->dc->clip.use = c; gc->dc->clip.x = cx; gc->dc->clip.y = cy; gc->dc->clip.w = cw; gc->dc->clip.h = ch;
}

View File

@ -122,7 +122,7 @@ polygon_edge_sorter(const void *a, const void *b)
void
evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int dx, int dy)
{
Cutout_Rects *rects;
static Cutout_Rects *rects = NULL;
Cutout_Rect *r;
int c, cx, cy, cw, ch, cr, cg, cb, ca, i;
int x = 0, y = 0, w = 0, h = 0;
@ -272,7 +272,7 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
/* our clip is 0 size.. abort */
if ((gc->dc->clip.w > 0) && (gc->dc->clip.h > 0))
{
rects = evas_common_draw_context_apply_cutouts(gc->dc);
rects = evas_common_draw_context_apply_cutouts(gc->dc, rects);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
@ -290,7 +290,6 @@ evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int
}
}
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
}
while (spans)

View File

@ -3,7 +3,7 @@
void
evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
{
Cutout_Rects *rects;
static Cutout_Rects *rects = NULL;
Cutout_Rect *r;
int c, cx, cy, cw, ch, cr, cg, cb, ca, i;
@ -37,7 +37,7 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
/* our clip is 0 size.. abort */
if ((gc->dc->clip.w > 0) && (gc->dc->clip.h > 0))
{
rects = evas_common_draw_context_apply_cutouts(gc->dc);
rects = evas_common_draw_context_apply_cutouts(gc->dc, rects);
for (i = 0; i < rects->active; ++i)
{
r = rects->rects + i;
@ -46,7 +46,6 @@ evas_gl_common_rect_draw(Evas_Engine_GL_Context *gc, int x, int y, int w, int h)
evas_gl_common_context_rectangle_push(gc, r->x, r->y, r->w, r->h, cr, cg, cb, ca);
}
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
}
/* restore clip info */

View File

@ -2747,7 +2747,7 @@ eng_image_scale_hint_get(void *data __UNUSED__, void *image)
}
static void
eng_image_map_draw(void *data, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level)
{
Evas_GL_Image *gim = image;
Render_Engine *re;
@ -2757,46 +2757,51 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, int np
eng_window_use(re->win);
evas_gl_common_context_target_surface_set(re->win->gl_context, surface);
re->win->gl_context->dc = context;
if (npoints != 4)
if (m->count != 4)
{
// FIXME: nash - you didn't fix this
abort();
}
if ((p[0].x == p[3].x) &&
(p[1].x == p[2].x) &&
(p[0].y == p[1].y) &&
(p[3].y == p[2].y) &&
(p[0].x <= p[1].x) &&
(p[0].y <= p[2].y) &&
(p[0].u == 0) &&
(p[0].v == 0) &&
(p[1].u == (gim->w << FP)) &&
(p[1].v == 0) &&
(p[2].u == (gim->w << FP)) &&
(p[2].v == (gim->h << FP)) &&
(p[3].u == 0) &&
(p[3].v == (gim->h << FP)) &&
(p[0].col == 0xffffffff) &&
(p[1].col == 0xffffffff) &&
(p[2].col == 0xffffffff) &&
(p[3].col == 0xffffffff))
if ((m->pts[0].x == m->pts[3].x) &&
(m->pts[1].x == m->pts[2].x) &&
(m->pts[0].y == m->pts[1].y) &&
(m->pts[3].y == m->pts[2].y) &&
(m->pts[0].x <= m->pts[1].x) &&
(m->pts[0].y <= m->pts[2].y) &&
(m->pts[0].u == 0) &&
(m->pts[0].v == 0) &&
(m->pts[1].u == (gim->w << FP)) &&
(m->pts[1].v == 0) &&
(m->pts[2].u == (gim->w << FP)) &&
(m->pts[2].v == (gim->h << FP)) &&
(m->pts[3].u == 0) &&
(m->pts[3].v == (gim->h << FP)) &&
(m->pts[0].col == 0xffffffff) &&
(m->pts[1].col == 0xffffffff) &&
(m->pts[2].col == 0xffffffff) &&
(m->pts[3].col == 0xffffffff))
{
int dx, dy, dw, dh;
dx = p[0].x >> FP;
dy = p[0].y >> FP;
dw = (p[2].x >> FP) - dx;
dh = (p[2].y >> FP) - dy;
dx = m->pts[0].x >> FP;
dy = m->pts[0].y >> FP;
dw = (m->pts[2].x >> FP) - dx;
dh = (m->pts[2].y >> FP) - dy;
eng_image_draw(data, context, surface, image,
0, 0, gim->w, gim->h, dx, dy, dw, dh, smooth);
}
else
{
evas_gl_common_image_map_draw(re->win->gl_context, image, npoints, p,
evas_gl_common_image_map_draw(re->win->gl_context, image, m->count, &m->pts[0],
smooth, level);
}
}
static void
eng_image_map_clean(void *data, RGBA_Map *m)
{
}
static void *
eng_image_map_surface_new(void *data, int w, int h, int alpha)
{
@ -4955,6 +4960,7 @@ module_open(Evas_Module *em)
ORD(image_map_draw);
ORD(image_map_surface_new);
ORD(image_map_surface_free);
ORD(image_map_clean);
ORD(image_content_hint_set);
ORD(image_content_hint_get);

View File

@ -939,41 +939,37 @@ image_loaded:
}
static void
eng_image_map_draw(void *data __UNUSED__, void *context, void *surface, void *image, int npoints, RGBA_Map_Point *p, int smooth, int level)
evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGBA_Image *im, RGBA_Map *m, int smooth, int level, int offset)
{
RGBA_Image *im;
if (m->count - offset < 3) return;
if (!image) return;
if (npoints < 3) return;
im = image;
if ((p[0].x == p[3].x) &&
(p[1].x == p[2].x) &&
(p[0].y == p[1].y) &&
(p[3].y == p[2].y) &&
(p[0].x <= p[1].x) &&
(p[0].y <= p[2].y) &&
(p[0].u == 0) &&
(p[0].v == 0) &&
(p[1].u == (int)(im->cache_entry.w << FP)) &&
(p[1].v == 0) &&
(p[2].u == (int)(im->cache_entry.w << FP)) &&
(p[2].v == (int)(im->cache_entry.h << FP)) &&
(p[3].u == 0) &&
(p[3].v == (int)(im->cache_entry.h << FP)) &&
(p[0].col == 0xffffffff) &&
(p[1].col == 0xffffffff) &&
(p[2].col == 0xffffffff) &&
(p[3].col == 0xffffffff))
if ((m->pts[0 + offset].x == m->pts[3 + offset].x) &&
(m->pts[1 + offset].x == m->pts[2 + offset].x) &&
(m->pts[0 + offset].y == m->pts[1 + offset].y) &&
(m->pts[3 + offset].y == m->pts[2 + offset].y) &&
(m->pts[0 + offset].x <= m->pts[1 + offset].x) &&
(m->pts[0 + offset].y <= m->pts[2 + offset].y) &&
(m->pts[0 + offset].u == 0) &&
(m->pts[0 + offset].v == 0) &&
(m->pts[1 + offset].u == (int)(im->cache_entry.w << FP)) &&
(m->pts[1 + offset].v == 0) &&
(m->pts[2 + offset].u == (int)(im->cache_entry.w << FP)) &&
(m->pts[2 + offset].v == (int)(im->cache_entry.h << FP)) &&
(m->pts[3 + offset].u == 0) &&
(m->pts[3 + offset].v == (int)(im->cache_entry.h << FP)) &&
(m->pts[0 + offset].col == 0xffffffff) &&
(m->pts[1 + offset].col == 0xffffffff) &&
(m->pts[2 + offset].col == 0xffffffff) &&
(m->pts[3 + offset].col == 0xffffffff))
{
int dx, dy, dw, dh;
dx = p[0].x >> FP;
dy = p[0].y >> FP;
dw = (p[2].x >> FP) - dx;
dh = (p[2].y >> FP) - dy;
dx = m->pts[0 + offset].x >> FP;
dy = m->pts[0 + offset].y >> FP;
dw = (m->pts[2 + offset].x >> FP) - dx;
dh = (m->pts[2 + offset].y >> FP) - dy;
eng_image_draw
(data, context, surface, image,
(data, context, surface, im,
0, 0, im->cache_entry.w, im->cache_entry.h,
dx, dy, dw, dh, smooth);
}
@ -981,20 +977,39 @@ eng_image_map_draw(void *data __UNUSED__, void *context, void *surface, void *im
{
#ifdef BUILD_PIPE_RENDER
if ((cpunum > 1))
evas_common_pipe_map_draw(im, surface, context, npoints, p, smooth, level);
{
evas_common_pipe_map_draw(im, surface, context, m, smooth, level);
return ;
}
else
#endif
evas_common_map_rgba(im, surface, context, npoints, p, smooth, level);
{
evas_common_map_rgba(im, surface, context, m->count - offset, &m->pts[offset], smooth, level);
}
}
evas_common_cpu_end_opt();
if (npoints > 4)
if (m->count > 4)
{
eng_image_map_draw(data, context, surface, image, npoints - 2, p + 2,
smooth, level);
evas_software_image_map_draw(data, context, surface, im, m, smooth, level, offset + 2);
}
}
static void
eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level)
{
if (!image) return;
if (m->count < 3) return;
evas_software_image_map_draw(data, context, surface, image, m, smooth, level, 0);
}
static void
eng_image_map_clean(void *data __UNUSED__, RGBA_Map *m)
{
evas_common_map_rgba_clean(m);
}
static void *
eng_image_map_surface_new(void *data __UNUSED__, int w, int h, int alpha)
{
@ -1843,6 +1858,7 @@ static Evas_Func func =
eng_image_map_draw,
eng_image_map_surface_new,
eng_image_map_surface_free,
eng_image_map_clean,
NULL, // eng_image_content_hint_set - software doesn't use it
NULL, // eng_image_content_hint_get - software doesn't use it
eng_font_pen_coords_get,
@ -2873,6 +2889,7 @@ module_open(Evas_Module *em)
}
init_gl();
evas_common_pipe_init();
em->functions = (void *)(&func);
cpunum = eina_cpu_count();

View File

@ -111,7 +111,7 @@ struct _Outbuf
/* 1 big buffer for updates - flush on idle_flush */
RGBA_Image *onebuf;
Eina_List *onebuf_regions;
Eina_Array onebuf_regions;
/* a list of pending regions to write to the target */
Eina_List *pending_writes;

View File

@ -181,6 +181,7 @@ evas_software_xlib_outbuf_free(Outbuf *buf)
if (buf->priv.pal)
evas_software_xlib_x_color_deallocate(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap,
buf->priv.x11.xlib.vis, buf->priv.pal);
eina_array_flush(&buf->priv.onebuf_regions);
free(buf);
_clear_xob(0);
}
@ -211,6 +212,8 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
buf->priv.mask_dither = shape_dither;
buf->priv.destination_alpha = destination_alpha;
eina_array_step_set(&buf->priv.onebuf_regions, sizeof (Eina_Array), 8);
{
Gfx_Func_Convert conv_func;
X_Output_Buffer *xob;
@ -379,8 +382,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
return NULL;
}
buf->priv.onebuf_regions = eina_list_append(buf->priv.onebuf_regions, rect);
if (buf->priv.onebuf)
if (!eina_array_push(&buf->priv.onebuf_regions, rect))
{
*cx = x;
*cy = y;
@ -708,20 +710,20 @@ evas_software_xlib_outbuf_flush(Outbuf *buf)
RGBA_Image *im;
Outbuf_Region *obr;
if ((buf->priv.onebuf) && (buf->priv.onebuf_regions))
if ((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions))
{
Eina_Rectangle *rect;
Eina_Array_Iterator it;
unsigned int i;
Region tmpr;
im = buf->priv.onebuf;
obr = im->extended_info;
tmpr = XCreateRegion();
while (buf->priv.onebuf_regions)
EINA_ARRAY_ITER_NEXT(&buf->priv.onebuf_regions, i, rect, it)
{
Eina_Rectangle *rect;
XRectangle xr;
rect = buf->priv.onebuf_regions->data;
buf->priv.onebuf_regions = eina_list_remove_list(buf->priv.onebuf_regions, buf->priv.onebuf_regions);
if (buf->rot == 0)
{
xr.x = rect->x;
@ -756,6 +758,7 @@ evas_software_xlib_outbuf_flush(Outbuf *buf)
xr.x, xr.y, xr.width, xr.height);
eina_rectangle_free(rect);
}
eina_array_clean(&buf->priv.onebuf_regions);
XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc, tmpr);
if (obr->xob)
evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
@ -1025,7 +1028,7 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
#if 1
#else
/* XX async push */
if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions)))
if (!((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions)))
{
if (buf->priv.debug)
evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
@ -1076,7 +1079,7 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
#if 1
#else
/* XX async push */
if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions)))
if (!((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions)))
evas_software_xlib_x_output_buffer_paste(obr->mxob,
buf->priv.x11.xlib.mask,
buf->priv.x11.xlib.gcm,