Qt 6.x
The Qt SDK
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
qwasmcompositor.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include "qwasmcompositor.h"
5#include "qwasmwindow.h"
6
7#include <qpa/qwindowsysteminterface.h>
8
9#include <emscripten/html5.h>
10
11using namespace emscripten;
12
14{
16}
17
19{
20 if (m_requestAnimationFrameId != -1)
21 emscripten_cancel_animation_frame(m_requestAnimationFrameId);
22
23 // TODO(mikolaj.boc): Investigate if m_isEnabled is needed at all. It seems like a frame should
24 // not be generated after this instead.
25 m_isEnabled = false; // prevent frame() from creating a new m_context
26}
27
30{
31 auto allWindows = screen()->allWindows();
32 setEnabled(std::any_of(allWindows.begin(), allWindows.end(), [](QWasmWindow *element) {
33 return !element->context2d().isUndefined();
34 }));
36 m_requestUpdateWindows.remove(window);
37}
38
40{
41 m_isEnabled = enabled;
42}
43
45{
46 auto it = m_requestUpdateWindows.find(window);
47 if (it == m_requestUpdateWindows.end()) {
48 m_requestUpdateWindows.insert(window, updateType);
49 } else {
50 // Already registered, but upgrade ExposeEventDeliveryType to UpdateRequestDeliveryType.
51 // if needed, to make sure QWindow::updateRequest's are matched.
52 if (it.value() == ExposeEventDelivery && updateType == UpdateRequestDelivery)
53 it.value() = UpdateRequestDelivery;
54 }
55
56 requestUpdate();
57}
58
59// Requests an update/new frame using RequestAnimationFrame
60void QWasmCompositor::requestUpdate()
61{
62 if (m_requestAnimationFrameId != -1)
63 return;
64
65 static auto frame = [](double frameTime, void *context) -> int {
66 Q_UNUSED(frameTime);
67
68 QWasmCompositor *compositor = reinterpret_cast<QWasmCompositor *>(context);
69
70 compositor->m_requestAnimationFrameId = -1;
71 compositor->deliverUpdateRequests();
72
73 return 0;
74 };
75 m_requestAnimationFrameId = emscripten_request_animation_frame(frame, this);
76}
77
78void QWasmCompositor::deliverUpdateRequests()
79{
80 // We may get new update requests during the window content update below:
81 // prepare for recording the new update set by setting aside the current
82 // update set.
83 auto requestUpdateWindows = m_requestUpdateWindows;
84 m_requestUpdateWindows.clear();
85
86 // Update window content, either all windows or a spesific set of windows. Use the correct
87 // update type: QWindow subclasses expect that requested and delivered updateRequests matches
88 // exactly.
89 m_inDeliverUpdateRequest = true;
90 for (auto it = requestUpdateWindows.constBegin(); it != requestUpdateWindows.constEnd(); ++it) {
91 auto *window = it.key();
92 UpdateRequestDeliveryType updateType = it.value();
93 deliverUpdateRequest(window, updateType);
94 }
95
96 m_inDeliverUpdateRequest = false;
97 frame(requestUpdateWindows.keys());
98}
99
100void QWasmCompositor::deliverUpdateRequest(QWasmWindow *window, UpdateRequestDeliveryType updateType)
101{
102 // Update by deliverUpdateRequest and expose event according to requested update
103 // type. If the window has not yet been exposed then we must expose it first regardless
104 // of update type. The deliverUpdateRequest must still be sent in this case in order
105 // to maintain correct window update state.
106 QWindow *qwindow = window->window();
107 QRect updateRect(QPoint(0, 0), qwindow->geometry().size());
108 if (updateType == UpdateRequestDelivery) {
109 if (qwindow->isExposed() == false)
111 window->deliverUpdateRequest();
112 } else {
114 }
115}
116
118{
119 // Request update to flush the updated backing store content, unless we are currently
120 // processing an update, in which case the new content will flushed as a part of that update.
121 if (!m_inDeliverUpdateRequest)
122 requestUpdateWindow(static_cast<QWasmWindow *>(window->handle()));
123}
124
125void QWasmCompositor::frame(const QList<QWasmWindow *> &windows)
126{
127 if (!m_isEnabled || !screen())
128 return;
129
130 for (QWasmWindow *window : windows)
131 window->paint();
132}
133
135{
136 return static_cast<QWasmScreen *>(parent());
137}
Definition qlist.h:74
iterator insert(const Key &key, const T &value)
Definition qmap.h:687
size_type remove(const Key &key)
Definition qmap.h:299
void clear()
Definition qmap.h:288
iterator find(const Key &key)
Definition qmap.h:640
iterator end()
Definition qmap.h:601
\inmodule QtCore
Definition qobject.h:90
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:241
const_iterator constBegin() const noexcept
Definition qset.h:139
const_iterator constEnd() const noexcept
Definition qset.h:143
void onWindowTreeChanged(QWasmWindowTreeNodeChangeType changeType, QWasmWindow *window)
void setEnabled(bool enabled)
void requestUpdateWindow(QWasmWindow *window, UpdateRequestDeliveryType updateType=ExposeEventDelivery)
void handleBackingStoreFlush(QWindow *window)
QWasmScreen * screen()
QWasmCompositor(QWasmScreen *screen)
QList< QWasmWindow * > allWindows()
static void setSynchronousWindowSystemEvents(bool enable)
static bool handleExposeEvent(QWindow *window, const QRegion &region)
\inmodule QtGui
Definition qwindow.h:63
QPainter paint
QSet< QString >::iterator it
static void * context
static QOpenGLCompositor * compositor
GLenum GLenum GLsizei const GLuint GLboolean enabled
QScreen * screen
[1]
Definition main.cpp:29
#define Q_UNUSED(x)
QWasmWindowTreeNodeChangeType
#define enabled
aWidget window() -> setWindowTitle("New Window Title")
[2]
QFrame frame
[0]