summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
diff options
context:
space:
mode:
authorMikolaj Boc <mikolaj.boc@qt.io>2022-11-14 09:12:34 +0100
committerMikolaj Boc <mikolaj.boc@qt.io>2022-11-26 11:23:13 +0100
commitfa27a59ec3cfc173d5ff202feb23e8b6e398dac9 (patch)
treea34f7a199611118e826a029a5bebf93f9425b32d /src/plugins/platforms/wasm/qwasmopenglcontext.cpp
parentc675c1c56d3c00b3c1de5aee8c7c6f7eeeb70bc1 (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.cpp63
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