WebAssembly multi canvas "Failed to make context current"
Unsolved
Qt for WebAssembly
-
I'm trying to use multiple canvases / screens to render multiple
QQuickView
windows in wasm. I'm using Qt 6.3.2// main.cpp #include <QGuiApplication> #include <QQuickView> int main(int argc, char *argv[]){ QGuiApplication app(argc, argv); const auto screens = app.screens(); if(screens.size() < 2){ qDebug() << "Expected at least 2 screens"; return 1; } for(auto & screen : screens){ qDebug() << screen; } QQuickView mainViewer; mainViewer.setScreen(screens[0]); mainViewer.setSource(QUrl(u"qrc:/wasm-multiwindow/main.qml"_qs)); mainViewer.setResizeMode(QQuickView::SizeRootObjectToView); QQuickView secondViewer; secondViewer.setScreen(screens[1]); secondViewer.setSource(QUrl(u"qrc:/wasm-multiwindow/second.qml"_qs)); secondViewer.setResizeMode(QQuickView::SizeRootObjectToView); mainViewer.show(); secondViewer.show(); return app.exec(); }
In the browser's console I get the following error:
QRhiGles2: Failed to make context current. Expect bad things to happen. Failed to start frame
If I set the same screen for both
QQuickView
objects, there's no error, but only one of them is visible of course. I have no issue running this code on x64 Linux target with two physical displays.So is this a bug
- in the browser?
- in Qt?
- in my code?
If it's option 3, maybe I could try to add manual locking around the opengl context?
Also, I have no problem creating 2 widgets on 2 canvases:
// this works #include <QApplication> #include <QWidget> int main(int argc, char *argv[]){ QApplication app(argc, argv); const auto screens = app.screens(); if(screens.size() < 2){ qDebug() << "Expected at least 2 screens"; return 1; } QWidget w1; w1.setScreen(screens[0]); w1.show(); QWidget w2; w2.setScreen(screens[1]); w2.show(); return app.exec(); }
For completeness here's rest of my code:
# wasm-multiwindow.pro QT += quick SOURCES += \ main.cpp resources.files = main.qml second.qml resources.prefix = /$${TARGET} RESOURCES += resources # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = # Additional import path used to resolve QML modules just for Qt Quick Designer QML_DESIGNER_IMPORT_PATH = # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
// main.qml import QtQuick Rectangle { width: 640 height: 480 visible: true color: "#ff0000" Text { text: "hello" } }
// second.qml import QtQuick Rectangle { width: 640 height: 480 visible: true color: "#00ff00" Text { text: "hi" } }
This is the default autogenerated HTML, with an extra canvas inserted.
<!doctype html> <html lang="en-us"> <head> <meta charset="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!--Set visual viewport size for mobile devices to the device size, witch results in a scale of 1 and a 1:1 mapping between CSS pixels and Qt device independent pixels. --> <meta name="viewport" content="width=device-width, height=device-height, user-scalable=0"/> <title>wasm-multiwindow</title> <style> /* Make the html body cover the entire (visual) viewport with no scroll bars. */ html, body { padding: 0; margin: 0; overflow:hidden; height: 100% } /* the canvas *must not* have any border or padding, or mouse coords will be wrong */ canvas { border: 0px none; background-color: white; height:50%; width:100%; } /* The contenteditable property is set to true for the canvas in order to support clipboard events. Hide the resulting focus frame and set the cursor back to the default cursor. */ canvas { outline: 0px solid transparent; caret-color: transparent; cursor:default } </style> </head> <body onload="init()"> <figure style="overflow:visible;" id="qtspinner"> <center style="margin-top:1.5em; line-height:150%"> <img src="qtlogo.svg" width="320" height="200" style="display:block"></img> <strong>Qt for WebAssembly: wasm-multiwindow</strong> <div id="qtstatus"></div> <noscript>JavaScript is disabled. Please enable JavaScript to use this application.</noscript> </center> </figure> <canvas id="qtcanvas" oncontextmenu="event.preventDefault()" contenteditable="true"></canvas> <canvas id="qtcanvas2" oncontextmenu="event.preventDefault()" contenteditable="true"></canvas> <script type='text/javascript'> function init() { var spinner = document.querySelector('#qtspinner'); var canvas = document.querySelector('#qtcanvas'); var canvas2 = document.querySelector('#qtcanvas2'); var status = document.querySelector('#qtstatus') var qtLoader = QtLoader({ canvasElements : [canvas, canvas2], showLoader: function(loaderStatus) { spinner.style.display = 'block'; canvas.style.display = 'none'; status.innerHTML = loaderStatus + "..."; }, showError: function(errorText) { status.innerHTML = errorText; spinner.style.display = 'block'; canvas.style.display = 'none'; }, showExit: function() { status.innerHTML = "Application exit"; if (qtLoader.exitCode !== undefined) status.innerHTML += " with code " + qtLoader.exitCode; if (qtLoader.exitText !== undefined) status.innerHTML += " (" + qtLoader.exitText + ")"; spinner.style.display = 'block'; canvas.style.display = 'none'; }, showCanvas: function() { spinner.style.display = 'none'; canvas.style.display = 'block'; }, }); qtLoader.loadEmscriptenModule("wasm-multiwindow"); } </script> <script type="text/javascript" src="qtloader.js"></script> </body> </html>
And here's the full console output:
writeStackCookie: 432bd0 qtloader.js:396:25 checkStackCookie: 432bd0 2 qtloader.js:396:25 QML debugging is enabled. Only use this in a safe environment. qtloader.js:396:25 checkStackCookie: 432bd0 qtloader.js:396:25 InstallTrigger is deprecated and will be removed in the future. qtloader.js line 467 > eval:7386:6 QScreen(0x93dba8, name="qtcanvas") qtloader.js:396:25 QScreen(0x93e410, name="qtcanvas2") qtloader.js:396:25 Blocking on the main thread is very dangerous, see https://emscripten.org/docs/porting/pthreads.html#blocking-on-the-main-browser-thread qtloader.js:396:25 writeStackCookie: 980340 da626f5d-f10d-4e17-8d04-6b0ecadc878f:842:6 writeStackCookie: 1c82f20 6ecfa28e-e258-4b5e-9554-21200ff1c8f1:842:6 checkStackCookie: 432bd0 qtloader.js:396:25 QRhiGles2: Failed to make context current. Expect bad things to happen. qtloader.js:396:25 Failed to start frame qtloader.js:396:25 checkStackCookie: 432bd0 qtloader.js:396:25 main loop exiting.. qtloader.js:396:25 QRhiGles2: Failed to make context current. Expect bad things to happen. qtloader.js:396:25 Failed to start frame qtloader.js:396:25