forked from enlightenment/efl
evas: make pipe rendering faster by forcing it to update region that fit in CPU cache.
NOTE: for people using Evas pipe rendering infrastructure. I am interested in reporting expedite test before and after this patch with the associated type of CPU (number, thread, cache). Thanks. SVN revision: 71887
This commit is contained in:
parent
9d96a8ec62
commit
c9cd50983f
|
@ -788,3 +788,6 @@
|
||||||
fixes 1 rounding error in text objects that placed ascent in the wrong
|
fixes 1 rounding error in text objects that placed ascent in the wrong
|
||||||
place by 1 pixel for even ascents.
|
place by 1 pixel for even ascents.
|
||||||
|
|
||||||
|
2012-06-10 Cedric Bail
|
||||||
|
|
||||||
|
* Limit the updated region to fit in CPU cache for Pipe rendering.
|
||||||
|
|
|
@ -7,6 +7,7 @@ Improvements:
|
||||||
* Lock less font rendering.
|
* Lock less font rendering.
|
||||||
* Reduce cost of propagating event by limiting the object we explore by using a bouncing box.
|
* Reduce cost of propagating event by limiting the object we explore by using a bouncing box.
|
||||||
* Don't wake up prepare thread if there is nothing to prepare.
|
* Don't wake up prepare thread if there is nothing to prepare.
|
||||||
|
* Limit the updated region to fit in CPU cache for Pipe rendering.
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
* Add missing files in the tarball.
|
* Add missing files in the tarball.
|
||||||
|
|
|
@ -70,17 +70,15 @@ evas_common_pipe_thread(void *data)
|
||||||
thinfo = data;
|
thinfo = data;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
RGBA_Pipe_Thread_Info *info;
|
const RGBA_Pipe_Thread_Info *info;
|
||||||
RGBA_Pipe *p;
|
RGBA_Pipe *p;
|
||||||
|
|
||||||
/* wait for start signal */
|
/* wait for start signal */
|
||||||
// INF(" TH %i START...", thinfo->thread_num);
|
// INF(" TH %i START...", thinfo->thread_num);
|
||||||
pthread_barrier_wait(&(thinfo->barrier[0]));
|
pthread_barrier_wait(&(thinfo->barrier[0]));
|
||||||
info = thinfo->info;
|
|
||||||
// if (info)
|
EINA_INLIST_FOREACH(thinfo->tasks, info)
|
||||||
// {
|
{
|
||||||
// thinfo->info = NULL;
|
|
||||||
// INF(" TH %i GO", thinfo->thread_num);
|
|
||||||
EINA_INLIST_FOREACH(EINA_INLIST_GET(info->im->cache_entry.pipe), p)
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(info->im->cache_entry.pipe), p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -91,10 +89,10 @@ evas_common_pipe_thread(void *data)
|
||||||
p->op[i].op_func(info->im, &(p->op[i]), info);
|
p->op[i].op_func(info->im, &(p->op[i]), info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(info);
|
}
|
||||||
// }
|
|
||||||
// INF(" TH %i DONE", thinfo->thread_num);
|
thinfo->tasks = NULL;
|
||||||
/* send finished signal */
|
|
||||||
pthread_barrier_wait(&(thinfo->barrier[1]));
|
pthread_barrier_wait(&(thinfo->barrier[1]));
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -105,40 +103,61 @@ evas_common_pipe_thread(void *data)
|
||||||
static int thread_num = 0;
|
static int thread_num = 0;
|
||||||
static Thinfo thinfo[TH_MAX];
|
static Thinfo thinfo[TH_MAX];
|
||||||
static pthread_barrier_t thbarrier[2];
|
static pthread_barrier_t thbarrier[2];
|
||||||
|
|
||||||
|
static RGBA_Pipe_Thread_Info *buf = NULL;
|
||||||
|
static unsigned int buf_size = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
evas_common_pipe_begin(RGBA_Image *im)
|
evas_common_pipe_begin(RGBA_Image *im)
|
||||||
{
|
{
|
||||||
|
#define SZ 128
|
||||||
#ifdef BUILD_PTHREAD
|
#ifdef BUILD_PTHREAD
|
||||||
int i, y, h;
|
unsigned int x, y, cpu;
|
||||||
|
RGBA_Pipe_Thread_Info *info;
|
||||||
|
unsigned int estimatex, estimatey;
|
||||||
|
unsigned int needed_size;
|
||||||
|
|
||||||
if (!im->cache_entry.pipe) return;
|
if (!im->cache_entry.pipe) return;
|
||||||
if (thread_num == 1) return;
|
if (thread_num == 1) return;
|
||||||
y = 0;
|
|
||||||
h = im->cache_entry.h / thread_num;
|
|
||||||
if (h < 1) h = 1;
|
|
||||||
for (i = 0; i < thread_num; i++)
|
|
||||||
{
|
|
||||||
RGBA_Pipe_Thread_Info *info;
|
|
||||||
|
|
||||||
// if (y >= im->cache_entry.h) break;
|
if (im->cache_entry.w * im->cache_entry.h / thread_num < SZ * SZ)
|
||||||
info = calloc(1, sizeof(RGBA_Pipe_Thread_Info));
|
|
||||||
info->im = im;
|
|
||||||
info->x = 0;
|
|
||||||
info->y = y;
|
|
||||||
info->w = im->cache_entry.w;
|
|
||||||
if (i == (thread_num - 1))
|
|
||||||
{
|
{
|
||||||
info->h = im->cache_entry.h - y;
|
estimatex = im->cache_entry.w;
|
||||||
|
estimatey = im->cache_entry.h / thread_num;
|
||||||
|
if (estimatey == 0) estimatey = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info->h = h;
|
estimatex = SZ;
|
||||||
|
estimatey = SZ;
|
||||||
}
|
}
|
||||||
y += info->h;
|
|
||||||
thinfo[i].info = info;
|
needed_size = ((im->cache_entry.w / estimatex) + 1 ) * ((im->cache_entry.h / estimatey) + 1);
|
||||||
|
if (buf_size < needed_size)
|
||||||
|
{
|
||||||
|
buf = realloc(buf, sizeof (RGBA_Pipe_Thread_Info) * needed_size);
|
||||||
|
buf_size = needed_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info = buf;
|
||||||
|
cpu = 0;
|
||||||
|
for (y = 0; y < im->cache_entry.h; y += estimatey)
|
||||||
|
for (x = 0; x < im->cache_entry.w; x += estimatex)
|
||||||
|
{
|
||||||
|
info->im = im;
|
||||||
|
info->x = x;
|
||||||
|
info->y = y;
|
||||||
|
info->w = (x + estimatex > im->cache_entry.w) ? im->cache_entry.w - x : estimatex;
|
||||||
|
info->h = (y + estimatey > im->cache_entry.h) ? im->cache_entry.h - y : estimatey;
|
||||||
|
|
||||||
|
thinfo[cpu].tasks = eina_inlist_prepend((void*) thinfo[cpu].tasks, EINA_INLIST_GET(info));
|
||||||
|
cpu++;
|
||||||
|
if (cpu >= (unsigned int) thread_num) cpu = 0;
|
||||||
|
|
||||||
|
info++;
|
||||||
|
}
|
||||||
|
|
||||||
/* tell worker threads to start */
|
/* tell worker threads to start */
|
||||||
pthread_barrier_wait(&(thbarrier[0]));
|
pthread_barrier_wait(&(thbarrier[0]));
|
||||||
#endif
|
#endif
|
||||||
|
@ -157,9 +176,16 @@ evas_common_pipe_flush(RGBA_Image *im)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
RGBA_Pipe_Thread_Info info;
|
||||||
RGBA_Pipe *p;
|
RGBA_Pipe *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
info.im = im;
|
||||||
|
info.x = 0;
|
||||||
|
info.y = 0;
|
||||||
|
info.w = im->cache_entry.w;
|
||||||
|
info.h = im->cache_entry.h;
|
||||||
|
|
||||||
/* process pipe - 1 thead */
|
/* process pipe - 1 thead */
|
||||||
for (p = im->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next)
|
for (p = im->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next)
|
||||||
{
|
{
|
||||||
|
@ -167,7 +193,7 @@ evas_common_pipe_flush(RGBA_Image *im)
|
||||||
{
|
{
|
||||||
if (p->op[i].op_func)
|
if (p->op[i].op_func)
|
||||||
{
|
{
|
||||||
p->op[i].op_func(im, &(p->op[i]), NULL);
|
p->op[i].op_func(im, &(p->op[i]), &info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,9 +234,7 @@ evas_common_pipe_free(RGBA_Image *im)
|
||||||
/* draw ops */
|
/* draw ops */
|
||||||
/**************** RECT ******************/
|
/**************** RECT ******************/
|
||||||
static void
|
static void
|
||||||
evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
|
evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
|
||||||
{
|
|
||||||
if (info)
|
|
||||||
{
|
{
|
||||||
RGBA_Draw_Context context;
|
RGBA_Draw_Context context;
|
||||||
|
|
||||||
|
@ -220,13 +244,6 @@ evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_
|
||||||
op->op.rect.x, op->op.rect.y,
|
op->op.rect.x, op->op.rect.y,
|
||||||
op->op.rect.w, op->op.rect.h);
|
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
|
EAPI void
|
||||||
evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
|
evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h)
|
||||||
|
@ -247,9 +264,7 @@ evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, i
|
||||||
|
|
||||||
/**************** LINE ******************/
|
/**************** LINE ******************/
|
||||||
static void
|
static void
|
||||||
evas_common_pipe_line_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
|
evas_common_pipe_line_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
|
||||||
{
|
|
||||||
if (info)
|
|
||||||
{
|
{
|
||||||
RGBA_Draw_Context context;
|
RGBA_Draw_Context context;
|
||||||
|
|
||||||
|
@ -259,13 +274,6 @@ evas_common_pipe_line_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Threa
|
||||||
op->op.line.x0, op->op.line.y0,
|
op->op.line.x0, op->op.line.y0,
|
||||||
op->op.line.x1, op->op.line.y1);
|
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
|
EAPI void
|
||||||
evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
|
evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
|
||||||
|
@ -301,9 +309,7 @@ evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
evas_common_pipe_poly_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
|
evas_common_pipe_poly_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
|
||||||
{
|
|
||||||
if (info)
|
|
||||||
{
|
{
|
||||||
RGBA_Draw_Context context;
|
RGBA_Draw_Context context;
|
||||||
|
|
||||||
|
@ -312,12 +318,6 @@ evas_common_pipe_poly_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Threa
|
||||||
evas_common_polygon_draw(dst, &(context),
|
evas_common_polygon_draw(dst, &(context),
|
||||||
op->op.poly.points, 0, 0);
|
op->op.poly.points, 0, 0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
evas_common_polygon_draw(dst, &(op->context),
|
|
||||||
op->op.poly.points, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
|
evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
|
||||||
|
@ -355,9 +355,7 @@ evas_common_pipe_op_text_free(RGBA_Pipe_Op *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
evas_common_pipe_text_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
|
evas_common_pipe_text_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
|
||||||
{
|
|
||||||
if (info)
|
|
||||||
{
|
{
|
||||||
RGBA_Draw_Context context;
|
RGBA_Draw_Context context;
|
||||||
|
|
||||||
|
@ -365,11 +363,6 @@ evas_common_pipe_text_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Threa
|
||||||
evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
|
evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h);
|
||||||
evas_common_font_draw(dst, &(context), op->op.text.x, op->op.text.y, op->op.text.intl_props);
|
evas_common_font_draw(dst, &(context), op->op.text.x, op->op.text.y, op->op.text.intl_props);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
evas_common_font_draw(dst, &(op->context), op->op.text.x, op->op.text.y, op->op.text.intl_props);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
|
evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc,
|
||||||
|
@ -402,9 +395,7 @@ evas_common_pipe_op_image_free(RGBA_Pipe_Op *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
|
evas_common_pipe_image_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
|
||||||
{
|
|
||||||
if (info)
|
|
||||||
{
|
{
|
||||||
RGBA_Draw_Context context;
|
RGBA_Draw_Context context;
|
||||||
|
|
||||||
|
@ -452,50 +443,6 @@ evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thre
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef SCALECACHE
|
|
||||||
evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src),
|
|
||||||
dst, &(op->context),
|
|
||||||
op->op.image.smooth,
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst,
|
evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst,
|
||||||
|
@ -540,9 +487,7 @@ evas_common_pipe_op_map_free(RGBA_Pipe_Op *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
evas_common_pipe_map_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info)
|
evas_common_pipe_map_draw_do(RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info)
|
||||||
{
|
|
||||||
if (info)
|
|
||||||
{
|
{
|
||||||
RGBA_Draw_Context context;
|
RGBA_Draw_Context context;
|
||||||
|
|
||||||
|
@ -553,13 +498,6 @@ evas_common_pipe_map_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread
|
||||||
&context, op->op.map.npoints, op->op.map.p,
|
&context, op->op.map.npoints, op->op.map.p,
|
||||||
op->op.map.smooth, op->op.map.level);
|
op->op.map.smooth, op->op.map.level);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
evas_common_map_rgba(op->op.map.src, dst,
|
|
||||||
&(op->context), op->op.map.npoints, op->op.map.p,
|
|
||||||
op->op.map.smooth, op->op.map.level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst,
|
evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst,
|
||||||
|
@ -742,7 +680,7 @@ evas_common_pipe_init(void)
|
||||||
CPU_SET(i % cpunum, &cpu);
|
CPU_SET(i % cpunum, &cpu);
|
||||||
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
|
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
|
||||||
thinfo[i].thread_num = i;
|
thinfo[i].thread_num = i;
|
||||||
thinfo[i].info = NULL;
|
thinfo[i].tasks = NULL;
|
||||||
thinfo[i].barrier = thbarrier;
|
thinfo[i].barrier = thbarrier;
|
||||||
/* setup initial locks */
|
/* setup initial locks */
|
||||||
pthread_create(&(thinfo[i].thread_id), &attr,
|
pthread_create(&(thinfo[i].thread_id), &attr,
|
||||||
|
@ -762,7 +700,7 @@ evas_common_pipe_init(void)
|
||||||
CPU_SET(i % cpunum, &cpu);
|
CPU_SET(i % cpunum, &cpu);
|
||||||
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
|
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
|
||||||
task_thinfo[i].thread_num = i;
|
task_thinfo[i].thread_num = i;
|
||||||
task_thinfo[i].info = NULL;
|
task_thinfo[i].tasks = NULL;
|
||||||
task_thinfo[i].barrier = task_thbarrier;
|
task_thinfo[i].barrier = task_thbarrier;
|
||||||
/* setup initial locks */
|
/* setup initial locks */
|
||||||
pthread_create(&(task_thinfo[i].thread_id), &attr,
|
pthread_create(&(task_thinfo[i].thread_id), &attr,
|
||||||
|
|
|
@ -10,7 +10,7 @@ typedef struct _Thinfo
|
||||||
int thread_num;
|
int thread_num;
|
||||||
pthread_t thread_id;
|
pthread_t thread_id;
|
||||||
pthread_barrier_t *barrier;
|
pthread_barrier_t *barrier;
|
||||||
RGBA_Pipe_Thread_Info *info;
|
const Eina_Inlist *tasks;
|
||||||
} Thinfo;
|
} Thinfo;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -726,7 +726,7 @@ struct _RGBA_Draw_Context
|
||||||
struct _RGBA_Pipe_Op
|
struct _RGBA_Pipe_Op
|
||||||
{
|
{
|
||||||
RGBA_Draw_Context context;
|
RGBA_Draw_Context context;
|
||||||
void (*op_func) (RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info);
|
void (*op_func) (RGBA_Image *dst, const RGBA_Pipe_Op *op, const RGBA_Pipe_Thread_Info *info);
|
||||||
void (*free_func) (RGBA_Pipe_Op *op);
|
void (*free_func) (RGBA_Pipe_Op *op);
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
@ -770,6 +770,7 @@ struct _RGBA_Pipe
|
||||||
|
|
||||||
struct _RGBA_Pipe_Thread_Info
|
struct _RGBA_Pipe_Thread_Info
|
||||||
{
|
{
|
||||||
|
EINA_INLIST;
|
||||||
RGBA_Image *im;
|
RGBA_Image *im;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue