Saving CPU while repainting component and its child components with setBufferedToImage


#1

Hello,

I was trying to save CPU from repainting unnecessary child components and I have found there is a nice function setBufferedToImage(bool).
But it was setting shouldBeBuffered flag for only itself and when there were many child components in its children I had to set shouldBeBuffered flag for every its children.
That’s why I have tried to declare following function…

void setBufferedToImageForCompoentAndItsChildren(Component& component, bool shouldBeBuffered) {
    component.setBufferedToImage(shouldBeBuffered);
    for (int idx = 0; idx < component.getNumChildComponents(); idx++) {
        setBufferedToImageForCompoentAndItsChildren(*component.getChildComponent(idx), shouldBeBuffered);
    }
}

And call this function at the end of constructor of main component.

MainContentComponent::MainContentComponent(...) {
    // add child components
    ... ... ...
    setBufferedToImageForCompoentAndItsChildren(*this, true);
}

Now it helps me to set all the components’ bufferedToImage flags and it saves much CPU.

Hope it can be helpful.

Regards,
Hasan


#2

There is no need for children to have setBufferedToImage() called, the component that has setBufferedToImage() called on it will repaint all it’s children, it does not paint just the one component. I was also initially confused by this, see this thread CachedComponentImage invalidation logic


#3

Perhaps there is room for improvement in the documentation of that method to clarify this aspect?


#4

Actually I thought as you do. But we can understand easily by simple example following.

Let’s assume there are 3 child components in one of children of main component and second one is positioned between other 2 components. If those 2 components should be repainted, then rectangle containing the 2nd one will be marked as dirty and it will be repainted every time.
I have tried to debug it several times, and finally I have found that I should call setBfferedToImage() for children as well as its parents.


#5

It seems a little odd to be calling setBufferedToImage in this way on other components… I’d have thought it would make more sense to call it inside the constructors of components which would benefit from being cached.


#6

Yes, you’re right. However, the component that I am working has many child components and customized children in their child components and so on. And so most of them are continuously repainted frequently, which they are not needed to repaint at that situation. Calling setBufferedToImage function for every component will not be such a good selection in my case.
I think, it would be better to support function like setBufferedToImage(bool shouldBeBuffered, bool shouldForAllChildren = false), so anyone who knows what he/she is doing will call this function as he/she wants.