1 #include "evas_common.h"
4 #ifdef BUILD_PIPE_RENDER
5 static RGBA_Pipe *evas_common_pipe_add(RGBA_Pipe *pipe, RGBA_Pipe_Op **op);
6 static void evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op);
7 static void evas_common_pipe_op_free(RGBA_Pipe_Op *op);
11 evas_common_pipe_add(RGBA_Pipe *rpipe, RGBA_Pipe_Op **op)
19 p = calloc(1, sizeof(RGBA_Pipe));
21 rpipe = (RGBA_Pipe *)eina_inlist_append(EINA_INLIST_GET(rpipe), EINA_INLIST_GET(p));
23 p = (RGBA_Pipe *)(EINA_INLIST_GET(rpipe))->last;
24 if (p->op_num == PIPE_LEN)
26 p = calloc(1, sizeof(RGBA_Pipe));
28 rpipe = (RGBA_Pipe *)eina_inlist_append(EINA_INLIST_GET(rpipe), EINA_INLIST_GET(p));
31 *op = &(p->op[p->op_num - 1]);
34 /* FIXME: PTHREAD init any thread locks etc */
40 evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op)
42 memcpy(&(op->context), dc, sizeof(RGBA_Draw_Context));
43 if (op->context.cutout.active > 0)
45 op->context.cutout.rects = malloc(sizeof(Cutout_Rect) * op->context.cutout.active);
46 memcpy(op->context.cutout.rects, dc->cutout.rects, sizeof(Cutout_Rect) * op->context.cutout.active);
50 op->context.cutout.rects = NULL;
55 evas_common_pipe_op_free(RGBA_Pipe_Op *op)
57 evas_common_draw_context_apply_clean_cutouts(&op->context.cutout);
63 evas_common_pipe_thread(void *data)
67 // INF("TH [...........");
71 const RGBA_Pipe_Thread_Info *info;
74 /* wait for start signal */
75 // INF(" TH %i START...", thinfo->thread_num);
76 pthread_barrier_wait(&(thinfo->barrier[0]));
78 EINA_INLIST_FOREACH(thinfo->tasks, info)
80 EINA_INLIST_FOREACH(EINA_INLIST_GET(thinfo->im->cache_entry.pipe), p)
84 for (i = 0; i < p->op_num; i++)
86 if (p->op[i].op_func && p->op[i].render)
87 p->op[i].op_func(thinfo->im, &(p->op[i]), info);
94 pthread_barrier_wait(&(thinfo->barrier[1]));
101 static Eina_List *im_task = NULL;
102 static Eina_List *text_task = NULL;
103 static Thinfo task_thinfo[TH_MAX];
104 static pthread_barrier_t task_thbarrier[2];
105 static LK(im_task_mutex);
106 static LK(text_task_mutex);
108 static int thread_num = 0;
109 static Thinfo thinfo[TH_MAX];
110 static pthread_barrier_t thbarrier[2];
112 static RGBA_Pipe_Thread_Info *buf = NULL;
113 static unsigned int buf_size = 0;
115 static Cutout_Rects *
116 evas_pipe_cutout_rects_pop(Thinfo *info)
120 r = eina_array_pop(&info->cutout_trash);
121 if (!r) r = evas_common_draw_context_cutouts_new();
126 evas_pipe_cutout_rects_push(Thinfo *info, Cutout_Rects *r)
128 /* evas_common_draw_context_apply_clean_cutouts(r); */
129 evas_common_draw_context_cutouts_free(r);
130 eina_array_push(&info->cutout_trash, r);
134 evas_pipe_cutout_rects_rotate(Cutout_Rects *r)
136 static int current = 0;
138 if (current >= thread_num) current = 0;
139 evas_pipe_cutout_rects_push(&task_thinfo[current], r);
144 evas_pipe_prepare_push(RGBA_Pipe_Op *op)
146 static int current = 0;
148 if (current >= thread_num) current = 0;
149 eina_array_push(&task_thinfo[current].rects_task, op);
156 evas_common_pipe_begin(RGBA_Image *im)
160 unsigned int x, y, cpu;
161 RGBA_Pipe_Thread_Info *info;
162 unsigned int estimatex, estimatey;
163 unsigned int needed_size;
165 if (!im->cache_entry.pipe) return;
166 if (thread_num == 1) return;
168 if (im->cache_entry.w * im->cache_entry.h / thread_num < SZ * SZ)
170 estimatex = im->cache_entry.w;
171 estimatey = im->cache_entry.h / thread_num;
172 if (estimatey == 0) estimatey = 1;
180 needed_size = ((im->cache_entry.w / estimatex) + 1 ) * ((im->cache_entry.h / estimatey) + 1);
181 if (buf_size < needed_size)
183 buf = realloc(buf, sizeof (RGBA_Pipe_Thread_Info) * needed_size);
184 buf_size = needed_size;
189 for (y = 0; y < im->cache_entry.h; y += estimatey)
190 for (x = 0; x < im->cache_entry.w; x += estimatex)
192 EINA_RECTANGLE_SET(&info->area, x, y,
193 (x + estimatex > im->cache_entry.w) ? im->cache_entry.w - x : estimatex,
194 (y + estimatey > im->cache_entry.h) ? im->cache_entry.h - y : estimatey);
197 thinfo[cpu].tasks = eina_inlist_prepend((void*) thinfo[cpu].tasks, EINA_INLIST_GET(info));
199 if (cpu >= (unsigned int) thread_num) cpu = 0;
204 /* tell worker threads to start */
205 pthread_barrier_wait(&(thbarrier[0]));
210 evas_common_pipe_flush(RGBA_Image *im)
212 if (!im->cache_entry.pipe) return;
216 /* sync worker threads */
217 pthread_barrier_wait(&(thbarrier[1]));
222 RGBA_Pipe_Thread_Info info;
226 EINA_RECTANGLE_SET(&info.area, 0, 0, im->cache_entry.w, im->cache_entry.h);
228 /* process pipe - 1 thead */
229 for (p = im->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next)
231 for (i = 0; i < p->op_num; i++)
233 if (p->op[i].render && p->op[i].op_func)
235 p->op[i].op_func(im, &(p->op[i]), &info);
241 evas_common_cpu_end_opt();
242 evas_common_pipe_free(im);
246 evas_common_pipe_free(RGBA_Image *im)
252 if (!im->cache_entry.pipe) return;
253 /* FIXME: PTHREAD join all threads here (if not finished) */
256 while (im->cache_entry.pipe)
258 p = im->cache_entry.pipe;
259 for (i = 0; i < p->op_num; i++)
261 if (p->op[i].free_func)
263 p->op[i].free_func(&(p->op[i]));
265 if (p->op[i].rects) evas_pipe_cutout_rects_rotate(p->op[i].rects);
267 im->cache_entry.pipe = (RGBA_Pipe *)eina_inlist_remove(EINA_INLIST_GET(im->cache_entry.pipe), EINA_INLIST_GET(p));
275 /**************** RECT ******************/
277 evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
279 RGBA_Draw_Context context;
281 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
282 evas_common_rectangle_draw_do(op->rects, &info->area, dst, &(context),
283 op->op.rect.x, op->op.rect.y,
284 op->op.rect.w, op->op.rect.h);
288 evas_common_pipe_rectangle_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
290 Cutout_Rects *recycle;
294 recycle = evas_pipe_cutout_rects_pop(info);
295 r = evas_common_rectangle_draw_prepare(recycle, dst, &(op->context),
296 op->op.rect.x, op->op.rect.y,
297 op->op.rect.w, op->op.rect.h);
298 if (recycle->active) op->rects = recycle;
299 else evas_pipe_cutout_rects_push(info, recycle);
305 evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
309 if ((w < 1) || (h < 1)) return;
310 dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
311 if (!dst->cache_entry.pipe) return;
316 op->op_func = evas_common_pipe_rectangle_draw_do;
317 op->free_func = evas_common_pipe_op_free;
318 op->prepare_func = evas_common_pipe_rectangle_prepare;
319 evas_pipe_prepare_push(op);
320 evas_common_pipe_draw_context_copy(dc, op);
323 /**************** LINE ******************/
325 evas_common_pipe_line_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
327 RGBA_Draw_Context context;
329 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
330 evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h);
331 evas_common_line_draw(dst, &(context),
332 op->op.line.x0, op->op.line.y0,
333 op->op.line.x1, op->op.line.y1);
337 evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
338 int x0, int y0, int x1, int y1)
342 dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
343 if (!dst->cache_entry.pipe) return;
348 op->op_func = evas_common_pipe_line_draw_do;
349 op->free_func = evas_common_pipe_op_free;
350 op->prepare_func = NULL;
351 op->render = EINA_TRUE;
352 evas_common_pipe_draw_context_copy(dc, op);
355 /**************** POLY ******************/
357 evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op)
360 RGBA_Polygon_Point *p;
362 while (op->op.poly.points)
364 p = op->op.poly.points;
365 op->op.poly.points = (RGBA_Polygon_Point *)eina_inlist_remove(EINA_INLIST_GET(op->op.poly.points),
370 evas_common_pipe_op_free(op);
374 evas_common_pipe_poly_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
376 RGBA_Draw_Context context;
378 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
379 evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h);
380 evas_common_polygon_draw(dst, &(context),
381 op->op.poly.points, op->op.poly.x, op->op.poly.y);
385 evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
386 RGBA_Polygon_Point *points, int x, int y)
389 /* RGBA_Polygon_Point *pts = NULL, *p, *pp; */
392 dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
393 if (!dst->cache_entry.pipe) return;
394 /* FIXME: copy points - maybe we should refcount? */
396 for (p = points; p; p = (RGBA_Polygon_Point *)(EINA_INLIST_GET(p))->next)
398 pp = calloc(1, sizeof(RGBA_Polygon_Point));
403 pts = (RGBA_Polygon_Point *)eina_inlist_append(EINA_INLIST_GET(pts), EINA_INLIST_GET(pp));
409 op->op.poly.points = points/* pts */;
410 op->op_func = evas_common_pipe_poly_draw_do;
411 op->free_func = evas_common_pipe_op_poly_free;
412 op->render = EINA_TRUE;
413 op->prepare_func = NULL; /* FIXME: If we really want to improve it, we should prepare span for it here */
414 evas_common_pipe_draw_context_copy(dc, op);
417 /**************** TEXT ******************/
419 evas_common_pipe_op_text_free(RGBA_Pipe_Op *op)
421 evas_common_text_props_content_unref(op->op.text.intl_props);
422 evas_common_pipe_op_free(op);
426 evas_common_pipe_text_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
428 RGBA_Draw_Context context;
430 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
431 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);
435 evas_common_pipe_text_draw_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
437 Cutout_Rects *recycle;
441 recycle = evas_pipe_cutout_rects_pop(info);
442 r = evas_common_font_draw_prepare_cutout(recycle, dst, &(op->context),
443 &(op->op.text.func));
444 if (recycle->active) op->rects = recycle;
445 else evas_pipe_cutout_rects_push(info, recycle);
451 evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
452 int x, int y, Evas_Text_Props *intl_props)
456 dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
457 if (!dst->cache_entry.pipe) return;
460 op->op.text.intl_props = intl_props;
461 evas_common_text_props_content_ref(intl_props);
462 op->op_func = evas_common_pipe_text_draw_do;
463 op->free_func = evas_common_pipe_op_text_free;
464 op->prepare_func = evas_common_pipe_text_draw_prepare;
465 evas_pipe_prepare_push(op);
466 evas_common_pipe_draw_context_copy(dc, op);
467 evas_common_pipe_text_prepare(intl_props);
470 /**************** IMAGE *****************/
472 evas_common_pipe_op_image_free(RGBA_Pipe_Op *op)
474 op->op.image.src->ref--;
475 if (op->op.image.src->ref == 0)
477 evas_cache_image_drop(&op->op.image.src->cache_entry);
479 evas_common_pipe_op_free(op);
483 evas_common_pipe_op_image_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
485 Cutout_Rects *recycle;
489 recycle = evas_pipe_cutout_rects_pop(info);
490 r = evas_common_scale_rgba_in_to_out_clip_prepare(recycle,
491 op->op.image.src, dst,
493 op->op.image.dx, op->op.image.dy,
494 op->op.image.dw, op->op.image.dh);
495 if (recycle->active) op->rects = recycle;
496 else evas_pipe_cutout_rects_push(info, recycle);
502 evas_common_pipe_image_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
504 RGBA_Draw_Context context;
506 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
509 /* FIXME: Make the scalecache path use the prepared Cutout ? */
510 evas_common_draw_context_clip_clip(&(context), info->area.x, info->area.y, info->area.w, info->area.h);
511 evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src),
523 if (op->op.image.smooth)
525 evas_common_scale_rgba_in_to_out_clip_smooth_do(op->rects, &info->area,
539 evas_common_scale_rgba_in_to_out_clip_sample_do(op->rects, &info->area,
555 evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst,
556 RGBA_Draw_Context *dc, int smooth,
557 int src_region_x, int src_region_y,
558 int src_region_w, int src_region_h,
559 int dst_region_x, int dst_region_y,
560 int dst_region_w, int dst_region_h)
565 // evas_common_pipe_flush(src);
566 dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
567 if (!dst->cache_entry.pipe) return;
568 op->op.image.smooth = smooth;
569 op->op.image.sx = src_region_x;
570 op->op.image.sy = src_region_y;
571 op->op.image.sw = src_region_w;
572 op->op.image.sh = src_region_h;
573 op->op.image.dx = dst_region_x;
574 op->op.image.dy = dst_region_y;
575 op->op.image.dw = dst_region_w;
576 op->op.image.dh = dst_region_h;
578 op->op.image.src = src;
579 op->op_func = evas_common_pipe_image_draw_do;
580 op->free_func = evas_common_pipe_op_image_free;
581 op->prepare_func = evas_common_pipe_op_image_prepare;
582 evas_pipe_prepare_push(op);
583 evas_common_pipe_draw_context_copy(dc, op);
585 evas_common_pipe_image_load(src);
589 evas_common_pipe_op_map_free(RGBA_Pipe_Op *op)
591 op->op.map.src->ref--;
592 if (op->op.map.src->ref == 0)
593 evas_cache_image_drop(&op->op.map.src->cache_entry);
594 /* free(op->op.map.p); */
595 evas_common_pipe_op_free(op);
599 evas_common_pipe_map_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
601 RGBA_Draw_Context context;
603 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
604 evas_common_map_rgba_do(&info->area, op->op.map.src, dst,
605 &context, op->op.map.m,
606 op->op.map.smooth, op->op.map.level);
610 evas_common_pipe_map_draw_prepare(void *data, RGBA_Image *dst, RGBA_Pipe_Op *op)
612 RGBA_Draw_Context context;
616 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
617 r = evas_common_map_rgba_prepare(op->op.map.src, dst,
618 &context, op->op.map.m);
624 evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst,
625 RGBA_Draw_Context *dc, RGBA_Map *m,
626 int smooth, int level)
629 /* RGBA_Map_Point *pts_copy; */
633 /* pts_copy = malloc(sizeof (RGBA_Map_Point) * 4); */
634 /* if (!pts_copy) return; */
635 dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op);
636 if (!dst->cache_entry.pipe)
638 /* free(pts_copy); */
642 /* for (i = 0; i < 4; ++i) */
643 /* pts_copy[i] = p[i]; */
645 op->op.map.smooth = smooth;
646 op->op.map.level = level;
648 op->op.map.src = src;
650 op->op_func = evas_common_pipe_map_draw_do;
651 op->free_func = evas_common_pipe_op_map_free;
652 op->prepare_func = evas_common_pipe_map_draw_prepare;
653 evas_pipe_prepare_push(op);
654 evas_common_pipe_draw_context_copy(dc, op);
656 evas_common_pipe_image_load(src);
660 evas_common_pipe_map_render(RGBA_Image *root)
665 /* Map imply that we need to process them recursively first. */
666 for (p = root->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next)
668 for (i = 0; i < p->op_num; i++)
670 if (p->op[i].op_func == evas_common_pipe_map_draw_do)
672 if (p->op[i].op.map.src->cache_entry.pipe)
673 evas_common_pipe_map_render(p->op[i].op.map.src);
675 else if (p->op[i].op_func == evas_common_pipe_image_draw_do)
677 if (p->op[i].op.image.src->cache_entry.pipe)
678 evas_common_pipe_map_render(p->op[i].op.image.src);
683 evas_common_pipe_begin(root);
684 evas_common_pipe_flush(root);
689 evas_common_pipe_load(void *data)
697 Eina_Array_Iterator it;
699 /* wait for start signal */
700 pthread_barrier_wait(&(tinfo->barrier[0]));
704 RGBA_Image *im = NULL;
707 im = eina_list_data_get(im_task);
708 im_task = eina_list_remove_list(im_task, im_task);
713 if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
714 evas_cache_image_load_data(&im->cache_entry);
715 evas_common_image_colorspace_normalize(im);
717 im->flags &= ~RGBA_IMAGE_TODO_LOAD;
723 Evas_Text_Props *text_props;
726 LKL(text_task_mutex);
727 fi = eina_list_data_get(text_task);
728 text_task = eina_list_remove_list(text_task, text_task);
729 LKU(text_task_mutex);
734 EINA_LIST_FREE(fi->task, text_props)
736 evas_common_font_draw_prepare(text_props);
737 text_props->changed = EINA_FALSE;
738 text_props->prepare = EINA_FALSE;
744 EINA_ARRAY_ITER_NEXT(&tinfo->rects_task, i, op, it)
745 op->render = op->prepare_func(tinfo, tinfo->im, op);
746 eina_array_clean(&tinfo->rects_task);
748 /* send finished signal */
749 pthread_barrier_wait(&(tinfo->barrier[1]));
756 static volatile int bval = 0;
759 evas_common_pipe_load_do(RGBA_Image *im)
764 for (i = 0; i < thread_num; i++)
765 task_thinfo[i].im = im;
767 /* Notify worker thread. */
768 pthread_barrier_wait(&(task_thbarrier[0]));
770 /* sync worker threads */
771 pthread_barrier_wait(&(task_thbarrier[1]));
776 evas_common_pipe_image_load(RGBA_Image *im)
778 if (im->flags & RGBA_IMAGE_TODO_LOAD)
781 if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888
782 && !evas_cache_image_is_loaded(&(im->cache_entry)))
785 if (!((!im->cs.data) || ((!im->cs.dirty) && (!(im->flags & RGBA_IMAGE_IS_DIRTY)))))
792 im_task = eina_list_append(im_task, im);
794 im->flags |= RGBA_IMAGE_TODO_LOAD;
798 evas_common_pipe_text_prepare(Evas_Text_Props *text_props)
802 fi = text_props->font_instance;
805 if (!text_props->changed && text_props->generation == fi->generation && text_props->glyphs)
812 LKL(text_task_mutex);
813 text_task = eina_list_append(text_task, fi);
814 LKU(text_task_mutex);
817 if (text_props->prepare) goto end;
818 text_props->prepare = EINA_TRUE;
819 fi->task = eina_list_append(fi->task, text_props);
826 evas_common_pipe_map_begin(RGBA_Image *root)
828 if (!evas_common_pipe_init())
832 EINA_LIST_FREE(im_task, im)
834 if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888)
835 evas_cache_image_load_data(&im->cache_entry);
836 evas_common_image_colorspace_normalize(im);
838 im->flags &= ~RGBA_IMAGE_TODO_LOAD;
842 evas_common_pipe_load_do(root);
844 evas_common_pipe_map_render(root);
849 evas_common_pipe_init(void)
851 #ifdef BUILD_PIPE_RENDER
857 cpunum = eina_cpu_count();
859 // on single cpu we still want this initted.. otherwise we block forever
860 // waiting onm pthread barriers for async rendering on a single core!
861 // if (thread_num == 1) return EINA_FALSE;
866 LKI(text_task_mutex);
868 pthread_barrier_init(&(thbarrier[0]), NULL, thread_num + 1);
869 pthread_barrier_init(&(thbarrier[1]), NULL, thread_num + 1);
870 for (i = 0; i < thread_num; i++)
875 pthread_attr_init(&attr);
877 CPU_SET(i % cpunum, &cpu);
878 pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
879 thinfo[i].thread_num = i;
880 thinfo[i].tasks = NULL;
881 thinfo[i].barrier = thbarrier;
882 /* setup initial locks */
883 pthread_create(&(thinfo[i].thread_id), &attr,
884 evas_common_pipe_thread, &(thinfo[i]));
885 pthread_attr_destroy(&attr);
888 pthread_barrier_init(&(task_thbarrier[0]), NULL, thread_num + 1);
889 pthread_barrier_init(&(task_thbarrier[1]), NULL, thread_num + 1);
890 for (i = 0; i < thread_num; i++)
895 pthread_attr_init(&attr);
897 CPU_SET(i % cpunum, &cpu);
898 pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
899 task_thinfo[i].thread_num = i;
900 task_thinfo[i].tasks = NULL;
901 task_thinfo[i].barrier = task_thbarrier;
902 eina_array_step_set(&task_thinfo[i].cutout_trash, sizeof (Eina_Array), 8);
903 eina_array_step_set(&task_thinfo[i].rects_task, sizeof (Eina_Array), 8);
904 /* setup initial locks */
905 pthread_create(&(task_thinfo[i].thread_id), &attr,
906 evas_common_pipe_load, &(task_thinfo[i]));
907 pthread_attr_destroy(&attr);
911 if (thread_num == 1) return EINA_FALSE;