Juce Plugins capped at 30 fps, with clipping bugs?


#1

So I’ve noticed issues with fast moving components in plugin Juce GUIs (on macOS 10.12.5). To investigate the issue, I made the following simple component, inspired by the AnimationDemo in JuceDemo:

struct FastBall : public Component {
    FastBall() {
        setSize(20,20);
    }
    void paint(Graphics& g) override {
        g.setColour(Colours::red);
        g.fillEllipse(0, 0, getWidth(), getHeight());
    }
    void step() {
        Component *parent = getParentComponent();
        setTopLeftPosition((getX()+10)%parent->getWidth(), (getY()+4)%parent->getHeight());
    }
};

Then I call step() in my timerCallback() at 60 Hz. Here’s a 60 fps video of the result.

This is in Ableton, but it’s the same in the Juce Host and others, for both AU and VST. Stepping through this video frame by frame, you can see that the UI is refreshed approximately every other frame, and worse, sometimes the ball is clipped. This seems to be because the clipBounds calculation and draw calls are out of sync.

Putting the same code in a native app (e.g. JuceDemo), the movement is smooth at 60 fps with no clip errors. Also, other (non-Juce) plugins animate smoothly at 60 fps.


#2

Anyone? If this is pervasive it’s pretty serious IMHO…


#3

This could be related to an issue we had some time ago in certain hosts, on certain versions of OSX, where if the plugin’s drawing wasn’t throttled, it starved the host’s GUI of paint callbacks and caused problems. IIRC we added a throttling mechanism that limited drawing to 30fps to avoid this situation, but never found a magic way of allowing both host + plugin to run at full frame rate without interfering with each other.


#4

okay, interesting! I don’t mind the 30 fps, but the rendering bugs are really annoying. That must be something else, or do you think it can be related?

What seems to happen is: sometimes the getClipBounds() for the draw call only includes the old position of the child that moves, not the new position, and therefore it gets clipped (or not drawn at all if it moves longer than its own size)


#5

Yeah, haven’t heard of any clipping bugs before, that’s odd. We’ll have to look into that.

If you search for “shouldThrottleRepaint” you’ll see the code I was talking about. Might be interesting to see if the clipping works OK if you disable the throttling.


#6

Yup, that did it! Forcing shouldThrottleRepaint() to return false gave smooth 60 fps rendering without clipping. So somehow that Timer is messing with the drawing, would be awesome if you guys could look into it! I’ve also seen this clip nastyness when just dragging components…


#7

I have a similar issue.
any chance we could get a way to force shouldThrottleRepaint() to return false? like an option in projucer perhaps?