Merge remote-tracking branch 'origin/5.15.0' into 5.15

Change-Id: I7341fbfbe7c3eeae44a7fea0bf534fda1180ac51
This commit is contained in:
Qt Forward Merge Bot 2020-05-14 14:09:26 +02:00
commit e0a79f8b29
3 changed files with 35 additions and 36 deletions

View File

@ -233,13 +233,6 @@ QVariant QWaylandIntegration::styleHint(StyleHint hint) const
if (hint == ShowIsFullScreen && mDisplay->windowManagerIntegration()) if (hint == ShowIsFullScreen && mDisplay->windowManagerIntegration())
return mDisplay->windowManagerIntegration()->showIsFullScreen(); return mDisplay->windowManagerIntegration()->showIsFullScreen();
switch (hint) {
case QPlatformIntegration::FontSmoothingGamma:
return qreal(1.0);
default:
break;
}
return QPlatformIntegration::styleHint(hint); return QPlatformIntegration::styleHint(hint);
} }

View File

@ -79,6 +79,13 @@ QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
, mFrameQueue(mDisplay->createEventQueue()) , mFrameQueue(mDisplay->createEventQueue())
, mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP")) , mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP"))
{ {
{
bool ok;
int frameCallbackTimeout = qEnvironmentVariableIntValue("QT_WAYLAND_FRAME_CALLBACK_TIMEOUT", &ok);
if (ok)
mFrameCallbackTimeout = frameCallbackTimeout;
}
static WId id = 1; static WId id = 1;
mWindowId = id++; mWindowId = id++;
initializeWlSurface(); initializeWlSurface();
@ -244,6 +251,8 @@ void QWaylandWindow::reset(bool sendDestroyEvent)
mShellSurface = nullptr; mShellSurface = nullptr;
delete mSubSurfaceWindow; delete mSubSurfaceWindow;
mSubSurfaceWindow = nullptr; mSubSurfaceWindow = nullptr;
invalidateSurface();
if (mSurface) { if (mSurface) {
emit wlSurfaceDestroyed(); emit wlSurfaceDestroyed();
QWriteLocker lock(&mSurfaceLock); QWriteLocker lock(&mSurfaceLock);
@ -255,10 +264,7 @@ void QWaylandWindow::reset(bool sendDestroyEvent)
mFrameCallback = nullptr; mFrameCallback = nullptr;
} }
int timerId = mFrameCallbackTimerId.fetchAndStoreOrdered(-1); mFrameCallbackElapsedTimer.invalidate();
if (timerId != -1) {
killTimer(timerId);
}
mWaitingForFrameCallback = false; mWaitingForFrameCallback = false;
mFrameCallbackTimedOut = false; mFrameCallbackTimedOut = false;
@ -600,15 +606,11 @@ const wl_callback_listener QWaylandWindow::callbackListener = {
void QWaylandWindow::handleFrameCallback() void QWaylandWindow::handleFrameCallback()
{ {
// Stop the timer and stop waiting immediately
int timerId = mFrameCallbackTimerId.fetchAndStoreOrdered(-1);
mWaitingForFrameCallback = false; mWaitingForFrameCallback = false;
mFrameCallbackElapsedTimer.invalidate();
// The rest can wait until we can run it on the correct thread // The rest can wait until we can run it on the correct thread
auto doHandleExpose = [this, timerId]() { auto doHandleExpose = [this]() {
if (timerId != -1)
killTimer(timerId);
bool wasExposed = isExposed(); bool wasExposed = isExposed();
mFrameCallbackTimedOut = false; mFrameCallbackTimedOut = false;
if (!wasExposed && isExposed()) // Did setting mFrameCallbackTimedOut make the window exposed? if (!wasExposed && isExposed()) // Did setting mFrameCallbackTimedOut make the window exposed?
@ -643,13 +645,6 @@ bool QWaylandWindow::waitForFrameSync(int timeout)
sendExposeEvent(QRect()); sendExposeEvent(QRect());
} }
// Stop current frame timer if any, can't use killTimer directly, because we might be on a diffent thread
// Ordered semantics is needed to avoid stopping the timer twice and not miss it when it's
// started by other writes
int fcbId = mFrameCallbackTimerId.fetchAndStoreOrdered(-1);
if (fcbId != -1)
QMetaObject::invokeMethod(this, [this, fcbId] { killTimer(fcbId); }, Qt::QueuedConnection);
return !mWaitingForFrameCallback; return !mWaitingForFrameCallback;
} }
@ -1105,8 +1100,16 @@ QVariant QWaylandWindow::property(const QString &name, const QVariant &defaultVa
void QWaylandWindow::timerEvent(QTimerEvent *event) void QWaylandWindow::timerEvent(QTimerEvent *event)
{ {
if (mFrameCallbackTimerId.testAndSetOrdered(event->timerId(), -1)) { if (event->timerId() != mFrameCallbackCheckIntervalTimerId)
killTimer(event->timerId()); return;
bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout);
if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) {
killTimer(mFrameCallbackCheckIntervalTimerId);
mFrameCallbackCheckIntervalTimerId = -1;
}
if (mFrameCallbackElapsedTimer.isValid() && callbackTimerExpired) {
mFrameCallbackElapsedTimer.invalidate();
qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed";
mFrameCallbackTimedOut = true; mFrameCallbackTimedOut = true;
mWaitingForUpdate = false; mWaitingForUpdate = false;
@ -1160,16 +1163,16 @@ void QWaylandWindow::handleUpdate()
mWaitingForFrameCallback = true; mWaitingForFrameCallback = true;
mWaitingForUpdate = false; mWaitingForUpdate = false;
// Stop current frame timer if any, can't use killTimer directly, see comment above.
int fcbId = mFrameCallbackTimerId.fetchAndStoreOrdered(-1);
if (fcbId != -1)
QMetaObject::invokeMethod(this, [this, fcbId] { killTimer(fcbId); }, Qt::QueuedConnection);
// Start a timer for handling the case when the compositor stops sending frame callbacks. // Start a timer for handling the case when the compositor stops sending frame callbacks.
QMetaObject::invokeMethod(this, [this] { // Again; can't do it directly if (mFrameCallbackTimeout > 0) {
if (mWaitingForFrameCallback) QMetaObject::invokeMethod(this, [this] {
mFrameCallbackTimerId = startTimer(100); if (mWaitingForFrameCallback) {
}, Qt::QueuedConnection); if (mFrameCallbackCheckIntervalTimerId < 0)
mFrameCallbackCheckIntervalTimerId = startTimer(mFrameCallbackTimeout);
mFrameCallbackElapsedTimer.start();
}
}, Qt::QueuedConnection);
}
} }
void QWaylandWindow::deliverUpdateRequest() void QWaylandWindow::deliverUpdateRequest()

View File

@ -58,6 +58,7 @@
#include <QtGui/QIcon> #include <QtGui/QIcon>
#include <QtCore/QVariant> #include <QtCore/QVariant>
#include <QtCore/QLoggingCategory> #include <QtCore/QLoggingCategory>
#include <QtCore/QElapsedTimer>
#include <qpa/qplatformwindow.h> #include <qpa/qplatformwindow.h>
@ -225,7 +226,8 @@ protected:
WId mWindowId; WId mWindowId;
bool mWaitingForFrameCallback = false; bool mWaitingForFrameCallback = false;
bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
QAtomicInt mFrameCallbackTimerId = -1; // Started on commit, reset on frame callback int mFrameCallbackCheckIntervalTimerId = -1;
QElapsedTimer mFrameCallbackElapsedTimer;
struct ::wl_callback *mFrameCallback = nullptr; struct ::wl_callback *mFrameCallback = nullptr;
struct ::wl_event_queue *mFrameQueue = nullptr; struct ::wl_event_queue *mFrameQueue = nullptr;
QWaitCondition mFrameSyncWait; QWaitCondition mFrameSyncWait;
@ -238,6 +240,7 @@ protected:
bool mCanResize = true; bool mCanResize = true;
bool mResizeDirty = false; bool mResizeDirty = false;
bool mResizeAfterSwap; bool mResizeAfterSwap;
int mFrameCallbackTimeout = 100;
QVariantMap m_properties; QVariantMap m_properties;
bool mSentInitialResize = false; bool mSentInitialResize = false;