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()
|
||||
{
|
||||
return &m_image;
|
||||
|
@ -44,6 +44,7 @@ class QWasmBackingStore : public QPlatformBackingStore
|
||||
public:
|
||||
QWasmBackingStore(QWasmCompositor *compositor, QWindow *window);
|
||||
~QWasmBackingStore();
|
||||
void destroy();
|
||||
|
||||
QPaintDevice *paintDevice() override;
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <QtGui/qopenglcontext.h>
|
||||
#include <QtGui/qopenglfunctions.h>
|
||||
#include <QtGui/qopengltextureblitter.h>
|
||||
#include <QtGui/qoffscreensurface.h>
|
||||
#include <QtGui/qpainter.h>
|
||||
#include <private/qpixmapcache_p.h>
|
||||
|
||||
@ -71,6 +72,28 @@ QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
|
||||
QWasmCompositor::~QWasmCompositor()
|
||||
{
|
||||
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)
|
||||
@ -653,7 +676,7 @@ void QWasmCompositor::frame()
|
||||
|
||||
m_needComposit = false;
|
||||
|
||||
if (m_windowStack.empty() || !screen())
|
||||
if (!m_isEnabled || m_windowStack.empty() || !screen())
|
||||
return;
|
||||
|
||||
QWasmWindow *someWindow = nullptr;
|
||||
@ -676,7 +699,9 @@ void QWasmCompositor::frame()
|
||||
m_context->create();
|
||||
}
|
||||
|
||||
m_context->makeCurrent(someWindow->window());
|
||||
bool ok = m_context->makeCurrent(someWindow->window());
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
if (!m_blitter->isCreated())
|
||||
m_blitter->create();
|
||||
|
@ -64,6 +64,7 @@ class QWasmCompositor : public QObject
|
||||
public:
|
||||
QWasmCompositor(QWasmScreen *screen);
|
||||
~QWasmCompositor();
|
||||
void destroy();
|
||||
|
||||
enum QWasmSubControl {
|
||||
SC_None = 0x00000000,
|
||||
|
@ -258,7 +258,9 @@ void QWasmIntegration::addScreen(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)
|
||||
|
@ -57,7 +57,12 @@ QWasmScreen::QWasmScreen(const QString &canvasId)
|
||||
|
||||
QWasmScreen::~QWasmScreen()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void QWasmScreen::destroy()
|
||||
{
|
||||
m_compositor->destroy();
|
||||
}
|
||||
|
||||
QWasmScreen *QWasmScreen::get(QPlatformScreen *screen)
|
||||
|
@ -52,6 +52,7 @@ class QWasmScreen : public QObject, public QPlatformScreen
|
||||
public:
|
||||
QWasmScreen(const QString &canvasId);
|
||||
~QWasmScreen();
|
||||
void destroy();
|
||||
|
||||
static QWasmScreen *get(QPlatformScreen *screen);
|
||||
static QWasmScreen *get(QScreen *screen);
|
||||
|
@ -65,6 +65,12 @@ QWasmWindow::~QWasmWindow()
|
||||
m_compositor->removeWindow(this);
|
||||
}
|
||||
|
||||
void QWasmWindow::destroy()
|
||||
{
|
||||
if (m_backingStore)
|
||||
m_backingStore->destroy();
|
||||
}
|
||||
|
||||
void QWasmWindow::initialize()
|
||||
{
|
||||
QRect rect = windowGeometry();
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
|
||||
QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingStore *backingStore);
|
||||
~QWasmWindow();
|
||||
void destroy();
|
||||
|
||||
void initialize() override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user