diff --git a/legacy/evas/src/lib/engines/common/Makefile.am b/legacy/evas/src/lib/engines/common/Makefile.am index 0bd7f1a97b..2fccfd5b0a 100644 --- a/legacy/evas/src/lib/engines/common/Makefile.am +++ b/legacy/evas/src/lib/engines/common/Makefile.am @@ -54,7 +54,8 @@ evas_scale_smooth.c \ evas_scale_span.c \ evas_tiler.c \ evas_regionbuf.c \ -evas_array_hash.c +evas_array_hash.c \ +evas_pipe.c EXTRA_DIST = \ evas_scale_smooth_scaler.c \ diff --git a/legacy/evas/src/lib/engines/common/evas_cpu.c b/legacy/evas/src/lib/engines/common/evas_cpu.c index 87ed7867b4..e0f7f1b002 100644 --- a/legacy/evas/src/lib/engines/common/evas_cpu.c +++ b/legacy/evas/src/lib/engines/common/evas_cpu.c @@ -208,52 +208,24 @@ evas_common_cpu_end_opt(void) } #endif +EAPI int +evas_common_cpu_count(void) +{ #ifdef BUILD_PTHREAD -EAPI void -_evas_lk_init(Lk *l) -{ - pthread_mutext_init(&(l->mutex), NULL); - l->wlk_id = 0; -// pthread_rwlock_init(&((x)->_reslock.rwl), NULL); + cpu_set_t cpu; + int i; + static int cpus = 0; + + if (cpus != 0) return cpus; + + sched_getaffinity(getpid(), sizeof(cpu), &cpu); + for (i = 0; i < TH_MAX; i++) + { + if (CPU_ISSET(i, &cpu)) cpus = i + 1; + else break; + } + return cpus; +#else + return 1; +#endif } - -EAPI void -_evas_lk_destroy(Lk *l) -{ - pthread_mutext_destroy(&(l->mutex), NULL); -// pthread_rwlock_destroy(&((x)->_reslock.rwl)); -} - -EAPI void -_evas_lk_read_lock(Lk *l) -{ - pthread_mutex_lock(&l->mutex); - pthread_mutex_unlock(&l->mutex); -// pthread_rwlock_rdlock(&((x)->_reslock.rwl)); -} - -EAPI void -_evas_lk_read_unlock(Lk *l) -{ - pthread_mutex_lock(&l->mutex); - pthread_mutex_unlock(&l->mutex); -// pthread_rwlock_unlock(&((x)->_reslock.rwl)); -} - -EAPI void -_evas_lk_write_lock(Lk *l) -{ - pthread_mutex_lock(&l->mutex); -// pthread_self(); -// pthread_equal(); - pthread_mutex_unlock(&l->mutex); -// pthread_rwlock_wrlock(&((x)->_reslock.rwl)); -} - -EAPI void -_evas_lk_write_unlock(Lk *l) -{ - pthread_mutex_lock(&l->mutex); - pthread_mutex_unlock(&l->mutex); -} -#endif diff --git a/legacy/evas/src/lib/engines/common/evas_draw_main.c b/legacy/evas/src/lib/engines/common/evas_draw_main.c index 071195afd0..0516d61db0 100644 --- a/legacy/evas/src/lib/engines/common/evas_draw_main.c +++ b/legacy/evas/src/lib/engines/common/evas_draw_main.c @@ -22,8 +22,6 @@ void evas_common_shutdown(void) { evas_font_dir_cache_free(); - evas_common_image_line_buffer_free(); - evas_common_image_alpha_line_buffer_free(); evas_common_image_cache_free(); } diff --git a/legacy/evas/src/lib/engines/common/evas_font_draw.c b/legacy/evas/src/lib/engines/common/evas_font_draw.c index ef9d5793b1..aae41df0e0 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_draw.c +++ b/legacy/evas/src/lib/engines/common/evas_font_draw.c @@ -176,6 +176,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int pen_x = x; pen_y = y; + LKL(fn->lock); evas_common_font_size_use(fn); use_kerning = FT_HAS_KERNING(fi->src->ft.face); prev_index = 0; @@ -338,4 +339,5 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int pen_x += fg->glyph->advance.x >> 16; prev_index = index; } + LKU(fn->lock); } diff --git a/legacy/evas/src/lib/engines/common/evas_font_load.c b/legacy/evas/src/lib/engines/common/evas_font_load.c index f96c773db8..995d455d11 100644 --- a/legacy/evas/src/lib/engines/common/evas_font_load.c +++ b/legacy/evas/src/lib/engines/common/evas_font_load.c @@ -265,6 +265,8 @@ evas_common_font_memory_load(const char *name, int size, const void *data, int d fn->fonts = evas_list_append(fn->fonts, fi); fn->hinting = FONT_BYTECODE_HINT; fi->hinting = fn->hinting; + fn->references = 1; + LKI(fn->lock); return fn; } @@ -301,7 +303,8 @@ evas_common_font_load(const char *name, int size) fn->fonts = evas_list_append(fn->fonts, fi); fn->hinting = FONT_BYTECODE_HINT; fi->hinting = fn->hinting; - + fn->references = 1; + LKI(fn->lock); return fn; } @@ -346,6 +349,8 @@ evas_common_font_free(RGBA_Font *fn) if (!fn) return; + fn->references--; + if (fn->references > 0) return; for (l = fn->fonts; l; l = l->next) { RGBA_Font_Int *fi; @@ -359,6 +364,7 @@ evas_common_font_free(RGBA_Font *fn) } } evas_list_free(fn->fonts); + LKD(fn->lock); free(fn); } diff --git a/legacy/evas/src/lib/engines/common/evas_gradient_main.c b/legacy/evas/src/lib/engines/common/evas_gradient_main.c index 727acffe0f..0f0c517238 100644 --- a/legacy/evas/src/lib/engines/common/evas_gradient_main.c +++ b/legacy/evas/src/lib/engines/common/evas_gradient_main.c @@ -143,6 +143,7 @@ evas_common_gradient_new(void) RGBA_Gradient *gr; gr = calloc(1, sizeof(RGBA_Gradient)); + gr->references = 1; return gr; } @@ -150,6 +151,8 @@ EAPI void evas_common_gradient_free(RGBA_Gradient *gr) { if (!gr) return; + gr->references--; + if (gr->references > 0) return; evas_common_gradient_clear(gr); if (gr->type.name) free(gr->type.name); if (gr->type.params) free(gr->type.params); @@ -481,7 +484,7 @@ evas_common_gradient_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, alpha_buf = evas_common_image_alpha_line_buffer_obtain(w); if (!alpha_buf) { - evas_common_image_line_buffer_release(); + evas_common_image_line_buffer_release(argb_buf); return; } bfunc = evas_common_gfx_func_composite_pixel_mask_span_get(argb_buf, dst, w, dc->render_op); @@ -496,9 +499,9 @@ evas_common_gradient_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, { if (!direct_copy) { - evas_common_image_line_buffer_release(); + evas_common_image_line_buffer_release(argb_buf); if (alpha_buf) - evas_common_image_alpha_line_buffer_release(); + evas_common_image_alpha_line_buffer_release(alpha_buf); } return; } @@ -534,9 +537,9 @@ evas_common_gradient_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, if (!direct_copy) { - evas_common_image_line_buffer_release(); + evas_common_image_line_buffer_release(argb_buf); if (alpha_buf) - evas_common_image_alpha_line_buffer_release(); + evas_common_image_alpha_line_buffer_release(alpha_buf); } } diff --git a/legacy/evas/src/lib/engines/common/evas_image_main.c b/legacy/evas/src/lib/engines/common/evas_image_main.c index 4a2e001793..780cc4052d 100644 --- a/legacy/evas/src/lib/engines/common/evas_image_main.c +++ b/legacy/evas/src/lib/engines/common/evas_image_main.c @@ -257,12 +257,16 @@ evas_common_image_new(void) im = calloc(1, sizeof(RGBA_Image)); if (!im) return NULL; im->flags = RGBA_IMAGE_NOTHING; + im->ref = 1; return im; } EAPI void evas_common_image_free(RGBA_Image *im) { + im->ref--; + if (im->ref > 0) return; + evas_common_pipe_free(im); if (im->image) evas_common_image_surface_free(im->image); if (im->info.file) evas_stringshare_del(im->info.file); // if (im->info.real_file) evas_stringshare_del(im->info.real_file); @@ -505,6 +509,8 @@ evas_common_image_line_buffer_obtain(int len) if (len < 1) return NULL; if (len < EVAS_RGBA_LINE_BUFFER_MIN_LEN) len = EVAS_RGBA_LINE_BUFFER_MIN_LEN; + return evas_common_image_create(len, 1); +/* if (evas_rgba_line_buffer) { if (evas_rgba_line_buffer->image->w >= len) @@ -522,11 +528,14 @@ evas_common_image_line_buffer_obtain(int len) evas_rgba_line_buffer = evas_common_image_create(len, 1); if (!evas_rgba_line_buffer) return NULL; return evas_rgba_line_buffer; + */ } EAPI void -evas_common_image_line_buffer_release(void) +evas_common_image_line_buffer_release(RGBA_Image *im) { + evas_common_image_free(im); +/* if (!evas_rgba_line_buffer) return; if (EVAS_RGBA_LINE_BUFFER_MAX_LEN < evas_rgba_line_buffer->image->w) { @@ -539,14 +548,18 @@ evas_common_image_line_buffer_release(void) evas_rgba_line_buffer = NULL; } } + */ } EAPI void -evas_common_image_line_buffer_free(void) +evas_common_image_line_buffer_free(RGBA_Image *im) { + evas_common_image_free(im); +/* if (!evas_rgba_line_buffer) return; evas_common_image_free(evas_rgba_line_buffer); evas_rgba_line_buffer = NULL; + */ } EAPI RGBA_Image * @@ -555,6 +568,8 @@ evas_common_image_alpha_line_buffer_obtain(int len) if (len < 1) return NULL; if (len < EVAS_ALPHA_LINE_BUFFER_MIN_LEN) len = EVAS_ALPHA_LINE_BUFFER_MIN_LEN; + return evas_common_image_alpha_create(len, 1); +/* if (evas_alpha_line_buffer) { if (evas_alpha_line_buffer->image->w >= len) @@ -571,11 +586,14 @@ evas_common_image_alpha_line_buffer_obtain(int len) } evas_alpha_line_buffer = evas_common_image_alpha_create(len, 1); return evas_alpha_line_buffer; + */ } EAPI void -evas_common_image_alpha_line_buffer_release(void) +evas_common_image_alpha_line_buffer_release(RGBA_Image *im) { + evas_common_image_free(im); +/* if (!evas_alpha_line_buffer) return; if (EVAS_ALPHA_LINE_BUFFER_MAX_LEN < evas_alpha_line_buffer->image->w) { @@ -588,14 +606,18 @@ evas_common_image_alpha_line_buffer_release(void) evas_alpha_line_buffer = NULL; } } + */ } EAPI void -evas_common_image_alpha_line_buffer_free(void) +evas_common_image_alpha_line_buffer_free(RGBA_Image *im) { + evas_common_image_free(im); +/* if (!evas_alpha_line_buffer) return; evas_common_image_free(evas_alpha_line_buffer); evas_alpha_line_buffer = NULL; + */ } EAPI void diff --git a/legacy/evas/src/lib/engines/common/evas_pipe.c b/legacy/evas/src/lib/engines/common/evas_pipe.c new file mode 100644 index 0000000000..88eecb7597 --- /dev/null +++ b/legacy/evas/src/lib/engines/common/evas_pipe.c @@ -0,0 +1,558 @@ +#include "evas_common.h" + +static RGBA_Pipe *evas_common_pipe_add(RGBA_Pipe *pipe, RGBA_Pipe_Op **op); +static void evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op); +static void evas_common_pipe_op_free(RGBA_Pipe_Op *op); + +/* utils */ +static RGBA_Pipe * +evas_common_pipe_add(RGBA_Pipe *pipe, RGBA_Pipe_Op **op) +{ + RGBA_Pipe *p; + int first_pipe = 0; + + if (!pipe) + { + first_pipe = 1; + p = calloc(1, sizeof(RGBA_Pipe)); + if (!p) return NULL; + pipe = evas_object_list_append(pipe, p); + } + p = (RGBA_Pipe *)((Evas_Object_List *)pipe)->last; + if (p->op_num == PIPE_LEN) + { + p = calloc(1, sizeof(RGBA_Pipe)); + if (!p) return NULL; + pipe = evas_object_list_append(pipe, p); + } + p->op_num++; + *op = &(p->op[p->op_num - 1]); + if (first_pipe) + { + /* FIXME: PTHREAD init any thread locks etc */ + } + return pipe; +} + +static void +evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op) +{ + Cutout_Rect *r, *r2; + + memcpy(&(op->context), dc, sizeof(RGBA_Draw_Context)); + op->context.cutout.rects = NULL; + for (r = dc->cutout.rects; r; r = (Cutout_Rect *)((Evas_Object_List *)r)->next) + { + r2 = calloc(1, sizeof(Cutout_Rect)); + if (r2) + { + r2->x = r->x; + r2->y = r->y; + r2->w = r->w; + r2->h = r->h; + op->context.cutout.rects = evas_object_list_append(op->context.cutout.rects, r2); + } + } +} + +static void +evas_common_pipe_op_free(RGBA_Pipe_Op *op) +{ + evas_common_draw_context_apply_free_cutouts(op->context.cutout.rects); +} + +/* main api calls */ +EAPI void +evas_common_pipe_begin(RGBA_Image *im) +{ + /* FIXME: PTHREAD start any processing threads and lock - otherwise do + * nothing */ +} + +#ifdef BUILD_PTHREAD +typedef struct _Thinfo +{ + int thread_num; + pthread_t thread_id; + pthread_barrier_t *barrier; + RGBA_Pipe_Thread_Info *info; +} Thinfo; + +static void * +evas_common_pipe_thread(void *data) +{ + Thinfo *thinfo; + +// printf("TH [...........\n"); + thinfo = data; + for (;;) + { + RGBA_Pipe_Thread_Info *info; + RGBA_Pipe *p; + + /* wait for start signal */ +// printf(" TH %i START...\n", thinfo->thread_num); + pthread_barrier_wait(&(thinfo->barrier[0])); + info = thinfo->info; +// if (info) +// { +// thinfo->info = NULL; +// printf(" TH %i GO\n", thinfo->thread_num); + for (p = info->im->pipe; p; p = (RGBA_Pipe *)((Evas_Object_List *)p)->next) + { + 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); + } + } + free(info); +// } +// printf(" TH %i DONE\n", thinfo->thread_num); + /* send finished signal */ + pthread_barrier_wait(&(thinfo->barrier[1])); + } + return NULL; +} +#endif + +EAPI void +evas_common_pipe_flush(RGBA_Image *im) +{ + + RGBA_Pipe *p; + int i, y, h; + + if (!im->pipe) return; +#ifdef BUILD_PTHREAD + /* FIXME: PTHREAD join all threads here (if not finished) or begin then join + * otherwise just process pipe */ + { + static int thread_num = 0; + static Thinfo thinfo[TH_MAX]; + static pthread_barrier_t barrier[2]; + + if (thread_num == 0) + { + thread_num = evas_common_cpu_count(); + pthread_barrier_init(&(barrier[0]), 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, &cpu); + pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu); + thinfo[i].thread_num = i; + thinfo[i].info = NULL; + thinfo[i].barrier = barrier; + /* setup initial locks */ + pthread_create(&(thinfo[i].thread_id), &attr, + evas_common_pipe_thread, &(thinfo[i])); + } + } + y = 0; + h = im->image->h / thread_num; + if (h < 1) h = 1; + for (i = 0; i < thread_num; i++) + { + RGBA_Pipe_Thread_Info *info; + +// if (y >= im->image->h) break; + info = calloc(1, sizeof(RGBA_Pipe_Thread_Info)); + info->im = im; + info->x = 0; + info->y = y; + info->w = im->image->w; + if (i == (thread_num - 1)) + info->h = im->image->h - y; + else + info->h = h; + y += info->h; + thinfo[i].info = info; + /* send startsignal */ +// printf("START %i\n", i); + } + pthread_barrier_init(&(barrier[1]), NULL, thread_num + 1); + pthread_barrier_wait(&(barrier[0])); + pthread_barrier_destroy(&(barrier[0])); + + pthread_barrier_init(&(barrier[0]), NULL, thread_num + 1); + pthread_barrier_wait(&(barrier[1])); + pthread_barrier_destroy(&(barrier[1])); +// printf("DONE\n"); + } + +#else + /* process pipe - 1 thead */ + for (p = im->pipe; p; p = (RGBA_Pipe *)((Evas_Object_List *)p)->next) + { + for (i = 0; i < p->op_num; i++) + { + if (p->op[i].op_func) + p->op[i].op_func(im, &(p->op[i]), NULL); + } + } +#endif + evas_common_cpu_end_opt(); + evas_common_pipe_free(im); +} + +EAPI void +evas_common_pipe_free(RGBA_Image *im) +{ + + RGBA_Pipe *p; + int i; + + if (!im->pipe) return; + /* FIXME: PTHREAD join all threads here (if not finished) + + /* free pipe */ + while (im->pipe) + { + p = im->pipe; + for (i = 0; i < p->op_num; i++) + { + if (p->op[i].free_func) + p->op[i].free_func(&(p->op[i])); + } + im->pipe = evas_object_list_remove(im->pipe, p); + free(p); + } +} + + + +/* draw ops */ +/**************** RECT ******************/ +static void +evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) +{ + if (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); + evas_common_rectangle_draw(dst, &(context), + op->op.rect.x, op->op.rect.y, + op->op.rect.w, op->op.rect.h); + } + else + evas_common_rectangle_draw(dst, &(op->context), + op->op.rect.x, op->op.rect.y, + op->op.rect.w, op->op.rect.h); +} + +EAPI void +evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, + int x, int y, int w, int h) +{ + RGBA_Pipe_Op *op; + + if ((w < 1) || (h < 1)) return; + dst->pipe = evas_common_pipe_add(dst->pipe, &op); + if (!dst->pipe) return; + op->op.rect.x = x; + op->op.rect.y = y; + op->op.rect.w = w; + op->op.rect.h = h; + op->op_func = evas_common_pipe_rectangle_draw_do; + op->free_func = evas_common_pipe_op_free; + evas_common_pipe_draw_context_copy(dc, op); +} + +/**************** LINE ******************/ +static void +evas_common_pipe_line_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) +{ + if (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); + evas_common_line_draw(dst, &(context), + op->op.line.x0, op->op.line.y0, + op->op.line.x1, op->op.line.y1); + } + else + evas_common_line_draw(dst, &(op->context), + op->op.line.x0, op->op.line.y0, + op->op.line.x1, op->op.line.y1); +} + +EAPI void +evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, + int x0, int y0, int x1, int y1) +{ + RGBA_Pipe_Op *op; + + dst->pipe = evas_common_pipe_add(dst->pipe, &op); + if (!dst->pipe) return; + op->op.line.x0 = x0; + op->op.line.y0 = y0; + op->op.line.x1 = x1; + op->op.line.y1 = y1; + op->op_func = evas_common_pipe_line_draw_do; + op->free_func = evas_common_pipe_op_free; + evas_common_pipe_draw_context_copy(dc, op); +} + +/**************** POLY ******************/ +static void +evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op) +{ + RGBA_Polygon_Point *p; + + while (op->op.poly.points) + { + p = op->op.poly.points; + op->op.poly.points = evas_object_list_remove(op->op.poly.points, p); + free(p); + } + evas_common_pipe_op_free(op); +} + +static void +evas_common_pipe_poly_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) +{ + if (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); + evas_common_polygon_draw(dst, &(context), + op->op.poly.points); + } + else + evas_common_polygon_draw(dst, &(op->context), + op->op.poly.points); +} + +EAPI void +evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, + RGBA_Polygon_Point *points) +{ + RGBA_Pipe_Op *op; + RGBA_Polygon_Point *pts = NULL, *p, *pp; + + if (!points) return; + dst->pipe = evas_common_pipe_add(dst->pipe, &op); + if (!dst->pipe) return; + /* FIXME: copy points - maybe we should refcount? */ + for (p = points; p; p = (RGBA_Polygon_Point *)((Evas_Object_List *)p)->next) + { + pp = calloc(1, sizeof(RGBA_Polygon_Point)); + if (pp) + { + pp->x = p->x; + pp->y = p->y; + pts = evas_object_list_append(pts, pp); + } + } + op->op.poly.points = pts; + op->op_func = evas_common_pipe_poly_draw_do; + op->free_func = evas_common_pipe_op_poly_free; + evas_common_pipe_draw_context_copy(dc, op); +} + +/**************** GRAD ******************/ +static void +evas_common_pipe_op_grad_free(RGBA_Pipe_Op *op) +{ + evas_common_gradient_free(op->op.grad.grad); + evas_common_pipe_op_free(op); +} + +static void +evas_common_pipe_grad_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) +{ + if (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); + evas_common_gradient_draw(dst, &(context), + op->op.grad.x, op->op.grad.y, + op->op.grad.w, op->op.grad.h, + op->op.grad.grad); + } + else + evas_common_gradient_draw(dst, &(op->context), + op->op.grad.x, op->op.grad.y, + op->op.grad.w, op->op.grad.h, + op->op.grad.grad); +} + +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) +{ + RGBA_Pipe_Op *op; + + if (!gr) return; + dst->pipe = evas_common_pipe_add(dst->pipe, &op); + if (!dst->pipe) return; + op->op.grad.x = x; + op->op.grad.y = y; + op->op.grad.w = w; + op->op.grad.h = h; + gr->references++; + op->op.grad.grad = gr; + op->op_func = evas_common_pipe_grad_draw_do; + op->free_func = evas_common_pipe_op_grad_free; + evas_common_pipe_draw_context_copy(dc, op); +} + +/**************** TEXT ******************/ +static void +evas_common_pipe_op_text_free(RGBA_Pipe_Op *op) +{ + evas_common_font_free(op->op.text.font); + free(op->op.text.text); + evas_common_pipe_op_free(op); +} + +static void +evas_common_pipe_text_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) +{ + if (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); + evas_common_font_draw(dst, &(context), + op->op.text.font, op->op.text.x, op->op.text.y, + op->op.text.text); + } + else + evas_common_font_draw(dst, &(op->context), + op->op.text.font, op->op.text.x, op->op.text.y, + op->op.text.text); +} + +EAPI void +evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, + RGBA_Font *fn, int x, int y, const char *text) +{ + RGBA_Pipe_Op *op; + +// return; /* FIXME: still need locks in fonts */ + if ((!fn) || (!text)) return; + dst->pipe = evas_common_pipe_add(dst->pipe, &op); + if (!dst->pipe) return; + op->op.text.x = x; + op->op.text.y = y; + op->op.text.text = strdup(text); + fn->references++; + op->op.text.font = fn; + op->op_func = evas_common_pipe_text_draw_do; + op->free_func = evas_common_pipe_op_text_free; + evas_common_pipe_draw_context_copy(dc, op); +} + +/**************** IMAGE *****************/ +static void +evas_common_pipe_op_image_free(RGBA_Pipe_Op *op) +{ + evas_common_image_free(op->op.image.src); + evas_common_pipe_op_free(op); +} + +static void +evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) +{ + if (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); + 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); + 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); + } + else + { + if (op->op.image.smooth) + evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src, + dst, &(op->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, &(op->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); + } +} + +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) +{ + RGBA_Pipe_Op *op; + + if (!src) return; +// evas_common_pipe_flush(src); + dst->pipe = evas_common_pipe_add(dst->pipe, &op); + if (!dst->pipe) return; + op->op.image.smooth = smooth; + op->op.image.sx = src_region_x; + op->op.image.sy = src_region_y; + op->op.image.sw = src_region_w; + op->op.image.sh = src_region_h; + op->op.image.dx = dst_region_x; + op->op.image.dy = dst_region_y; + op->op.image.dw = dst_region_w; + op->op.image.dh = dst_region_h; + src->ref++; + op->op.image.src = src; + 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); +} diff --git a/legacy/evas/src/lib/engines/common/evas_scale_sample.c b/legacy/evas/src/lib/engines/common/evas_scale_sample.c index 306997431b..c864e5d760 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_sample.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_sample.c @@ -283,7 +283,7 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst, #endif { /* a scanline buffer */ - buf = malloc(dst_clip_w * sizeof(DATA32)); + buf = alloca(dst_clip_w * sizeof(DATA32)); if (!buf) goto no_buf; for (y = 0; y < dst_clip_h; y++) @@ -299,7 +299,6 @@ scale_rgba_in_to_out_clip_sample_internal(RGBA_Image *src, RGBA_Image *dst, func(buf, NULL, dc->mul.col, dptr, dst_clip_w); dptr += dst_w; } - free(buf); } } diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c index bb1b785246..04d44f08f1 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c @@ -18,10 +18,7 @@ goto done_scale_down; /* a scanline buffer */ - line_buf = evas_common_image_line_buffer_obtain(dst_clip_w); - if (!line_buf) - goto done_scale_down; - buf = line_buf->image->data; + buf = alloca(dst_clip_w * sizeof(DATA32)); if (dc->mul.use) func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op); @@ -47,7 +44,6 @@ } done_scale_down: - evas_common_image_line_buffer_release(); if (xpoints) free(xpoints); if (ypoints) free(ypoints); if (xapoints) free(xapoints); diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_up.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_up.c index 91cf4c1c3c..8688af6d31 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_up.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_up.c @@ -29,10 +29,7 @@ } if (!direct_scale) { - im_buf = evas_common_image_line_buffer_obtain(dst_clip_w); - if (!im_buf) - return; - buf = im_buf->image->data; + buf = alloca(dst_clip_w * sizeof(DATA32)); if (dc->mul.use) func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op); else @@ -231,6 +228,5 @@ } } done_scale_up: - if (!direct_scale) - evas_common_image_line_buffer_release(); + return; } diff --git a/legacy/evas/src/lib/include/evas_common.h b/legacy/evas/src/lib/include/evas_common.h index 498f86b943..bea7276310 100644 --- a/legacy/evas/src/lib/include/evas_common.h +++ b/legacy/evas/src/lib/include/evas_common.h @@ -14,42 +14,26 @@ #ifdef BUILD_PTHREAD # include -typedef struct _Lk Lk; - -struct _Lk -{ - pthread_mutex_t mutex; // lock for read/write to this struct - pthread_t wlk_id; // who has the write lock - int wlk_count; // how many times does the write lock have refs - int rlk_count; // read lock count -// pthread_rwlock_t rwl; -}; - -# define ELK Lk _lk -# define ELK_ADD(x) _evas_lk_init(&((x)->_lk)) -# define ELK_DEL(x) _evas_lk_destroy(&((x)->_lk)) -# define ELK_RLK(x) _evas_lk_read_lock(&((x)->_lk)) -# define ELK_WLK(x) _evas_lk_read_unlock(&((x)->_lk)) -# define ELK_RUL(x) _evas_lk_write_lock(&((x)->_lk)) -# define ELK_WUL(x) _evas_lk_write_unlock(&((x)->_lk)) +# include +# define LK(x) pthread_mutex_t x +# define LKI(x) pthread_mutex_init(&(x), NULL); +# define LKD(x) pthread_mutex_destroy(&(x)); +# define LKL(x) pthread_mutex_lock(&(x)); +# define LKU(x) pthread_mutex_unlock(&(x)); +# define TH(x) pthread_t x +# define THI(x) int x +# define TH_MAX 4 #else -# define ELK -# define ELK_ADD(x) -# define ELK_DEL(x) -# define ELK_RLK(x) -# define ELK_WLK(x) -# define ELK_RUL(x) -# define ELK_WUL(x) +# define LK(x) +# define LKI(x) +# define LKD(x) +# define LKL(x) +# define LKU(x) +# define TH(x) +# define THI(x) +# define TH_MAX 0 #endif -typedef struct _Glk Glk; - -struct _Glk -{ - ELK; - int _dummy; -}; - #include #include #include @@ -130,6 +114,9 @@ typedef struct _Evas_Object_List Evas_Object_List; typedef struct _Evas_Hash_El Evas_Hash_El; typedef struct _RGBA_Image_Loadopts RGBA_Image_Loadopts; +typedef struct _RGBA_Pipe_Op RGBA_Pipe_Op; +typedef struct _RGBA_Pipe RGBA_Pipe; +typedef struct _RGBA_Pipe_Thread_Info RGBA_Pipe_Thread_Info; typedef struct _RGBA_Image RGBA_Image; typedef struct _RGBA_Surface RGBA_Surface; typedef struct _RGBA_Image_Span RGBA_Image_Span; @@ -280,6 +267,55 @@ struct _RGBA_Surface RGBA_Image *im; }; +struct _RGBA_Pipe_Op +{ + RGBA_Draw_Context context; + void (*op_func) (RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info); + void (*free_func) (RGBA_Pipe_Op *op); + + union { + struct { + int x, y, w, h; + } rect; + struct { + int x0, y0, x1, y1; + } line; + struct { + RGBA_Polygon_Point *points; + } poly; + struct { + RGBA_Gradient *grad; + int x, y, w, h; + } grad; + struct { + RGBA_Font *font; + int x, y; + char *text; + } text; + struct { + RGBA_Image *src; + int sx, sy, sw, sh, dx, dy, dw, dh; + int smooth; + char *text; + } image; + } op; +}; + +#define PIPE_LEN 256 + +struct _RGBA_Pipe +{ + Evas_Object_List _list_data; + int op_num; + RGBA_Pipe_Op op[PIPE_LEN]; +}; + +struct _RGBA_Pipe_Thread_Info +{ + RGBA_Image *im; + int x, y, w, h; +}; + struct _RGBA_Image_Loadopts { int scale_down_by; // if > 1 then use this @@ -307,6 +343,8 @@ struct _RGBA_Image void *extended_info; RGBA_Image_Loadopts load_opts; unsigned char scale; + RGBA_Pipe *pipe; + int ref; }; struct _RGBA_Gradient_Color_Stop @@ -363,6 +401,8 @@ struct _RGBA_Gradient RGBA_Gradient_Type *geometer; void *gdata; } type; + + int references; }; struct _RGBA_Gradient_Type @@ -389,6 +429,8 @@ struct _RGBA_Font { Evas_List *fonts; Font_Hint_Flags hinting; + int references; + LK(lock); }; struct _RGBA_Font_Int @@ -421,7 +463,6 @@ struct _RGBA_Font_Source void *data; int data_size; - int current_size; Evas_Array_Hash *charmap; @@ -606,7 +647,8 @@ int evas_common_cpu_have_cpuid (void); int evas_common_cpu_has_feature (unsigned int feature); EAPI void evas_common_cpu_can_do (int *mmx, int *sse, int *sse2); EAPI void evas_common_cpu_end_opt (void); - +EAPI int evas_common_cpu_count (void); + /****/ EAPI void evas_common_blend_init (void); @@ -777,12 +819,12 @@ EAPI int evas_common_image_ram_usage (RGBA_Image *im); EAPI void evas_common_image_dirty (RGBA_Image *im); EAPI RGBA_Image *evas_common_image_line_buffer_obtain (int len); -EAPI void evas_common_image_line_buffer_release (void); -EAPI void evas_common_image_line_buffer_free (void); +EAPI void evas_common_image_line_buffer_release (RGBA_Image *im); +EAPI void evas_common_image_line_buffer_free (RGBA_Image *im); EAPI RGBA_Image *evas_common_image_alpha_line_buffer_obtain (int len); -EAPI void evas_common_image_alpha_line_buffer_release (void); -EAPI void evas_common_image_alpha_line_buffer_free (void); +EAPI void evas_common_image_alpha_line_buffer_release (RGBA_Image *im); +EAPI void evas_common_image_alpha_line_buffer_free (RGBA_Image *im); /*done*/ EAPI RGBA_Image *evas_common_load_image_from_file (const char *file, const char *key, RGBA_Image_Loadopts *lo); @@ -939,6 +981,20 @@ EAPI void evas_common_draw_context_set_anti_alias (RGBA_Draw_Co EAPI void evas_common_draw_context_set_color_interpolation (RGBA_Draw_Context *dc, int color_space); EAPI void evas_common_draw_context_set_render_op (RGBA_Draw_Context *dc, int op); +/****/ +/* image rendering pipelines... new optional system - non-immediate and + * 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); +EAPI void evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points); +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_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_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); + void evas_font_dir_cache_free(void); Evas_Array_Hash *evas_common_array_hash_new (void); @@ -956,15 +1012,3 @@ void evas_stringshare_shutdown(void); #endif #endif - -/* FIXME: need... */ - -/* modular image loader system (from ram, or fd) */ -/* loaders: png, jpg, ppm, pgm, argb */ -/* finish renderers for lower bit depths & color allocator */ - -/* and perhaps later on... */ -/* multiply pixels by pixels */ -/* oval / oval segment (arc) (filled/unfilled) */ -/* radial gradient fill */ -/* my own font renderer that can load bdf & pcf fonts? */ diff --git a/legacy/evas/src/modules/engines/buffer/evas_engine.c b/legacy/evas/src/modules/engines/buffer/evas_engine.c index aa09321793..d56bffae99 100644 --- a/legacy/evas/src/modules/engines/buffer/evas_engine.c +++ b/legacy/evas/src/modules/engines/buffer/evas_engine.c @@ -293,6 +293,8 @@ eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int Render_Engine *re; re = (Render_Engine *)data; + evas_common_pipe_begin(surface); + evas_common_pipe_flush(surface); evas_buffer_outbuf_buf_push_updated_region(re->ob, surface, x, y, w, h); evas_buffer_outbuf_buf_free_region_for_update(re->ob, surface); evas_common_cpu_end_opt(); diff --git a/legacy/evas/src/modules/engines/fb/evas_engine.c b/legacy/evas/src/modules/engines/fb/evas_engine.c index 444c0836f7..a0ddfa9cec 100644 --- a/legacy/evas/src/modules/engines/fb/evas_engine.c +++ b/legacy/evas/src/modules/engines/fb/evas_engine.c @@ -217,6 +217,8 @@ eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int Render_Engine *re; re = (Render_Engine *)data; + evas_common_pipe_begin(surface); + evas_common_pipe_flush(surface); evas_fb_outbuf_fb_push_updated_region(re->ob, surface, x, y, w, h); evas_fb_outbuf_fb_free_region_for_update(re->ob, surface); evas_common_cpu_end_opt(); diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c index e124435586..7286691469 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -140,15 +140,23 @@ eng_context_render_op_get(void *data, void *context) static void eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h) { +#ifdef BUILD_PTHREAD + evas_common_pipe_rectangle_draw(surface, context, x, y, w, h); +#else evas_common_rectangle_draw(surface, context, x, y, w, h); evas_common_cpu_end_opt(); +#endif } static void eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2) { +#ifdef BUILD_PTHREAD + evas_common_pipe_line_draw(surface, context, x1, y1, x2, y2); +#else evas_common_line_draw(surface, context, x1, y1, x2, y2); evas_common_cpu_end_opt(); +#endif } static void * @@ -166,8 +174,12 @@ eng_polygon_points_clear(void *data, void *context, void *polygon) static void eng_polygon_draw(void *data, void *context, void *surface, void *polygon) { +#ifdef BUILD_PTHREAD + evas_common_pipe_polygon_draw(surface, context, polygon); +#else evas_common_polygon_draw(surface, context, polygon); evas_common_cpu_end_opt(); +#endif } static void * @@ -295,7 +307,12 @@ eng_gradient_render_post(void *data, void *gradient) static void eng_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h) { +#ifdef BUILD_PTHREAD + evas_common_pipe_grad_draw(surface, context, x, y, w, h, gradient); +#else evas_common_gradient_draw(surface, context, x, y, w, h, gradient); + evas_common_cpu_end_opt(); +#endif } static void * @@ -484,6 +501,11 @@ static void eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { evas_common_load_image_data_from_file(image); +#ifdef BUILD_PTHREAD + evas_common_pipe_image_draw(image, surface, context, smooth, + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h); +#else if (smooth) evas_common_scale_rgba_in_to_out_clip_smooth(image, surface, context, src_x, src_y, src_w, src_h, @@ -493,6 +515,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h); evas_common_cpu_end_opt(); +#endif } static char * @@ -631,8 +654,13 @@ eng_font_char_at_coords_get(void *data, void *font, const char *text, int x, int static void eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text) { - if ((w == ow) && (h == oh)) - evas_common_font_draw(surface, context, font, x, y, text); +#ifdef BUILD_PTHREAD + evas_common_pipe_text_draw(surface, context, font, x, y, text); +#else + evas_common_font_draw(surface, context, font, x, y, text); + evas_common_cpu_end_opt(); +#endif +#if 0 else { /* create output surface size ow x oh and scale to w x h */ @@ -670,7 +698,7 @@ eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y evas_common_draw_context_free(dc); } } - evas_common_cpu_end_opt(); +#endif } static void diff --git a/legacy/evas/src/modules/engines/software_qtopia/evas_engine.c b/legacy/evas/src/modules/engines/software_qtopia/evas_engine.c index e3fc2d5557..d59eff77a7 100644 --- a/legacy/evas/src/modules/engines/software_qtopia/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_qtopia/evas_engine.c @@ -232,6 +232,8 @@ eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int Evas_Engine_Info_Software_Qtopia *info; re = (Render_Engine *)data; + evas_common_pipe_begin(surface); + evas_common_pipe_flush(surface); evas_qtopia_outbuf_software_qtopia_push_updated_region(re->ob, surface, x, y, w, h); evas_qtopia_outbuf_software_qtopia_free_region_for_update(re->ob, surface); evas_common_cpu_end_opt(); diff --git a/legacy/evas/src/modules/engines/software_x11/evas_engine.c b/legacy/evas/src/modules/engines/software_x11/evas_engine.c index 115abd4660..2bdbc8b863 100644 --- a/legacy/evas/src/modules/engines/software_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_x11/evas_engine.c @@ -356,6 +356,8 @@ eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int Render_Engine *re; re = (Render_Engine *)data; + evas_common_pipe_begin(surface); + evas_common_pipe_flush(surface); evas_software_x11_outbuf_push_updated_region(re->ob, surface, x, y, w, h); evas_software_x11_outbuf_free_region_for_update(re->ob, surface); evas_common_cpu_end_opt(); diff --git a/legacy/evas/src/modules/engines/software_xcb/evas_engine.c b/legacy/evas/src/modules/engines/software_xcb/evas_engine.c index 15a5b6ed2e..968f3e33d3 100644 --- a/legacy/evas/src/modules/engines/software_xcb/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_xcb/evas_engine.c @@ -427,6 +427,8 @@ eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int Render_Engine *re; re = (Render_Engine *)data; + evas_common_pipe_begin(surface); + evas_common_pipe_flush(surface); evas_software_xcb_outbuf_push_updated_region(re->ob, surface, x, y, w, h); evas_software_xcb_outbuf_free_region_for_update(re->ob, surface); evas_common_cpu_end_opt();