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
This commit is contained in:
Carsten Haitzler 2006-11-13 23:23:44 +00:00
parent 13ba0a5f57
commit 9781eb9b38
18 changed files with 762 additions and 127 deletions

View File

@ -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 \

View File

@ -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

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -14,42 +14,26 @@
#ifdef BUILD_PTHREAD
# include <pthread.h>
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 <sched.h>
# 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -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? */

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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();

View File

@ -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();

View File

@ -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();