Frequent repaint and CPU usage


#1

Hello,

I have an application which needs to do frequent redraws, lets say 30 times per second. When I do this, the larger my component is the more the CPU use increases, even if I do nothing in paint. To illustrate this I have modified the juce tutorial, to do nothing but start a timer which calls repaint every 33 ms. There is a single component and it has nothing in paint. In Full screen, on a computer with a single CPU Pentium 4 2.0 GHz, 1 GB of RAM, this takes more then 30 % of CPU. It takes less then 2% in a smaller size.

I do realize that some of this makes sense, as we go through a lot of pixels, even if I do noting in repaint, juce must still do something and paint all pixels grey and there are more of them when in full screen. (I can see my (empty - grey) component being re-drawn when I use JUCE_ENABLE_REPAINT_DEBUGGING). I am also afraid this might be an OS problem, but so far I observed the increase Windows 7 and Windows XP. I also realize it might not be so bad that the thread that does the painting used up the CPU when there is nothing else to do, however the problem is it uses it even when there is.

My actual application is a video player. I use ffmpeg for decoding the video. On the computer mentioned above, my video player was unusable in full screen mode, while other video players(VLC, Windows Media Player) worked fine. VLC in fact at full screen uses 5 % CPU, while doing all the decoding, re-sampiling, re-scaling necessary and displaying the images. Even forgetting about possible hardware acceleration that I am not doing, my empty full screen app refreshing at the obvious same rate eats 30% .

I have been profiling this for a while, although I did not concentrate on this (repaint frequent rate) directly yet. My previous bottleneck was the image rescaling (I tracked it all the way inside TransformedImageFillEdgeTableRenderer::generate), in particular even with low quality rendering at neirest-neghbour, CPU was very high. I was able to push the rescaling down in the FFMPEG library, which saved me a bit of CPU - from 30% to 22% on a Intel Core i5, but didn’t help much on the less powerful one.

I have however checked all my CPU uses and my next bottleneck is indeed the frequent repaint. I am about to start profiling this scenario and see where the CPU is used most, but I would like to know if anyone else experience something like this and was able to fix it. Alternatively, if it is impossible/ not recomended to do a repaint every 33 ms in full screen, I would also like to know so I know where to compromise.

Thank you very much for all your help,
I have attached the app source, although it is simply the tutorial modified…


#2

I assume you’re talking about Windows, where it does indeed have to copy all those pixels from memory to the screen each time you repaint, which is a hell of a lot of bytes to push around.

The best way to do this would actually be with openGL, either using the existing OpenGLComponent, or wait for my next-generation openGL stuff which will integrate all the juce drawing into the openGL pipeline. That’s probably how the VLC player works, and I think some other people on here have used that approach.

Or just use a DirectShowComponent to play the video!


#3

Thank you very much for the prompt reply. Both proposed solutions sound as if they would help and I will investigate them both.

If I understand correctly something does happen during juce rendering on windows that uses a lot of Cpu that would not be an issue on Linux and that can be avoided for now by using OpenGL rendering?

I also understand you plan to make possible in the future using OpenGL rendering for the whole GUI? If so do you know if this might be available in a not too far away future?

Thanks again,