Image Permanence

Hi everyone-

Here’s a JUCE branch that adds support for Image permanence:

As discussed on this thread, I think we need the ability to distinguish between “permanent” and “disposable” images. Disposable images are created procedurally and can be kept entirely in GPU memory. Permanent images are stored in both GPU and CPU memory; if the GPU resets and the data in GPU memory is lost, the Image can be recreated from the software backup.

Some images don’t need to be backed up and are therefore disposable:

  • Cached component images
  • Effect output images
  • Any image that’s procedurally or dynamically generated

Backing up the image from GPU memory to CPU memory can take several milliseconds per image, so skipping the backup improves performance and saves CPU memory.

Note that disposable images will be limited to the maximum texture size for the GPU.

I tried to think of a minimally invasive way to mark an image as disposable or permanent. I ended up adding an optional parameter to the Image constructor:

class JUCE_API  Image  final
{
public:

    //....

    enum Permanence
    {
        permanent,    // the image data will never be deleted
        disposable    // the image data may be arbitrarily deleted by the GPU
    };

    Image (PixelFormat format, int imageWidth, int imageHeight, bool clearImage, Permanence requestedPermanence = permanent);

    Image (PixelFormat format, int imageWidth, int imageHeight, bool clearImage, const ImageType& type, Permanence requestedPermanence = permanent);


class JUCE_API  ImagePixelData  : public ReferenceCountedObject
{
public:
    ImagePixelData (Image::PixelFormat, int width, int height, Image::Permanence requestedPermanence = Image::Permanence::permanent);

Images are permement by default. To specify that you want a disposable GPU-only Image:

auto disposableGPUOnlyImage = juce::Image{ juce::Image::ARGB, getWidth(), getHeight(), true, juce::Image::Permanence::disposable };

Here’s an example project that shows the paint time and can switch between using disposable and permanent images.

The example also demonstrates using double-buffering to create a persistence effect. The background is a component with setBufferedToImage set to true.

Please note that this is not an official JUCE change; this is an attempt to diagnose and solve various reported performance issues. Any official JUCE change will likely be different.

Matt

4 Likes

On my machine, each frame takes about 6 msec to render permanent images at 3440x1440:

Switching to disposable images cuts the render time to 200 microseconds (about 30x faster).

Matt

9 Likes