summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmopenglcontext.cpp')
-rw-r--r--src/plugins/platforms/wasm/qwasmopenglcontext.cpp55
1 files changed, 33 insertions, 22 deletions
diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
index 3dfb201367a..80e842f83dc 100644
--- a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
+++ b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
@@ -2,6 +2,8 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "qwasmopenglcontext.h"
+
+#include "qwasmoffscreensurface.h"
#include "qwasmintegration.h"
#include <EGL/egl.h>
#include <emscripten/bind.h>
@@ -18,23 +20,22 @@ EMSCRIPTEN_BINDINGS(qwasmopenglcontext)
QT_BEGIN_NAMESPACE
-QWasmOpenGLContext::QWasmOpenGLContext(const QSurfaceFormat &format)
- : m_requestedFormat(format)
+QWasmOpenGLContext::QWasmOpenGLContext(QOpenGLContext *context)
+ : m_requestedFormat(context->format()), m_qGlContext(context)
{
m_requestedFormat.setRenderableType(QSurfaceFormat::OpenGLES);
// if we set one, we need to set the other as well since in webgl, these are tied together
- if (format.depthBufferSize() < 0 && format.stencilBufferSize() > 0)
- m_requestedFormat.setDepthBufferSize(16);
-
- if (format.stencilBufferSize() < 0 && format.depthBufferSize() > 0)
- m_requestedFormat.setStencilBufferSize(8);
+ if (m_requestedFormat.depthBufferSize() < 0 && m_requestedFormat.stencilBufferSize() > 0)
+ m_requestedFormat.setDepthBufferSize(16);
+ if (m_requestedFormat.stencilBufferSize() < 0 && m_requestedFormat.depthBufferSize() > 0)
+ m_requestedFormat.setStencilBufferSize(8);
}
QWasmOpenGLContext::~QWasmOpenGLContext()
{
- if (!m_context)
+ if (!m_webGLContext)
return;
// Destroy GL context. Work around bug in emscripten_webgl_destroy_context
@@ -44,9 +45,9 @@ QWasmOpenGLContext::~QWasmOpenGLContext()
emscripten::val savedRemoveAllHandlersOnTargetFunction =
jsEvents["removeAllHandlersOnTarget"];
jsEvents.set("removeAllHandlersOnTarget", emscripten::val::module_property("qtDoNothing"));
- emscripten_webgl_destroy_context(m_context);
+ emscripten_webgl_destroy_context(m_webGLContext);
jsEvents.set("removeAllHandlersOnTarget", savedRemoveAllHandlersOnTargetFunction);
- m_context = 0;
+ m_webGLContext = 0;
}
bool QWasmOpenGLContext::isOpenGLVersionSupported(QSurfaceFormat format)
@@ -61,18 +62,28 @@ bool QWasmOpenGLContext::isOpenGLVersionSupported(QSurfaceFormat format)
bool QWasmOpenGLContext::maybeCreateEmscriptenContext(QPlatformSurface *surface)
{
- if (m_context && m_surface == surface)
+ if (m_webGLContext && m_surface == surface)
return true;
- // TODO(mikolajboc): Use OffscreenCanvas if available.
- if (surface->surface()->surfaceClass() == QSurface::Offscreen)
- return false;
-
m_surface = surface;
-
- auto *window = static_cast<QWasmWindow *>(surface);
- m_context = createEmscriptenContext(window->canvasSelector(), m_requestedFormat);
- return true;
+ if (surface->surface()->surfaceClass() == QSurface::Offscreen) {
+ if (const auto *shareContext = m_qGlContext->shareContext()) {
+ // Since there are no resource sharing capabilities with WebGL whatsoever, we use the
+ // same actual underlaying WebGL context. This is not perfect, but it works in most
+ // cases.
+ m_webGLContext =
+ static_cast<QWasmOpenGLContext *>(shareContext->handle())->m_webGLContext;
+ } else {
+ // The non-shared offscreen context is heavily limited on WASM, but we provide it anyway
+ // for potential pixel readbacks.
+ m_webGLContext = createEmscriptenContext(
+ static_cast<QWasmOffscreenSurface *>(surface)->id(), m_requestedFormat);
+ }
+ } else {
+ m_webGLContext = createEmscriptenContext(
+ static_cast<QWasmWindow *>(surface)->canvasSelector(), m_requestedFormat);
+ }
+ return m_webGLContext > 0;
}
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE
@@ -116,7 +127,7 @@ bool QWasmOpenGLContext::makeCurrent(QPlatformSurface *surface)
if (!maybeCreateEmscriptenContext(surface))
return false;
- return emscripten_webgl_make_context_current(m_context) == EMSCRIPTEN_RESULT_SUCCESS;
+ return emscripten_webgl_make_context_current(m_webGLContext) == EMSCRIPTEN_RESULT_SUCCESS;
}
void QWasmOpenGLContext::swapBuffers(QPlatformSurface *surface)
@@ -132,7 +143,7 @@ void QWasmOpenGLContext::doneCurrent()
bool QWasmOpenGLContext::isSharing() const
{
- return false;
+ return m_qGlContext->shareContext();
}
bool QWasmOpenGLContext::isValid() const
@@ -142,7 +153,7 @@ bool QWasmOpenGLContext::isValid() const
// 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);
+ return !m_webGLContext || !emscripten_is_webgl_context_lost(m_webGLContext);
}
QFunctionPointer QWasmOpenGLContext::getProcAddress(const char *procName)