* evas: improve thread rendering by moving image loading in worker thread.

SVN revision: 47434
This commit is contained in:
Cedric BAIL 2010-03-24 19:07:59 +00:00
parent 3059ecd31c
commit 3d27a7b9e4
6 changed files with 183 additions and 44 deletions

View File

@ -128,6 +128,7 @@ EAPI void evas_cache_image_set(Evas_Cache_Image *cache, int
EAPI Image_Entry* evas_cache_image_alone(Image_Entry *im);
EAPI Image_Entry* evas_cache_image_dirty(Image_Entry *im, int x, int y, int w, int h);
EAPI void evas_cache_image_load_data(Image_Entry *im);
EAPI Eina_Bool evas_cache_image_is_loaded(Image_Entry *im);
EAPI void evas_cache_image_surface_alloc(Image_Entry *im, int w, int h);
EAPI DATA32* evas_cache_image_pixels(Image_Entry *im);
EAPI Image_Entry* evas_cache_image_copied_data(Evas_Cache_Image *cache, int w, int h, DATA32 *image_data, int alpha, int cspace);

View File

@ -1179,6 +1179,16 @@ evas_cache_image_load_data(Image_Entry *im)
#endif
}
EAPI Eina_Bool
evas_cache_image_is_loaded(Image_Entry *im)
{
assert(im);
if (im->flags.loaded)
return EINA_TRUE;
return EINA_FALSE;
}
EAPI void
evas_cache_image_preload_data(Image_Entry *im, const void *target)
{

View File

@ -116,7 +116,7 @@ static Thinfo thinfo[TH_MAX];
static pthread_barrier_t thbarrier[2];
#endif
EAPI void
static void
evas_common_pipe_begin(RGBA_Image *im)
{
#ifdef BUILD_PTHREAD
@ -124,33 +124,6 @@ evas_common_pipe_begin(RGBA_Image *im)
if (!im->pipe) return;
if (thread_num == 1) return;
if (thread_num == 0)
{
int cpunum;
cpunum = eina_cpu_count();
thread_num = cpunum;
if (thread_num == 1) return;
pthread_barrier_init(&(thbarrier[0]), NULL, thread_num + 1);
pthread_barrier_init(&(thbarrier[1]), NULL, thread_num + 1);
for (i = 0; i < thread_num; i++)
{
pthread_attr_t attr;
cpu_set_t cpu;
pthread_attr_init(&attr);
CPU_ZERO(&cpu);
CPU_SET(i % cpunum, &cpu);
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
thinfo[i].thread_num = i;
thinfo[i].info = NULL;
thinfo[i].barrier = thbarrier;
/* setup initial locks */
pthread_create(&(thinfo[i].thread_id), &attr,
evas_common_pipe_thread, &(thinfo[i]));
pthread_attr_destroy(&attr);
}
}
y = 0;
h = im->cache_entry.h / thread_num;
if (h < 1) h = 1;
@ -183,7 +156,7 @@ evas_common_pipe_begin(RGBA_Image *im)
#endif
}
EAPI void
static void
evas_common_pipe_flush(RGBA_Image *im)
{
@ -675,6 +648,8 @@ evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst,
op->op_func = evas_common_pipe_image_draw_do;
op->free_func = evas_common_pipe_op_image_free;
evas_common_pipe_draw_context_copy(dc, op);
evas_common_pipe_image_load(src);
}
static void
@ -743,10 +718,12 @@ evas_common_pipe_map4_draw(RGBA_Image *src, RGBA_Image *dst,
op->op_func = evas_common_pipe_map4_draw_do;
op->free_func = evas_common_pipe_op_map4_free;
evas_common_pipe_draw_context_copy(dc, op);
evas_common_pipe_image_load(src);
}
EAPI void
evas_common_pipe_map4_begin(RGBA_Image *root)
static void
evas_common_pipe_map4_render(RGBA_Image *root)
{
RGBA_Pipe *p;
int i;
@ -759,12 +736,12 @@ evas_common_pipe_map4_begin(RGBA_Image *root)
if (p->op[i].op_func == evas_common_pipe_map4_draw_do)
{
if (p->op[i].op.map4.src->pipe)
evas_common_pipe_map4_begin(p->op[i].op.map4.src);
evas_common_pipe_map4_render(p->op[i].op.map4.src);
}
else if (p->op[i].op_func == evas_common_pipe_image_draw_do)
{
if (p->op[i].op.image.src->pipe)
evas_common_pipe_map4_begin(p->op[i].op.image.src);
evas_common_pipe_map4_render(p->op[i].op.image.src);
}
}
}
@ -772,4 +749,163 @@ evas_common_pipe_map4_begin(RGBA_Image *root)
evas_common_pipe_begin(root);
evas_common_pipe_flush(root);
}
#ifdef BUILD_PTHREAD
static Eina_List *task = NULL;
static Thinfo task_thinfo[TH_MAX];
static pthread_barrier_t task_thbarrier[2];
static LK(task_mutext) = PTHREAD_MUTEX_INITIALIZER;
#endif
#ifdef BUILD_PTHREAD
static void*
evas_common_pipe_load(void *data)
{
Thinfo *thinfo;
thinfo = data;
for (;;)
{
/* wait for start signal */
pthread_barrier_wait(&(thinfo->barrier[0]));
while (task)
{
RGBA_Image *im = NULL;
LKL(task_mutext);
im = eina_list_data_get(task);
task = eina_list_remove_list(task, task);
LKU(task_mutext);
if (im)
{
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
evas_common_image_colorspace_normalize(im);
im->flags &= ~RGBA_IMAGE_TODO_LOAD;
}
}
/* send finished signal */
pthread_barrier_wait(&(thinfo->barrier[1]));
}
return NULL;
}
#endif
static void
evas_common_pipe_image_load_do(void)
{
#ifdef BUILD_PTHREAD
/* Notify worker thread. */
pthread_barrier_wait(&(task_thbarrier[0]));
/* sync worker threads */
pthread_barrier_wait(&(task_thbarrier[1]));
#endif
}
static Eina_Bool
evas_common_pipe_init(void)
{
#ifdef BUILD_PTHREAD
if (thread_num == 0)
{
int cpunum;
int i;
cpunum = eina_cpu_count();
thread_num = cpunum;
if (thread_num == 1) return EINA_FALSE;
pthread_barrier_init(&(thbarrier[0]), NULL, thread_num + 1);
pthread_barrier_init(&(thbarrier[1]), NULL, thread_num + 1);
for (i = 0; i < thread_num; i++)
{
pthread_attr_t attr;
cpu_set_t cpu;
pthread_attr_init(&attr);
CPU_ZERO(&cpu);
CPU_SET(i % cpunum, &cpu);
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
thinfo[i].thread_num = i;
thinfo[i].info = NULL;
thinfo[i].barrier = thbarrier;
/* setup initial locks */
pthread_create(&(thinfo[i].thread_id), &attr,
evas_common_pipe_thread, &(thinfo[i]));
pthread_attr_destroy(&attr);
}
pthread_barrier_init(&(task_thbarrier[0]), NULL, thread_num + 1);
pthread_barrier_init(&(task_thbarrier[1]), NULL, thread_num + 1);
for (i = 0; i < thread_num; i++)
{
pthread_attr_t attr;
cpu_set_t cpu;
pthread_attr_init(&attr);
CPU_ZERO(&cpu);
CPU_SET(i % cpunum, &cpu);
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
task_thinfo[i].thread_num = i;
task_thinfo[i].info = NULL;
task_thinfo[i].barrier = task_thbarrier;
/* setup initial locks */
pthread_create(&(task_thinfo[i].thread_id), &attr,
evas_common_pipe_load, &(task_thinfo[i]));
pthread_attr_destroy(&attr);
}
}
if (thread_num == 1) return EINA_FALSE;
return EINA_TRUE;
#endif
return EINA_FALSE;
}
EAPI void
evas_common_pipe_image_load(RGBA_Image *im)
{
if (im->flags & RGBA_IMAGE_TODO_LOAD)
return ;
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888
&& !evas_cache_image_is_loaded(&(im->cache_entry)))
goto add_task;
if ((!im->cs.data) || ((!im->cs.dirty) && (!(im->flags & RGBA_IMAGE_IS_DIRTY))))
goto add_task;
return ;
add_task:
task = eina_list_append(task, im);
im->flags |= RGBA_IMAGE_TODO_LOAD;
}
EAPI void
evas_common_pipe_map4_begin(RGBA_Image *root)
{
if (!evas_common_pipe_init())
{
RGBA_Image *im;
EINA_LIST_FREE(task, im)
{
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
evas_common_image_colorspace_normalize(im);
im->flags &= ~RGBA_IMAGE_TODO_LOAD;
}
}
evas_common_pipe_image_load_do();
evas_common_pipe_map4_render(root);
}
#endif

View File

@ -6,8 +6,6 @@
* threadable
*/
EAPI void evas_common_pipe_begin(RGBA_Image *im);
EAPI void evas_common_pipe_flush(RGBA_Image *im);
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);
@ -15,6 +13,7 @@ EAPI void evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGB
EAPI void evas_common_pipe_grad_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h, RGBA_Gradient *gr);
EAPI void evas_common_pipe_grad2_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h, RGBA_Gradient2 *gr);
EAPI void evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text);
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_map4_draw(RGBA_Image *src, RGBA_Image *dst,
RGBA_Draw_Context *dc, RGBA_Map_Point *p,

View File

@ -427,6 +427,7 @@ typedef enum _RGBA_Image_Flags
/* RGBA_IMAGE_ALPHA_SPARSE = (1 << 5), */
/* RGBA_IMAGE_LOADED = (1 << 6), */
/* RGBA_IMAGE_NEED_DATA = (1 << 7) */
RGBA_IMAGE_TODO_LOAD = (1 << 8),
} RGBA_Image_Flags;
typedef enum _Convert_Pal_Mode

View File

@ -739,9 +739,6 @@ eng_image_draw(void *data __UNUSED__, void *context, void *surface, void *image,
#ifdef BUILD_PIPE_RENDER
if (cpunum > 1)
{
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
evas_common_image_colorspace_normalize(im);
evas_common_rgba_image_scalecache_prepare(im, surface, context, smooth,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h);
@ -816,12 +813,7 @@ eng_image_map4_draw(void *data __UNUSED__, void *context, void *surface, void *i
else
#ifdef BUILD_PIPE_RENDER
if (cpunum > 1)
{
if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
evas_cache_image_load_data(&im->cache_entry);
evas_common_image_colorspace_normalize(im);
evas_common_pipe_map4_draw(im, surface, context, p, smooth, level);
}
evas_common_pipe_map4_draw(im, surface, context, p, smooth, level);
else
#endif
evas_common_map4_rgba(im, surface, context, p, smooth, level);