Any way to make SVG to Drawable conversion a compile time step?

My upcoming plugin has a very nice looking SVG only based GUI design. While looking great at every scale, opening the plugin editor takes quite a long time, just ran a profiling session and this is what it reveals:

Seems like parsing the SVGs which are embedded as binary data takes quite a lot time. Beneath trying to cache them somehow to speed up editor reopening, I wonder if there is any way to move this parsing step completely towards compile time, as this data is compile time static in the end.

I’m not aware of any option like this – but maybe someone else already faced such a problem?

Is this maybe a debug build?

Nope, this occurs with a release build

Is your svg particularly huge or does it have any ‘edge case’ object (anything other than shapes or vectors)?
Working myself with 99% svg gui and loading about 50 of them with the editor, but experiencing no problems.

Try removing suspect svg subparts one by one (on some svg editors if you make a group invisible they skip exporting it) and measure performance changes.

Edit: you can avoid the svg parse step by rastering on svg export, but if your goal is to have a big plugin resize range , I guess this defeats most of the purpose of starting with an svg, since you’re practically pre-embedding pngs inside your svg. But hey here’s your ‘moving it to compile time’ if you want it.

The SVGs are created by a graphics designer via Adobe Illustrator, which I don‘t own a copy of – so I can‘t simply export stripped down versions of them myself. And yes, they are quite complex, but they also look super nice – kind of photorealistic look, not the usual modern „flat“ look most vector based UIs look like.

Of course I could go with PNGs, but I definetively want a crisp rezisable UI, translating great to every screen resolution which I got this way. And as long as the drawing itself doesn’t take too much resources, I‘d really like to stick to the approach and only find a way to initialise my resources quicker

I’d dig in to the profile a bit more closely. There might be specific bits of the SVG that can be optimised as others have alluded to in this thread.

For example, if a lot of time is spent parsing the paths, you might be able to simplify the paths a bit (basically so they have less points) without sacrificing the actual shape of them.
Illustrator can do this so you might have to check with your designer.


Another thing to think about is how long does the rest of your plugin/UI take to load? You might want to simply parse the SVG on a background thread when the plugin loads so it’s ready for when the UI is displayed. If this only takes 1s (as shown in your profile) it’s unlikely anyone will notice.

1 Like

Maybe your svg contains words that have been converted to outlines at a very high resolution. Or maybe all curves have been flattened at extreme resolution. In those cases you could try to optimize the svgs so they use less path segments and maybe get things to render faster.

If you really want to rasterize during compilation you could use Inkscape and its command line interface to create .pngs at different resolutions during compilation.

The first step would of course be to install Inkscape and see whether it can correctly load your complex svgs.

Thank you for the suggestions. Will try to find out what’s inside those svgs & try to optimize them together with my designer. But I guess that could take some time to finish.

In the meantime I moved to loading the SVGs on a background thread when the processor is created. This works quite well and the editor now opens a lot faster.

And one last thing, I never wanted to rasterize my SVGs during compilation, I just saw that the step of parsing from an XML into some binary representation used by the drawable class took up a long time and was asking myself if this parsing step could somehow be done at compile time – and some sort of binary representation of the drawable object could be stored as binary data instead, but I guess the answer is no :wink:

If you have a copy of Sketch, there is a plugin for it called SVGO (SVG optimiser), which can reduce the size of SVGs a fair bit in some cases.

2 Likes

I agree that having a constexpr version of this (and a lot of other functionality in juce) would be good but it probably isn’t coming any time soon as there are lots of allocations during the parsing stage. It would either need a big refactor to use some pre-allocated storage or possibly use C++20 where you can allocate (in some situations).

Meanwhile you can hack something for monochromatic SVGs, the path supports saving to a binary blob:
writePathToStream(). You can use that result in the BinaryData and load using loadPathFromData().

Nice one! Unfortunately my SVGs are no monochromatic paths, but something like that was one of the possible options I had in mind when asking this question. A complete constexpr solution to that as @dave96 mentioned would of course be the great, but I see that this would probably need a lot of restructuring in the drawable class or even a total rework. Maybe something like that could come together with new SVG parsing functionality that doesn’t need a message manager lock somewhen in future :upside_down_face:

There is much to wish for left in the current version, one that was always bothering me is that the Drawables inherit Component (which I guess is the reason for the MessageManagerLock).

A short term solution to just separate the current Drawables from Component (which would be possible by creating different Drawable classes and provide an interface for backward compatibility, that inherits Component and that new drawables). But that was already declined with the hint “to make it right”. We will see when the backlog dries out, so we find that at the bottom.

2 Likes

Indeed, SVG should support rendering text … glyphs

1 Like