Merge remote-tracking branch 'origin/5.12' into dev
Conflicts: .qmake.conf src/3rdparty/protocol/qt_attribution.json src/client/qwaylandintegration.cpp Change-Id: I475889f2817c7094b68a2948fdd34ddf8b0c486f
This commit is contained in:
commit
35463d211f
@ -154,5 +154,20 @@ Copyright © 2015, 2016 Jan Arne Petersen"
|
||||
"License": "MIT License",
|
||||
"LicenseFile": "MIT_LICENSE.txt",
|
||||
"Copyright": "Copyright © 2014, 2015 Collabora, Ltd."
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"Id": "wayland-eglstream-controller",
|
||||
"Name": "Wayland EGLStream Controller Protocol",
|
||||
"QDocModule": "qtwaylandcompositor",
|
||||
"QtUsage": "Used in the Qt Wayland Compositor",
|
||||
"Files": "wayland-eglstream-controller.xml",
|
||||
|
||||
"Description": "Allows clients to request that the compositor creates its EGLStream.",
|
||||
"Homepage": "https://github.com/NVIDIA/egl-wayland",
|
||||
"LicenseId": "MIT",
|
||||
"License": "MIT License",
|
||||
"LicenseFile": "MIT_LICENSE.txt",
|
||||
"Copyright": "Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved."
|
||||
}
|
||||
]
|
||||
|
37
src/3rdparty/wayland/protocols/wl-eglstream-controller.xml
vendored
Normal file
37
src/3rdparty/wayland/protocols/wl-eglstream-controller.xml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wl_eglstream_controller">
|
||||
<copyright>
|
||||
Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
<interface name="wl_eglstream_controller" version="1">
|
||||
<request name="attach_eglstream_consumer">
|
||||
<description summary="Create server stream and attach consumer">
|
||||
Creates the corresponding server side EGLStream from the given wl_buffer
|
||||
and attaches a consumer to it.
|
||||
</description>
|
||||
<arg name="wl_surface" type="object" interface="wl_surface"
|
||||
summary="wl_surface corresponds to the client surface associated with
|
||||
newly created eglstream"/>
|
||||
<arg name="wl_resource" type="object" interface="wl_buffer"
|
||||
summary="wl_resource corresponding to an EGLStream"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
@ -343,6 +343,7 @@ void QWaylandIntegration::initializeClientBufferIntegration()
|
||||
|
||||
if (targetKey.isEmpty()) {
|
||||
if (mDisplay->hardwareIntegration()
|
||||
&& mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("wayland-eglstream-controller")
|
||||
&& mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("linux-dmabuf-unstable-v1")) {
|
||||
targetKey = mDisplay->hardwareIntegration()->clientBufferIntegration();
|
||||
} else {
|
||||
|
@ -359,8 +359,6 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect)
|
||||
{
|
||||
if (!(mShellSurface && mShellSurface->handleExpose(rect)))
|
||||
QWindowSystemInterface::handleExposeEvent(window(), rect);
|
||||
else
|
||||
qCDebug(lcQpaWayland) << "sendExposeEvent: intercepted by shell extension, not sending";
|
||||
mLastExposeGeometry = rect;
|
||||
}
|
||||
|
||||
@ -549,11 +547,18 @@ void QWaylandWindow::handleScreenRemoved(QScreen *qScreen)
|
||||
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
|
||||
{
|
||||
Q_ASSERT(!buffer->committed());
|
||||
if (mFrameCallback) {
|
||||
wl_callback_destroy(mFrameCallback);
|
||||
mFrameCallback = nullptr;
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
handleUpdate();
|
||||
mFrameCallback = frame();
|
||||
wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this);
|
||||
mWaitingForFrameSync = true;
|
||||
buffer->setBusy();
|
||||
|
||||
QtWayland::wl_surface::attach(buffer->buffer(), x, y);
|
||||
attach(buffer->buffer(), x, y);
|
||||
} else {
|
||||
QtWayland::wl_surface::attach(nullptr, 0, 0);
|
||||
}
|
||||
@ -623,9 +628,11 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uin
|
||||
Q_UNUSED(callback);
|
||||
QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
|
||||
|
||||
self->mWaitingForFrameCallback = false;
|
||||
if (self->mUpdateRequested)
|
||||
self->mWaitingForFrameSync = false;
|
||||
if (self->mUpdateRequested) {
|
||||
self->mUpdateRequested = false;
|
||||
self->deliverUpdateRequest();
|
||||
}
|
||||
}
|
||||
|
||||
QMutex QWaylandWindow::mFrameSyncMutex;
|
||||
@ -633,10 +640,10 @@ QMutex QWaylandWindow::mFrameSyncMutex;
|
||||
void QWaylandWindow::waitForFrameSync()
|
||||
{
|
||||
QMutexLocker locker(&mFrameSyncMutex);
|
||||
if (!mWaitingForFrameCallback)
|
||||
if (!mWaitingForFrameSync)
|
||||
return;
|
||||
mDisplay->flushRequests();
|
||||
while (mWaitingForFrameCallback)
|
||||
while (mWaitingForFrameSync)
|
||||
mDisplay->blockingReadEvents();
|
||||
}
|
||||
|
||||
@ -1037,88 +1044,12 @@ QVariant QWaylandWindow::property(const QString &name, const QVariant &defaultVa
|
||||
return m_properties.value(name, defaultValue);
|
||||
}
|
||||
|
||||
void QWaylandWindow::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if (event->timerId() == mFallbackUpdateTimerId) {
|
||||
killTimer(mFallbackUpdateTimerId);
|
||||
mFallbackUpdateTimerId = -1;
|
||||
|
||||
if (!isExposed()) {
|
||||
qCDebug(lcWaylandBackingstore) << "Fallback update timer: Window not exposed,"
|
||||
<< "not delivering update request.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (mWaitingForUpdate && mUpdateRequested && !mWaitingForFrameCallback) {
|
||||
qCWarning(lcWaylandBackingstore) << "Delivering update request through fallback timer,"
|
||||
<< "may not be in sync with display";
|
||||
deliverUpdateRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QWaylandWindow::requestUpdate()
|
||||
{
|
||||
if (mUpdateRequested)
|
||||
return;
|
||||
|
||||
mUpdateRequested = true;
|
||||
|
||||
// If we have a frame callback all is good and will be taken care of there
|
||||
if (mWaitingForFrameCallback)
|
||||
return;
|
||||
|
||||
// If we've already called deliverUpdateRequest(), but haven't seen any attach+commit/swap yet
|
||||
if (mWaitingForUpdate) {
|
||||
// Ideally, we should just have returned here, but we're not guaranteed that the client
|
||||
// will actually update, so start this timer to deliver another request update after a while
|
||||
// *IF* the client doesn't update.
|
||||
int fallbackTimeout = 100;
|
||||
mFallbackUpdateTimerId = startTimer(fallbackTimeout);
|
||||
return;
|
||||
}
|
||||
|
||||
// Some applications (such as Qt Quick) depend on updates being delivered asynchronously,
|
||||
// so use invokeMethod to delay the delivery a bit.
|
||||
QMetaObject::invokeMethod(this, [this] {
|
||||
// Things might have changed in the meantime
|
||||
if (mUpdateRequested && !mWaitingForUpdate && !mWaitingForFrameCallback)
|
||||
deliverUpdateRequest();
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
// Should be called whenever we commit a buffer (directly through wl_surface.commit or indirectly
|
||||
// with eglSwapBuffers) to know when it's time to commit the next one.
|
||||
// Can be called from the render thread (without locking anything) so make sure to not make races in this method.
|
||||
void QWaylandWindow::handleUpdate()
|
||||
{
|
||||
// TODO: Should sync subsurfaces avoid requesting frame callbacks?
|
||||
|
||||
if (mFrameCallback) {
|
||||
wl_callback_destroy(mFrameCallback);
|
||||
mFrameCallback = nullptr;
|
||||
}
|
||||
|
||||
if (mFallbackUpdateTimerId != -1) {
|
||||
// Ideally, we would stop the fallback timer here, but since we're on another thread,
|
||||
// it's not allowed. Instead we set mFallbackUpdateTimer to -1 here, so we'll just
|
||||
// ignore it if it times out before it's cleaned up by the invokeMethod call.
|
||||
int id = mFallbackUpdateTimerId;
|
||||
mFallbackUpdateTimerId = -1;
|
||||
QMetaObject::invokeMethod(this, [=] { killTimer(id); }, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
mFrameCallback = frame();
|
||||
wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this);
|
||||
mWaitingForFrameCallback = true;
|
||||
mWaitingForUpdate = false;
|
||||
}
|
||||
|
||||
void QWaylandWindow::deliverUpdateRequest()
|
||||
{
|
||||
mUpdateRequested = false;
|
||||
mWaitingForUpdate = true;
|
||||
QPlatformWindow::deliverUpdateRequest();
|
||||
if (!mWaitingForFrameSync)
|
||||
QPlatformWindow::requestUpdate();
|
||||
else
|
||||
mUpdateRequested = true;
|
||||
}
|
||||
|
||||
void QWaylandWindow::addAttachOffset(const QPoint point)
|
||||
|
@ -193,10 +193,7 @@ public:
|
||||
|
||||
bool startSystemMove(const QPoint &pos) override;
|
||||
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
void requestUpdate() override;
|
||||
void handleUpdate();
|
||||
void deliverUpdateRequest() override;
|
||||
|
||||
public slots:
|
||||
void applyConfigure();
|
||||
@ -216,14 +213,10 @@ protected:
|
||||
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
|
||||
|
||||
WId mWindowId;
|
||||
bool mWaitingForFrameCallback = false;
|
||||
bool mWaitingForFrameSync = false;
|
||||
struct ::wl_callback *mFrameCallback = nullptr;
|
||||
QWaitCondition mFrameSyncWait;
|
||||
|
||||
// True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
|
||||
bool mWaitingForUpdate = false;
|
||||
int mFallbackUpdateTimerId = -1;
|
||||
|
||||
QMutex mResizeLock;
|
||||
bool mWaitingToApplyConfigure = false;
|
||||
bool mCanResize = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user