Improve rendering performance with tiled background


#1

I’m filling a background component with a tiled image using code modified from the juce demo . .

    void drawTiling (Graphics& g, const Image& image)
    {
        auto a(AffineTransform::scale (0.2f) );
        auto b(AffineTransform::translation ((float) (image.getWidth() / -2), (float) (image.getHeight() / -2)));
        auto c(AffineTransform::rotation (35.f / (180.f/float_Pi)));
        
        FillType fill (image, a.followedBy(b).followedBy(c) );

        g.setFillType (fill);
        g.fillAll();
    }

This is being called from the paint method in the parent component. Unfortunately, this destroys the frame rate of all the stuff drawn on top of this component. Interestingly, filling the component with a texture made of small images (like in the introjucer code) does not have much of an impact on the rendering speed of other components. Is there a way to somehow cache or otherwise optimise this so that I can have an arbitrary background texture with good rendering speed on top?


#2

looks like `drawTiling’ does all those image transforms all the time. Can you create a transformed copy of the original image on resize and tile that on paint without transforms.


#3

Is there a method to create a new image copy from a transformed image? . . . or do you mean edit the binary image source in an external editor?


#4

One way would be to create a new image the size of your component, then draw to it using your existing `drawTiling’ method, like this

drawTiling(Graphics(newImage), image);

that would then render onto your `newImage’ the exact same as you are doing now. Then in your paint method, just paint your new image first as your background.

Remember to regenerate the `newImage’ whenever the component is resized.


#5

Cool. That works well . . .

This in resized() . . .

        bgImage = Image(Image::PixelFormat::ARGB,   //PixelFormat format,
                        std::max(getWidth(), 1),                 //int imageWidth,
                        std::max(getHeight(), 1),                //int imageHeight,
                        true                                              //bool clearImage
                        );
        Graphics g(bgImage);
        drawTiling( g, *logoImg );

This in paint . . .

g.drawImageAt (bgImage, //const Image &imageToDraw,
                       0,             //int topLeftX,
                       0,             //int topLeftY,
                       false         //bool fillAlphaChannelWithCurrentBrush=false);
                       );

The std::max calls are in there as you hit assertion failures with a zero sized image