diff options
author | Mikolaj Boc <mikolaj.boc@qt.io> | 2022-11-14 09:12:34 +0100 |
---|---|---|
committer | Mikolaj Boc <mikolaj.boc@qt.io> | 2022-11-26 11:23:13 +0100 |
commit | fa27a59ec3cfc173d5ff202feb23e8b6e398dac9 (patch) | |
tree | a34f7a199611118e826a029a5bebf93f9425b32d /src/plugins/platforms/wasm/qwasmopenglcontext.cpp | |
parent | c675c1c56d3c00b3c1de5aee8c7c6f7eeeb70bc1 (diff) |
Use the browser compositor for drawing windows on WASM
Make the browser compositor draw the window non-client area (using css
+ html). Get rid of OpenGL usage in non-OpenGL windows and use canvas
2d context instead to blit the texture (QImage).
Also, as part of the change, remove the deprecated canvas element support
in QScreen.
Fixes: QTBUG-107116
Fixes: QTBUG-107219
Change-Id: I65f0d91831c806315685ca681ac0e416673f5cd5
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Aleksandr Reviakin <aleksandr.reviakin@qt.io>
Reviewed-by: David Skoland <david.skoland@qt.io>
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmopenglcontext.cpp')
-rw-r--r-- | src/plugins/platforms/wasm/qwasmopenglcontext.cpp | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp index df72397211..3dfb201367 100644 --- a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp +++ b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp @@ -34,18 +34,19 @@ QWasmOpenGLContext::QWasmOpenGLContext(const QSurfaceFormat &format) QWasmOpenGLContext::~QWasmOpenGLContext() { - if (m_context) { - // Destroy GL context. Work around bug in emscripten_webgl_destroy_context - // which removes all event handlers on the canvas by temporarily replacing the function - // that does the removal with a function that does nothing. - emscripten::val jsEvents = emscripten::val::module_property("JSEvents"); - emscripten::val savedRemoveAllHandlersOnTargetFunction = - jsEvents["removeAllHandlersOnTarget"]; - jsEvents.set("removeAllHandlersOnTarget", emscripten::val::module_property("qtDoNothing")); - emscripten_webgl_destroy_context(m_context); - jsEvents.set("removeAllHandlersOnTarget", savedRemoveAllHandlersOnTargetFunction); - m_context = 0; - } + if (!m_context) + return; + + // Destroy GL context. Work around bug in emscripten_webgl_destroy_context + // which removes all event handlers on the canvas by temporarily replacing the function + // that does the removal with a function that does nothing. + emscripten::val jsEvents = emscripten::val::module_property("JSEvents"); + emscripten::val savedRemoveAllHandlersOnTargetFunction = + jsEvents["removeAllHandlersOnTarget"]; + jsEvents.set("removeAllHandlersOnTarget", emscripten::val::module_property("qtDoNothing")); + emscripten_webgl_destroy_context(m_context); + jsEvents.set("removeAllHandlersOnTarget", savedRemoveAllHandlersOnTargetFunction); + m_context = 0; } bool QWasmOpenGLContext::isOpenGLVersionSupported(QSurfaceFormat format) @@ -60,25 +61,23 @@ bool QWasmOpenGLContext::isOpenGLVersionSupported(QSurfaceFormat format) bool QWasmOpenGLContext::maybeCreateEmscriptenContext(QPlatformSurface *surface) { - // 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) + if (m_context && m_surface == surface) + return true; + + // TODO(mikolajboc): Use OffscreenCanvas if available. + if (surface->surface()->surfaceClass() == QSurface::Offscreen) return false; - if (m_context) - return m_screen == screen; - m_context = createEmscriptenContext(QWasmScreen::get(screen)->canvasTargetId(), m_requestedFormat); - m_screen = screen; + m_surface = surface; + + auto *window = static_cast<QWasmWindow *>(surface); + m_context = createEmscriptenContext(window->canvasSelector(), m_requestedFormat); return true; } -EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(const QString &canvasTargetId, QSurfaceFormat format) +EMSCRIPTEN_WEBGL_CONTEXT_HANDLE +QWasmOpenGLContext::createEmscriptenContext(const std::string &canvasSelector, + QSurfaceFormat format) { EmscriptenWebGLContextAttributes attributes; emscripten_webgl_init_context_attributes(&attributes); // Populate with default attributes @@ -92,17 +91,14 @@ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(cons // WebGL doesn't allow separate attach buffers to STENCIL_ATTACHMENT and DEPTH_ATTACHMENT // we need both or none - bool useDepthStencil = (format.depthBufferSize() > 0 || format.stencilBufferSize() > 0); + const bool useDepthStencil = (format.depthBufferSize() > 0 || format.stencilBufferSize() > 0); // WebGL offers enable/disable control but not size control for these attributes.alpha = format.alphaBufferSize() > 0; attributes.depth = useDepthStencil; attributes.stencil = useDepthStencil; - QByteArray convasSelector = canvasTargetId.toUtf8(); - EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(convasSelector.constData(), &attributes); - - return context; + return emscripten_webgl_create_context(canvasSelector.c_str(), &attributes); } QSurfaceFormat QWasmOpenGLContext::format() const @@ -117,8 +113,7 @@ GLuint QWasmOpenGLContext::defaultFramebufferObject(QPlatformSurface *surface) c bool QWasmOpenGLContext::makeCurrent(QPlatformSurface *surface) { - bool ok = maybeCreateEmscriptenContext(surface); - if (!ok) + if (!maybeCreateEmscriptenContext(surface)) return false; return emscripten_webgl_make_context_current(m_context) == EMSCRIPTEN_RESULT_SUCCESS; @@ -142,7 +137,7 @@ bool QWasmOpenGLContext::isSharing() const bool QWasmOpenGLContext::isValid() const { - if (!(isOpenGLVersionSupported(m_requestedFormat))) + if (!isOpenGLVersionSupported(m_requestedFormat)) return false; // Note: we get isValid() calls before we see the surface and can |