wasm: controlled screen destruction
Freeing OpenGL resources requires a current context, which (on wasm) requires a screen. Add a destroy() functions to QWasmScreen, QWasmCompositor, QWasmWindow, and QWasmBackingStore which facilitates OpenGL cleanup before we start deleting screen objects. Task-number: QTBUG-75463 Change-Id: I9954b536416b9147965c74459ccad838d1578778 Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
This commit is contained in:
parent
4e0f262892
commit
c8c4819b7b
@ -55,6 +55,12 @@ QWasmBackingStore::~QWasmBackingStore()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWasmBackingStore::destroy()
|
||||||
|
{
|
||||||
|
if (m_texture->isCreated())
|
||||||
|
m_texture->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
QPaintDevice *QWasmBackingStore::paintDevice()
|
QPaintDevice *QWasmBackingStore::paintDevice()
|
||||||
{
|
{
|
||||||
return &m_image;
|
return &m_image;
|
||||||
|
@ -44,6 +44,7 @@ class QWasmBackingStore : public QPlatformBackingStore
|
|||||||
public:
|
public:
|
||||||
QWasmBackingStore(QWasmCompositor *compositor, QWindow *window);
|
QWasmBackingStore(QWasmCompositor *compositor, QWindow *window);
|
||||||
~QWasmBackingStore();
|
~QWasmBackingStore();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
QPaintDevice *paintDevice() override;
|
QPaintDevice *paintDevice() override;
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <QtGui/qopenglcontext.h>
|
#include <QtGui/qopenglcontext.h>
|
||||||
#include <QtGui/qopenglfunctions.h>
|
#include <QtGui/qopenglfunctions.h>
|
||||||
#include <QtGui/qopengltextureblitter.h>
|
#include <QtGui/qopengltextureblitter.h>
|
||||||
|
#include <QtGui/qoffscreensurface.h>
|
||||||
#include <QtGui/qpainter.h>
|
#include <QtGui/qpainter.h>
|
||||||
#include <private/qpixmapcache_p.h>
|
#include <private/qpixmapcache_p.h>
|
||||||
|
|
||||||
@ -71,6 +72,28 @@ QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
|
|||||||
QWasmCompositor::~QWasmCompositor()
|
QWasmCompositor::~QWasmCompositor()
|
||||||
{
|
{
|
||||||
delete m_frameBuffer;
|
delete m_frameBuffer;
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWasmCompositor::destroy()
|
||||||
|
{
|
||||||
|
// Destroy OpenGL resources. This is done here in a separate function
|
||||||
|
// which can be called while screen() still returns a valid screen
|
||||||
|
// (which it might not, during destruction). A valid QScreen is
|
||||||
|
// a requirement for QOffscreenSurface on Wasm since the native
|
||||||
|
// context is tied to a single canvas.
|
||||||
|
if (m_context) {
|
||||||
|
QOffscreenSurface offScreenSurface(screen()->screen());
|
||||||
|
offScreenSurface.setFormat(m_context->format());
|
||||||
|
offScreenSurface.create();
|
||||||
|
m_context->makeCurrent(&offScreenSurface);
|
||||||
|
for (QWasmWindow *window : m_windowStack)
|
||||||
|
window->destroy();
|
||||||
|
m_blitter.reset(nullptr);
|
||||||
|
m_context.reset(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isEnabled = false; // prevent frame() from creating a new m_context
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmCompositor::setEnabled(bool enabled)
|
void QWasmCompositor::setEnabled(bool enabled)
|
||||||
@ -653,7 +676,7 @@ void QWasmCompositor::frame()
|
|||||||
|
|
||||||
m_needComposit = false;
|
m_needComposit = false;
|
||||||
|
|
||||||
if (m_windowStack.empty() || !screen())
|
if (!m_isEnabled || m_windowStack.empty() || !screen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QWasmWindow *someWindow = nullptr;
|
QWasmWindow *someWindow = nullptr;
|
||||||
@ -676,7 +699,9 @@ void QWasmCompositor::frame()
|
|||||||
m_context->create();
|
m_context->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_context->makeCurrent(someWindow->window());
|
bool ok = m_context->makeCurrent(someWindow->window());
|
||||||
|
if (!ok)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!m_blitter->isCreated())
|
if (!m_blitter->isCreated())
|
||||||
m_blitter->create();
|
m_blitter->create();
|
||||||
|
@ -64,6 +64,7 @@ class QWasmCompositor : public QObject
|
|||||||
public:
|
public:
|
||||||
QWasmCompositor(QWasmScreen *screen);
|
QWasmCompositor(QWasmScreen *screen);
|
||||||
~QWasmCompositor();
|
~QWasmCompositor();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
enum QWasmSubControl {
|
enum QWasmSubControl {
|
||||||
SC_None = 0x00000000,
|
SC_None = 0x00000000,
|
||||||
|
@ -258,7 +258,9 @@ void QWasmIntegration::addScreen(const QString &canvasId)
|
|||||||
|
|
||||||
void QWasmIntegration::removeScreen(const QString &canvasId)
|
void QWasmIntegration::removeScreen(const QString &canvasId)
|
||||||
{
|
{
|
||||||
QWindowSystemInterface::handleScreenRemoved(m_screens.take(canvasId));
|
QWasmScreen *exScreen = m_screens.take(canvasId);
|
||||||
|
exScreen->destroy(); // clean up before deleting the screen
|
||||||
|
QWindowSystemInterface::handleScreenRemoved(exScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWasmIntegration::resizeScreen(const QString &canvasId)
|
void QWasmIntegration::resizeScreen(const QString &canvasId)
|
||||||
|
@ -57,7 +57,12 @@ QWasmScreen::QWasmScreen(const QString &canvasId)
|
|||||||
|
|
||||||
QWasmScreen::~QWasmScreen()
|
QWasmScreen::~QWasmScreen()
|
||||||
{
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWasmScreen::destroy()
|
||||||
|
{
|
||||||
|
m_compositor->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
QWasmScreen *QWasmScreen::get(QPlatformScreen *screen)
|
QWasmScreen *QWasmScreen::get(QPlatformScreen *screen)
|
||||||
|
@ -52,6 +52,7 @@ class QWasmScreen : public QObject, public QPlatformScreen
|
|||||||
public:
|
public:
|
||||||
QWasmScreen(const QString &canvasId);
|
QWasmScreen(const QString &canvasId);
|
||||||
~QWasmScreen();
|
~QWasmScreen();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
static QWasmScreen *get(QPlatformScreen *screen);
|
static QWasmScreen *get(QPlatformScreen *screen);
|
||||||
static QWasmScreen *get(QScreen *screen);
|
static QWasmScreen *get(QScreen *screen);
|
||||||
|
@ -65,6 +65,12 @@ QWasmWindow::~QWasmWindow()
|
|||||||
m_compositor->removeWindow(this);
|
m_compositor->removeWindow(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QWasmWindow::destroy()
|
||||||
|
{
|
||||||
|
if (m_backingStore)
|
||||||
|
m_backingStore->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
void QWasmWindow::initialize()
|
void QWasmWindow::initialize()
|
||||||
{
|
{
|
||||||
QRect rect = windowGeometry();
|
QRect rect = windowGeometry();
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
|
|
||||||
QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingStore *backingStore);
|
QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingStore *backingStore);
|
||||||
~QWasmWindow();
|
~QWasmWindow();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
void initialize() override;
|
void initialize() override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user