Is there any way to convert svg to Image on a background thread?

My app has 100s of svgs that need to be displayed. The need to be converted to Image and then image processing functions called upon them. This is pretty slow, so I’d like to do it in a background thread.

My svg to Image function looks like this:

juce::Image rasterizeSVG (juce::String svgText, int w, int h)
{
	Image img (Image::ARGB, w, h, true);
	Graphics g (img);

	if (auto svg = XmlDocument::parse (svgText))
	{
		std::unique_ptr<Drawable> drawable;

		{
			const MessageManagerLock mmLock;
			drawable = Drawable::createFromSVG (*svg);
			drawable->setTransformToFit (Rectangle<float> (0.0f, 0.0f, float (w), float (h)), RectanglePlacement::centred);
			drawable->draw (g, 1.f);
		}

    }

	return img;
}

If I don’t lock the message manager, it starts throwing asserts. Is there any way around this, or a different way to convert to image?

The image processing seems to be the slowest part, so it’s ok even if I have to lock the message manager. Still, it would be better if I didn’t have to.

2 Likes

Part of the problem is that Drawable is a derivative of Component, whose operations and data are heavily tied to the message thread. I’m not sure there’s a way around this situation.

1 Like

Which asserts do you hit?

I realise G-Mon can speak for himself, but my guess is that he’s hitting JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN or JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED (although it’s probably both that will be hit!).

I have always found it curious that the Juce SVG-facilities are tied to the Drawable class, is there some good reason that is so? @jules One can’t even find anything in the documentation class index by searching for SVG, since it’s hidden in the Drawable class.

Yes, I’m hitting ASSERT_MESSAGE_MANAGER_IS_LOCKED, after the Drawable loads the SVG it calls repaint on itself. A hack could be for Drawable to always use triggerAsyncUpdate to repaint itself.

But it seems it would make more sense to separate the SVG drawing from the component.

Yes, I’ve regretted that decision for a long time, but would break a lot of code to change it now!

Would a simple check to isVisible work here?

it’d be worth it for everyone to make this change. Any outdated code that this would break should be updated anyway.

embrace the change

emmmmbrrraaaaccceee ittttt!!!

also, folks can just set up a specific commit before this breaking change as a submodule in their project. so it’s really only a problem for people who use the latest commit of the develop branch…

5 Likes

A smooth transition could be moving the Drawable classes into classes, that don’t inherit Component and create a Component wrapper around it for backward compatibility… Sure it is extra work, but given the number of times you regretted it, probably worth it…

EDIT: here as a feature request:

6 Likes

Would a simple check to isVisible work here?

No, because the sub component Drawables are visible. setVisible is also throwing asserts.

@G-Mon did you ever find a solution to this? We’ve just hit the same problem.

Long term solution: vote for my Feature Request, link three posts above :slight_smile:

@Daniel done!

1 Like

Nope, I grab a message manager lock, kind of a pain.