wasm: fix texture leak when window is destroyed in a different context

Reproduce:
Show first window in first canvas;
Show second window in second canvas;
After screens are rendered destroy first window in first canvas

Change-Id: Ifbeb4824c1fdedecf24d5d20e58613d15c066420
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Alexandra Cherdantseva 2020-01-20 17:10:26 +03:00
parent e8793476ac
commit 0efdf54a16
5 changed files with 36 additions and 9 deletions

View File

@ -36,7 +36,7 @@
#include <QtGui/qpainter.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformscreen.h>
#include <QtGui/qoffscreensurface.h>
#include <QtGui/qbackingstore.h>
QT_BEGIN_NAMESPACE
@ -53,12 +53,29 @@ QWasmBackingStore::QWasmBackingStore(QWasmCompositor *compositor, QWindow *windo
QWasmBackingStore::~QWasmBackingStore()
{
auto window = this->window();
QWasmIntegration::get()->removeBackingStore(window);
destroy();
QWasmWindow *wasmWindow = static_cast<QWasmWindow *>(window->handle());
if (wasmWindow)
wasmWindow->setBackingStore(nullptr);
}
void QWasmBackingStore::destroy()
{
if (m_texture->isCreated())
m_texture->destroy();
if (m_texture->isCreated()) {
auto context = m_compositor->context();
auto currentContext = QOpenGLContext::currentContext();
if (!currentContext || !QOpenGLContext::areSharing(context, currentContext)) {
QOffscreenSurface offScreenSurface(m_compositor->screen()->screen());
offScreenSurface.setFormat(context->format());
offScreenSurface.create();
context->makeCurrent(&offScreenSurface);
m_texture->destroy();
} else {
m_texture->destroy();
}
}
}
QPaintDevice *QWasmBackingStore::paintDevice()
@ -81,9 +98,9 @@ void QWasmBackingStore::updateTexture()
if (m_dirty.isNull())
return;
if (m_recreateTexture && m_texture->isCreated()) {
if (m_recreateTexture) {
m_recreateTexture = false;
m_texture->destroy();
destroy();
}
if (!m_texture->isCreated()) {

View File

@ -59,7 +59,6 @@ QWasmCompositedWindow::QWasmCompositedWindow()
QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
:QObject(screen)
, m_frameBuffer(nullptr)
, m_blitter(new QOpenGLTextureBlitter)
, m_needComposit(false)
, m_inFlush(false)
@ -71,7 +70,6 @@ QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
QWasmCompositor::~QWasmCompositor()
{
delete m_frameBuffer;
destroy();
}
@ -748,3 +746,8 @@ QWasmScreen *QWasmCompositor::screen()
{
return static_cast<QWasmScreen *>(parent());
}
QOpenGLContext *QWasmCompositor::context()
{
return m_context.data();
}

View File

@ -125,11 +125,13 @@ public:
static QWasmTitleBarOptions makeTitleBarOptions(const QWasmWindow *window);
static QRect titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::SubControls subcontrol);
QWasmScreen *screen();
QOpenGLContext *context();
private slots:
void frame();
private:
QWasmScreen *screen();
void notifyTopWindowChanged(QWasmWindow *window);
void drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
void drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
@ -138,7 +140,6 @@ private:
void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window);
void drwPanelButton();
QImage *m_frameBuffer;
QScopedPointer<QOpenGLContext> m_context;
QScopedPointer<QOpenGLTextureBlitter> m_blitter;

View File

@ -193,6 +193,11 @@ QPlatformBackingStore *QWasmIntegration::createPlatformBackingStore(QWindow *win
#endif
}
void QWasmIntegration::removeBackingStore(QWindow* window)
{
m_backingStores.remove(window);
}
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QWasmIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{

View File

@ -88,6 +88,7 @@ public:
void resizeScreen(const QString &canvasId);
void resizeAllScreens();
void updateDpi();
void removeBackingStore(QWindow* window);
private:
mutable QWasmFontDatabase *m_fontDb;