aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorPaulo Alcantara <pcacjr@profusion.mobi>2013-01-15 17:35:11 +0000
committerUlisses Furquim <ulisses@profusion.mobi>2013-01-15 17:35:11 +0000
commitb557bd9e0d3f1e056a7c554d9767710e096dace8 (patch)
tree2d3aabf729a3e9d4f987d26c557c34381ceb33ae /src/lib
parentedje: artificial depend on epp. (diff)
downloadefl-b557bd9e0d3f1e056a7c554d9767710e096dace8.tar.gz
efl/engines: Introduce multi_font_draw() function
This new engine function will only be used in software generic for now - since it's the only engine used with the async render. This function has been introduced in order to avoid growing thread command queue too much to draw a text_props at a time on render calls from textgrid objects. Patch by: Paulo Alcantara <pcacjr@profusion.mobi> SVN revision: 82832
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/evas/canvas/evas_main.c2
-rw-r--r--src/lib/evas/canvas/evas_object_textgrid.c128
-rw-r--r--src/lib/evas/canvas/evas_render.c16
-rw-r--r--src/lib/evas/common/evas_font_draw.c15
-rw-r--r--src/lib/evas/common/evas_text_utils.h27
-rw-r--r--src/lib/evas/include/evas_private.h5
6 files changed, 169 insertions, 24 deletions
diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c
index 0dc6fae1b8..dbe07e1d31 100644
--- a/src/lib/evas/canvas/evas_main.c
+++ b/src/lib/evas/canvas/evas_main.c
@@ -144,6 +144,7 @@ _constructor(Eo *eo_obj, void *class_data, va_list *list EINA_UNUSED)
EVAS_ARRAY_SET(e, clip_changes);
EVAS_ARRAY_SET(e, image_unref_queue);
EVAS_ARRAY_SET(e, glyph_unref_queue);
+ EVAS_ARRAY_SET(e, texts_unref_queue);
#undef EVAS_ARRAY_SET
}
@@ -251,6 +252,7 @@ _destructor(Eo *eo_e, void *_pd, va_list *list EINA_UNUSED)
eina_array_flush(&e->clip_changes);
eina_array_flush(&e->image_unref_queue);
eina_array_flush(&e->glyph_unref_queue);
+ eina_array_flush(&e->texts_unref_queue);
EINA_LIST_FREE(e->touch_points, touch_point)
free(touch_point);
diff --git a/src/lib/evas/canvas/evas_object_textgrid.c b/src/lib/evas/canvas/evas_object_textgrid.c
index 63f557732e..4e80f7a568 100644
--- a/src/lib/evas/canvas/evas_object_textgrid.c
+++ b/src/lib/evas/canvas/evas_object_textgrid.c
@@ -23,8 +23,8 @@ typedef struct _Evas_Object_Textgrid_Row Evas_Object_Textgrid_Row;
typedef struct _Evas_Object_Textgrid_Rect Evas_Object_Textgrid_Rect;
typedef struct _Evas_Object_Textgrid_Text Evas_Object_Textgrid_Text;
typedef struct _Evas_Object_Textgrid_Line Evas_Object_Textgrid_Line;
-typedef struct _Evas_Textgrid_Hash_Master Evas_Textgrid_Hash_Master;
-typedef struct _Evas_Textgrid_Hash_Glyphs Evas_Textgrid_Hash_Glyphs;
+typedef struct _Evas_Textgrid_Hash_Master Evas_Textgrid_Hash_Master;
+typedef struct _Evas_Textgrid_Hash_Glyphs Evas_Textgrid_Hash_Glyphs;
struct _Evas_Textgrid_Hash_Master
{
@@ -370,7 +370,7 @@ static void
evas_object_textgrid_row_clear(Evas_Object_Textgrid *o, Evas_Object_Textgrid_Row *r)
{
int i;
-
+
if (r->rects)
{
free(r->rects);
@@ -480,7 +480,7 @@ evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row, int x, int w
if (row->rects_num > row->rects_alloc)
{
Evas_Object_Textgrid_Rect *t;
-
+
row->rects_alloc += 8; // dont expect many rects per line
t = realloc(row->rects, sizeof(Evas_Object_Textgrid_Rect) * row->rects_alloc);
if (!t)
@@ -501,11 +501,13 @@ evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row, int x, int w
static void
evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row, Evas_Object *eo_obj, Evas_Object_Textgrid *o, int x, Eina_Unicode codepoint, int r, int g, int b, int a)
{
+ unsigned int text_props_index;
+
row->texts_num++;
if (row->texts_num > row->texts_alloc)
{
Evas_Object_Textgrid_Text *t;
-
+
row->texts_alloc += 32; // expect more text per line
t = realloc(row->texts, sizeof(Evas_Object_Textgrid_Text) * row->texts_alloc);
if (!t)
@@ -516,7 +518,9 @@ evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row, Evas_Object
row->texts = t;
}
- row->texts[row->texts_num - 1].text_props = evas_object_textgrid_textprop_ref(eo_obj, o, codepoint);
+ text_props_index = evas_object_textgrid_textprop_ref(eo_obj, o, codepoint);
+
+ row->texts[row->texts_num - 1].text_props = text_props_index;
row->texts[row->texts_num - 1].x = x;
row->texts[row->texts_num - 1].r = r;
row->texts[row->texts_num - 1].g = g;
@@ -531,7 +535,7 @@ evas_object_textgrid_row_line_append(Evas_Object_Textgrid_Row *row, int x, int w
if (row->lines_num > row->lines_alloc)
{
Evas_Object_Textgrid_Line *t;
-
+
row->lines_alloc += 8; // dont expect many lines per line
t = realloc(row->lines, sizeof(Evas_Object_Textgrid_Line) * row->lines_alloc);
if (!t)
@@ -550,6 +554,18 @@ evas_object_textgrid_row_line_append(Evas_Object_Textgrid_Row *row, int x, int w
row->lines[row->lines_num - 1].a = a;
}
+static Eina_Bool
+_drop_glyphs_ref(const void *container EINA_UNUSED, void *data, void *fdata)
+{
+ Evas_Font_Array_Data *fad = data;
+ Evas_Public_Data *pd = fdata;
+
+ evas_common_font_glyphs_unref(fad->glyphs);
+ eina_array_pop(&pd->glyph_unref_queue);
+
+ return EINA_TRUE;
+}
+
static void
evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async)
{
@@ -559,13 +575,13 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
int xx, yy, xp, yp, w, h, ww, hh;
int rr = 0, rg = 0, rb = 0, ra = 0, rx = 0, rw = 0, run;
- /* render object to surface with context, and offxet by x,y */
+ /* render object to surface with context, and offset by x,y */
Evas_Object_Textgrid *o = eo_data_get(eo_obj, MY_CLASS);
ENFN->context_multiplier_unset(output, context);
ENFN->context_render_op_set(output, context, obj->cur.render_op);
if (!(o->font) || (!o->cur.cells)) return;
-
+
w = o->cur.char_width;
h = o->cur.char_height;
ww = obj->cur.geometry.w;
@@ -575,7 +591,7 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
{
Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]);
-
+
if (row->ch1 < 0)
{
cells += o->cur.w;
@@ -661,34 +677,104 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
{
Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]);
+ Evas_Font_Array *texts;
xp = obj->cur.geometry.x + x;
for (xx = 0; xx < row->rects_num; xx++)
{
ENFN->context_color_set(output, context,
row->rects[xx].r, row->rects[xx].g,
- row->rects[xx].b, row->rects[xx].a);
+ row->rects[xx].b, row->rects[xx].a);
ENFN->rectangle_draw(output, context, surface,
xp + row->rects[xx].x, yp,
row->rects[xx].w, h,
do_async);
}
- for (xx = 0; xx < row->texts_num; xx++)
+
+ if (row->texts_num)
{
- ENFN->context_color_set(output, context,
- row->texts[xx].r, row->texts[xx].g,
- row->texts[xx].b, row->texts[xx].a);
- evas_font_draw_async_check(obj, output, context, surface, o->font,
- xp + row->texts[xx].x, yp + o->max_ascent,
- ww, hh, ww, hh,
- evas_object_textgrid_textprop_int_to(o, row->texts[xx].text_props),
- do_async);
+ if ((do_async) && (ENFN->multi_font_draw))
+ {
+ Eina_Bool async_unref;
+
+ texts = malloc(sizeof(*texts));
+ texts->array = eina_inarray_new(sizeof(Evas_Font_Array_Data),
+ 32);
+ texts->refcount = 1;
+
+ for (xx = 0; xx < row->texts_num; xx++)
+ {
+ Evas_Text_Props *props;
+ Evas_Font_Array_Data fad;
+
+ props =
+ evas_object_textgrid_textprop_int_to
+ (o, row->texts[xx].text_props);
+
+ evas_common_font_draw_prepare(props);
+
+ evas_common_font_glyphs_ref(props->glyphs);
+ evas_unref_queue_glyph_put(obj->layer->evas,
+ props->glyphs);
+
+ fad.color.r = row->texts[xx].r;
+ fad.color.g = row->texts[xx].g;
+ fad.color.b = row->texts[xx].b;
+ fad.color.a = row->texts[xx].a;
+ fad.x = row->texts[xx].x;
+ fad.glyphs = props->glyphs;
+
+ if (eina_inarray_push(texts->array, &fad) < 0)
+ ERR("Failed to push text onto texts array %p",
+ texts->array);
+ }
+
+ async_unref =
+ ENFN->multi_font_draw(output, context, surface,
+ o->font, xp, yp + o->max_ascent,
+ ww, hh, ww, hh, texts, do_async);
+ if (async_unref)
+ evas_unref_queue_texts_put(obj->layer->evas, texts);
+ else
+ {
+ eina_inarray_foreach(texts->array, _drop_glyphs_ref,
+ obj->layer->evas);
+ eina_inarray_free(texts->array);
+ free(texts);
+ }
+ }
+ else
+ {
+ for (xx = 0; xx < row->texts_num; xx++)
+ {
+ Evas_Text_Props *props;
+ unsigned int r, g, b, a;
+ int tx = xp + row->texts[xx].x;
+ int ty = yp + o->max_ascent;
+
+ props =
+ evas_object_textgrid_textprop_int_to
+ (o, row->texts[xx].text_props);
+
+ r = row->texts[xx].r;
+ g = row->texts[xx].g;
+ b = row->texts[xx].b;
+ a = row->texts[xx].a;
+
+ ENFN->context_color_set(output, context,
+ r, g, b, a);
+ evas_font_draw_async_check(obj, output, context, surface,
+ o->font, tx, ty, ww, hh,
+ ww, hh, props, do_async);
+ }
+ }
}
+
for (xx = 0; xx < row->lines_num; xx++)
{
ENFN->context_color_set(output, context,
row->lines[xx].r, row->lines[xx].g,
- row->lines[xx].b, row->lines[xx].a);
+ row->lines[xx].b, row->lines[xx].a);
ENFN->rectangle_draw(output, context, surface,
xp + row->lines[xx].x, yp + row->lines[xx].y,
row->lines[xx].w, 1,
diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c
index 0b7a056eda..0136f736a9 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -1843,6 +1843,14 @@ _drop_glyph_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_
return EINA_TRUE;
}
+static Eina_Bool
+_drop_texts_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
+{
+ evas_common_font_fonts_unref(data);
+
+ return EINA_TRUE;
+}
+
static void
evas_render_wakeup(Evas *eo_e)
{
@@ -1887,6 +1895,8 @@ evas_render_wakeup(Evas *eo_e)
eina_array_clean(&e->image_unref_queue);
eina_array_foreach(&e->glyph_unref_queue, _drop_glyph_ref, NULL);
eina_array_clean(&e->glyph_unref_queue);
+ eina_array_foreach(&e->texts_unref_queue, _drop_texts_ref, NULL);
+ eina_array_clean(&e->texts_unref_queue);
up_cb = e->render.updates_cb;
up_data = e->render.data;
@@ -2172,4 +2182,10 @@ evas_unref_queue_glyph_put(Evas_Public_Data *pd, void *glyph)
eina_array_push(&pd->glyph_unref_queue, glyph);
}
+void
+evas_unref_queue_texts_put(Evas_Public_Data *pd, void *texts)
+{
+ eina_array_push(&pd->texts_unref_queue, texts);
+}
+
/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
diff --git a/src/lib/evas/common/evas_font_draw.c b/src/lib/evas/common/evas_font_draw.c
index cfb8aac6f9..99883926ae 100644
--- a/src/lib/evas/common/evas_font_draw.c
+++ b/src/lib/evas/common/evas_font_draw.c
@@ -239,6 +239,21 @@ evas_common_font_glyphs_unref(Evas_Glyph_Array *array)
free(array);
}
+void
+evas_common_font_fonts_ref(Evas_Font_Array *array)
+{
+ array->refcount++;
+}
+
+void
+evas_common_font_fonts_unref(Evas_Font_Array *array)
+{
+ if (--array->refcount) return;
+
+ eina_inarray_free(array->array);
+ free(array);
+}
+
EAPI void
evas_common_font_draw_prepare(Evas_Text_Props *text_props)
{
diff --git a/src/lib/evas/common/evas_text_utils.h b/src/lib/evas/common/evas_text_utils.h
index f2f65a396b..144761ea28 100644
--- a/src/lib/evas/common/evas_text_utils.h
+++ b/src/lib/evas/common/evas_text_utils.h
@@ -1,12 +1,13 @@
#ifndef _EVAS_TEXT_UTILS_H
# define _EVAS_TEXT_UTILS_H
-
-typedef struct _Evas_Text_Props Evas_Text_Props;
+typedef struct _Evas_Text_Props Evas_Text_Props;
// special case props
-typedef struct _Evas_Text_Props_One Evas_Text_Props_One;
+typedef struct _Evas_Text_Props_One Evas_Text_Props_One;
typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info;
+typedef struct _Evas_Font_Array_Data Evas_Font_Array_Data;
+typedef struct _Evas_Font_Array Evas_Font_Array;
typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info;
typedef enum
@@ -100,6 +101,21 @@ struct _Evas_Text_Props_Info
unsigned int refcount; // 4
};
+struct _Evas_Font_Array_Data
+{
+ struct {
+ unsigned char r, g, b, a;
+ } color;
+ int x;
+ Evas_Glyph_Array *glyphs;
+};
+
+struct _Evas_Font_Array
+{
+ Eina_Inarray *array;
+ unsigned int refcount;
+};
+
/* Sorted in visual order when created */
struct _Evas_Font_Glyph_Info
{
@@ -125,6 +141,11 @@ void
evas_common_font_glyphs_unref(Evas_Glyph_Array *array);
void
+evas_common_font_fonts_ref(Evas_Font_Array *array);
+void
+evas_common_font_fonts_unref(Evas_Font_Array *array);
+
+void
evas_common_text_props_bidi_set(Evas_Text_Props *props,
Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start);
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 4a7ec28e74..c5527db740 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -388,6 +388,7 @@ struct _Evas_Public_Data
Eina_Array clip_changes;
Eina_Array image_unref_queue;
Eina_Array glyph_unref_queue;
+ Eina_Array texts_unref_queue;
Eina_Clist calc_list;
Eina_Clist calc_done;
@@ -900,6 +901,9 @@ struct _Evas_Func
/* max size query */
void (*image_max_size_get) (void *data, int *maxw, int *maxh);
+
+ /* multiple font draws */
+ Eina_Bool (*multi_font_draw) (void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w, int h, int ow, int oh, Evas_Font_Array *texts, Eina_Bool do_async);
};
struct _Evas_Image_Load_Func
@@ -1051,6 +1055,7 @@ void _evas_object_textblock_rehint(Evas_Object *obj);
void evas_unref_queue_image_put(Evas_Public_Data *pd, void *image);
void evas_unref_queue_glyph_put(Evas_Public_Data *pd, void *glyph);
+void evas_unref_queue_texts_put(Evas_Public_Data *pd, void *glyph);
void evas_draw_image_map_async_check(Evas_Object_Protected_Data *obj,
void *data, void *context, void *surface,