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:
Cedric Bail 2017-09-17 11:46:09 -07:00
parent e380ddb742
commit 39fdfc3cac
4 changed files with 46 additions and 17 deletions

View File

@ -11,7 +11,7 @@
static Eina_Bool
_ector_renderer_software_gradient_linear_ector_renderer_prepare(Eo *obj,
Ector_Renderer_Software_Gradient_Data *pd)
Ector_Renderer_Software_Gradient_Data *pd)
{
if (!pd->surface)
{
@ -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;
@ -46,19 +46,19 @@ _ector_renderer_software_gradient_linear_ector_renderer_prepare(Eo *obj,
static Eina_Bool
_ector_renderer_software_gradient_linear_ector_renderer_draw(Eo *obj EINA_UNUSED,
Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
unsigned int mul_col EINA_UNUSED)
Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
unsigned int mul_col EINA_UNUSED)
{
return EINA_TRUE;
}
static Eina_Bool
_ector_renderer_software_gradient_linear_ector_renderer_software_fill(Eo *obj EINA_UNUSED,
Ector_Renderer_Software_Gradient_Data *pd)
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;
}

View File

@ -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;
@ -57,9 +57,9 @@ _ector_renderer_software_gradient_radial_ector_renderer_prepare(Eo *obj, Ector_R
// Clearly duplicated and should be in a common place...
static Eina_Bool
_ector_renderer_software_gradient_radial_ector_renderer_draw(Eo *obj EINA_UNUSED,
Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
unsigned int mul_col EINA_UNUSED)
Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
unsigned int mul_col EINA_UNUSED)
{
return EINA_TRUE;
}
@ -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;
}

View File

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

View File

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