* 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.
* 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.
* 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.
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)
/* 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
{
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;
{
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;
}
_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);
}
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
{
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
}
_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;
}
evas_object_map_update(obj, off_x, off_y, sw, sh, sw, sh);
- pts = obj->spans->pts;
if (obj->cur.map->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
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);
EAPI void
evas_common_draw_context_cutouts_free(Cutout_Rects* rects)
{
+ if (!rects) return ;
rects->active = 0;
}
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
}
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;
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)
}
}
}
- 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;
}
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);
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)
{
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
{
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);
EVAS_FONT_WALK_TEXT_START()
{
- Evas_Glyph glyph;
+ Evas_Glyph *glyph;
FT_UInt idx;
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
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;
+
+ glyphs_max += 8;
+ tmp = realloc(glyphs, glyphs_max * sizeof (Evas_Glyph));
+ if (!tmp) return ;
+ glyphs = tmp;
+ text_props->glyphs = glyphs;
+ }
+
+ glyph = glyphs + glyphs_length++;
- eina_binbuf_append_length(text_props->bin, (void*) &glyph, sizeof (Evas_Glyph));
+ 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
*/
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;
/* 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;
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;
+}
+
// }
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);
{
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;
}
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);
#include "evas_common.h"
+#include "evas_private.h"
#include "evas_blend_private.h"
#ifdef EVAS_CSERVE2
#include "evas_cs2_private.h"
Span span[2];
};
-static FPc
+static inline FPc
_interp(int x1, int x2, int p, FPc u1, FPc u2)
{
FPc u;
return u1 + u;
}
-static DATA32
+static inline DATA32
_interp_col(int x1, int x2, int p, DATA32 col1, DATA32 col2)
{
x2 -= x1;
return INTERP_256(p, col2, col1);
}
-static void
+static inline void
_limit(Span *s, int c1, int c2, int nocol)
{
if (s->x1 < c1)
}
}
+/* 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
#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;
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;
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
+ }
+}
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 */
// 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
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)
#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"
+ }
+}
-// THIS IS DEPRECATED. WILL GO EVENTUALLTY. NO NEED TO SUPPORT ANYMORE
-
#include "evas_common.h"
#include <unistd.h>
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);
}
}
}
#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
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;
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);
}
{
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);
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
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);
}
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);
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);
}
{
RGBA_Polygon_Point *p;
+#if 0
while (op->op.poly.points)
{
p = op->op.poly.points;
EINA_INLIST_GET(p));
free(p);
}
+#endif
evas_common_pipe_op_free(op);
}
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
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));
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);
}
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
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);
}
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,
#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
}
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);
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);
}
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);
+}
+
+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);
- 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);
+ 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);
}
#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)
{
tinfo = data;
for (;;)
{
+ RGBA_Pipe_Op *op;
+ Eina_Array_Iterator it;
+ unsigned int i;
/* wait for start signal */
pthread_barrier_wait(&(tinfo->barrier[0]));
}
}
+ 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]));
}
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
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]));
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);
}
}
- evas_common_pipe_load_do();
+ evas_common_pipe_load_do(root);
evas_common_pipe_map_render(root);
}
#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
* 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);
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 */
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 */
#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);
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;
/* 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)
{
#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;
+}
+
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 */
#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,
int src_region_x, int src_region_y,
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;
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;
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,
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
# 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;
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;
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
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);
}
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);
/* 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
Evas_Text_Props_Info *info;
void *font_instance;
- Eina_Binbuf *bin;
+ Evas_Glyph *glyphs;
+ int glyphs_length;
int generation;
Eina_Bool changed : 1;
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;
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;
}
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;
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;
}
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;
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;
}
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;
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;
}
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 {
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;
} 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
struct _RGBA_Pipe_Thread_Info
{
EINA_INLIST;
- RGBA_Image *im;
- int x, y, w, h;
+ Eina_Rectangle area;
};
#endif
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);
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;
surface->SetClip(surface, &cr);
cb(surface, dc, &cr, data);
}
- evas_common_draw_context_apply_clear_cutouts(rects);
}
static void
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;
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;
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;
}
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;
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;
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;
}
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;
/* 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;
}
}
}
- evas_common_draw_context_apply_clear_cutouts(rects);
}
}
while (spans)
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;
/* 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;
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 */
}
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;
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)
{
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);
}
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)
-{
- RGBA_Image *im;
-
- 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))
+evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGBA_Image *im, RGBA_Map *m, int smooth, int level, int offset)
+{
+ if (m->count - offset < 3) return;
+
+ 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);
}
{
#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)
{
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,
}
init_gl();
+ evas_common_pipe_init();
em->functions = (void *)(&func);
cpunum = eina_cpu_count();
/* 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;
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);
}
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;
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;
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;
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,
#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,
#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,