QUItCoding / qnanopainter

Library for implementing OpenGL accelerated Qt (Quick) C++ UI components.
http://quitcoding.com
Other
405 stars 79 forks source link

Fix QNanoWidget OpenGL context usage #83

Open hartcw opened 7 months ago

hartcw commented 7 months ago

When using multiple QNanoWidgets, each widget will get a unique instance of a QOpenGLContext object. When the global instance of QNanoPainter is initialised, it happens against the OpenGL context owned by one of the QNanoWidgets (which ever is painted first).

This means that the global instance of QNanoPainter may not work correctly when used with other QNanoWidget instances. There are 2 things needed to fix this:

hartcw commented 7 months ago

May need to rework this patch, the QOpenGLContext::globalShareContext() has this note:

Warning: Do not attempt to make the context returned by this function current on any surface. Instead, you can create a new context which shares with the global one, and then make the new context current.

QUItCoding commented 7 months ago

I haven't really been using QNanoWidget other than in the simple example. So based on that note, patch should actually use https://doc.qt.io/qt-6/qopenglcontext.html#setShareContext ?

hartcw commented 7 months ago

I think that, if the QNanoPainter is going to be shared globally (with either QNanoWidget or QNanoQuickItemPainter), then QNanoPainter should create and own its own QOpenGLContext instance. And it should ensure that it is shared with the QOpenGLContext instance owned by the QNanoWidget (or QNanoQuickItemPainter).

For my usecase, I definitely want to use a global shared QNanoPainter, because I will be using the same opengl textures in multiple widgets, and it will save texture memory.

I'll rework this patch to add a QOpenGLContext member to the QNanoPainter class. That should fix both QNanoWidget and QNanoQuickItemPainter code paths when using multiple widgets/items.

Regarding using QOpenGLContext::setShareContext(), that is one way to implement it. The other simpler way is to set the Qt::AA_ShareOpenGLContexts attribute, then Qt will automatically handle this for us.

hartcw commented 7 months ago

@QUItCoding please recheck, I made some improvements to the patch. With this, it should fix both QNanoWidget and QNanoQuickItem code paths. And it means QNANO_ENABLE_PAINTER_SHARING can probably be removed.

Note. I've only tested the QNanoWidget and QNanoWindow paths, and not the QNanoQuickItem paths.

QUItCoding commented 7 months ago

Tested that Gallery / QNanoPainter features example crashes with this patch when swiping to right & left for while. There are also outputs "Attempting to create QWindow-based QOffscreenSurface outside the gui thread. Expect failures."