[JUCE 8][BUG] Assertion Failure When Clearing Image in Paint Method

Hello!

I’ve encountered what seems to be a bug in JUCE 8, which, by the way, is very promising. I can easily reproduce this issue using the audio plugin demo “Hello World.”

Here’s a brief overview of the issue:

In Editor class, I declare a std::unique_ptr<Image>:

std::unique_ptr<Image> MyImage;

In the editor constructor, I initialize the image like this:

AudioPluginAudioProcessorEditor::AudioPluginAudioProcessorEditor (AudioPluginAudioProcessor& p)
    : AudioProcessorEditor (&p), processorRef (p)
{
    juce::ignoreUnused (processorRef);
    setSize (400, 300);
    MyImage = std::make_unique<juce::Image>(juce::Image::ARGB, 200, 200, true);
}

However, in the paint method, I encounter an assertion failure when attempting to clear a portion of MyImage:

void AudioPluginAudioProcessorEditor::paint (juce::Graphics& g)
{
    // Fill the background with a solid color
    g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId));

    g.setColour (juce::Colours::white);
    g.setFont (15.0f);
    g.drawFittedText ("Hello World!", getLocalBounds(), juce::Justification::centred, 1);

    juce::Graphics goff (*MyImage);
    goff.fillAll (juce::Colours::green);
    juce::Rectangle<int> area (20, 20, 60, 60);
    MyImage->clear (area); // ASSERT HERE IN D2D
    if (MyImage != nullptr && MyImage->isValid())
        g.drawImageAt (*MyImage, 0, 0, false);
}

If I remove the MyImage->clear(area); line, the green square is drawn without any issues.

My setup:

  • OS: Microsoft Windows 11 Home, Version 10.0.22621 Build 22621
  • System Type: x64-based PC
  • Processor: AMD Ryzen 7 5700U with Radeon Graphics, 1801 MHz, 8 Core(s), 16 Logical Processor(s)
  • Adapter Type: AMD Radeon Graphics Processor (0x164C), Advanced Micro Devices, Inc. compatible

Could I be doing something wrong here, or is this a bug in JUCE 8?

Thanks in advance for any help!


Please can you let us know which version of JUCE 8 (8.0.0, 8.0.1, develop…) you’re using when you see this problem? If you haven’t tried develop yet, do you still see the problem after switching to that branch?

I just tried to switch my project from JUCE 7 to latest JUCE 8.0.1 from juce.com (downloaded yestersay). The problem appeared on first run, and I tried to reproduce it on plugin demo.

I think there’s a couple of problems, both potentially issues in JUCE 8, one of which has a workaround:

  • Currently, Image::clear will internally use the same ID2D1DeviceContext as the juce::Graphics instance, which ends up putting the DeviceContext into an invalid state. This is arguably a bug in JUCE, but you can work around it by ensuring that you don’t have a juce::Graphics instance alive and drawing into the image at the point where you call Image::clear. An easy way to do this is to add in an extra scope to ensure that the Graphics instance is not in-scope when clear is called:
    juce::Image image { juce::Image::ARGB, 200, 200, true };
    {
        juce::Graphics goff (image);
        goff.fillAll (juce::Colours::green);
    }
    image.clear ({ 20, 20, 60, 60 });
    
  • While investigating this, it seems that the Direct2D implementation of Image::clear() may always clear the entire image, rather than just the requested area. We’ll have a fix out for this in the next few days.

Great!

While investigating this, it seems that the Direct2D implementation of Image::clear() may always clear the entire image, rather than just the requested area. We’ll have a fix out for this in the next few days.

Great II !

Thank you for your kind answer Reuk.

I can confirm that the Image::clear() on Windows does not work as expected : all the image is cleared and not only the rectangle.
On MacOS it works perfectly but the same code on Windows does not work.

A fix for this issue is now available on the develop branch:

We’ve also added some assertions to warn about misuse when multiple BitmapData or Graphics instances are all attempting to modify the same Image simultaneously.

1 Like