Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
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 <private/qeventdispatcher_wasm_p.h>
8
9#include <qpa/qwindowsysteminterface.h>
10
11#include <emscripten/html5.h>
12
13using namespace emscripten;
14
15bool QWasmCompositor::m_requestUpdateHoldEnabled = true;
16
21
23{
24 if (m_requestAnimationFrameId != -1)
25 emscripten_cancel_animation_frame(m_requestAnimationFrameId);
26
27 // TODO(mikolaj.boc): Investigate if m_isEnabled is needed at all. It seems like a frame should
28 // not be generated after this instead.
29 m_isEnabled = false; // prevent frame() from creating a new m_context
30}
31
34{
35 auto allWindows = screen()->allWindows();
36 setEnabled(std::any_of(allWindows.begin(), allWindows.end(), [](QWasmWindow *element) {
37 return !element->context2d().isUndefined();
38 }));
40 m_requestUpdateWindows.remove(window);
41}
42
44{
45 m_isEnabled = enabled;
46}
47
48// requestUpdate delivery is initially disabled at startup, while Qt completes
49// startup tasks such as font loading. This function enables requestUpdate delivery
50// again.
52{
53 const bool wasEnabled = m_requestUpdateHoldEnabled;
54 m_requestUpdateHoldEnabled = false;
55 return wasEnabled;
56}
57
59{
60 auto it = m_requestUpdateWindows.find(window);
61 if (it == m_requestUpdateWindows.end()) {
62 m_requestUpdateWindows.insert(window, updateType);
63 } else {
64 // Already registered, but upgrade ExposeEventDeliveryType to UpdateRequestDeliveryType.
65 // if needed, to make sure QWindow::updateRequest's are matched.
66 if (it.value() == ExposeEventDelivery && updateType == UpdateRequestDelivery)
67 it.value() = UpdateRequestDelivery;
68 }
69
71}
72
73// Requests an update/new frame using RequestAnimationFrame
75{
76 if (m_requestAnimationFrameId != -1)
77 return;
78
79 if (m_requestUpdateHoldEnabled)
80 return;
81
82 static auto frame = [](double frameTime, void *context) -> int {
83 Q_UNUSED(frameTime);
84
85 QWasmCompositor *compositor = reinterpret_cast<QWasmCompositor *>(context);
86
87 compositor->m_requestAnimationFrameId = -1;
88 compositor->deliverUpdateRequests();
89
90 return 0;
91 };
92 m_requestAnimationFrameId = emscripten_request_animation_frame(frame, this);
93}
94
95void QWasmCompositor::deliverUpdateRequests()
96{
97 // We may get new update requests during the window content update below:
98 // prepare for recording the new update set by setting aside the current
99 // update set.
100 auto requestUpdateWindows = m_requestUpdateWindows;
101 m_requestUpdateWindows.clear();
102
103 // Update window content, either all windows or a spesific set of windows. Use the correct
104 // update type: QWindow subclasses expect that requested and delivered updateRequests matches
105 // exactly.
106 m_inDeliverUpdateRequest = true;
107 for (auto it = requestUpdateWindows.constBegin(); it != requestUpdateWindows.constEnd(); ++it) {
108 auto *window = it.key();
109 UpdateRequestDeliveryType updateType = it.value();
110 deliverUpdateRequest(window, updateType);
111 }
112
113 m_inDeliverUpdateRequest = false;
114 frame(requestUpdateWindows.keys());
115}
116
117void QWasmCompositor::deliverUpdateRequest(QWasmWindow *window, UpdateRequestDeliveryType updateType)
118{
119 QWindow *qwindow = window->window();
120
121 // Make sure the DPR value for the window is up to date on expose/repaint.
122 // FIXME: listen to native DPR change events instead, if/when available.
124
125 // Update by deliverUpdateRequest and expose event according to requested update
126 // type. If the window has not yet been exposed then we must expose it first regardless
127 // of update type. The deliverUpdateRequest must still be sent in this case in order
128 // to maintain correct window update state.
129 QRect updateRect(QPoint(0, 0), qwindow->geometry().size());
130 if (updateType == UpdateRequestDelivery) {
131 if (qwindow->isExposed() == false)
133 window->deliverUpdateRequest();
134 } else {
136 }
137}
138
140{
141 // Request update to flush the updated backing store content, unless we are currently
142 // processing an update, in which case the new content will flushed as a part of that update.
143 if (!m_inDeliverUpdateRequest)
144 requestUpdateWindow(static_cast<QWasmWindow *>(window->handle()));
145}
146
147void QWasmCompositor::frame(const QList<QWasmWindow *> &windows)
148{
149 if (!m_isEnabled || !screen())
150 return;
151
152 for (QWasmWindow *window : windows)
153 window->paint();
154}
155
157{
158 return static_cast<QWasmScreen *>(parent());
159}
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
size_type remove(const Key &key)
Definition qmap.h:300
void clear()
Definition qmap.h:289
iterator find(const Key &key)
Definition qmap.h:641
iterator end()
Definition qmap.h:602
\inmodule QtCore
Definition qobject.h:103
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
const_iterator constBegin() const noexcept
Definition qset.h:139
const_iterator constEnd() const noexcept
Definition qset.h:143
void onWindowTreeChanged(QWasmWindowTreeNodeChangeType changeType, QWasmWindow *window)
static bool releaseRequestUpdateHold()
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 void handleWindowDevicePixelRatioChanged(QWindow *window)
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]