Dplug
Dplug copied to clipboard
Towards solving the gordian knot of dirty rectangles in GUIGraphics
In IWindowListener
, the following functions are guaranteed to be called non-concurrently:
-
onDraw
-
onResized
-
recomputeDirtyAreas
-
getDirtyRectangle
getDirtyRectangle
semantics is that once you have pulled the dirtyRectangle, you commit to have it mark as dirty to the OS, and consequent onDraw
ensues with the proper WM_PAINT / dirtied area.
Try to see if there is potential conflict with:
getDirtyRectangle
then onResized
then onResized
since it may lead to the pending rect being abandoned.
Shouldn't be an issue inside the Window implementation since we can expect the OS to send an Expose/WM_PAINT event for the whole window in case of resize (Linux also?)
The high-level overview is that there are two places (for both Raw and PBR layers) where dirty rects can live:
- thread-protected
dirtyListRaw
anddirtyListPBR
, maintain some non-overlap, notable the audio thread can call setDirty directly. - "contractual" list of rects in
_rectsToUpdateDisjointedRaw
/_rectsToUpdateDisjointedPBR
and that breaks atomicity badly.
Those things should probably be merged, but doing that would also require that the dirty lists in UIContext are synchronized, then the audio thread would not be able to call them (only onAnimate), and onAnimate can currently be concurrent with other IWindowListener functions.
But at least we have a logn-term plan.
A good way to stress resizing is to override checkSizeConstraint
in the VST3 client to always return true (well, except for REAPER on linux + macOS see #559 )
Ideally would need another list of rects apart _rectsToUpdateDisjointedRaw
/_rectsToUpdateDisjointedPBR
from in "onDraw", that deals with resized rect and borders. (but can eliminate all races without doing that).