📜 ⬆️ ⬇️

Qt Everywhere: WebAssembly and WebGL streaming

Qt Everywhere - this is how Qt source archives are named. In 5.12.0, WebAssembly and WebGL streaming are delivered and everywhere sounds different. So I asked for something to prototype. A prototype chat on web sockets was quickly thrown in to test network support. Under the cut there will be an instruction for building and running a project on WebAssembly, an example of invoking JavaScript from C ++.


Building Qt with WebAsse Assembly


First you need to put the toolchain emscripten , which will collect Qt. Do not forget to write the environment variables that qmake would find emcc. The configure script was run with the following parameters:


 ./configure \ -prefix /home/dmitry/Qt/5.12.0/wasm \ -xplatform wasm-emscripten \ -confirm-license -opensource \ -nomake tests \ -c++std c++1z \ -nomake examples \ -release \ -no-dbus \ -skip qtxmlpatterns \ -skip qttools 

Further, as elsewhere:


 $ make $ make install 

Build and run the project


 $ ~/Qt/5.12.0/wasm/bin/qmake $ make $ emrun chat.html 

Platform specific code


Sewing the url on which the backend is hanging is not very good, because want to run on an arbitrary port. In case of work from the browser, you need to take location.hostname and location.port to determine where the backend is running. To do this, have a little pee on JavaScript.


For lovers of defines, there is Q_OS_WASM , but I prefer to move the code into pimpl and separate files. Pimpl is superfluous here, but I’ll break the code into different files


Let's get some config


 //config.h #pragma once #include <QtCore/QUrl> class Config { public: static QUrl wsUrl(); }; 

and two implementations


 //config.cpp #include <QtCore/QCoreApplication> #include <QtCore/QCommandLineParser> #include "config.h" QUrl Config::wsUrl() { QCommandLineParser parser; QCommandLineOption wsOption(QStringList() << "u" << "url" , "WebSocket url" , "url" , "ws://localhost:1234"); parser.addOption(wsOption); parser.process(*QCoreApplication::instance()); return QUrl(parser.value(wsOption)); } 

 //config_wasm.cpp #include <QtCore/QByteArray> #include <emscripten/emscripten.h> #include <emscripten/html5.h> #include "config.h" QUrl Config::wsUrl() { QByteArray buff(1024, 0); EM_ASM_({ var url = "ws://"+ window.location.hostname + ":" + window.location.port + "/ws"; stringToUTF8(url, $0, $1); }, buff.data(), buff.size()); return QUrl(QString::fromUtf8(buff)); } 

It remains to register in the pro file


 wasm { SOURCES += config_wasm.cpp } else { SOURCES += config.cpp } 

EM_ASM_ is the magic of emscripten that allows you to call JavaScript code from C ++. Although it could be done without JavaScript


 emscripten::val location = emscripten::val::global("location"); auto host = QString::fromStdString(location["host"].as<string>()); auto protocol = QString::fromStdString(location["protocol"].as<string>()); 

Browser support


Desktop browsers: runs and works in hrome, Firefox, Safari, Edge (here it was necessary to enable the experimental functions of JavaScript). Depending on the hardware, there may be significant delays in compiling the WebAssembly.


In Chrome, Andorid can take minutes to compile WebAssembly. Immediately noticed the lack of support for mobile browsers, namely, there is no calling the system keyboard, when trying to enter text.


Safari on iOS 12 here the application crashes at the WebAssembly compilation stage and I did not debug. Theoretically, you can go to asm.js, but this requires a separate study.


Qt Quick WebGL


The blog positioned as VNC on web sockets with rendering on WebGL. From Qt WebSockets and Qt dependencies compiled with OpenGL ES 2 support i. drive on hardware without a GPU will be painful. To support it, just put Qt WebGL Streaming Plugin in an online installer and run the application with the -platform webgl or -platform webgl:port=80 parameter if you need to specify a port.


But this technology has its limitations:



I also noticed a drop in fps during StackView animation on transitions between screens. The dignity of WebGL streaming:



Ways to use WebAssembly and WebGL Streaming


Alternative to Wt when there is a ready application in C ++ and you need to fasten a web interface to it. For example web-interface to torrent rocking.


Web interface for some smart home. Not for nothing, in Qt, they delivered MQTT, and on msorvig / qt-webassembly-examples an example of mqtt_simpleclient . You can have a common UI code that works on the tablet and in the browser.


The code is available on GitHub , prepared binaries in the same place


')

Source: https://habr.com/ru/post/430954/


All Articles