Too much redraw (with vst/rtas adapter and bias peak)

A customer reported me, that the plug-in gui in pro-tools (with fxpansion vst-rtas adapter, mac os x) is very very slow. (slows down the whole system)

I found out the every time doIdleCallback() is called the complete GUI is redrawn, even when nothing is changed and the window is on top of all other windows and no mouse moves are happen and so on.

Bias Peak has a similar behavior.

Its seems that something is generating wrong redraw messages?

I contacted fxpansion support, they said that probably part of the problem is that the vst opcode effEditDraw is not supported, but i think the problem is not that there are too little redraws, there are too much.

Small JUCE GUIs with few elements will not have a problem, but if you have a gui with much elements and layers this become a big problem, because the whole message queue is full with this wrong redraw actions.

Any help appreciated !

Hmm, sounds like something that only the fx chaps could sort out. You could always build your plugin as a native RTAS if you want protools support.

i found out that all self generated repaints (like changing visibility or position) are generated by Component::internalRepaint(). These needless repaint messages seems to be generated somewhere else. Can you give me hint where to search?

Besides Bias Peak seems to have the same problem

Yes, if i had the license…, i would do this :frowning:

You could stick a breakpoint in the mac componentpeer repaint() call and see where that’s getting called from, perhaps?

Hi Jules,

do you mean
juce::HIViewComponentPeer::repaint at juce_mac_Windowing.cpp:757 ?

I sticked a breakpoint in this class, but only the regular repaintings are annouced through this function.
But for the other (needles) repaintings, this function isn’t called.
Is this possible? Do the come directly from the OS?

this is what i get when i stick a breakpoint in my main windows paint method (while a needless repaint)

#0	0x1bd84308 in my_plugin_window::paint at my_plugin_window.cpp:1064
#1	0x1bdce294 in juce::Component::paintEntireComponent at juce_Component.cpp:1735
#2	0x1bdce461 in juce::Component::paintEntireComponent at juce_Component.cpp:1767
#3	0x1bdbcf52 in juce::ComponentPeer::handlePaint at juce_ComponentPeer.cpp:392
#4	0x1bf71a6c in juce::HIViewComponentPeer::RepaintManager::paint at juce_mac_Windowing.cpp:949
#5	0x1bf724ed in juce::HIViewComponentPeer::hiViewDraw at juce_mac_Windowing.cpp:1461
#6	0x1bf72edc in juce::HIViewComponentPeer::hiViewEventHandler at juce_mac_Windowing.cpp:1724
#7	0x92def4d7 in DispatchEventToHandlers
#8	0x92deeb7c in SendEventToEventTargetInternal
#9	0x92deea41 in SendEventToEventTargetWithOptions
#10	0x92e1bf98 in HIView::SendDraw
#11	0x92ed8417 in HIView::RecursiveDrawNonComposited
#12	0x92ed7bde in HIView::DrawNonComposited
#13	0x92e1ba20 in HIView::Draw
#14	0x92e3a8b6 in HIViewRender
#15	0x1bf70ee4 in juce::HIViewComponentPeer::performAnyPendingRepaintsNow at juce_mac_Windowing.cpp:842
#16	0x1bf396a2 in JuceVSTWrapper::doIdleCallback at juce_VstWrapper.cpp:1105
#17	0x1bf39a16 in JuceVSTWrapper::dispatcher at juce_VstWrapper.cpp:1175
#18	0x1bd37308 in AudioEffect::dispatchEffectClass at audioeffect.cpp:32

Locals in Repaint Manager
w= same as plugin width
h= same as plugin height

Hmm. Ok. HIViewRender is only supposed to draw the invalid bits of the window, but it sounds like here it’s just redrawing the whole thing every time. Not sure if it’s HIViewRender that’s not doing its job, or whether something else keeps invalidating it.

yes, its seems that something marks the whole screen as invalid every time.

Well, if something else is calling the OS functions to invalidate the window, then we’re stuffed - can’t do anything about that.

But this is worth a try - in juce_mac_Windowing.cpp, 842:

if (HIViewGetNeedsDisplay (viewRef)) HIViewRender (viewRef);

No idea if that’ll help, but there’s just a chance that HIViewRender might be dumbly repainting the whole window when it’s not needed.

very interesting effect now:

In ProTools the GUI will be redrawn only one-time! It seems that it is back-buffered in the OS, and the OS doesn’t has the need to redraw it. The (self generated) redraws seems to be ignored. The GUI has always the initial state.

In Ableton Live anything still works correct!
I compiled with 10.3 and 10.4 settings, both are equal!

Ah! That explains why in the wrapper, they probably force the repaint. Otherwise, many plugins wouldn’t actually get redrawn. That’s annoying, can’t think of a good solution… Maybe need to ask the fxpansion chaps.

Hi Jules,

i found a solution that helps to reduce (not remove) the problem.
What do you think of that?

Adding in HIViewComponentPeer::RepaintManager

int getNumberOfRegionsNeedingRepaint() { return regionsNeedingRepaint.getNumRectangles(); };

Adding in HIViewComponentPeer::performAnyPendingRepaintsNow()

	if (HIViewGetNeedsDisplay(viewRef) || ( repainter->getNumberOfRegionsNeedingRepaint() > 0) )
				HIViewRender (viewRef);

What do you think of it?
The whole screen will be repainted too, but not always when the Idle method is called.

Ok - that’s a neat idea. It’d certainly stop the unnecessary paints, but I’ve a fear it could also stop some of the necessary ones. There are times when the OS needs a repaint but nothing in juce has changed, and those would get ignored.

yes, as far i understand in this case HIViewGetNeedsDisplay(viewRef) will be true.

I will do some tests…