From 9c196b40d10f992b5ecc71f2e0093cff2308ed88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 7 May 2019 23:26:28 +0200 Subject: wasm: remove qDebug Change-Id: Ic9812421b2a79a33bb138f448fe132dab141b724 Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/plugins/platforms/wasm') diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 6a02a457a0..7126c00354 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -337,8 +337,6 @@ QWasmEventTranslator::QWasmEventTranslator(QWasmScreen *screen) void QWasmEventTranslator::initEventHandlers() { - qDebug() << "QWasmEventTranslator::initEventHandlers"; - QByteArray _canvasId = screen()->canvasId().toUtf8(); const char *canvasId = _canvasId.constData(); -- cgit v1.2.3 From 22c3c55de44b9b900b5e4d7040a9c3f906d0bfa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 26 Apr 2019 15:33:49 +0200 Subject: wasm: install one browser window resize handler Install one browser window resize handler instead of per-canvas resize handlers, which avoids having to uninstall on QScreen destruction. Task-number: QTBUG-75463 Change-Id: I8345262a906ed735f8e9e146f1e963f515cf0d25 Reviewed-by: Lorn Potter --- .../platforms/wasm/qwasmeventtranslator.cpp | 18 ------------------ src/plugins/platforms/wasm/qwasmeventtranslator.h | 2 -- src/plugins/platforms/wasm/qwasmintegration.cpp | 22 ++++++++++++++++++++++ src/plugins/platforms/wasm/qwasmintegration.h | 1 + 4 files changed, 23 insertions(+), 20 deletions(-) (limited to 'src/plugins/platforms/wasm') diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 7126c00354..f586c5378e 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -375,9 +375,6 @@ void QWasmEventTranslator::initEventHandlers() emscripten_set_touchend_callback(canvasId, (void *)this, 1, &touchCallback); emscripten_set_touchmove_callback(canvasId, (void *)this, 1, &touchCallback); emscripten_set_touchcancel_callback(canvasId, (void *)this, 1, &touchCallback); - - emscripten_set_resize_callback(nullptr, (void *)this, 1, uiEvent_cb); // Note: handles browser window resize - } template @@ -909,19 +906,4 @@ bool QWasmEventTranslator::processKeyboard(int eventType, const EmscriptenKeyboa return accepted; } -int QWasmEventTranslator::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData) -{ - Q_UNUSED(e) - QWasmEventTranslator *eventTranslator = static_cast(userData); - - if (eventType == EMSCRIPTEN_EVENT_RESIZE) { - // This resize event is called when the HTML window is resized. Depending - // on the page layout the the canvas might also have been resized, so we - // update the Qt screen size (and canvas render size). - eventTranslator->screen()->updateQScreenAndCanvasRenderSize(); - } - - return 0; -} - QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h index d6043072ba..1655b7226a 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.h +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h @@ -57,8 +57,6 @@ public: static int touchCallback(int eventType, const EmscriptenTouchEvent *ev, void *userData); - static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData); - void processEvents(); void initEventHandlers(); int handleTouch(int eventType, const EmscriptenTouchEvent *touchEvent); diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index e601d553f2..703b0fde0b 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -115,6 +115,21 @@ QWasmIntegration::QWasmIntegration() } emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload")); + + // install browser window resize handler + auto onWindowResize = [](int eventType, const EmscriptenUiEvent *e, void *userData) -> int { + Q_UNUSED(eventType); + Q_UNUSED(e); + Q_UNUSED(userData); + + // This resize event is called when the HTML window is resized. Depending + // on the page layout the the canvas(es) might also have been resized, so we + // update the Qt screen sizes (and canvas render sizes). + if (QWasmIntegration *integration = QWasmIntegration::get()) + integration->resizeAllScreens(); + return 0; + }; + emscripten_set_resize_callback(nullptr, nullptr, 1, onWindowResize); } QWasmIntegration::~QWasmIntegration() @@ -245,4 +260,11 @@ void QWasmIntegration::resizeScreen(const QString &canvasId) m_screens.value(canvasId)->updateQScreenAndCanvasRenderSize(); } +void QWasmIntegration::resizeAllScreens() +{ + qDebug() << "resizeAllScreens"; + for (QWasmScreen *screen : m_screens) + screen->updateQScreenAndCanvasRenderSize(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h index 11d8d0f7f5..d5011db067 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.h +++ b/src/plugins/platforms/wasm/qwasmintegration.h @@ -81,6 +81,7 @@ public: void addScreen(const QString &canvasId); void removeScreen(const QString &canvasId); void resizeScreen(const QString &canvasId); + void resizeAllScreens(); private: mutable QWasmFontDatabase *m_fontDb; -- cgit v1.2.3 From 6d7c7a5ddafc8005969d4d99dc0c92b49ac4bcb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Sat, 27 Apr 2019 00:27:19 +0200 Subject: wasm: prevent crash on null backingstore pointer We can get draw calls in between creating the platform window and the platform backing store. Task-number: QTBUG-75463 Change-Id: If0b67d40fac84e466f204ec23a267aa4c6121cbd Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmcompositor.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/plugins/platforms/wasm') diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index e6a69c4814..b3234197d0 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -251,6 +251,8 @@ void QWasmCompositor::blit(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, void QWasmCompositor::drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window) { QWasmBackingStore *backingStore = window->backingStore(); + if (!backingStore) + return; QOpenGLTexture const *texture = backingStore->getUpdatedTexture(); -- cgit v1.2.3 From 00de44701d1496377632681c5228af4abfea0033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Sat, 27 Apr 2019 00:30:20 +0200 Subject: wasm: use correct coordinates when blitting The target position is the position on the canvas, not the global position on the page. Task-number: QTBUG-75463 Change-Id: I4ea2c9afacd2065fa975f6fa2e6a93d98f637854 Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmcompositor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms/wasm') diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index b3234197d0..9d99c21195 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -255,8 +255,9 @@ void QWasmCompositor::drawWindowContent(QOpenGLTextureBlitter *blitter, QWasmScr return; QOpenGLTexture const *texture = backingStore->getUpdatedTexture(); - - blit(blitter, screen, texture, window->geometry()); + QPoint windowCanvasPosition = window->geometry().topLeft() - screen->geometry().topLeft(); + QRect windowCanvasGeometry = QRect(windowCanvasPosition, window->geometry().size()); + blit(blitter, screen, texture, windowCanvasGeometry); } QPalette QWasmCompositor::makeWindowPalette() -- cgit v1.2.3 From 4e0f26289244d587714abf8adda932cce5697925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 29 Apr 2019 01:11:25 +0200 Subject: wasm: add QWasmOffscreenSurface This no-op implementation is sufficient to support OpenGL cleanup use cases, where the OpenGL context needs to be made current at times where we don't have a window available. A specific requirement on WebAssembly is that the context is tied to one specific screen; which is an extra requirement on QWasmOffscreenSurface, compared to the other platforms. Task-number: QTBUG-75463 Change-Id: Ie3658cb235bf342be66f19dfe981e3a56a90e1b6 Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmintegration.cpp | 6 +++ src/plugins/platforms/wasm/qwasmintegration.h | 1 + .../platforms/wasm/qwasmoffscreensurface.cpp | 41 ++++++++++++++++++ src/plugins/platforms/wasm/qwasmoffscreensurface.h | 49 ++++++++++++++++++++++ src/plugins/platforms/wasm/wasm.pro | 6 ++- 5 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/wasm/qwasmoffscreensurface.cpp create mode 100644 src/plugins/platforms/wasm/qwasmoffscreensurface.h (limited to 'src/plugins/platforms/wasm') diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index 703b0fde0b..0d22d31c25 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -35,6 +35,7 @@ #include "qwasmtheme.h" #include "qwasmclipboard.h" #include "qwasmservices.h" +#include "qwasmoffscreensurface.h" #include "qwasmwindow.h" #ifndef QT_NO_OPENGL @@ -188,6 +189,11 @@ QPlatformOpenGLContext *QWasmIntegration::createPlatformOpenGLContext(QOpenGLCon } #endif +QPlatformOffscreenSurface *QWasmIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const +{ + return new QWasmOffscrenSurface(surface); +} + QPlatformFontDatabase *QWasmIntegration::fontDatabase() const { if (m_fontDb == nullptr) diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h index d5011db067..dc1cc72382 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.h +++ b/src/plugins/platforms/wasm/qwasmintegration.h @@ -65,6 +65,7 @@ public: #ifndef QT_NO_OPENGL QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; #endif + QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; QPlatformFontDatabase *fontDatabase() const override; QAbstractEventDispatcher *createEventDispatcher() const override; QVariant styleHint(QPlatformIntegration::StyleHint hint) const override; diff --git a/src/plugins/platforms/wasm/qwasmoffscreensurface.cpp b/src/plugins/platforms/wasm/qwasmoffscreensurface.cpp new file mode 100644 index 0000000000..a205e5ddea --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmoffscreensurface.cpp @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasmoffscreensurface.h" + +QWasmOffscrenSurface::QWasmOffscrenSurface(QOffscreenSurface *offscreenSurface) + :QPlatformOffscreenSurface(offscreenSurface) +{ + +} + +QWasmOffscrenSurface::~QWasmOffscrenSurface() +{ + +} diff --git a/src/plugins/platforms/wasm/qwasmoffscreensurface.h b/src/plugins/platforms/wasm/qwasmoffscreensurface.h new file mode 100644 index 0000000000..9d3e805be0 --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmoffscreensurface.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWASMOFFSCREENSURFACE_H +#define QWASMOFFSCREENSURFACE_H + +#include + +QT_BEGIN_NAMESPACE + +class QOffscreenSurface; +class QWasmOffscrenSurface : public QPlatformOffscreenSurface +{ +public: + explicit QWasmOffscrenSurface(QOffscreenSurface *offscreenSurface); + ~QWasmOffscrenSurface(); +private: + +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro index e8728d9dba..c28df8f893 100644 --- a/src/plugins/platforms/wasm/wasm.pro +++ b/src/plugins/platforms/wasm/wasm.pro @@ -20,7 +20,8 @@ SOURCES = \ qwasmopenglcontext.cpp \ qwasmtheme.cpp \ qwasmclipboard.cpp \ - qwasmservices.cpp + qwasmservices.cpp \ + qwasmoffscreensurface.cpp HEADERS = \ qwasmintegration.h \ @@ -35,7 +36,8 @@ HEADERS = \ qwasmopenglcontext.h \ qwasmtheme.h \ qwasmclipboard.h \ - qwasmservices.h + qwasmservices.h \ + qwasmoffscreensurface.h wasmfonts.files = \ ../../../3rdparty/wasm/Vera.ttf \ -- cgit v1.2.3 From c8c4819b7b2f20c2972c31c49547ce5b59fe1240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 29 Apr 2019 00:35:42 +0200 Subject: 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 --- src/plugins/platforms/wasm/qwasmbackingstore.cpp | 6 +++++ src/plugins/platforms/wasm/qwasmbackingstore.h | 1 + src/plugins/platforms/wasm/qwasmcompositor.cpp | 29 ++++++++++++++++++++++-- src/plugins/platforms/wasm/qwasmcompositor.h | 1 + src/plugins/platforms/wasm/qwasmintegration.cpp | 4 +++- src/plugins/platforms/wasm/qwasmscreen.cpp | 5 ++++ src/plugins/platforms/wasm/qwasmscreen.h | 1 + src/plugins/platforms/wasm/qwasmwindow.cpp | 6 +++++ src/plugins/platforms/wasm/qwasmwindow.h | 1 + 9 files changed, 51 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms/wasm') diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.cpp b/src/plugins/platforms/wasm/qwasmbackingstore.cpp index 5b40c44807..e8eda2605f 100644 --- a/src/plugins/platforms/wasm/qwasmbackingstore.cpp +++ b/src/plugins/platforms/wasm/qwasmbackingstore.cpp @@ -55,6 +55,12 @@ QWasmBackingStore::~QWasmBackingStore() { } +void QWasmBackingStore::destroy() +{ + if (m_texture->isCreated()) + m_texture->destroy(); +} + QPaintDevice *QWasmBackingStore::paintDevice() { return &m_image; diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.h b/src/plugins/platforms/wasm/qwasmbackingstore.h index 6ffa262e3d..4bca83c457 100644 --- a/src/plugins/platforms/wasm/qwasmbackingstore.h +++ b/src/plugins/platforms/wasm/qwasmbackingstore.h @@ -44,6 +44,7 @@ class QWasmBackingStore : public QPlatformBackingStore public: QWasmBackingStore(QWasmCompositor *compositor, QWindow *window); ~QWasmBackingStore(); + void destroy(); QPaintDevice *paintDevice() override; diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index 9d99c21195..6d211667be 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -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(); diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h index 3104573073..98f4a79b27 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.h +++ b/src/plugins/platforms/wasm/qwasmcompositor.h @@ -64,6 +64,7 @@ class QWasmCompositor : public QObject public: QWasmCompositor(QWasmScreen *screen); ~QWasmCompositor(); + void destroy(); enum QWasmSubControl { SC_None = 0x00000000, diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index 0d22d31c25..93d3b5f76d 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -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) diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp index a26cafa900..74d47555fc 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.cpp +++ b/src/plugins/platforms/wasm/qwasmscreen.cpp @@ -57,7 +57,12 @@ QWasmScreen::QWasmScreen(const QString &canvasId) QWasmScreen::~QWasmScreen() { + destroy(); +} +void QWasmScreen::destroy() +{ + m_compositor->destroy(); } QWasmScreen *QWasmScreen::get(QPlatformScreen *screen) diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h index 82d2a83edb..4ad4ffa9ad 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.h +++ b/src/plugins/platforms/wasm/qwasmscreen.h @@ -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); diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 39797cb09d..594db65cfd 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -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(); diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h index cbbce99aeb..a098172649 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.h +++ b/src/plugins/platforms/wasm/qwasmwindow.h @@ -58,6 +58,7 @@ public: QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingStore *backingStore); ~QWasmWindow(); + void destroy(); void initialize() override; -- cgit v1.2.3 From 77216c5c5295a38cc432135e31529335c18c5a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 29 Apr 2019 01:19:14 +0200 Subject: wasm: rewrite/simplify OpenglContext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don’t need the contextLost callback since we can poll for the “lost” status in isValid() Recreating the native context is not very helpful, since it destroys all current context state. Remove this logic. Support makeCurrent() on different surfaces, as long as they refer to the same screen. Create the native context (and record which screen) on the first call to makeCurrent() Task-number: QTBUG-75463 Change-Id: I6eb830df14578ffdbed5b0505fe860ce433e4f9b Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmopenglcontext.cpp | 59 +++++++++++------------ src/plugins/platforms/wasm/qwasmopenglcontext.h | 6 +-- 2 files changed, 30 insertions(+), 35 deletions(-) (limited to 'src/plugins/platforms/wasm') diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp index ae43e2ebf0..0eaffdb77e 100644 --- a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp +++ b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp @@ -41,40 +41,31 @@ QWasmOpenGLContext::QWasmOpenGLContext(const QSurfaceFormat &format) QWasmOpenGLContext::~QWasmOpenGLContext() { - if (m_context) + if (m_context) { emscripten_webgl_destroy_context(m_context); + m_context = 0; + } } -void QWasmOpenGLContext::maybeRecreateEmscriptenContext(QPlatformSurface *surface) +bool QWasmOpenGLContext::maybeCreateEmscriptenContext(QPlatformSurface *surface) { - // Native emscripten contexts are tied to a single surface. Recreate - // the context if the surface is changed. - if (surface != m_surface) { - m_surface = surface; - - // Destroy existing context - if (m_context) - emscripten_webgl_destroy_context(m_context); - - // Create new context - const QString canvasId = QWasmScreen::get(surface->screen())->canvasId(); - m_context = createEmscriptenContext(canvasId, m_requestedFormat); - - // Register context-lost callback. - auto callback = [](int eventType, const void *reserved, void *userData) -> EM_BOOL - { - Q_UNUSED(eventType); - Q_UNUSED(reserved); - // The application may get contex-lost if e.g. moved to the background. Set - // m_contextLost which will make isValid() return false. Application code will - // then detect this and recrate the the context, resulting in a new QWasmOpenGLContext - // instance. - reinterpret_cast(userData)->m_contextLost = true; - return true; - }; - bool capture = true; - emscripten_set_webglcontextlost_callback(canvasId.toLocal8Bit().constData(), this, capture, callback); - } + // Native emscripten/WebGL contexts are tied to a single screen/canvas. The first + // call to this function creates a native canvas for the given screen, subsequent + // calls verify that the surface is on/off the same screen. + QPlatformScreen *screen = surface->screen(); + if (m_context && !screen) + return false; // Alternative: return true to support makeCurrent on QOffScreenSurface with + // no screen. However, Qt likes to substitute QGuiApplication::primaryScreen() + // for null screens, which foils this plan. + if (!screen) + return false; + if (m_context) + return m_screen == screen; + + QString canvasId = QWasmScreen::get(screen)->canvasId(); + m_context = createEmscriptenContext(canvasId, m_requestedFormat); + m_screen = screen; + return true; } EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(const QString &canvasId, QSurfaceFormat format) @@ -113,7 +104,9 @@ GLuint QWasmOpenGLContext::defaultFramebufferObject(QPlatformSurface *surface) c bool QWasmOpenGLContext::makeCurrent(QPlatformSurface *surface) { - maybeRecreateEmscriptenContext(surface); + bool ok = maybeCreateEmscriptenContext(surface); + if (!ok) + return false; return emscripten_webgl_make_context_current(m_context) == EMSCRIPTEN_RESULT_SUCCESS; } @@ -136,7 +129,9 @@ bool QWasmOpenGLContext::isSharing() const bool QWasmOpenGLContext::isValid() const { - return (m_contextLost == false); + // Note: we get isValid() calls before we see the surface and can + // create a native context, so no context is also a valid state. + return !m_context || !emscripten_is_webgl_context_lost(m_context); } QFunctionPointer QWasmOpenGLContext::getProcAddress(const char *procName) diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.h b/src/plugins/platforms/wasm/qwasmopenglcontext.h index 126b596a7e..d27007e8ea 100644 --- a/src/plugins/platforms/wasm/qwasmopenglcontext.h +++ b/src/plugins/platforms/wasm/qwasmopenglcontext.h @@ -34,6 +34,7 @@ QT_BEGIN_NAMESPACE +class QPlatformScreen; class QWasmOpenGLContext : public QPlatformOpenGLContext { public: @@ -50,12 +51,11 @@ public: QFunctionPointer getProcAddress(const char *procName) override; private: - void maybeRecreateEmscriptenContext(QPlatformSurface *surface); + bool maybeCreateEmscriptenContext(QPlatformSurface *surface); static EMSCRIPTEN_WEBGL_CONTEXT_HANDLE createEmscriptenContext(const QString &canvasId, QSurfaceFormat format); - bool m_contextLost = false; QSurfaceFormat m_requestedFormat; - QPlatformSurface *m_surface = nullptr; + QPlatformScreen *m_screen = nullptr; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE m_context = 0; }; -- cgit v1.2.3 From df9f9fb368cc2dc17c57030e1df51804c2f2265d Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 30 May 2019 18:30:17 +1000 Subject: wasm: handle mouse events even when not over a window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the mouse button is held and mouse moves from over the window, that window would never register the button up event, and cause issue like being able to move a dialog around by simply moving the mouse around. Change-Id: I1363ac9c9f4113a79bf6863668ba74b90b1cea4a Fixes: QTBUG-75951 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/plugins/platforms/wasm') diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index f586c5378e..3895646b89 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -552,9 +552,12 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven Qt::KeyboardModifiers modifiers = translateMouseEventModifier(mouseEvent); QWindow *window2 = screen()->compositor()->windowAt(globalPoint, 5); - if (window2 == nullptr) - return; - lastWindow = window2; + + if (window2 == nullptr) { + window2 = lastWindow; + } else { + lastWindow = window2; + } QPoint localPoint = window2->mapFromGlobal(globalPoint); bool interior = window2->geometry().contains(globalPoint); @@ -616,7 +619,7 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven } if (resizeMode != QWasmWindow::ResizeNone && !(htmlWindow->m_windowState & Qt::WindowFullScreen)) { - QPoint delta = QPoint(mouseEvent->canvasX, mouseEvent->canvasY) - resizePoint; + QPoint delta = QPoint(mouseEvent->targetX, mouseEvent->targetY) - resizePoint; resizeWindow(draggedWindow, resizeMode, resizeStartRect, delta); } } -- cgit v1.2.3