forked from enlightenment/efl
ector: move gradient color computation to a pool of thread.
This has been a long standing plan for improving performance in rendering vector object. If your test involve updating gradient, you will get another speedup of around 15%. Combined with previous shape, we get a 65% improvement with doing the CPU intensive computation in there own thread before the rendering kickoff. This was motly theorical until now, but well, it works great !
This commit is contained in:
parent
e380ddb742
commit
39fdfc3cac
|
@ -21,7 +21,7 @@ _ector_renderer_software_gradient_linear_ector_renderer_prepare(Eo *obj,
|
|||
pd->surface = efl_data_xref(base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
|
||||
}
|
||||
|
||||
update_color_table(pd);
|
||||
ector_software_gradient_color_update(pd);
|
||||
|
||||
pd->linear.x1 = pd->gld->start.x;
|
||||
pd->linear.y1 = pd->gld->start.y;
|
||||
|
@ -58,7 +58,7 @@ _ector_renderer_software_gradient_linear_ector_renderer_software_fill(Eo *obj EI
|
|||
Ector_Renderer_Software_Gradient_Data *pd)
|
||||
{
|
||||
ector_software_rasterizer_linear_gradient_set(pd->surface->rasterizer, pd);
|
||||
|
||||
ector_software_gradient_color_update(pd);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,7 @@ _ector_renderer_software_gradient_linear_efl_object_constructor(Eo *obj,
|
|||
|
||||
pd->gd = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_MIXIN, obj);
|
||||
pd->gld = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN, obj);
|
||||
pd->done = EINA_TRUE;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ _ector_renderer_software_gradient_radial_ector_renderer_prepare(Eo *obj, Ector_R
|
|||
pd->surface = efl_data_xref(base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
|
||||
}
|
||||
|
||||
update_color_table(pd);
|
||||
ector_software_gradient_color_update(pd);
|
||||
|
||||
pd->radial.cx = pd->grd->radial.x;
|
||||
pd->radial.cy = pd->grd->radial.y;
|
||||
|
@ -69,6 +69,7 @@ static Eina_Bool
|
|||
_ector_renderer_software_gradient_radial_ector_renderer_software_fill(Eo *obj EINA_UNUSED, Ector_Renderer_Software_Gradient_Data *pd)
|
||||
{
|
||||
ector_software_rasterizer_radial_gradient_set(pd->surface->rasterizer, pd);
|
||||
ector_software_gradient_color_update(pd);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -79,6 +80,7 @@ _ector_renderer_software_gradient_radial_efl_object_constructor(Eo *obj,
|
|||
obj = efl_constructor(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS));
|
||||
pd->gd = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_MIXIN, obj);
|
||||
pd->gld = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN, obj);
|
||||
pd->done = EINA_TRUE;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
|
|
@ -339,17 +339,40 @@ _generate_gradient_color_table(Efl_Gfx_Gradient_Stop *gradient_stops, int stop_c
|
|||
return alpha;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
update_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
|
||||
static void
|
||||
_update_color_table(void *data, Ector_Software_Thread *t EINA_UNUSED)
|
||||
{
|
||||
if (gdata->color_table) return;
|
||||
Ector_Renderer_Software_Gradient_Data *gdata = data;
|
||||
|
||||
gdata->color_table = malloc(GRADIENT_STOPTABLE_SIZE * 4);
|
||||
gdata->alpha = _generate_gradient_color_table(gdata->gd->colors, gdata->gd->colors_count,
|
||||
gdata->color_table, GRADIENT_STOPTABLE_SIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
_done_color_table(void *data)
|
||||
{
|
||||
Ector_Renderer_Software_Gradient_Data *gdata = data;
|
||||
|
||||
gdata->done = EINA_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
ector_software_gradient_color_update(Ector_Renderer_Software_Gradient_Data *gdata)
|
||||
{
|
||||
if (!gdata->done)
|
||||
{
|
||||
ector_software_wait(_update_color_table, _done_color_table, gdata);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (!gdata->color_table)
|
||||
{
|
||||
gdata->done = EINA_FALSE;
|
||||
ector_software_schedule(_update_color_table, _done_color_table, gdata);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
destroy_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
|
||||
{
|
||||
|
|
|
@ -44,8 +44,10 @@ typedef struct _Ector_Renderer_Software_Gradient_Data
|
|||
Software_Gradient_Linear_Data linear;
|
||||
Software_Gradient_Radial_Data radial;
|
||||
};
|
||||
Eina_Bool alpha;
|
||||
uint32_t* color_table;
|
||||
|
||||
Eina_Bool alpha;
|
||||
Eina_Bool done;
|
||||
} Ector_Renderer_Software_Gradient_Data;
|
||||
|
||||
typedef struct _Shape_Rle_Data
|
||||
|
@ -133,7 +135,6 @@ void ector_software_rasterizer_destroy_rle_data(Shape_Rle_Data *rle);
|
|||
|
||||
|
||||
// Gradient Api
|
||||
void update_color_table(Ector_Renderer_Software_Gradient_Data *gdata);
|
||||
void destroy_color_table(Ector_Renderer_Software_Gradient_Data *gdata);
|
||||
void fetch_linear_gradient(uint32_t *buffer, Span_Data *data, int y, int x, int length);
|
||||
void fetch_radial_gradient(uint32_t *buffer, Span_Data *data, int y, int x, int length);
|
||||
|
@ -146,4 +147,6 @@ typedef void (*Ector_Thread_Worker_Cb)(void *data, Ector_Software_Thread *thread
|
|||
void ector_software_wait(Ector_Thread_Worker_Cb cb, Eina_Free_Cb done, void *data);
|
||||
void ector_software_schedule(Ector_Thread_Worker_Cb cb, Eina_Free_Cb done, void *data);
|
||||
|
||||
void ector_software_gradient_color_update(Ector_Renderer_Software_Gradient_Data *gdata);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue