The paintFBO gets created lazily in paintGL call to make sure GL context is valid. I'm releasing the FBO but removed the release from the snippet. I'm not doing anything specifically with threads. Just normal widgets. I've trimmed my code down to just drawPaintStrokes() and I'm getting the following error:
QOpenGLDebugMessage("APISource", 1282, "GL_INVALID_OPERATION error generated. Object is owned by another context and may not be bound here.", "HighSeverity", "ErrorType")
Searching around the web, I've seen people claim this is an nvidia driver issue specific to not cleaning up FBOs. Right now all the code is doing is binding the FBO in widget 1, releasing the FBO in widget 1, then trying to do the same in widget 2.
Here's a link where someone seems to be running into the same issue:
https://devtalk.nvidia.com/default/topic/1043241/linux/framebuffer-doesnt-get-unbound-glitches-only-on-nvidia/post/5292053/#5292053