summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/wasm/qwasmbackingstore.cpp2
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.cpp148
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.h19
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp2
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.cpp10
5 files changed, 116 insertions, 65 deletions
diff --git a/src/plugins/platforms/wasm/qwasmbackingstore.cpp b/src/plugins/platforms/wasm/qwasmbackingstore.cpp
index 3d667ccf97..989c2a1b90 100644
--- a/src/plugins/platforms/wasm/qwasmbackingstore.cpp
+++ b/src/plugins/platforms/wasm/qwasmbackingstore.cpp
@@ -90,7 +90,7 @@ void QWasmBackingStore::flush(QWindow *window, const QRegion &region, const QPoi
Q_UNUSED(offset);
m_dirty |= region;
- m_compositor->requestRedraw();
+ m_compositor->handleBackingStoreFlush();
}
void QWasmBackingStore::updateTexture()
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp
index 063144d71d..aa498c8238 100644
--- a/src/plugins/platforms/wasm/qwasmcompositor.cpp
+++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp
@@ -28,6 +28,7 @@
****************************************************************************/
#include "qwasmcompositor.h"
+#include "qwasmeventdispatcher.h"
#include "qwasmwindow.h"
#include "qwasmstylepixmaps_p.h"
@@ -69,6 +70,8 @@ QWasmCompositor::QWasmCompositor(QWasmScreen *screen)
QWasmCompositor::~QWasmCompositor()
{
+ if (m_requestAnimationFrameId != -1)
+ emscripten_cancel_animation_frame(m_requestAnimationFrameId);
destroy();
}
@@ -148,7 +151,7 @@ void QWasmCompositor::setVisible(QWasmWindow *window, bool visible)
else
m_globalDamage = compositedWindow.window->geometry(); // repaint previously covered area.
- requestRedraw();
+ requestUpdateWindow(window, QWasmCompositor::ExposeEventDelivery);
}
void QWasmCompositor::raise(QWasmWindow *window)
@@ -181,16 +184,7 @@ void QWasmCompositor::setParent(QWasmWindow *window, QWasmWindow *parent)
{
m_compositedWindows[window].parentWindow = parent;
- requestRedraw();
-}
-
-void QWasmCompositor::flush(QWasmWindow *window, const QRegion &region)
-{
- QWasmCompositedWindow &compositedWindow = m_compositedWindows[window];
- compositedWindow.flushPending = true;
- compositedWindow.damage = region;
-
- requestRedraw();
+ requestUpdate();
}
int QWasmCompositor::windowCount() const
@@ -198,28 +192,6 @@ int QWasmCompositor::windowCount() const
return m_windowStack.count();
}
-
-void QWasmCompositor::redrawWindowContent()
-{
- // Redraw window content by sending expose events. This redraw
- // will cause a backing store flush, which will call requestRedraw()
- // to composit.
- for (QWasmWindow *platformWindow : m_windowStack) {
- QWindow *window = platformWindow->window();
- QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(
- window, QRect(QPoint(0, 0), window->geometry().size()));
- }
-}
-
-void QWasmCompositor::requestRedraw()
-{
- if (m_needComposit)
- return;
-
- m_needComposit = true;
- QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
-}
-
QWindow *QWasmCompositor::windowAt(QPoint globalPoint, int padding) const
{
int index = m_windowStack.count() - 1;
@@ -245,17 +217,6 @@ QWindow *QWasmCompositor::keyWindow() const
return m_windowStack.at(m_windowStack.count() - 1)->window();
}
-bool QWasmCompositor::event(QEvent *ev)
-{
- if (ev->type() == QEvent::UpdateRequest) {
- if (m_isEnabled)
- frame();
- return true;
- }
-
- return QObject::event(ev);
-}
-
void QWasmCompositor::blit(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QOpenGLTexture *texture, QRect targetGeometry)
{
QMatrix4x4 m;
@@ -366,6 +327,97 @@ QRect QWasmCompositor::titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::Su
return rect;
}
+void QWasmCompositor::requestUpdateAllWindows()
+{
+ m_requestUpdateAllWindows = true;
+ requestUpdate();
+}
+
+void QWasmCompositor::requestUpdateWindow(QWasmWindow *window, UpdateRequestDeliveryType updateType)
+{
+ auto it = m_requestUpdateWindows.find(window);
+ if (it == m_requestUpdateWindows.end()) {
+ m_requestUpdateWindows.insert(window, updateType);
+ } else {
+ // Already registered, but upgrade ExposeEventDeliveryType to UpdateRequestDeliveryType.
+ // if needed, to make sure QWindow::updateRequest's are matched.
+ if (it.value() == ExposeEventDelivery && updateType == UpdateRequestDelivery)
+ it.value() = UpdateRequestDelivery;
+ }
+
+ requestUpdate();
+}
+
+// Requests an upate/new frame using RequestAnimationFrame
+void QWasmCompositor::requestUpdate()
+{
+ if (m_requestAnimationFrameId != -1)
+ return;
+
+ static auto frame = [](double frameTime, void *context) -> int {
+ Q_UNUSED(frameTime);
+ QWasmCompositor *compositor = reinterpret_cast<QWasmCompositor *>(context);
+ compositor->m_requestAnimationFrameId = -1;
+ compositor->deliverUpdateRequests();
+ return 0;
+ };
+ m_requestAnimationFrameId = emscripten_request_animation_frame(frame, this);
+}
+
+void QWasmCompositor::deliverUpdateRequests()
+{
+ // We may get new update requests during the window content update below:
+ // prepare for recording the new update set by setting aside the current
+ // update set.
+ auto requestUpdateWindows = m_requestUpdateWindows;
+ m_requestUpdateWindows.clear();
+ bool requestUpdateAllWindows = m_requestUpdateAllWindows;
+ m_requestUpdateAllWindows = false;
+
+ // Update window content, either all windows or a spesific set of windows. Use the correct update
+ // type: QWindow subclasses expect that requested and delivered updateRequests matches exactly.
+ m_inDeliverUpdateRequest = true;
+ if (requestUpdateAllWindows) {
+ for (QWasmWindow *window : m_windowStack) {
+ auto it = requestUpdateWindows.find(window);
+ UpdateRequestDeliveryType updateType =
+ (it == m_requestUpdateWindows.end() ? ExposeEventDelivery : it.value());
+ deliverUpdateRequest(window, updateType);
+ }
+ } else {
+ for (auto it = requestUpdateWindows.constBegin(); it != requestUpdateWindows.constEnd(); ++it) {
+ auto *window = it.key();
+ UpdateRequestDeliveryType updateType = it.value();
+ deliverUpdateRequest(window, updateType);
+ }
+ }
+ m_inDeliverUpdateRequest = false;
+
+ // Compose window content
+ frame();
+}
+
+void QWasmCompositor::deliverUpdateRequest(QWasmWindow *window, UpdateRequestDeliveryType updateType)
+{
+ // update by deliverUpdateRequest and expose event accordingly.
+ if (updateType == UpdateRequestDelivery) {
+ window->QPlatformWindow::deliverUpdateRequest();
+ } else {
+ QWindow *qwindow = window->window();
+ QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(
+ qwindow, QRect(QPoint(0, 0), qwindow->geometry().size()));
+ }
+}
+
+void QWasmCompositor::handleBackingStoreFlush()
+{
+ // Request update to flush the updated backing store content,
+ // unless we are currently processing an update, in which case
+ // the new content will flushed as a part of that update.
+ if (!m_inDeliverUpdateRequest)
+ requestUpdate();
+}
+
int dpiScaled(qreal value)
{
return value * (qreal(qt_defaultDpiX()) / 96.0);
@@ -678,11 +730,6 @@ void QWasmCompositor::drawWindow(QOpenGLTextureBlitter *blitter, QWasmScreen *sc
void QWasmCompositor::frame()
{
- if (!m_needComposit)
- return;
-
- m_needComposit = false;
-
if (!m_isEnabled || m_windowStack.empty() || !screen())
return;
@@ -748,8 +795,7 @@ void QWasmCompositor::notifyTopWindowChanged(QWasmWindow *window)
return;
}
- requestRedraw();
-
+ requestUpdate();
}
QWasmScreen *QWasmCompositor::screen()
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h
index b579059344..1a51016c03 100644
--- a/src/plugins/platforms/wasm/qwasmcompositor.h
+++ b/src/plugins/platforms/wasm/qwasmcompositor.h
@@ -110,25 +110,24 @@ public:
void lower(QWasmWindow *window);
void setParent(QWasmWindow *window, QWasmWindow *parent);
- void flush(QWasmWindow *surface, const QRegion &region);
-
int windowCount() const;
- void redrawWindowContent();
- void requestRedraw();
-
QWindow *windowAt(QPoint globalPoint, int padding = 0) const;
QWindow *keyWindow() const;
- bool event(QEvent *event);
-
static QWasmTitleBarOptions makeTitleBarOptions(const QWasmWindow *window);
static QRect titlebarRect(QWasmTitleBarOptions tb, QWasmCompositor::SubControls subcontrol);
QWasmScreen *screen();
QOpenGLContext *context();
-private slots:
+ enum UpdateRequestDeliveryType { ExposeEventDelivery, UpdateRequestDelivery };
+ void requestUpdateAllWindows();
+ void requestUpdateWindow(QWasmWindow *window, UpdateRequestDeliveryType updateType = ExposeEventDelivery);
+ void requestUpdate();
+ void deliverUpdateRequests();
+ void deliverUpdateRequest(QWasmWindow *window, UpdateRequestDeliveryType updateType);
+ void handleBackingStoreFlush();
void frame();
private:
@@ -152,6 +151,10 @@ private:
bool m_isEnabled;
QSize m_targetSize;
qreal m_targetDevicePixelRatio;
+ QMap<QWasmWindow *, UpdateRequestDeliveryType> m_requestUpdateWindows;
+ bool m_requestUpdateAllWindows = false;
+ int m_requestAnimationFrameId = -1;
+ bool m_inDeliverUpdateRequest = false;
static QPalette makeWindowPalette();
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index 0b11415fd3..3cc067bbe7 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -216,7 +216,7 @@ void QWasmScreen::updateQScreenAndCanvasRenderSize()
QPoint position(rect["left"].as<int>() - offset.x(), rect["top"].as<int>() - offset.y());
setGeometry(QRect(position, cssSize.toSize()));
- m_compositor->redrawWindowContent();
+ m_compositor->requestUpdateAllWindows();
}
void QWasmScreen::canvasResizeObserverCallback(emscripten::val entries, emscripten::val)
diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp
index 9c5f1e4e74..3819e8daa6 100644
--- a/src/plugins/platforms/wasm/qwasmwindow.cpp
+++ b/src/plugins/platforms/wasm/qwasmwindow.cpp
@@ -111,8 +111,6 @@ void QWasmWindow::setGeometry(const QRect &rect)
}
QWindowSystemInterface::handleGeometryChange(window(), r);
QPlatformWindow::setGeometry(r);
-
- QWindowSystemInterface::flushWindowSystemEvents();
invalidate();
}
@@ -128,7 +126,6 @@ void QWasmWindow::setVisible(bool visible)
else if (m_windowState & Qt::WindowMaximized)
newGeom = platformScreen()->availableGeometry();
}
- QPlatformWindow::setVisible(visible);
m_compositor->setVisible(this, visible);
@@ -366,7 +363,7 @@ QRegion QWasmWindow::titleControlRegion() const
void QWasmWindow::invalidate()
{
- m_compositor->requestRedraw();
+ m_compositor->requestUpdateWindow(this);
}
QWasmCompositor::SubControls QWasmWindow::activeSubControl() const
@@ -397,6 +394,11 @@ qreal QWasmWindow::devicePixelRatio() const
void QWasmWindow::requestUpdate()
{
+ if (m_compositor) {
+ m_compositor->requestUpdateWindow(this, QWasmCompositor::UpdateRequestDelivery);
+ return;
+ }
+
static auto frame = [](double time, void *context) -> int {
Q_UNUSED(time);
QWasmWindow *window = static_cast<QWasmWindow *>(context);