Welcome Guest! You need to login or register to make posts.

Notification

Icon
Error

Options
Go to last post Go to first unread
Chris Jones  
#1 Posted : Tuesday, June 21, 2016 1:21:44 AM(UTC)
Chris Jones

Rank: Advanced Member

Groups: Member
Joined: 6/9/2016(UTC)
Posts: 30

Thanks: 20 times
Is there any documentation that details thread safety of GraphicsMill? For example to keep our UI interaction smooth, i'm thinking of moving rendering bitmaps to a separate thread.

My current thought is to create a GraphicsContainer, perform all of the operations on the UI thread, then on the background thread create and render the bitmap using the container, convert it to RGB from CMYK if required then convert to an InteropBitmap for use in WPF.

Is this possible? or if not do you have any suggestions?

Thanks
Eugene Kosmin  
#2 Posted : Tuesday, June 21, 2016 2:37:57 AM(UTC)
Eugene Kosmin

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 9/19/2006(UTC)
Posts: 439

Was thanked: 22 time(s) in 22 post(s)
Hi Chris,

Graphics Mill is not thread-safe by design, except little parts related to font handling.

You need to copy GraphicsContainer before rendering. There is no API for this, but you can draw GraphicsContainer on another one. Here is a pseudocode:

Code:

static class Extensions
{
    public static GraphicsContainer GetCopy(this GraphicsContainer gc)
    {
        var copy = new GraphicsContainer(gc.Width, gc.Height, gc.DpiX, gc.DpiY);

        using (var gr = copy.GetGraphics())
        {
            gr.DrawContainer(gc, 0, 0);
        }

        return copy;
    }

    public static void Save(this GraphicsContainer gc, string path)
    {
        using (var ig = new ImageGenerator(gc, PixelFormat.Format32bppArgb, RgbColor.Transparent))
        using (var writer = ImageWriter.Create(path))
        {
            Pipeline.Run(ig + writer);
        }
    }
}

var gc = new GraphicsContainer(width, height, dpiX, dpiY);

// GUI thread
lock(gc)
{
    using (var gr = gc.GetGraphics())
    {
        gr.FillRectangle(...);
        // other drawing
    }
}

// Background thread
GraphicsContainer copy = null;

lock(gc)
{
    copy = gc.GetCopy();
}

using (copy)
{
    copy.Save("out.png");
}
Best regards,
Eugene Kosmin.
Aurigma Development Team
thanks 1 user thanked Eugene Kosmin for this useful post.
Chris Jones on 6/21/2016(UTC)
Chris Jones  
#3 Posted : Tuesday, June 21, 2016 2:58:03 AM(UTC)
Chris Jones

Rank: Advanced Member

Groups: Member
Joined: 6/9/2016(UTC)
Posts: 30

Thanks: 20 times
Thanks, so basically as long as you only access the container on one thread at a time it will be fine?

For example, can i start 4 threads and get each thread to render into different bitmaps/containers at once? i.e. as long as i don't try to access the same bitmap/container from multiple threads there shouldn't be any conflicts?
Eugene Kosmin  
#4 Posted : Tuesday, June 21, 2016 3:41:29 AM(UTC)
Eugene Kosmin

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 9/19/2006(UTC)
Posts: 439

Was thanked: 22 time(s) in 22 post(s)
Possible conflict can occur when you render and change a content of GraphicsContent simultaneously.

And another bad thing – GraphicsContainer is a pretty complex object. It can hold pipelines inside with decoders, transforms, and other pipeline elements. There is no deep copy occurs when you get a copy as I described earlier. All of them are not thread-safe and I guess there can be a problem with rendering with several threads. However, if you use only vector data and pre-rendered bitmaps, there is a chance it will work fine.

Best regards,
Eugene Kosmin.
Aurigma Development Team
thanks 1 user thanked Eugene Kosmin for this useful post.
Chris Jones on 6/21/2016(UTC)
Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.