I have multithreaded app where each thread create its own surface, render content, save it and destroy all.
However, after some time (eg. 20 images is saved), the app stucks in _cairo_atomic_init_once_enter
from cairo-atomic-private.h
.
Here is stack-trace from Visual Studio:
[Inline Frame] app.exe!_cairo_atomic_init_once_enter(unsigned int *) Line 409 C
app.exe!_cairo_image_spans_compositor_get() Line 3135 C
[Inline Frame] app.exe!_cairo_image_surface_init(_cairo_image_surface *) Line 176 C
app.exe!_cairo_image_surface_create_for_pixman_image(pixman_image * pixman_image=0x0000023c1d1f31f0, pixman_format_code_t pixman_format=PIXMAN_a8r8g8b8) Line 197 C
app.exe!_cairo_image_surface_create_with_pixman_format(unsigned char * data=0x0000000000000000, pixman_format_code_t pixman_format=PIXMAN_a8r8g8b8, int width, int height, int stride=-1) Line 355 C
app.exe!cairo_image_surface_create(_cairo_format format, int width, int height) Line 403 C
and I am calling:
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, int(w), int(h));
My parallel loop is done via:
std::vector<int> xSeq(countX);
std::iota(std::begin(xSeq), std::end(xSeq), 0); // Fill with 0, 1, ..., countX.
std::for_each(std::execution::par, std::begin(xSeq), std::end(xSeq), [&](auto x)
{
//create cairo surface, write to it, store it and release it
}
If I run serial version, all is working correctly.
Edit: To store surface to image, I dont use internal PNG saver. I have my own implementation, that is based on:
cairo_surface_flush(surface);
data = cairo_image_surface_get_data(surface);
data
contains raw data from cairo and I process them manually and store them with my own compression system.
In some cases, I also use the same system to "inject" data to cairo surface. I obtain data
pointer, manually rewrite some pixels and call cairo_surface_mark_dirty(surface)
to notify Cairo about the change.