From 9781eb9b3841811efa5afff72d34001c44f2106c Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Mon, 13 Nov 2006 23:23:44 +0000 Subject: [PATCH] 1. evas gets a pipeline with deferred rendering ability (sometimes faster, sometimes slower) 2. --enable-pthreads will enable multi-threaded rendering (current support is for up to 4 threads so if you have a new fanled quad core or dual cpu dual core box or whatever you will in theory be able to max moe of its cpu grunt with the software rendering engine. this can only be done because i added the pipelines which means almsot entirely lock-free multithreading internally in evas. the only locks are for fonts but with a little work i might be able to remove some/most of those too) for now pthreaded rendering likely will be linux only (it relies on sched.h for setting scheduler params to force the slave threads to run on separate cpu's as linux likes to keep them on the same cpu otherwise and thus we get no speedups at all - only slowdowns). aso note that it is a bit of a mixed bag. complex ops (like smooth scaling with alpha blending) get speedups, but simple ops (like blits/fills) slow down. this all neds examination and tweaking still - but it's a start. SVN revision: 27098 --- .../evas/src/lib/engines/common/Makefile.am | 3 +- legacy/evas/src/lib/engines/common/evas_cpu.c | 66 +-- .../src/lib/engines/common/evas_draw_main.c | 2 - .../src/lib/engines/common/evas_font_draw.c | 2 + .../src/lib/engines/common/evas_font_load.c | 8 +- .../lib/engines/common/evas_gradient_main.c | 13 +- .../src/lib/engines/common/evas_image_main.c | 30 +- .../evas/src/lib/engines/common/evas_pipe.c | 558 ++++++++++++++++++ .../lib/engines/common/evas_scale_sample.c | 3 +- .../common/evas_scale_smooth_scaler_down.c | 6 +- .../common/evas_scale_smooth_scaler_up.c | 8 +- legacy/evas/src/lib/include/evas_common.h | 146 +++-- .../src/modules/engines/buffer/evas_engine.c | 2 + .../evas/src/modules/engines/fb/evas_engine.c | 2 + .../engines/software_generic/evas_engine.c | 34 +- .../engines/software_qtopia/evas_engine.c | 2 + .../engines/software_x11/evas_engine.c | 2 + .../engines/software_xcb/evas_engine.c | 2 + 18 files changed, 762 insertions(+), 127 deletions(-) create mode 100644 legacy/evas/src/lib/engines/common/evas_pipe.c 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();