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
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_ector_renderer_software_gradient_linear_ector_renderer_prepare(Eo *obj,
|
_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)
|
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);
|
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.x1 = pd->gld->start.x;
|
||||||
pd->linear.y1 = pd->gld->start.y;
|
pd->linear.y1 = pd->gld->start.y;
|
||||||
|
@ -46,19 +46,19 @@ _ector_renderer_software_gradient_linear_ector_renderer_prepare(Eo *obj,
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_ector_renderer_software_gradient_linear_ector_renderer_draw(Eo *obj EINA_UNUSED,
|
_ector_renderer_software_gradient_linear_ector_renderer_draw(Eo *obj EINA_UNUSED,
|
||||||
Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
|
Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
|
||||||
Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
|
Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
|
||||||
unsigned int mul_col EINA_UNUSED)
|
unsigned int mul_col EINA_UNUSED)
|
||||||
{
|
{
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_ector_renderer_software_gradient_linear_ector_renderer_software_fill(Eo *obj EINA_UNUSED,
|
_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_rasterizer_linear_gradient_set(pd->surface->rasterizer, pd);
|
||||||
|
ector_software_gradient_color_update(pd);
|
||||||
return EINA_TRUE;
|
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->gd = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_MIXIN, obj);
|
||||||
pd->gld = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN, obj);
|
pd->gld = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN, obj);
|
||||||
|
pd->done = EINA_TRUE;
|
||||||
|
|
||||||
return obj;
|
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);
|
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.cx = pd->grd->radial.x;
|
||||||
pd->radial.cy = pd->grd->radial.y;
|
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...
|
// Clearly duplicated and should be in a common place...
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_ector_renderer_software_gradient_radial_ector_renderer_draw(Eo *obj EINA_UNUSED,
|
_ector_renderer_software_gradient_radial_ector_renderer_draw(Eo *obj EINA_UNUSED,
|
||||||
Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
|
Ector_Renderer_Software_Gradient_Data *pd EINA_UNUSED,
|
||||||
Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
|
Efl_Gfx_Render_Op op EINA_UNUSED, Eina_Array *clips EINA_UNUSED,
|
||||||
unsigned int mul_col EINA_UNUSED)
|
unsigned int mul_col EINA_UNUSED)
|
||||||
{
|
{
|
||||||
return EINA_TRUE;
|
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_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_rasterizer_radial_gradient_set(pd->surface->rasterizer, pd);
|
||||||
|
ector_software_gradient_color_update(pd);
|
||||||
return EINA_TRUE;
|
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));
|
obj = efl_constructor(efl_super(obj, ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS));
|
||||||
pd->gd = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_MIXIN, obj);
|
pd->gd = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_MIXIN, obj);
|
||||||
pd->gld = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN, obj);
|
pd->gld = efl_data_xref(obj, ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN, obj);
|
||||||
|
pd->done = EINA_TRUE;
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,17 +339,40 @@ _generate_gradient_color_table(Efl_Gfx_Gradient_Stop *gradient_stops, int stop_c
|
||||||
return alpha;
|
return alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
void
|
_update_color_table(void *data, Ector_Software_Thread *t EINA_UNUSED)
|
||||||
update_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
|
|
||||||
{
|
{
|
||||||
if (gdata->color_table) return;
|
Ector_Renderer_Software_Gradient_Data *gdata = data;
|
||||||
|
|
||||||
gdata->color_table = malloc(GRADIENT_STOPTABLE_SIZE * 4);
|
gdata->color_table = malloc(GRADIENT_STOPTABLE_SIZE * 4);
|
||||||
gdata->alpha = _generate_gradient_color_table(gdata->gd->colors, gdata->gd->colors_count,
|
gdata->alpha = _generate_gradient_color_table(gdata->gd->colors, gdata->gd->colors_count,
|
||||||
gdata->color_table, GRADIENT_STOPTABLE_SIZE);
|
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
|
void
|
||||||
destroy_color_table(Ector_Renderer_Software_Gradient_Data *gdata)
|
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_Linear_Data linear;
|
||||||
Software_Gradient_Radial_Data radial;
|
Software_Gradient_Radial_Data radial;
|
||||||
};
|
};
|
||||||
Eina_Bool alpha;
|
|
||||||
uint32_t* color_table;
|
uint32_t* color_table;
|
||||||
|
|
||||||
|
Eina_Bool alpha;
|
||||||
|
Eina_Bool done;
|
||||||
} Ector_Renderer_Software_Gradient_Data;
|
} Ector_Renderer_Software_Gradient_Data;
|
||||||
|
|
||||||
typedef struct _Shape_Rle_Data
|
typedef struct _Shape_Rle_Data
|
||||||
|
@ -133,7 +135,6 @@ void ector_software_rasterizer_destroy_rle_data(Shape_Rle_Data *rle);
|
||||||
|
|
||||||
|
|
||||||
// Gradient Api
|
// Gradient Api
|
||||||
void update_color_table(Ector_Renderer_Software_Gradient_Data *gdata);
|
|
||||||
void destroy_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_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);
|
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_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_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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue