mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
cogl-path: Use true copy-on-write semantics
Previously a path copy was implemented such that only the array of path nodes was shared with the source and the rest of the data is copied. This was so that the copy could avoid a deep copy if the source path is appended to because the copy keeps track of its own length. This optimisation is probably not worthwhile because it makes the copies less cheap. Instead the CoglPath struct now just contains a single pointer to a new CoglPathData struct which is separately ref-counted. When the path is modified it will be copied if the ref count on the data is not 1.
This commit is contained in:
parent
582bd409dd
commit
8193e12546
@ -57,24 +57,20 @@ typedef struct _CoglBezCubic
|
|||||||
} CoglBezCubic;
|
} CoglBezCubic;
|
||||||
|
|
||||||
typedef struct _CoglPath CoglPath;
|
typedef struct _CoglPath CoglPath;
|
||||||
|
typedef struct _CoglPathData CoglPathData;
|
||||||
|
|
||||||
struct _CoglPath
|
struct _CoglPath
|
||||||
{
|
{
|
||||||
CoglHandleObject _parent;
|
CoglHandleObject _parent;
|
||||||
|
|
||||||
/* If this path was created with cogl_path_copy then parent_path
|
CoglPathData *data;
|
||||||
will point to the copied path. Otherwise it will be
|
};
|
||||||
COGL_INVALID_HANDLE to indicate that we own path_nodes. */
|
|
||||||
CoglHandle parent_path;
|
struct _CoglPathData
|
||||||
/* Pointer to the path nodes array. This will point directly into
|
{
|
||||||
the parent path if this path is a copy */
|
unsigned int ref_count;
|
||||||
|
|
||||||
GArray *path_nodes;
|
GArray *path_nodes;
|
||||||
/* Number of nodes to render from the data. This may be different
|
|
||||||
from path_nodes->len if this is a copied path and the parent path
|
|
||||||
was appended to. If that is the case then we need to be careful
|
|
||||||
to check that the size of a sub path doesn't extend past
|
|
||||||
path_size */
|
|
||||||
unsigned int path_size;
|
|
||||||
|
|
||||||
floatVec2 path_start;
|
floatVec2 path_start;
|
||||||
floatVec2 path_pen;
|
floatVec2 path_pen;
|
||||||
|
243
cogl/cogl-path.c
243
cogl/cogl-path.c
@ -46,42 +46,39 @@ static void _cogl_path_free (CoglPath *path);
|
|||||||
|
|
||||||
COGL_HANDLE_DEFINE (Path, path);
|
COGL_HANDLE_DEFINE (Path, path);
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_path_data_unref (CoglPathData *data)
|
||||||
|
{
|
||||||
|
if (--data->ref_count <= 0)
|
||||||
|
{
|
||||||
|
g_array_free (data->path_nodes, TRUE);
|
||||||
|
|
||||||
|
g_slice_free (CoglPathData, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cogl_path_modify (CoglPath *path)
|
_cogl_path_modify (CoglPath *path)
|
||||||
{
|
{
|
||||||
/* This needs to be called whenever the path is about to be modified
|
/* This needs to be called whenever the path is about to be modified
|
||||||
to implement copy-on-write semantics. Note that the current
|
to implement copy-on-write semantics */
|
||||||
mechanism assumes that a path will only ever be appended to (ie,
|
|
||||||
the path won't be cleared or have nodes in the middle
|
|
||||||
changed). This means that we don't need to keep track of how many
|
|
||||||
copies a node has because the copies can just keep track of the
|
|
||||||
number of nodes they should draw */
|
|
||||||
|
|
||||||
/* If this path is a copy then we need to actually copy the data so
|
/* If there is more than one path using the data then we need to
|
||||||
we can modify it */
|
copy the data instead */
|
||||||
if (path->parent_path)
|
if (path->data->ref_count != 1)
|
||||||
{
|
{
|
||||||
CoglPath *old_path = COGL_PATH (path->parent_path);
|
CoglPathData *old_data = path->data;
|
||||||
CoglPathNode *old_nodes = &g_array_index (old_path->path_nodes,
|
|
||||||
CoglPathNode, 0);
|
|
||||||
CoglPathNode *new_nodes;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
path->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
|
path->data = g_slice_dup (CoglPathData, old_data);
|
||||||
/* The parent path may have extra nodes added after the copy was
|
path->data->path_nodes = g_array_new (FALSE, FALSE,
|
||||||
made so we need to truncate it */
|
sizeof (CoglPathNode));
|
||||||
g_array_set_size (path->path_nodes, path->path_size);
|
g_array_append_vals (path->data->path_nodes,
|
||||||
memcpy (path->path_nodes->data, old_nodes,
|
old_data->path_nodes->data,
|
||||||
sizeof (CoglPathNode) * path->path_size);
|
old_data->path_nodes->len);
|
||||||
/* We need to make sure the last path size doesn't extend past
|
|
||||||
the total path size */
|
|
||||||
new_nodes = &g_array_index (path->path_nodes, CoglPathNode, 0);
|
|
||||||
for (i = 0; i < path->path_size; i += new_nodes[i].path_size)
|
|
||||||
if (i + new_nodes[i].path_size >= path->path_size)
|
|
||||||
new_nodes[i].path_size = path->path_size - i;
|
|
||||||
|
|
||||||
cogl_handle_unref (path->parent_path);
|
path->data->ref_count = 1;
|
||||||
path->parent_path = COGL_INVALID_HANDLE;
|
|
||||||
|
_cogl_path_data_unref (old_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +89,7 @@ _cogl_path_add_node (gboolean new_sub_path,
|
|||||||
{
|
{
|
||||||
CoglPathNode new_node;
|
CoglPathNode new_node;
|
||||||
CoglPath *path;
|
CoglPath *path;
|
||||||
|
CoglPathData *data;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -99,29 +97,30 @@ _cogl_path_add_node (gboolean new_sub_path,
|
|||||||
|
|
||||||
_cogl_path_modify (path);
|
_cogl_path_modify (path);
|
||||||
|
|
||||||
|
data = path->data;
|
||||||
|
|
||||||
new_node.x = x;
|
new_node.x = x;
|
||||||
new_node.y = y;
|
new_node.y = y;
|
||||||
new_node.path_size = 0;
|
new_node.path_size = 0;
|
||||||
|
|
||||||
if (new_sub_path || path->path_size == 0)
|
if (new_sub_path || data->path_nodes->len == 0)
|
||||||
path->last_path = path->path_size;
|
data->last_path = data->path_nodes->len;
|
||||||
|
|
||||||
g_array_append_val (path->path_nodes, new_node);
|
g_array_append_val (data->path_nodes, new_node);
|
||||||
path->path_size++;
|
|
||||||
|
|
||||||
g_array_index (path->path_nodes, CoglPathNode, path->last_path).path_size++;
|
g_array_index (data->path_nodes, CoglPathNode, data->last_path).path_size++;
|
||||||
|
|
||||||
if (path->path_size == 1)
|
if (data->path_nodes->len == 1)
|
||||||
{
|
{
|
||||||
path->path_nodes_min.x = path->path_nodes_max.x = x;
|
data->path_nodes_min.x = data->path_nodes_max.x = x;
|
||||||
path->path_nodes_min.y = path->path_nodes_max.y = y;
|
data->path_nodes_min.y = data->path_nodes_max.y = y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (x < path->path_nodes_min.x) path->path_nodes_min.x = x;
|
if (x < data->path_nodes_min.x) data->path_nodes_min.x = x;
|
||||||
if (x > path->path_nodes_max.x) path->path_nodes_max.x = x;
|
if (x > data->path_nodes_max.x) data->path_nodes_max.x = x;
|
||||||
if (y < path->path_nodes_min.y) path->path_nodes_min.y = y;
|
if (y < data->path_nodes_min.y) data->path_nodes_min.y = y;
|
||||||
if (y > path->path_nodes_max.y) path->path_nodes_max.y = y;
|
if (y > data->path_nodes_max.y) data->path_nodes_max.y = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,12 +129,12 @@ _cogl_path_stroke_nodes (void)
|
|||||||
{
|
{
|
||||||
unsigned int path_start = 0;
|
unsigned int path_start = 0;
|
||||||
unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||||
CoglPath *path;
|
CoglPathData *data;
|
||||||
CoglMaterialFlushOptions options;
|
CoglMaterialFlushOptions options;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
data = COGL_PATH (ctx->current_path)->data;
|
||||||
|
|
||||||
_cogl_journal_flush ();
|
_cogl_journal_flush ();
|
||||||
|
|
||||||
@ -153,17 +152,13 @@ _cogl_path_stroke_nodes (void)
|
|||||||
|
|
||||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||||
|
|
||||||
while (path_start < path->path_size)
|
while (path_start < data->path_nodes->len)
|
||||||
{
|
{
|
||||||
CoglPathNode *node = &g_array_index (path->path_nodes, CoglPathNode,
|
CoglPathNode *node = &g_array_index (data->path_nodes, CoglPathNode,
|
||||||
path_start);
|
path_start);
|
||||||
|
|
||||||
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode), &node->x) );
|
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode), &node->x) );
|
||||||
/* We need to limit the size of the sub path to the size of our
|
GE( glDrawArrays (GL_LINE_STRIP, 0, node->path_size) );
|
||||||
path in case this path is a copy and the parent path has
|
|
||||||
grown */
|
|
||||||
GE( glDrawArrays (GL_LINE_STRIP, 0,
|
|
||||||
MIN (node->path_size, path->path_size - path_start)) );
|
|
||||||
|
|
||||||
path_start += node->path_size;
|
path_start += node->path_size;
|
||||||
}
|
}
|
||||||
@ -226,7 +221,7 @@ _cogl_add_path_to_stencil_buffer (CoglHandle path_handle,
|
|||||||
_cogl_material_get_cogl_enable_flags (ctx->source_material);
|
_cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||||
_cogl_enable (enable_flags);
|
_cogl_enable (enable_flags);
|
||||||
|
|
||||||
_cogl_path_get_bounds (path->path_nodes_min, path->path_nodes_max,
|
_cogl_path_get_bounds (path->data->path_nodes_min, path->data->path_nodes_max,
|
||||||
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
|
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
|
||||||
|
|
||||||
GE( glEnable (GL_STENCIL_TEST) );
|
GE( glEnable (GL_STENCIL_TEST) );
|
||||||
@ -275,17 +270,13 @@ _cogl_add_path_to_stencil_buffer (CoglHandle path_handle,
|
|||||||
}
|
}
|
||||||
ctx->n_texcoord_arrays_enabled = 0;
|
ctx->n_texcoord_arrays_enabled = 0;
|
||||||
|
|
||||||
while (path_start < path->path_size)
|
while (path_start < path->data->path_nodes->len)
|
||||||
{
|
{
|
||||||
CoglPathNode *node =
|
CoglPathNode *node =
|
||||||
&g_array_index (path->path_nodes, CoglPathNode, path_start);
|
&g_array_index (path->data->path_nodes, CoglPathNode, path_start);
|
||||||
|
|
||||||
GE (glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode), &node->x));
|
GE (glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode), &node->x));
|
||||||
/* We need to limit the size of the sub path to the size of our
|
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, node->path_size));
|
||||||
path in case this path is a copy and the parent path has
|
|
||||||
grown */
|
|
||||||
GE (glDrawArrays (GL_TRIANGLE_FAN, 0,
|
|
||||||
MIN (node->path_size, path->path_size - path_start)));
|
|
||||||
|
|
||||||
path_start += node->path_size;
|
path_start += node->path_size;
|
||||||
}
|
}
|
||||||
@ -522,7 +513,7 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
|
|||||||
static void
|
static void
|
||||||
_cogl_path_fill_nodes (void)
|
_cogl_path_fill_nodes (void)
|
||||||
{
|
{
|
||||||
CoglPath *path;
|
CoglPathData *data;
|
||||||
float bounds_x;
|
float bounds_x;
|
||||||
float bounds_y;
|
float bounds_y;
|
||||||
float bounds_w;
|
float bounds_w;
|
||||||
@ -530,9 +521,9 @@ _cogl_path_fill_nodes (void)
|
|||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
data = COGL_PATH (ctx->current_path)->data;
|
||||||
|
|
||||||
_cogl_path_get_bounds (path->path_nodes_min, path->path_nodes_max,
|
_cogl_path_get_bounds (data->path_nodes_min, data->path_nodes_max,
|
||||||
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
|
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
|
||||||
|
|
||||||
if (G_LIKELY (!(cogl_debug_flags & COGL_DEBUG_FORCE_SCANLINE_PATHS)) &&
|
if (G_LIKELY (!(cogl_debug_flags & COGL_DEBUG_FORCE_SCANLINE_PATHS)) &&
|
||||||
@ -568,17 +559,12 @@ _cogl_path_fill_nodes (void)
|
|||||||
{
|
{
|
||||||
unsigned int path_start = 0;
|
unsigned int path_start = 0;
|
||||||
|
|
||||||
while (path_start < path->path_size)
|
while (path_start < data->path_nodes->len)
|
||||||
{
|
{
|
||||||
CoglPathNode *node = &g_array_index (path->path_nodes, CoglPathNode,
|
CoglPathNode *node = &g_array_index (data->path_nodes, CoglPathNode,
|
||||||
path_start);
|
path_start);
|
||||||
|
|
||||||
/* We need to limit the size of the sub path to the size of
|
_cogl_path_fill_nodes_scanlines (node, node->path_size,
|
||||||
our path in case this path is a copy and the parent path
|
|
||||||
has grown */
|
|
||||||
_cogl_path_fill_nodes_scanlines (node,
|
|
||||||
MIN (node->path_size,
|
|
||||||
path->path_size - path_start),
|
|
||||||
bounds_x, bounds_y,
|
bounds_x, bounds_y,
|
||||||
bounds_w, bounds_h);
|
bounds_w, bounds_h);
|
||||||
|
|
||||||
@ -600,7 +586,7 @@ cogl_path_fill_preserve (void)
|
|||||||
{
|
{
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
if (COGL_PATH (ctx->current_path)->path_size == 0)
|
if (COGL_PATH (ctx->current_path)->data->path_nodes->len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_cogl_path_fill_nodes ();
|
_cogl_path_fill_nodes ();
|
||||||
@ -619,7 +605,7 @@ cogl_path_stroke_preserve (void)
|
|||||||
{
|
{
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
if (COGL_PATH (ctx->current_path)->path_size == 0)
|
if (COGL_PATH (ctx->current_path)->data->path_nodes->len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_cogl_path_stroke_nodes ();
|
_cogl_path_stroke_nodes ();
|
||||||
@ -629,62 +615,62 @@ void
|
|||||||
cogl_path_move_to (float x,
|
cogl_path_move_to (float x,
|
||||||
float y)
|
float y)
|
||||||
{
|
{
|
||||||
CoglPath *path;
|
CoglPathData *data;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
_cogl_path_add_node (TRUE, x, y);
|
_cogl_path_add_node (TRUE, x, y);
|
||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
data = COGL_PATH (ctx->current_path)->data;
|
||||||
|
|
||||||
path->path_start.x = x;
|
data->path_start.x = x;
|
||||||
path->path_start.y = y;
|
data->path_start.y = y;
|
||||||
|
|
||||||
path->path_pen = path->path_start;
|
data->path_pen = data->path_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_path_rel_move_to (float x,
|
cogl_path_rel_move_to (float x,
|
||||||
float y)
|
float y)
|
||||||
{
|
{
|
||||||
CoglPath *path;
|
CoglPathData *data;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
data = COGL_PATH (ctx->current_path)->data;
|
||||||
|
|
||||||
cogl_path_move_to (path->path_pen.x + x,
|
cogl_path_move_to (data->path_pen.x + x,
|
||||||
path->path_pen.y + y);
|
data->path_pen.y + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_path_line_to (float x,
|
cogl_path_line_to (float x,
|
||||||
float y)
|
float y)
|
||||||
{
|
{
|
||||||
CoglPath *path;
|
CoglPathData *data;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
_cogl_path_add_node (FALSE, x, y);
|
_cogl_path_add_node (FALSE, x, y);
|
||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
data = COGL_PATH (ctx->current_path)->data;
|
||||||
|
|
||||||
path->path_pen.x = x;
|
data->path_pen.x = x;
|
||||||
path->path_pen.y = y;
|
data->path_pen.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_path_rel_line_to (float x,
|
cogl_path_rel_line_to (float x,
|
||||||
float y)
|
float y)
|
||||||
{
|
{
|
||||||
CoglPath *path;
|
CoglPathData *data;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
data = COGL_PATH (ctx->current_path)->data;
|
||||||
|
|
||||||
cogl_path_line_to (path->path_pen.x + x,
|
cogl_path_line_to (data->path_pen.x + x,
|
||||||
path->path_pen.y + y);
|
data->path_pen.y + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -696,10 +682,10 @@ cogl_path_close (void)
|
|||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
path = COGL_PATH (ctx->current_path);
|
||||||
|
|
||||||
_cogl_path_add_node (FALSE, path->path_start.x,
|
_cogl_path_add_node (FALSE, path->data->path_start.x,
|
||||||
path->path_start.y);
|
path->data->path_start.y);
|
||||||
|
|
||||||
path->path_pen = path->path_start;
|
path->data->path_pen = path->data->path_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -847,14 +833,14 @@ _cogl_path_rel_arc (float center_x,
|
|||||||
float angle_2,
|
float angle_2,
|
||||||
float angle_step)
|
float angle_step)
|
||||||
{
|
{
|
||||||
CoglPath *path;
|
CoglPathData *data;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
data = COGL_PATH (ctx->current_path)->data;
|
||||||
|
|
||||||
_cogl_path_arc (path->path_pen.x + center_x,
|
_cogl_path_arc (data->path_pen.x + center_x,
|
||||||
path->path_pen.y + center_y,
|
data->path_pen.y + center_y,
|
||||||
radius_x, radius_y,
|
radius_x, radius_y,
|
||||||
angle_1, angle_2,
|
angle_1, angle_2,
|
||||||
angle_step, 0 /* no move */);
|
angle_step, 0 /* no move */);
|
||||||
@ -902,16 +888,16 @@ cogl_path_round_rectangle (float x_1,
|
|||||||
270,
|
270,
|
||||||
arc_step);
|
arc_step);
|
||||||
|
|
||||||
cogl_path_line_to (path->path_pen.x + inner_width,
|
cogl_path_line_to (path->data->path_pen.x + inner_width,
|
||||||
path->path_pen.y);
|
path->data->path_pen.y);
|
||||||
_cogl_path_rel_arc (0, radius,
|
_cogl_path_rel_arc (0, radius,
|
||||||
radius, radius,
|
radius, radius,
|
||||||
-90,
|
-90,
|
||||||
0,
|
0,
|
||||||
arc_step);
|
arc_step);
|
||||||
|
|
||||||
cogl_path_line_to (path->path_pen.x,
|
cogl_path_line_to (path->data->path_pen.x,
|
||||||
path->path_pen.y + inner_height);
|
path->data->path_pen.y + inner_height);
|
||||||
|
|
||||||
_cogl_path_rel_arc (-radius, 0,
|
_cogl_path_rel_arc (-radius, 0,
|
||||||
radius, radius,
|
radius, radius,
|
||||||
@ -919,8 +905,8 @@ cogl_path_round_rectangle (float x_1,
|
|||||||
90,
|
90,
|
||||||
arc_step);
|
arc_step);
|
||||||
|
|
||||||
cogl_path_line_to (path->path_pen.x - inner_width,
|
cogl_path_line_to (path->data->path_pen.x - inner_width,
|
||||||
path->path_pen.y);
|
path->data->path_pen.y);
|
||||||
_cogl_path_rel_arc (0, -radius,
|
_cogl_path_rel_arc (0, -radius,
|
||||||
radius, radius,
|
radius, radius,
|
||||||
90,
|
90,
|
||||||
@ -1042,7 +1028,7 @@ cogl_path_curve_to (float x_1,
|
|||||||
path = COGL_PATH (ctx->current_path);
|
path = COGL_PATH (ctx->current_path);
|
||||||
|
|
||||||
/* Prepare cubic curve */
|
/* Prepare cubic curve */
|
||||||
cubic.p1 = path->path_pen;
|
cubic.p1 = path->data->path_pen;
|
||||||
cubic.p2.x = x_1;
|
cubic.p2.x = x_1;
|
||||||
cubic.p2.y = y_1;
|
cubic.p2.y = y_1;
|
||||||
cubic.p3.x = x_2;
|
cubic.p3.x = x_2;
|
||||||
@ -1055,7 +1041,7 @@ cogl_path_curve_to (float x_1,
|
|||||||
|
|
||||||
/* Add last point */
|
/* Add last point */
|
||||||
_cogl_path_add_node (FALSE, cubic.p4.x, cubic.p4.y);
|
_cogl_path_add_node (FALSE, cubic.p4.x, cubic.p4.y);
|
||||||
path->path_pen = cubic.p4;
|
path->data->path_pen = cubic.p4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1066,18 +1052,18 @@ cogl_path_rel_curve_to (float x_1,
|
|||||||
float x_3,
|
float x_3,
|
||||||
float y_3)
|
float y_3)
|
||||||
{
|
{
|
||||||
CoglPath *path;
|
CoglPathData *data;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
data = COGL_PATH (ctx->current_path)->data;
|
||||||
|
|
||||||
cogl_path_curve_to (path->path_pen.x + x_1,
|
cogl_path_curve_to (data->path_pen.x + x_1,
|
||||||
path->path_pen.y + y_1,
|
data->path_pen.y + y_1,
|
||||||
path->path_pen.x + x_2,
|
data->path_pen.x + x_2,
|
||||||
path->path_pen.y + y_2,
|
data->path_pen.y + y_2,
|
||||||
path->path_pen.x + x_3,
|
data->path_pen.x + x_3,
|
||||||
path->path_pen.y + y_3);
|
data->path_pen.y + y_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglHandle
|
CoglHandle
|
||||||
@ -1107,12 +1093,14 @@ CoglHandle
|
|||||||
_cogl_path_new (void)
|
_cogl_path_new (void)
|
||||||
{
|
{
|
||||||
CoglPath *path;
|
CoglPath *path;
|
||||||
|
CoglPathData *data;
|
||||||
|
|
||||||
path = g_slice_new (CoglPath);
|
path = g_slice_new (CoglPath);
|
||||||
path->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
|
data = path->data = g_slice_new (CoglPathData);
|
||||||
path->last_path = 0;
|
|
||||||
path->parent_path = COGL_INVALID_HANDLE;
|
data->ref_count = 1;
|
||||||
path->path_size = 0;
|
data->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
|
||||||
|
data->last_path = 0;
|
||||||
|
|
||||||
return _cogl_path_handle_new (path);
|
return _cogl_path_handle_new (path);
|
||||||
}
|
}
|
||||||
@ -1129,8 +1117,9 @@ cogl_path_copy (CoglHandle handle)
|
|||||||
|
|
||||||
old_path = COGL_PATH (handle);
|
old_path = COGL_PATH (handle);
|
||||||
|
|
||||||
new_path = g_slice_dup (CoglPath, old_path);
|
new_path = g_slice_new (CoglPath);
|
||||||
new_path->parent_path = cogl_handle_ref (handle);
|
new_path->data = old_path->data;
|
||||||
|
new_path->data->ref_count++;
|
||||||
|
|
||||||
return _cogl_path_handle_new (new_path);
|
return _cogl_path_handle_new (new_path);
|
||||||
}
|
}
|
||||||
@ -1138,11 +1127,7 @@ cogl_path_copy (CoglHandle handle)
|
|||||||
static void
|
static void
|
||||||
_cogl_path_free (CoglPath *path)
|
_cogl_path_free (CoglPath *path)
|
||||||
{
|
{
|
||||||
if (path->parent_path)
|
_cogl_path_data_unref (path->data);
|
||||||
cogl_handle_unref (path->parent_path);
|
|
||||||
else
|
|
||||||
g_array_free (path->path_nodes, TRUE);
|
|
||||||
|
|
||||||
g_slice_free (CoglPath, path);
|
g_slice_free (CoglPath, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1231,7 +1216,7 @@ cogl_path_curve2_to (float x_1,
|
|||||||
path = COGL_PATH (ctx->current_path);
|
path = COGL_PATH (ctx->current_path);
|
||||||
|
|
||||||
/* Prepare quadratic curve */
|
/* Prepare quadratic curve */
|
||||||
quad.p1 = ctx->path_pen;
|
quad.p1 = path->data->path_pen;
|
||||||
quad.p2.x = x_1;
|
quad.p2.x = x_1;
|
||||||
quad.p2.y = y_1;
|
quad.p2.y = y_1;
|
||||||
quad.p3.x = x_2;
|
quad.p3.x = x_2;
|
||||||
@ -1242,7 +1227,7 @@ cogl_path_curve2_to (float x_1,
|
|||||||
|
|
||||||
/* Add last point */
|
/* Add last point */
|
||||||
_cogl_path_add_node (FALSE, quad.p3.x, quad.p3.y);
|
_cogl_path_add_node (FALSE, quad.p3.x, quad.p3.y);
|
||||||
path->path_pen = quad.p3;
|
path->data->path_pen = quad.p3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1251,16 +1236,16 @@ cogl_rel_curve2_to (float x_1,
|
|||||||
float x_2,
|
float x_2,
|
||||||
float y_2)
|
float y_2)
|
||||||
{
|
{
|
||||||
CoglPath *path;
|
CoglPathData *data;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
path = COGL_PATH (ctx->current_path);
|
data = COGL_PATH (ctx->current_path)->data;
|
||||||
|
|
||||||
cogl_path_curve2_to (path->path_pen.x + x_1,
|
cogl_path_curve2_to (data->path_pen.x + x_1,
|
||||||
path->path_pen.y + y_1,
|
data->path_pen.y + y_1,
|
||||||
path->path_pen.x + x_2,
|
data->path_pen.x + x_2,
|
||||||
path->path_pen.y + y_2);
|
data->path_pen.y + y_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user