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",
|
"License": "MIT License",
|
||||||
"LicenseFile": "MIT_LICENSE.txt",
|
"LicenseFile": "MIT_LICENSE.txt",
|
||||||
"Copyright": "Copyright © 2014, 2015 Collabora, Ltd."
|
"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 (targetKey.isEmpty()) {
|
||||||
if (mDisplay->hardwareIntegration()
|
if (mDisplay->hardwareIntegration()
|
||||||
|
&& mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("wayland-eglstream-controller")
|
||||||
&& mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("linux-dmabuf-unstable-v1")) {
|
&& mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("linux-dmabuf-unstable-v1")) {
|
||||||
targetKey = mDisplay->hardwareIntegration()->clientBufferIntegration();
|
targetKey = mDisplay->hardwareIntegration()->clientBufferIntegration();
|
||||||
} else {
|
} else {
|
||||||
|
@ -359,8 +359,6 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect)
|
|||||||
{
|
{
|
||||||
if (!(mShellSurface && mShellSurface->handleExpose(rect)))
|
if (!(mShellSurface && mShellSurface->handleExpose(rect)))
|
||||||
QWindowSystemInterface::handleExposeEvent(window(), rect);
|
QWindowSystemInterface::handleExposeEvent(window(), rect);
|
||||||
else
|
|
||||||
qCDebug(lcQpaWayland) << "sendExposeEvent: intercepted by shell extension, not sending";
|
|
||||||
mLastExposeGeometry = rect;
|
mLastExposeGeometry = rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,11 +547,18 @@ void QWaylandWindow::handleScreenRemoved(QScreen *qScreen)
|
|||||||
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
|
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!buffer->committed());
|
Q_ASSERT(!buffer->committed());
|
||||||
|
if (mFrameCallback) {
|
||||||
|
wl_callback_destroy(mFrameCallback);
|
||||||
|
mFrameCallback = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
handleUpdate();
|
mFrameCallback = frame();
|
||||||
|
wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this);
|
||||||
|
mWaitingForFrameSync = true;
|
||||||
buffer->setBusy();
|
buffer->setBusy();
|
||||||
|
|
||||||
QtWayland::wl_surface::attach(buffer->buffer(), x, y);
|
attach(buffer->buffer(), x, y);
|
||||||
} else {
|
} else {
|
||||||
QtWayland::wl_surface::attach(nullptr, 0, 0);
|
QtWayland::wl_surface::attach(nullptr, 0, 0);
|
||||||
}
|
}
|
||||||
@ -623,9 +628,11 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uin
|
|||||||
Q_UNUSED(callback);
|
Q_UNUSED(callback);
|
||||||
QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
|
QWaylandWindow *self = static_cast<QWaylandWindow*>(data);
|
||||||
|
|
||||||
self->mWaitingForFrameCallback = false;
|
self->mWaitingForFrameSync = false;
|
||||||
if (self->mUpdateRequested)
|
if (self->mUpdateRequested) {
|
||||||
|
self->mUpdateRequested = false;
|
||||||
self->deliverUpdateRequest();
|
self->deliverUpdateRequest();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutex QWaylandWindow::mFrameSyncMutex;
|
QMutex QWaylandWindow::mFrameSyncMutex;
|
||||||
@ -633,10 +640,10 @@ QMutex QWaylandWindow::mFrameSyncMutex;
|
|||||||
void QWaylandWindow::waitForFrameSync()
|
void QWaylandWindow::waitForFrameSync()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mFrameSyncMutex);
|
QMutexLocker locker(&mFrameSyncMutex);
|
||||||
if (!mWaitingForFrameCallback)
|
if (!mWaitingForFrameSync)
|
||||||
return;
|
return;
|
||||||
mDisplay->flushRequests();
|
mDisplay->flushRequests();
|
||||||
while (mWaitingForFrameCallback)
|
while (mWaitingForFrameSync)
|
||||||
mDisplay->blockingReadEvents();
|
mDisplay->blockingReadEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1037,88 +1044,12 @@ QVariant QWaylandWindow::property(const QString &name, const QVariant &defaultVa
|
|||||||
return m_properties.value(name, defaultValue);
|
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()
|
void QWaylandWindow::requestUpdate()
|
||||||
{
|
{
|
||||||
if (mUpdateRequested)
|
if (!mWaitingForFrameSync)
|
||||||
return;
|
QPlatformWindow::requestUpdate();
|
||||||
|
else
|
||||||
mUpdateRequested = true;
|
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandWindow::addAttachOffset(const QPoint point)
|
void QWaylandWindow::addAttachOffset(const QPoint point)
|
||||||
|
@ -193,10 +193,7 @@ public:
|
|||||||
|
|
||||||
bool startSystemMove(const QPoint &pos) override;
|
bool startSystemMove(const QPoint &pos) override;
|
||||||
|
|
||||||
void timerEvent(QTimerEvent *event) override;
|
|
||||||
void requestUpdate() override;
|
void requestUpdate() override;
|
||||||
void handleUpdate();
|
|
||||||
void deliverUpdateRequest() override;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void applyConfigure();
|
void applyConfigure();
|
||||||
@ -216,14 +213,10 @@ protected:
|
|||||||
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
|
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
|
||||||
|
|
||||||
WId mWindowId;
|
WId mWindowId;
|
||||||
bool mWaitingForFrameCallback = false;
|
bool mWaitingForFrameSync = false;
|
||||||
struct ::wl_callback *mFrameCallback = nullptr;
|
struct ::wl_callback *mFrameCallback = nullptr;
|
||||||
QWaitCondition mFrameSyncWait;
|
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;
|
QMutex mResizeLock;
|
||||||
bool mWaitingToApplyConfigure = false;
|
bool mWaitingToApplyConfigure = false;
|
||||||
bool mCanResize = true;
|
bool mCanResize = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user