On 5 Dec 2024, at 10:49, Stephan Bergmann <[email protected]> wrote:
Hi all,
Hi Stephan,
We are leveraging Qt's fine Wasm/Emscripten platform support in a project where
we compile LibreOffice with Emscripten to run in the browser
We need Emscripten's -sPROXY_TO_PTHREAD setting, which moves the application's
main thread off the browser main thread into a pthread, to which it transfers
any canvas DOM element as an OffscreenCanvas upfront). We need that, among
others, because the LibreOffice code wants to arbitrarily spawn further threads
from within event loop callbacks, something that would run into deadlocks
without -sPROXY_TO_PTHREAD.
This sounds like the (known) issue where blocking the main thread can prevent
the browser from servicing the secondary thread, and deadlock. If you can avoid
this then starting threads should work, so it might be worth revisiting.
In particular calling pthread_join() can prevent the browser from creating a
web worker for the thread, which is for sure a deadlock (I don’t know what the
LibreOffice code looks like here, though).
Qt does not appear to support -sPROXY_TO_PTHREAD out of the box. But for that
old Qt 5.15.2, it was relatively easy to patch things up: There was only a
single qtcanvas DOM element, so Emscripten can be instructed to transfer it
with -sOFFSCREENCAVNASES_TO_PTHRAD=#qtcanvas. And Qt code that accessed browser
functionality that is only available on the browser's main thread (so cannot be
accessed directly any more with -sPROXY_TO_PTHREAD) was relatively rare, and I
patched that up by sprinkling in some
emscripten_async_run_in_main_runtime_thread etc., and that appeared to mostly
work well enough.
Now, with recent Qt 6, things have apparently changed rather drastically.
There is no longer a single #qtcanvas DOM element, but each window is its own,
dynamically added canvas element, and interaction with browser functionality
that is only available on the browser's main thread has grown significantly.
To a point that I quickly gave up trying to carry my patching approach forward
:)
Yes, Qt 6 has definitively moved in a direction which makes PROXY_TO_PTHREAD
harder to support. We access native API directly and create <canvas> instances
on demand.
So, my question is what the general opinion here is regarding support for
Emscripten's -sPROXY_TO_PTHREAD in today's Qt 6. Has this been discussed
before? Is it considered something that you wouldn't want to support, or
something that would be supported if somebody set out to actually implement it,
or…?
There has been some discussions, although no serious efforts at implementing
it. The question would be if this be implemented in a non-obtrusive (or
not-too-obtrusive) way in Qt. Typical native API usage can look like
emscripten::val rect =
m_window.call<emscripten::val>("getBoundingClientRect");
emscripten::val top = rect["top"].as<qreal>();
In theory val::call() (or a wrapper) could proxy to the browser main thread,
and return a DOMRect moved to the proxy thread. I think we don’t want to wrap
all of the individual API usage sites in
emscripten_async_run_in_main_runtime_thread().
Would it be better to implement this in Emscripten itself? There is
https://github.com/emscripten-core/emscripten/issues/9847, but it was closed.
First steps could be to create a prototype which demonstrates that the approach
can work, and shows what the code would look like.
Regards,
Morten
--
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development