[New Module] Melatonin Blur

Happy Friday, here’s a new JUCE module!

I worked hard on this the last few weeks. I wrote and benchmarked a couple dozen Stack Blur and convolution implementations. Need to give up for now :slight_smile:

Hopefully this will encourage others to make modern vector UIs in JUCE. It should let you use as many drop shadows and inner shadows you like without compromising painting performance:

Let me know if you give it a try. I have a few ideas for how the API could be nicer, but would love feedback.

IPP isn’t a hard requirement for Windows: a lot of performance gains come from caching shadows/blurs for future repaints.

Big thanks to @RolandMR for letting me embed Gin for the Windows ARGB case (the one case I wasn’t able to improve upon Stack Blur!)

EDIT: @kunitoki pointed out the main macOS implementation won’t work on macOS < 11.0, so I’ll get a fallback in there next week. Just not sure how to test that…


Thanks for your hard work, much appreciated!

1 Like

Excellent! Looking forward to checking this out in detail.

1 Like

Usually, if you specify an explicit macOS deployment target in your test project using e.g. -DCMAKE_OSX_DEPLOYMENT_TARGET="10.14" (or whatever minimal deployment target you are aiming for) you’ll get a compile time warning if you are using an API that is not supported for that macOS version. You can then use e.g.

if (__builtin_available (macOS 11, *))
   // code path for macOS 11 and higher
   // fallback implementation

I hope I didn’t tell you stuff that you already knew anyway :wink:


Yeah, strange, my main project has CMAKE_OSX_DEPLOYMENT_TARGET set to 10.13, but I’m not seeing a warning!

Thanks, that’s useful. Haven’t wrastled much with macOS versions at runtime.

Glad I could help.

It might be worth inspecting the deployment target of the resulting binary using otool -l. I experienced two cases where the expected deployment did not match the actual one, first was not declaring the CMAKE_OSX_DEPLOYMENT_TARGET as a cache variable prior to the project call, the second one was when a subproject included from the top level CMakeLists also declared a deployment target and silently overwrote the top level target.

1 Like

Congrats for the release, really nice and detailed work there !

1 Like

Amazing work!

1 Like

Fantastic work! Juce team, it makes me sad that this person had to suffer through this so that we can have a drop shadow in a gui in 2023.

1 Like

Thanks for the support everyone. Just a heads up that I’m working on compatibility for older macOS versions now.

@Fandusss I don’t want to turn this thread into a general JUCE discussion, but I have to say that working on this gave me a new level of respect for how just much work goes into building and maintaining a foundational cross-platform framework like JUCE. Not only did I spent weeks auditing, testing and benchmarking available algorithms on multiple platforms, but I had to brush up on image compositing, package for release (still need to get tests in CI) and now there are all sorts of cross-platform and legacy version challenges.

So this one tiny piece of the pie basically took me 2 full time months of dev time. I honestly feel quite grateful that all the really hard stuff in JUCE (compositing, painting, platform and DAW compatibility, parameters, audio APIs) is just handled — we never really see the details of that work or know how much time goes into getting it solid.

Perhaps it’s also ideal for little specialized pockets of things like blurs/shadows and other UI niceties to be open-source third-party modules. The JUCE team is quite small and they have a very large list of actually hard fundamentals that are constantly breaking! For example, I can’t imagine the time investment with something like unicode support (announced with JUCE 7). Based on my recent experience, I’m guessing a solid dev-year or more of work? (Looking forward to my emojis! :grinning:)


@sudara (and all those that have been contributing to the blur investigations and improvements) this looks really interesting :clap:.

@sudara I just went to try and run this and hit issues with it trying to use vImageSepConvolve_ARGB8888 (and some other similar methods) these appear to be macOS 14.0+ and I’m running 13.5.2. Am I missing something?

Yes, turns out my top picks for macOS ended being vImage calls that were 14.0+ for ARGB and 11.0+ for single channel — I’m working now on all the fallbacks! I was working in a vacuum getting the implementations running and benchmarking them, completely forgot about things like different versions of operating systems, lol.

1 Like

Alright, cool. If you aren’t sad about it I sure have no reason to be. Great work again, I respect the depth you went to here.

1 Like

:heart: I mean, the synth I was working on (that hasn’t been touched in 2 months) is sad, maybe a few of the alpha testers too… :slight_smile:

But I’m very happy to be able to get back to UI iteration that isn’t compromised by performance concerns!

1 Like

No need to apologise at all, I get it it’s not easy to get this working for all platforms and OS versions!

1 Like

Oh also, the blog post about the module made the front page of hacker news yesterday, in case anyone wants to check the comments out there — some interesting implementation ideas (and amazingly nobody was rude/mean this time!)


Awesome, gonna check this out dor sure!!

1 Like

I don’t think we do a very good job of communicating how difficult the problems JUCE faces are, especially for tasks that appear relatively small. From the outside I suspect it often looks like we’re presented with fully-formed ideas or code and then it takes us months to actually implement any changes where we have spent weeks JUCE-ifying things unnecessarily. Having another voice saying it can be much more difficult than you expect is welcome.

I’m sure there are lots of exceptions to the above, please don’t derail this thread with your favourite grievance! I just wanted to thank Sudara for his support.


Really cool, thanks!

Any clue what could be causing these artifacts on the buttons? It works fine for the elements.

I’ll take a look — are you on Windows using the fallback implementation by any chance (meaning, not using IPP)