2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
5 #include "evas_common.h"
7 static RGBA_Pipe *evas_common_pipe_add(RGBA_Pipe *pipe, RGBA_Pipe_Op **op);
8 static void evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op);
9 static void evas_common_pipe_op_free(RGBA_Pipe_Op *op);
13 evas_common_pipe_add(RGBA_Pipe *pipe, RGBA_Pipe_Op **op)
21 p = calloc(1, sizeof(RGBA_Pipe));
23 pipe = evas_object_list_append(pipe, p);
25 p = (RGBA_Pipe *)((Evas_Object_List *)pipe)->last;
26 if (p->op_num == PIPE_LEN)
28 p = calloc(1, sizeof(RGBA_Pipe));
30 pipe = evas_object_list_append(pipe, p);
33 *op = &(p->op[p->op_num - 1]);
36 /* FIXME: PTHREAD init any thread locks etc */
42 evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op)
44 memcpy(&(op->context), dc, sizeof(RGBA_Draw_Context));
45 if (op->context.cutout.active > 0)
47 op->context.cutout.rects = malloc(sizeof(Cutout_Rect) * op->context.cutout.active);
48 memcpy(op->context.cutout.rects, dc->cutout.rects, sizeof(Cutout_Rect) * op->context.cutout.active);
51 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);
62 typedef struct _Thinfo
66 pthread_barrier_t *barrier;
67 RGBA_Pipe_Thread_Info *info;
71 evas_common_pipe_thread(void *data)
75 // printf("TH [...........\n");
79 RGBA_Pipe_Thread_Info *info;
82 /* wait for start signal */
83 // printf(" TH %i START...\n", thinfo->thread_num);
84 pthread_barrier_wait(&(thinfo->barrier[0]));
88 // thinfo->info = NULL;
89 // printf(" TH %i GO\n", thinfo->thread_num);
90 for (p = info->im->pipe; p; p = (RGBA_Pipe *)((Evas_Object_List *)p)->next)
94 for (i = 0; i < p->op_num; i++)
97 p->op[i].op_func(info->im, &(p->op[i]), info);
102 // printf(" TH %i DONE\n", thinfo->thread_num);
103 /* send finished signal */
104 pthread_barrier_wait(&(thinfo->barrier[1]));
111 static int thread_num = 0;
112 static Thinfo thinfo[TH_MAX];
113 static pthread_barrier_t thbarrier[2];
117 evas_common_pipe_begin(RGBA_Image *im)
122 if (!im->pipe) return;
123 if (thread_num == 1) return;
128 cpunum = evas_common_cpu_count();
130 if (thread_num == 1) return;
131 pthread_barrier_init(&(thbarrier[0]), NULL, thread_num + 1);
132 pthread_barrier_init(&(thbarrier[1]), NULL, thread_num + 1);
133 for (i = 0; i < thread_num; i++)
138 pthread_attr_init(&attr);
140 CPU_SET(i % cpunum, &cpu);
141 pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
142 thinfo[i].thread_num = i;
143 thinfo[i].info = NULL;
144 thinfo[i].barrier = thbarrier;
145 /* setup initial locks */
146 pthread_create(&(thinfo[i].thread_id), &attr,
147 evas_common_pipe_thread, &(thinfo[i]));
148 pthread_attr_destroy(&attr);
152 h = im->cache_entry.h / thread_num;
154 for (i = 0; i < thread_num; i++)
156 RGBA_Pipe_Thread_Info *info;
158 // if (y >= im->cache_entry.h) break;
159 info = calloc(1, sizeof(RGBA_Pipe_Thread_Info));
163 info->w = im->cache_entry.w;
165 info->h = thread_num;
169 info->w = im->cache_entry.w;
170 if (i == (thread_num - 1))
171 info->h = im->cache_entry.h - y;
176 thinfo[i].info = info;
178 /* tell worker threads to start */
179 pthread_barrier_wait(&(thbarrier[0]));
184 evas_common_pipe_flush(RGBA_Image *im)
190 if (!im->pipe) return;
194 /* sync worker threads */
195 pthread_barrier_wait(&(thbarrier[1]));
200 /* process pipe - 1 thead */
201 for (p = im->pipe; p; p = (RGBA_Pipe *)((Evas_Object_List *)p)->next)
203 for (i = 0; i < p->op_num; i++)
205 if (p->op[i].op_func)
206 p->op[i].op_func(im, &(p->op[i]), NULL);
210 evas_common_cpu_end_opt();
211 evas_common_pipe_free(im);
215 evas_common_pipe_free(RGBA_Image *im)
221 if (!im->pipe) return;
222 /* FIXME: PTHREAD join all threads here (if not finished) */
228 for (i = 0; i < p->op_num; i++)
230 if (p->op[i].free_func)
231 p->op[i].free_func(&(p->op[i]));
233 im->pipe = evas_object_list_remove(im->pipe, p);
241 /**************** RECT ******************/
243 evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
247 RGBA_Draw_Context context;
249 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
251 evas_common_draw_context_set_sli(&(context), info->y, info->h);
253 evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
255 evas_common_rectangle_draw(dst, &(context),
256 op->op.rect.x, op->op.rect.y,
257 op->op.rect.w, op->op.rect.h);
260 evas_common_rectangle_draw(dst, &(op->context),
261 op->op.rect.x, op->op.rect.y,
262 op->op.rect.w, op->op.rect.h);
266 evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
267 int x, int y, int w, int h)
271 if ((w < 1) || (h < 1)) return;
272 dst->pipe = evas_common_pipe_add(dst->pipe, &op);
273 if (!dst->pipe) return;
278 op->op_func = evas_common_pipe_rectangle_draw_do;
279 op->free_func = evas_common_pipe_op_free;
280 evas_common_pipe_draw_context_copy(dc, op);
283 /**************** LINE ******************/
285 evas_common_pipe_line_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
289 RGBA_Draw_Context context;
291 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
293 evas_common_draw_context_set_sli(&(context), info->y, info->h);
295 evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
297 evas_common_line_draw(dst, &(context),
298 op->op.line.x0, op->op.line.y0,
299 op->op.line.x1, op->op.line.y1);
302 evas_common_line_draw(dst, &(op->context),
303 op->op.line.x0, op->op.line.y0,
304 op->op.line.x1, op->op.line.y1);
308 evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
309 int x0, int y0, int x1, int y1)
313 dst->pipe = evas_common_pipe_add(dst->pipe, &op);
314 if (!dst->pipe) return;
319 op->op_func = evas_common_pipe_line_draw_do;
320 op->free_func = evas_common_pipe_op_free;
321 evas_common_pipe_draw_context_copy(dc, op);
324 /**************** POLY ******************/
326 evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op)
328 RGBA_Polygon_Point *p;
330 while (op->op.poly.points)
332 p = op->op.poly.points;
333 op->op.poly.points = evas_object_list_remove(op->op.poly.points, p);
336 evas_common_pipe_op_free(op);
340 evas_common_pipe_poly_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
344 RGBA_Draw_Context context;
346 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
348 evas_common_draw_context_set_sli(&(context), info->y, info->h);
350 evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
352 evas_common_polygon_draw(dst, &(context),
356 evas_common_polygon_draw(dst, &(op->context),
361 evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
362 RGBA_Polygon_Point *points)
365 RGBA_Polygon_Point *pts = NULL, *p, *pp;
368 dst->pipe = evas_common_pipe_add(dst->pipe, &op);
369 if (!dst->pipe) return;
370 /* FIXME: copy points - maybe we should refcount? */
371 for (p = points; p; p = (RGBA_Polygon_Point *)((Evas_Object_List *)p)->next)
373 pp = calloc(1, sizeof(RGBA_Polygon_Point));
378 pts = evas_object_list_append(pts, pp);
381 op->op.poly.points = pts;
382 op->op_func = evas_common_pipe_poly_draw_do;
383 op->free_func = evas_common_pipe_op_poly_free;
384 evas_common_pipe_draw_context_copy(dc, op);
387 /**************** GRAD ******************/
389 evas_common_pipe_op_grad_free(RGBA_Pipe_Op *op)
391 evas_common_gradient_free(op->op.grad.grad);
392 evas_common_pipe_op_free(op);
396 evas_common_pipe_grad_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
400 RGBA_Draw_Context context;
402 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
404 evas_common_draw_context_set_sli(&(context), info->y, info->h);
406 evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
408 evas_common_gradient_draw(dst, &(context),
409 op->op.grad.x, op->op.grad.y,
410 op->op.grad.w, op->op.grad.h,
414 evas_common_gradient_draw(dst, &(op->context),
415 op->op.grad.x, op->op.grad.y,
416 op->op.grad.w, op->op.grad.h,
421 evas_common_pipe_grad_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
422 int x, int y, int w, int h, RGBA_Gradient *gr)
427 dst->pipe = evas_common_pipe_add(dst->pipe, &op);
428 if (!dst->pipe) return;
434 op->op.grad.grad = gr;
435 op->op_func = evas_common_pipe_grad_draw_do;
436 op->free_func = evas_common_pipe_op_grad_free;
437 evas_common_pipe_draw_context_copy(dc, op);
440 /**************** TEXT ******************/
442 evas_common_pipe_op_text_free(RGBA_Pipe_Op *op)
444 evas_common_font_free(op->op.text.font);
445 free(op->op.text.text);
446 evas_common_pipe_op_free(op);
450 evas_common_pipe_text_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
454 RGBA_Draw_Context context;
456 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
458 evas_common_draw_context_set_sli(&(context), info->y, info->h);
460 evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
462 evas_common_font_draw(dst, &(context),
463 op->op.text.font, op->op.text.x, op->op.text.y,
467 evas_common_font_draw(dst, &(op->context),
468 op->op.text.font, op->op.text.x, op->op.text.y,
473 evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
474 RGBA_Font *fn, int x, int y, const char *text)
478 if ((!fn) || (!text)) return;
479 dst->pipe = evas_common_pipe_add(dst->pipe, &op);
480 if (!dst->pipe) return;
483 op->op.text.text = strdup(text);
485 op->op.text.font = fn;
486 op->op_func = evas_common_pipe_text_draw_do;
487 op->free_func = evas_common_pipe_op_text_free;
488 evas_common_pipe_draw_context_copy(dc, op);
491 /**************** IMAGE *****************/
493 evas_common_pipe_op_image_free(RGBA_Pipe_Op *op)
495 op->op.image.src->ref--;
496 if (op->op.image.src->ref == 0)
497 evas_cache_image_drop(&op->op.image.src->cache_entry);
498 evas_common_pipe_op_free(op);
502 evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
506 RGBA_Draw_Context context;
508 memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context));
510 evas_common_draw_context_set_sli(&(context), info->y, info->h);
512 evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
514 if (op->op.image.smooth)
515 evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src,
526 evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src,
539 if (op->op.image.smooth)
540 evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src,
551 evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src,
565 evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst,
566 RGBA_Draw_Context *dc, int smooth,
567 int src_region_x, int src_region_y,
568 int src_region_w, int src_region_h,
569 int dst_region_x, int dst_region_y,
570 int dst_region_w, int dst_region_h)
575 // evas_common_pipe_flush(src);
576 dst->pipe = evas_common_pipe_add(dst->pipe, &op);
577 if (!dst->pipe) return;
578 op->op.image.smooth = smooth;
579 op->op.image.sx = src_region_x;
580 op->op.image.sy = src_region_y;
581 op->op.image.sw = src_region_w;
582 op->op.image.sh = src_region_h;
583 op->op.image.dx = dst_region_x;
584 op->op.image.dy = dst_region_y;
585 op->op.image.dw = dst_region_w;
586 op->op.image.dh = dst_region_h;
588 op->op.image.src = src;
589 op->op_func = evas_common_pipe_image_draw_do;
590 op->free_func = evas_common_pipe_op_image_free;
591 evas_common_pipe_draw_context_copy(dc, op);