mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-08 12:38:02 +02:00
recording: Avoid refcycles by always copying the command array.
Short-term solution to avoid the refleaks and to make the test suite happy. A more elegant solution would be to track the references and avoid the substantial memory overhead of copying the recording surfaces. Thanks to Benjamin Otte for pointing out the solution to avoiding refcycles.
This commit is contained in:
parent
6a06e0ef7b
commit
e532980539
2 changed files with 12 additions and 12 deletions
|
|
@ -132,7 +132,6 @@ typedef struct _cairo_recording_surface {
|
|||
cairo_clip_t clip;
|
||||
|
||||
cairo_array_t commands;
|
||||
cairo_surface_t *commands_owner;
|
||||
|
||||
int replay_start_idx;
|
||||
} cairo_recording_surface_t;
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@ cairo_recording_surface_create (cairo_content_t content,
|
|||
}
|
||||
|
||||
_cairo_array_init (&recording_surface->commands, sizeof (cairo_command_t *));
|
||||
recording_surface->commands_owner = NULL;
|
||||
|
||||
recording_surface->replay_start_idx = 0;
|
||||
|
||||
|
|
@ -182,12 +181,6 @@ _cairo_recording_surface_finish (void *abstract_surface)
|
|||
cairo_command_t **elements;
|
||||
int i, num_elements;
|
||||
|
||||
if (recording_surface->commands_owner) {
|
||||
cairo_surface_destroy (recording_surface->commands_owner);
|
||||
_cairo_clip_fini (&recording_surface->clip);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
num_elements = recording_surface->commands.num_elements;
|
||||
elements = _cairo_array_index (&recording_surface->commands, 0);
|
||||
for (i = 0; i < num_elements; i++) {
|
||||
|
|
@ -613,6 +606,7 @@ _cairo_recording_surface_snapshot (void *abstract_other)
|
|||
{
|
||||
cairo_recording_surface_t *other = abstract_other;
|
||||
cairo_recording_surface_t *recording_surface;
|
||||
cairo_status_t status;
|
||||
|
||||
recording_surface = malloc (sizeof (cairo_recording_surface_t));
|
||||
if (unlikely (recording_surface == NULL))
|
||||
|
|
@ -626,14 +620,21 @@ _cairo_recording_surface_snapshot (void *abstract_other)
|
|||
recording_surface->extents_pixels = other->extents_pixels;
|
||||
recording_surface->extents = other->extents;
|
||||
recording_surface->unbounded = other->unbounded;
|
||||
recording_surface->replay_start_idx = other->replay_start_idx;
|
||||
recording_surface->content = other->content;
|
||||
|
||||
_cairo_array_init_snapshot (&recording_surface->commands, &other->commands);
|
||||
recording_surface->commands_owner = cairo_surface_reference (&other->base);
|
||||
|
||||
_cairo_clip_init_copy (&recording_surface->clip, &other->clip);
|
||||
|
||||
/* XXX We should in theory be able to reuse the original array, but we
|
||||
* need to handle reference cycles during subsurface and self-copy.
|
||||
*/
|
||||
recording_surface->replay_start_idx = 0;
|
||||
_cairo_array_init (&recording_surface->commands, sizeof (cairo_command_t *));
|
||||
status = _cairo_recording_surface_replay (&other->base, &recording_surface->base);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (&recording_surface->base);
|
||||
return _cairo_surface_create_in_error (status);
|
||||
}
|
||||
|
||||
return &recording_surface->base;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue