Hmm
What if you call Repaint instead of Invalidate?
Note that is doesn't really fix this problem on MacOS but it might on Windows.
Edit: something that seems to work, is to add a boolean WaitingForDisplay. After calling Invalidate, set this boolean to True. In the Idle event, do not call render when it is True. And in the FormPaint, set it to False.