[cairo-bugs] [Bug 74355] Line drawing not thread-safe

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Thu Feb 6 10:41:24 PST 2014


https://bugs.freedesktop.org/show_bug.cgi?id=74355

--- Comment #3 from H. Guijt <hguijtra at xs4all.nl> ---
The following program should reproduce the problem but _doesn't_. I'm at a loss
why since it goes through the exact same steps the larger application does; the
only thing I can think of right now is that it might actually be a stack
problem for the worker threads - this might not occur if the whole thing runs
on a single thread. Not quite sure what to make of it right now, but I will
continue to investigate.

------

#include <array>
#include <cairo-win32.h>
#include <future>
#include <iostream>

const int Width = 2000;
const int Height = 1000;
const int NumThreads = 4;

double RandomValue (double Range)
{    return (Range * rand ()) / RAND_MAX;
}

void DrawCurve (cairo_t *Cairo)
{    ::cairo_set_source_rgba (Cairo, RandomValue (1.0), RandomValue (1.0),
RandomValue (1.0), RandomValue (1.0));
    ::cairo_set_line_width (Cairo, RandomValue (10.0));

    const struct {
        int Size;
        double Pattern [6];
    } Patterns [] = {
        { 0, {  0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } },
        { 2, {  0.0, 4.0, 0.0, 0.0, 0.0, 0.0 } },
        { 2, { 12.0, 4.0, 0.0, 0.0, 0.0, 0.0 } },
        { 4, { 12.0, 4.0, 0.0, 4.0, 0.0, 0.0 } },
        { 6, { 12.0, 4.0, 0.0, 4.0, 0.0, 4.0 } },
    };

    const int LinePattern = static_cast<int> (RandomValue (7.0));
    if (LinePattern == 6) 
        ::cairo_set_dash (Cairo, nullptr, 0, 0.0);
    else 
        ::cairo_set_dash (Cairo, Patterns [LinePattern].Pattern, Patterns
[LinePattern].Size, 0.0);

    ::cairo_move_to (Cairo, RandomValue (Width), RandomValue (Height));
    const int NumLines = static_cast<int> (RandomValue (2000.0));
    for (int x=0; x<NumLines; ++x) 
        ::cairo_line_to (Cairo, RandomValue (Width), RandomValue (Height));

    ::cairo_stroke (Cairo);
}

int main (int argc, const char* argv [])
{
    int It = 0;
for (;;) {
    std::cout << "Iteration " << ++It << "\n";

    struct THREADDATA {
        std::future<void> Future;
        cairo_surface_t *CairoSurface;
        cairo_t *Cairo;

        THREADDATA () {};
        THREADDATA (const THREADDATA &Other) {};
    };

    std::array<THREADDATA, NumThreads> Threads;

    // Set up the surfaces.

    for (auto &Thread : Threads) {
        Thread.CairoSurface = ::cairo_image_surface_create
(CAIRO_FORMAT_ARGB32, Width, Height);
        Thread.Cairo = ::cairo_create (Thread.CairoSurface);

        // Make the surface transparent.
        ::cairo_set_operator (Thread.Cairo, CAIRO_OPERATOR_SOURCE);
        ::cairo_set_source_rgba (Thread.Cairo, 0.0, 0.0, 0.0, 0.0);
        ::cairo_rectangle (Thread.Cairo, 0, 0, Width, Height);
        ::cairo_fill (Thread.Cairo);
        ::cairo_set_operator (Thread.Cairo, CAIRO_OPERATOR_OVER);
    }

    // Draw the curves on separate threads.

    for (auto &Thread : Threads) {
        Thread.Future = std::async (std::launch::async, [&Thread] {
            for (int x=0; x<250; ++x)
                DrawCurve (Thread.Cairo);
        });
    }

    // Wait for completion.

    for (auto &Thread : Threads) 
        Thread.Future.get ();

    // Create the final graph.

    cairo_surface_t *CairoSurface = ::cairo_image_surface_create
(CAIRO_FORMAT_ARGB32, Width, Height);
    cairo_t *Cairo = ::cairo_create (CairoSurface);

    for (auto &Thread : Threads) {
        ::cairo_set_source_surface (Cairo, Thread.CairoSurface, 0, 0);
        ::cairo_rectangle (Cairo, 0, 0, Width, Height);
        ::cairo_fill (Cairo);

        ::cairo_destroy (Thread.Cairo);
        ::cairo_surface_destroy (Thread.CairoSurface);
    }

    ::cairo_surface_write_to_png (CairoSurface, "c:\\result.png");
    ::cairo_destroy (Cairo);
    ::cairo_surface_destroy (CairoSurface);
}
    return 0;
}

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo-bugs/attachments/20140206/2e4c50a9/attachment.html>


More information about the cairo-bugs mailing list