From 7414c2c404cc241b1dbfa2d15aee2917a3b0cfb2 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 23 Jan 2015 21:02:37 +0100 Subject: QOpenGLWidget/QOpenGLWindow: add a destructor which calls makeCurrent Generally speaking, QOpenGLWindow subclasses are going to use some various QOpenGL* wrapper object to handle their buffers, FBOs, etc. Some of those QOpenGL* wrappers are QObjects, hence it should be safe to have them as child objects, and expect Qt to clean them up properly; but that doesn't happen because of how the destruction will work. In particular, when the subclass object is deleted, there may not be the right OpenGL context set as current. The deletion will go up to ~QObject, where the child objects will be deleted, resulting in a crash. That will *also* happen if someone connected to the context's aboutToBeDestroyed() signal: the context will in fact be deleted after the child objects, since it's stored in QOpenGLWindowPrivate, whose dtor will be run after ~QObject (!). Now, in the general case, QOpenGLWindow subclasses should always have a dtor in which they call makeCurrent() (also because various QOpenGL* class are not QObjects, hence they're kept around as full members instead of pointers-to); but at the same time we should clean up properly the QObject children. All of the above of course stands for QOpenGLWidget as well. Task-number: QTBUG-44094 Change-Id: I2379041fe175416936f6d40292039f773a515b35 Reviewed-by: Sean Harmer Reviewed-by: Laszlo Agocs --- src/gui/kernel/qopenglwindow.cpp | 25 +++++++++++++++++++++++++ src/gui/kernel/qopenglwindow.h | 1 + 2 files changed, 26 insertions(+) (limited to 'src/gui/kernel') diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index c58e296b5a..741df78407 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -336,6 +336,31 @@ QOpenGLWindow::QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior update { setSurfaceType(QSurface::OpenGLSurface); } + +/*! + Destroys the QOpenGLWindow instance, freeing its resources. + + The OpenGLWindow's context is made current in the destructor, allowing for + safe destruction of any child object that may need to release OpenGL + resources belonging to the context provided by this window. + + \warning if you have objects wrapping OpenGL resources (such as + QOpenGLBuffer, QOpenGLShaderProgram, etc.), as members of a QOpenGLWindow + subclass, you may need to add a call to makeCurrent() in that subclass' + destructor as well. Due to the rules of C++ object destruction, those objects + will be destroyed \e{before} calling this function (but after that the + destructor of the subclass has run), therefore making the OpenGL context + current in this function happens too late for their safe disposal. + + \sa makeCurrent + + \since 5.5 +*/ +QOpenGLWindow::~QOpenGLWindow() +{ + makeCurrent(); +} + /*! \return the update behavior for this QOpenGLWindow. */ diff --git a/src/gui/kernel/qopenglwindow.h b/src/gui/kernel/qopenglwindow.h index 6b64271b7b..86c51676f8 100644 --- a/src/gui/kernel/qopenglwindow.h +++ b/src/gui/kernel/qopenglwindow.h @@ -60,6 +60,7 @@ public: explicit QOpenGLWindow(UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = 0); explicit QOpenGLWindow(QOpenGLContext *shareContext, UpdateBehavior updateBehavior = NoPartialUpdate, QWindow *parent = 0); + ~QOpenGLWindow(); UpdateBehavior updateBehavior() const; bool isValid() const; -- cgit v1.2.3