forked from enlightenment/efl
efl gfx_path: introduce efl_gfx_path_reserve()
Summary: This method reserves path commands buffer in advance. If user know the count of path commands coming, they can reserve commands buffer in advance to avoid buffer growing job. This reserved buffer would grow up by double size, if the buffer is full. @feature Reviewers: #committers, cedric Reviewed By: #committers, cedric Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D7456
This commit is contained in:
parent
47728f0c89
commit
e9ef999de6
|
@ -22,10 +22,17 @@ struct _Efl_Gfx_Path_Data
|
|||
|
||||
unsigned int commands_count;
|
||||
unsigned int points_count;
|
||||
|
||||
unsigned int reserved_pts_cnt; //Reserved Points Count
|
||||
unsigned int reserved_cmd_cnt; //Reserved Commands Count
|
||||
|
||||
char *path_data;
|
||||
Eina_Bool convex;
|
||||
};
|
||||
|
||||
static void _path_interpolation(Eo *obj, Efl_Gfx_Path_Data *pd, char *from, char *to, double pos);
|
||||
static void _efl_gfx_path_reset(Eo *obj, Efl_Gfx_Path_Data *pd);
|
||||
|
||||
static inline unsigned int
|
||||
_efl_gfx_path_command_length(Efl_Gfx_Path_Command command)
|
||||
{
|
||||
|
@ -65,8 +72,6 @@ efl_gfx_path_grow(Efl_Gfx_Path_Command command,
|
|||
Efl_Gfx_Path_Data *pd,
|
||||
double **offset_point)
|
||||
{
|
||||
Efl_Gfx_Path_Command *cmd_tmp;
|
||||
double *pts_tmp;
|
||||
unsigned int cmd_length = 0, pts_length = 0;
|
||||
|
||||
cmd_length = pd->commands_count ? pd->commands_count : 1;
|
||||
|
@ -75,27 +80,38 @@ efl_gfx_path_grow(Efl_Gfx_Path_Command command,
|
|||
if (_efl_gfx_path_command_length(command))
|
||||
{
|
||||
pts_length += _efl_gfx_path_command_length(command);
|
||||
pts_tmp = realloc(pd->points, pts_length * sizeof (double));
|
||||
if (!pts_tmp) return EINA_FALSE;
|
||||
|
||||
pd->points = pts_tmp;
|
||||
//grow up twice
|
||||
if (pts_length > pd->reserved_pts_cnt)
|
||||
{
|
||||
double *pts_tmp = realloc(pd->points, sizeof(double) * (pts_length * 2));
|
||||
if (!pts_tmp) return EINA_FALSE;
|
||||
pd->reserved_pts_cnt = pts_length * 2;
|
||||
pd->points = pts_tmp;
|
||||
}
|
||||
|
||||
*offset_point =
|
||||
pd->points + pts_length - _efl_gfx_path_command_length(command);
|
||||
}
|
||||
|
||||
cmd_tmp = realloc(pd->commands,
|
||||
(cmd_length + 1) * sizeof (Efl_Gfx_Path_Command));
|
||||
if (!cmd_tmp) return EINA_FALSE;
|
||||
pd->commands = cmd_tmp;
|
||||
//grow up twice
|
||||
if ((cmd_length + 1) > pd->reserved_cmd_cnt)
|
||||
{
|
||||
Efl_Gfx_Path_Command *cmd_tmp =
|
||||
realloc(pd->commands, (cmd_length * 2) * sizeof (Efl_Gfx_Path_Command));
|
||||
if (!cmd_tmp) return EINA_FALSE;
|
||||
pd->reserved_cmd_cnt = (cmd_length * 2);
|
||||
pd->commands = cmd_tmp;
|
||||
}
|
||||
|
||||
pd->commands_count = cmd_length + 1;
|
||||
pd->points_count = pts_length;
|
||||
|
||||
// Append the command
|
||||
cmd_tmp[cmd_length - 1] = command;
|
||||
pd->commands[cmd_length - 1] = command;
|
||||
|
||||
// NULL terminate the stream
|
||||
cmd_tmp[cmd_length] = EFL_GFX_PATH_COMMAND_TYPE_END;
|
||||
|
||||
pd->commands[cmd_length] = EFL_GFX_PATH_COMMAND_TYPE_END;
|
||||
pd->convex = EINA_FALSE;
|
||||
|
||||
return EINA_TRUE;
|
||||
|
@ -148,25 +164,20 @@ _efl_gfx_path_current_search(const Efl_Gfx_Path_Command *cmd,
|
|||
|
||||
EOLIAN static void
|
||||
_efl_gfx_path_path_set(Eo *obj, Efl_Gfx_Path_Data *pd,
|
||||
const Efl_Gfx_Path_Command *commands,
|
||||
const double *points)
|
||||
const Efl_Gfx_Path_Command *commands,
|
||||
const double *points)
|
||||
{
|
||||
if (!commands)
|
||||
{
|
||||
_efl_gfx_path_reset(obj, pd);
|
||||
return;
|
||||
}
|
||||
|
||||
Efl_Gfx_Path_Change_Event ev = { EFL_GFX_CHANGE_FLAG_PATH };
|
||||
Efl_Gfx_Path_Command *cmds;
|
||||
double *pts;
|
||||
unsigned int cmds_length = 0, pts_length = 0;
|
||||
|
||||
if (!commands)
|
||||
{
|
||||
free(pd->commands);
|
||||
pd->commands = NULL;
|
||||
free(pd->points);
|
||||
pd->points = NULL;
|
||||
pd->current.x = pd->current.y = 0;
|
||||
pd->current_ctrl.x = pd->current_ctrl.y = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
_efl_gfx_path_length(commands, &cmds_length, &pts_length);
|
||||
|
||||
cmds = realloc(pd->commands, sizeof (Efl_Gfx_Path_Command) * cmds_length);
|
||||
|
@ -181,14 +192,17 @@ _efl_gfx_path_path_set(Eo *obj, Efl_Gfx_Path_Data *pd,
|
|||
pd->commands_count = cmds_length;
|
||||
pd->points_count = pts_length;
|
||||
|
||||
memcpy(pd->commands, commands, sizeof (Efl_Gfx_Path_Command) * cmds_length);
|
||||
memcpy(pd->points, points, sizeof (double) * pts_length);
|
||||
//full reserved memory
|
||||
pd->reserved_cmd_cnt = cmds_length;
|
||||
pd->reserved_pts_cnt = pts_length;
|
||||
|
||||
memcpy(pd->commands, commands, sizeof(Efl_Gfx_Path_Command) * cmds_length);
|
||||
memcpy(pd->points, points, sizeof(double) * pts_length);
|
||||
|
||||
_efl_gfx_path_current_search(pd->commands, pd->points,
|
||||
&pd->current.x, &pd->current.y,
|
||||
&pd->current_ctrl.x, &pd->current_ctrl.y);
|
||||
|
||||
end:
|
||||
efl_event_callback_call(obj, EFL_GFX_PATH_EVENT_CHANGED, &ev);
|
||||
}
|
||||
|
||||
|
@ -275,9 +289,6 @@ interpolate(double from, double to, double pos_map)
|
|||
return (from * (1.0 - pos_map)) + (to * pos_map);
|
||||
}
|
||||
|
||||
static void _path_interpolation(Eo *obj, Efl_Gfx_Path_Data *pd, char *from, char *to, double pos);
|
||||
static void _efl_gfx_path_reset(Eo *obj, Efl_Gfx_Path_Data *pd);
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_gfx_path_interpolate(Eo *obj, Efl_Gfx_Path_Data *pd,
|
||||
const Eo *from, const Eo *to, double pos_map)
|
||||
|
@ -344,6 +355,8 @@ _efl_gfx_path_interpolate(Eo *obj, Efl_Gfx_Path_Data *pd,
|
|||
|
||||
pd->points_count = from_pd->points_count;
|
||||
pd->commands_count = from_pd->commands_count;
|
||||
pd->reserved_cmd_cnt = from_pd->commands_count;
|
||||
pd->reserved_pts_cnt = from_pd->points_count;
|
||||
|
||||
interv = interpolate(from_pd->current.x, to_pd->current.x, pos_map);
|
||||
pd->current.x = interv;
|
||||
|
@ -379,18 +392,39 @@ _efl_gfx_path_equal_commands(Eo *obj EINA_UNUSED,
|
|||
return _efl_gfx_path_equal_commands_internal(with_pd, pd);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_gfx_path_reserve(Eo *obj EINA_UNUSED, Efl_Gfx_Path_Data *pd,
|
||||
unsigned int cmd_count, unsigned int pts_count)
|
||||
{
|
||||
if (pd->reserved_cmd_cnt < cmd_count)
|
||||
{
|
||||
//+1 for path close.
|
||||
pd->reserved_cmd_cnt = cmd_count + 1;
|
||||
pd->commands = realloc(pd->commands, sizeof(Efl_Gfx_Path_Command) * pd->reserved_cmd_cnt);
|
||||
}
|
||||
|
||||
if (pd->reserved_pts_cnt < pts_count)
|
||||
{
|
||||
pd->reserved_pts_cnt = pts_count;
|
||||
pd->points = realloc(pd->points, sizeof(double) * pts_count);
|
||||
}
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_gfx_path_reset(Eo *obj, Efl_Gfx_Path_Data *pd)
|
||||
{
|
||||
Efl_Gfx_Path_Change_Event ev = { EFL_GFX_CHANGE_FLAG_PATH };
|
||||
|
||||
free(pd->commands);
|
||||
pd->reserved_cmd_cnt = 0;
|
||||
pd->commands = NULL;
|
||||
pd->commands_count = 0;
|
||||
|
||||
free(pd->points);
|
||||
pd->reserved_pts_cnt = 0;
|
||||
pd->points = NULL;
|
||||
pd->points_count = 0;
|
||||
|
||||
free(pd->path_data);
|
||||
pd->path_data = NULL;
|
||||
|
||||
|
|
|
@ -280,6 +280,18 @@ mixin Efl.Gfx.Path
|
|||
@in with: const(Efl.Object); [[Object]]
|
||||
}
|
||||
}
|
||||
reserve {
|
||||
[[Reserve path commands buffer in advance. If you know the count of
|
||||
path commands coming, you can reserve commands buffer in advance
|
||||
to avoid buffer growing job.
|
||||
|
||||
@since 1.22
|
||||
]]
|
||||
params {
|
||||
@in cmd_count: uint; [[Commands count to reserve]]
|
||||
@in pts_count: uint; [[Pointers count to reserve]]
|
||||
}
|
||||
}
|
||||
}
|
||||
events {
|
||||
changed: Efl.Gfx.Path_Change_Event; [[Graphics path was changed.]]
|
||||
|
|
Loading…
Reference in New Issue