diff options
Diffstat (limited to 'src')
21 files changed, 159 insertions, 121 deletions
diff --git a/src/client/qwaylandclipboard.cpp b/src/client/qwaylandclipboard.cpp index 369c6ec07..81f48e05e 100644 --- a/src/client/qwaylandclipboard.cpp +++ b/src/client/qwaylandclipboard.cpp @@ -93,8 +93,10 @@ QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode) void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) { auto *seat = mDisplay->currentInputDevice(); - if (!seat) + if (!seat) { + qCWarning(lcQpaWayland) << "Can't set clipboard contents with no wl_seats available"; return; + } static const QString plain = QStringLiteral("text/plain"); static const QString utf8 = QStringLiteral("text/plain;charset=utf-8"); @@ -135,14 +137,20 @@ bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const bool QWaylandClipboard::ownsMode(QClipboard::Mode mode) const { - if (mode != QClipboard::Clipboard) + QWaylandInputDevice *seat = mDisplay->currentInputDevice(); + if (!seat) return false; - QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice(); - if (!inputDevice || !inputDevice->dataDevice()) + switch (mode) { + case QClipboard::Clipboard: + return seat->dataDevice() && seat->dataDevice()->selectionSource() != nullptr; +#if QT_CONFIG(wayland_client_primary_selection) + case QClipboard::Selection: + return seat->primarySelectionDevice() && seat->primarySelectionDevice()->selectionSource() != nullptr; +#endif + default: return false; - - return inputDevice->dataDevice()->selectionSource() != nullptr; + } } } diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp index fc3c7077a..f7d135e49 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp @@ -81,7 +81,14 @@ QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const void QWaylandDataDevice::invalidateSelectionOffer() { + if (m_selectionOffer.isNull()) + return; + m_selectionOffer.reset(); + +#if QT_CONFIG(clipboard) + QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard); +#endif } QWaylandDataSource *QWaylandDataDevice::selectionSource() const diff --git a/src/client/qwaylandprimaryselectionv1.cpp b/src/client/qwaylandprimaryselectionv1.cpp index 3ddf6dac3..832f96780 100644 --- a/src/client/qwaylandprimaryselectionv1.cpp +++ b/src/client/qwaylandprimaryselectionv1.cpp @@ -96,6 +96,15 @@ QWaylandPrimarySelectionDeviceV1::~QWaylandPrimarySelectionDeviceV1() destroy(); } +void QWaylandPrimarySelectionDeviceV1::invalidateSelectionOffer() +{ + if (!m_selectionOffer) + return; + + m_selectionOffer.reset(); + QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Selection); +} + void QWaylandPrimarySelectionDeviceV1::setSelectionSource(QWaylandPrimarySelectionSourceV1 *source) { if (source) { diff --git a/src/client/qwaylandprimaryselectionv1_p.h b/src/client/qwaylandprimaryselectionv1_p.h index b165c51b8..3f0a42a67 100644 --- a/src/client/qwaylandprimaryselectionv1_p.h +++ b/src/client/qwaylandprimaryselectionv1_p.h @@ -125,7 +125,7 @@ class QWaylandPrimarySelectionDeviceV1 : public QObject, public QtWayland::zwp_p public: ~QWaylandPrimarySelectionDeviceV1() override; QWaylandPrimarySelectionOfferV1 *selectionOffer() const { return m_selectionOffer.data(); } - void invalidateSelectionOffer() { m_selectionOffer.reset(); } + void invalidateSelectionOffer(); QWaylandPrimarySelectionSourceV1 *selectionSource() const { return m_selectionSource.data(); } void setSelectionSource(QWaylandPrimarySelectionSourceV1 *source); diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 2704705e7..bffb57015 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -1081,25 +1081,6 @@ QVariant QWaylandWindow::property(const QString &name, const QVariant &defaultVa void QWaylandWindow::timerEvent(QTimerEvent *event) { - if (event->timerId() == mFallbackUpdateTimerId) { - killTimer(mFallbackUpdateTimerId); - mFallbackUpdateTimerId = -1; - qCDebug(lcWaylandBackingstore) << "mFallbackUpdateTimer timed out"; - - if (!isExposed()) { - qCDebug(lcWaylandBackingstore) << "Fallback update timer: Window not exposed," - << "not delivering update request."; - return; - } - - if (mWaitingForUpdate && hasPendingUpdateRequest() && !mWaitingForFrameCallback) { - qCWarning(lcWaylandBackingstore) << "Delivering update request through fallback timer," - << "may not be in sync with display"; - deliverUpdateRequest(); - } - } - - if (mFrameCallbackTimerId.testAndSetOrdered(event->timerId(), -1)) { killTimer(event->timerId()); qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; @@ -1111,6 +1092,7 @@ void QWaylandWindow::timerEvent(QTimerEvent *event) void QWaylandWindow::requestUpdate() { + qCDebug(lcWaylandBackingstore) << "requestUpdate"; Q_ASSERT(hasPendingUpdateRequest()); // should be set by QPA // If we have a frame callback all is good and will be taken care of there @@ -1118,20 +1100,17 @@ void QWaylandWindow::requestUpdate() 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; - } + // This is a somewhat redundant behavior and might indicate a bug in the calling code, so log + // here so we can get this information when debugging update/frame callback issues. + // Continue as nothing happened, though. + if (mWaitingForUpdate) + qCDebug(lcWaylandBackingstore) << "requestUpdate called twice without committing anything"; // 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 (hasPendingUpdateRequest() && !mWaitingForUpdate && !mWaitingForFrameCallback) + if (hasPendingUpdateRequest() && !mWaitingForFrameCallback) deliverUpdateRequest(); }, Qt::QueuedConnection); } @@ -1141,6 +1120,7 @@ void QWaylandWindow::requestUpdate() // Can be called from the render thread (without locking anything) so make sure to not make races in this method. void QWaylandWindow::handleUpdate() { + qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread(); // TODO: Should sync subsurfaces avoid requesting frame callbacks? QReadLocker lock(&mSurfaceLock); if (!mSurface) @@ -1151,15 +1131,6 @@ void QWaylandWindow::handleUpdate() 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, [this, id] { killTimer(id); }, Qt::QueuedConnection); - } - mFrameCallback = mSurface->frame(); wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); mWaitingForFrameCallback = true; @@ -1179,6 +1150,7 @@ void QWaylandWindow::handleUpdate() void QWaylandWindow::deliverUpdateRequest() { + qCDebug(lcWaylandBackingstore) << "deliverUpdateRequest"; mWaitingForUpdate = true; QPlatformWindow::deliverUpdateRequest(); } diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 8d582eb7e..c488c2e3f 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -230,7 +230,6 @@ protected: // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer bool mWaitingForUpdate = false; - int mFallbackUpdateTimerId = -1; // Started when waiting for app to commit QMutex mResizeLock; bool mWaitingToApplyConfigure = false; diff --git a/src/client/qwaylandwindowmanagerintegration.cpp b/src/client/qwaylandwindowmanagerintegration.cpp index 17ae8a5ae..dd1acaf72 100644 --- a/src/client/qwaylandwindowmanagerintegration.cpp +++ b/src/client/qwaylandwindowmanagerintegration.cpp @@ -110,13 +110,17 @@ void QWaylandWindowManagerIntegration::windowmanager_quit() void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url) { Q_ASSERT(isInitialized()); - QByteArray data = url.toString().toUtf8(); + QString data = url.toString(); static const int chunkSize = 128; while (!data.isEmpty()) { - QByteArray chunk = data.left(chunkSize); + QString chunk = data.left(chunkSize); data = data.mid(chunkSize); - open_url(!data.isEmpty(), QString::fromUtf8(chunk)); + if (chunk.at(chunk.size() - 1).isHighSurrogate() && !data.isEmpty()) { + chunk.append(data.at(0)); + data = data.mid(1); + } + open_url(!data.isEmpty(), chunk); } } diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 471018ebd..ae0d793d3 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -366,8 +366,6 @@ void QWaylandCompositorPrivate::initializeHardwareIntegration() loadClientBufferIntegration(); loadServerBufferIntegration(); - if (client_buffer_integration) - client_buffer_integration->initializeHardware(display); if (server_buffer_integration) server_buffer_integration->initializeHardware(q); #endif @@ -399,12 +397,32 @@ void QWaylandCompositorPrivate::loadClientBufferIntegration() if (!targetKey.isEmpty()) { client_buffer_integration.reset(QtWayland::ClientBufferIntegrationFactory::create(targetKey, QStringList())); if (client_buffer_integration) { + qCDebug(qLcWaylandCompositorHardwareIntegration) << "Loaded client buffer integration:" << targetKey; client_buffer_integration->setCompositor(q); - if (hw_integration) - hw_integration->setClientBufferIntegration(targetKey); + if (!client_buffer_integration->initializeHardware(display)) { + qCWarning(qLcWaylandCompositorHardwareIntegration) + << "Failed to initialize hardware for client buffer integration:" << targetKey; + client_buffer_integration.reset(); + } + } else { + qCWarning(qLcWaylandCompositorHardwareIntegration) + << "Failed to load client buffer integration:" << targetKey; } } - //BUG: if there is no client buffer integration, bad things will happen when opengl is used + + if (!client_buffer_integration) { + qCWarning(qLcWaylandCompositorHardwareIntegration) + << "No client buffer integration was loaded, this means that clients will fall back" + << "to use CPU buffers (wl_shm) for transmitting buffers instead of using zero-copy" + << "GPU buffer handles. Expect serious performance impact with OpenGL clients due" + << "to potentially multiple copies between CPU and GPU memory per buffer.\n" + << "See the QtWayland readme for more info about how to build and configure Qt for" + << "your device."; + return; + } + + if (client_buffer_integration && hw_integration) + hw_integration->setClientBufferIntegration(targetKey); #endif } diff --git a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h index 0195f3d4b..2e962273f 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h +++ b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h @@ -64,7 +64,7 @@ public: void setCompositor(QWaylandCompositor *compositor) { m_compositor = compositor; } QWaylandCompositor *compositor() const { return m_compositor; } - virtual void initializeHardware(struct ::wl_display *display) = 0; + virtual bool initializeHardware(struct ::wl_display *display) = 0; virtual ClientBuffer *createBufferFor(struct ::wl_resource *buffer) = 0; diff --git a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp index de39ff1d2..8ddb4f951 100644 --- a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp +++ b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp @@ -67,46 +67,48 @@ BrcmEglIntegration::BrcmEglIntegration() { } -void BrcmEglIntegration::initializeHardware(struct ::wl_display *display) +bool BrcmEglIntegration::initializeHardware(struct ::wl_display *display) { Q_D(BrcmEglIntegration); QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - if (nativeInterface) { - d->egl_display = nativeInterface->nativeResourceForIntegration("EglDisplay"); - if (!d->egl_display) - qWarning("Failed to acquire EGL display from platform integration"); + if (!nativeInterface) + return false; - d->eglQueryGlobalImageBRCM = (PFNEGLQUERYGLOBALIMAGEBRCMPROC) eglGetProcAddress("eglQueryGlobalImageBRCM"); + d->egl_display = nativeInterface->nativeResourceForIntegration("EglDisplay"); + if (!d->egl_display) + qWarning("Failed to acquire EGL display from platform integration"); - if (!d->eglQueryGlobalImageBRCM) { - qWarning("Failed to resolve eglQueryGlobalImageBRCM"); - return; - } + d->eglQueryGlobalImageBRCM = (PFNEGLQUERYGLOBALIMAGEBRCMPROC) eglGetProcAddress("eglQueryGlobalImageBRCM"); - d->glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES"); + if (!d->eglQueryGlobalImageBRCM) { + qWarning("Failed to resolve eglQueryGlobalImageBRCM"); + return false; + } + + d->glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES"); - if (!d->glEGLImageTargetTexture2DOES) { - qWarning("Failed to resolve glEGLImageTargetTexture2DOES"); - return; - } + if (!d->glEGLImageTargetTexture2DOES) { + qWarning("Failed to resolve glEGLImageTargetTexture2DOES"); + return false; + } - d->eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR"); + d->eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR"); - if (!d->eglCreateImageKHR) { - qWarning("Failed to resolve eglCreateImageKHR"); - return; - } + if (!d->eglCreateImageKHR) { + qWarning("Failed to resolve eglCreateImageKHR"); + return false; + } - d->eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR"); + d->eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress("eglDestroyImageKHR"); - if (!d->eglDestroyImageKHR) { - qWarning("Failed to resolve eglDestroyImageKHR"); - return; - } - d->valid = true; - init(display, 1); + if (!d->eglDestroyImageKHR) { + qWarning("Failed to resolve eglDestroyImageKHR"); + return false; } + d->valid = true; + init(display, 1); + return true; } QtWayland::ClientBuffer *BrcmEglIntegration::createBufferFor(wl_resource *buffer) diff --git a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h index 3728da7bc..4bc98e8c5 100644 --- a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h +++ b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h @@ -47,7 +47,7 @@ class BrcmEglIntegration : public QtWayland::ClientBufferIntegration, public QtW public: BrcmEglIntegration(); - void initializeHardware(struct ::wl_display *display) override; + bool initializeHardware(struct ::wl_display *display) override; QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer) override; protected: diff --git a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp index 101e29891..4f01f855e 100644 --- a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp +++ b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.cpp @@ -275,7 +275,7 @@ LinuxDmabufClientBufferIntegration::~LinuxDmabufClientBufferIntegration() m_importedBuffers.clear(); } -void LinuxDmabufClientBufferIntegration::initializeHardware(struct ::wl_display *display) +bool LinuxDmabufClientBufferIntegration::initializeHardware(struct ::wl_display *display) { m_linuxDmabuf.reset(new LinuxDmabuf(display, this)); @@ -286,40 +286,40 @@ void LinuxDmabufClientBufferIntegration::initializeHardware(struct ::wl_display egl_query_dmabuf_formats_ext = reinterpret_cast<PFNEGLQUERYDMABUFFORMATSEXTPROC>(eglGetProcAddress("eglQueryDmaBufFormatsEXT")); if (!egl_query_dmabuf_modifiers_ext || !egl_query_dmabuf_formats_ext) { qCWarning(qLcWaylandCompositorHardwareIntegration) << "Failed to initialize EGL display. Could not find eglQueryDmaBufModifiersEXT and eglQueryDmaBufFormatsEXT."; - return; + return false; } egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL")); egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL")); if ((!egl_bind_wayland_display || !egl_unbind_wayland_display) && !ignoreBindDisplay) { qCWarning(qLcWaylandCompositorHardwareIntegration) << "Failed to initialize EGL display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL."; - return; + return false; } egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); if (!egl_create_image || !egl_destroy_image) { qCWarning(qLcWaylandCompositorHardwareIntegration) << "Failed to initialize EGL display. Could not find eglCreateImageKHR and eglDestroyImageKHR."; - return; + return false; } // initialize EGL display QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); if (!nativeInterface) { qCWarning(qLcWaylandCompositorHardwareIntegration) << "Failed to initialize EGL display. No native platform interface available."; - return; + return false; } m_eglDisplay = nativeInterface->nativeResourceForIntegration("EglDisplay"); if (!m_eglDisplay) { qCWarning(qLcWaylandCompositorHardwareIntegration) << "Failed to initialize EGL display. Could not get EglDisplay for window."; - return; + return false; } const char *extensionString = eglQueryString(m_eglDisplay, EGL_EXTENSIONS); if (!extensionString || !strstr(extensionString, "EGL_EXT_image_dma_buf_import")) { qCWarning(qLcWaylandCompositorHardwareIntegration) << "Failed to initialize EGL display. There is no EGL_EXT_image_dma_buf_import extension."; - return; + return false; } if (strstr(extensionString, "EGL_EXT_image_dma_buf_import_modifiers")) m_supportsDmabufModifiers = true; @@ -331,7 +331,7 @@ void LinuxDmabufClientBufferIntegration::initializeHardware(struct ::wl_display qCWarning(qLcWaylandCompositorHardwareIntegration) << "Could not bind Wayland display. Ignoring."; } else { qCWarning(qLcWaylandCompositorHardwareIntegration) << "Failed to initialize EGL display. Could not bind Wayland display."; - return; + return false; } } } @@ -342,6 +342,7 @@ void LinuxDmabufClientBufferIntegration::initializeHardware(struct ::wl_display modifiers[format] = supportedDrmModifiers(format); } m_linuxDmabuf->setSupportedModifiers(modifiers); + return true; } QVector<uint32_t> LinuxDmabufClientBufferIntegration::supportedDrmFormats() diff --git a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.h b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.h index cbbd4d9ba..8909fa89f 100644 --- a/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.h +++ b/src/hardwareintegration/compositor/linux-dmabuf-unstable-v1/linuxdmabufclientbufferintegration.h @@ -67,7 +67,7 @@ public: LinuxDmabufClientBufferIntegration(); ~LinuxDmabufClientBufferIntegration() override; - void initializeHardware(struct ::wl_display *display) override; + bool initializeHardware(struct ::wl_display *display) override; QtWayland::ClientBuffer *createBufferFor(wl_resource *resource) override; bool importBuffer(wl_resource *resource, LinuxDmabufWlBuffer *linuxDmabufBuffer); void removeBuffer(wl_resource *resource); diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp index cbbe397f8..fe35b92cd 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp @@ -393,7 +393,7 @@ WaylandEglClientBufferIntegration::~WaylandEglClientBufferIntegration() } } -void WaylandEglClientBufferIntegration::initializeHardware(struct wl_display *display) +bool WaylandEglClientBufferIntegration::initializeHardware(struct wl_display *display) { Q_D(WaylandEglClientBufferIntegration); @@ -402,39 +402,39 @@ void WaylandEglClientBufferIntegration::initializeHardware(struct wl_display *di QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); if (!nativeInterface) { qWarning("QtCompositor: Failed to initialize EGL display. No native platform interface available."); - return; + return false; } d->egl_display = nativeInterface->nativeResourceForIntegration("EglDisplay"); if (!d->egl_display) { qWarning("QtCompositor: Failed to initialize EGL display. Could not get EglDisplay for window."); - return; + return false; } const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS); if ((!extensionString || !strstr(extensionString, "EGL_WL_bind_wayland_display")) && !ignoreBindDisplay) { qWarning("QtCompositor: Failed to initialize EGL display. There is no EGL_WL_bind_wayland_display extension."); - return; + return false; } d->egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL")); d->egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL")); if ((!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display) && !ignoreBindDisplay) { qWarning("QtCompositor: Failed to initialize EGL display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL."); - return; + return false; } d->egl_query_wayland_buffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL_compat>(eglGetProcAddress("eglQueryWaylandBufferWL")); if (!d->egl_query_wayland_buffer) { qWarning("QtCompositor: Failed to initialize EGL display. Could not find eglQueryWaylandBufferWL."); - return; + return false; } d->egl_create_image = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); d->egl_destroy_image = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); if (!d->egl_create_image || !d->egl_destroy_image) { qWarning("QtCompositor: Failed to initialize EGL display. Could not find eglCreateImageKHR and eglDestroyImageKHR."); - return; + return false; } if (d->egl_bind_wayland_display && d->egl_unbind_wayland_display) { @@ -442,7 +442,7 @@ void WaylandEglClientBufferIntegration::initializeHardware(struct wl_display *di if (!d->display_bound) { if (!ignoreBindDisplay) { qWarning("QtCompositor: Failed to initialize EGL display. Could not bind Wayland display."); - return; + return false; } else { qWarning("QtCompositor: Could not bind Wayland display. Ignoring."); } @@ -454,6 +454,7 @@ void WaylandEglClientBufferIntegration::initializeHardware(struct wl_display *di d->funcs->initialize(d->egl_display); d->valid = true; + return true; } QtWayland::ClientBuffer *WaylandEglClientBufferIntegration::createBufferFor(wl_resource *buffer) diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h index bbc0eafef..3b9959e2f 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h @@ -45,7 +45,7 @@ public: WaylandEglClientBufferIntegration(); ~WaylandEglClientBufferIntegration() override; - void initializeHardware(struct ::wl_display *display) override; + bool initializeHardware(struct ::wl_display *display) override; QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer) override; diff --git a/src/hardwareintegration/compositor/wayland-eglstream-controller/waylandeglstreamintegration.cpp b/src/hardwareintegration/compositor/wayland-eglstream-controller/waylandeglstreamintegration.cpp index 8285e18d4..6c031aa89 100644 --- a/src/hardwareintegration/compositor/wayland-eglstream-controller/waylandeglstreamintegration.cpp +++ b/src/hardwareintegration/compositor/wayland-eglstream-controller/waylandeglstreamintegration.cpp @@ -298,7 +298,7 @@ void WaylandEglStreamClientBufferIntegration::attachEglStreamConsumer(struct ::w d->initEglStream(clientBuffer, wl_buffer); } -void WaylandEglStreamClientBufferIntegration::initializeHardware(struct wl_display *display) +bool WaylandEglStreamClientBufferIntegration::initializeHardware(struct wl_display *display) { Q_D(WaylandEglStreamClientBufferIntegration); @@ -307,32 +307,32 @@ void WaylandEglStreamClientBufferIntegration::initializeHardware(struct wl_displ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); if (!nativeInterface) { qWarning("QtCompositor: Failed to initialize EGL display. No native platform interface available."); - return; + return false; } d->egl_display = nativeInterface->nativeResourceForIntegration("EglDisplay"); if (!d->egl_display) { qWarning("QtCompositor: Failed to initialize EGL display. Could not get EglDisplay for window."); - return; + return false; } const char *extensionString = eglQueryString(d->egl_display, EGL_EXTENSIONS); if ((!extensionString || !strstr(extensionString, "EGL_WL_bind_wayland_display")) && !ignoreBindDisplay) { qWarning("QtCompositor: Failed to initialize EGL display. There is no EGL_WL_bind_wayland_display extension."); - return; + return false; } d->egl_bind_wayland_display = reinterpret_cast<PFNEGLBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglBindWaylandDisplayWL")); d->egl_unbind_wayland_display = reinterpret_cast<PFNEGLUNBINDWAYLANDDISPLAYWL>(eglGetProcAddress("eglUnbindWaylandDisplayWL")); if ((!d->egl_bind_wayland_display || !d->egl_unbind_wayland_display) && !ignoreBindDisplay) { qWarning("QtCompositor: Failed to initialize EGL display. Could not find eglBindWaylandDisplayWL and eglUnbindWaylandDisplayWL."); - return; + return false; } d->egl_query_wayland_buffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL_compat>(eglGetProcAddress("eglQueryWaylandBufferWL")); if (!d->egl_query_wayland_buffer) { qWarning("QtCompositor: Failed to initialize EGL display. Could not find eglQueryWaylandBufferWL."); - return; + return false; } if (d->egl_bind_wayland_display && d->egl_unbind_wayland_display) { @@ -340,7 +340,7 @@ void WaylandEglStreamClientBufferIntegration::initializeHardware(struct wl_displ if (!d->display_bound) { if (!ignoreBindDisplay) { qWarning("QtCompositor: Failed to initialize EGL display. Could not bind Wayland display."); - return; + return false; } else { qWarning("QtCompositor: Could not bind Wayland display. Ignoring."); } @@ -351,6 +351,12 @@ void WaylandEglStreamClientBufferIntegration::initializeHardware(struct wl_displ d->funcs = new QEGLStreamConvenience; d->funcs->initialize(d->egl_display); + if (!d->funcs->initialized) { + qWarning(qLcWaylandCompositorHardwareIntegration) << "Failed to initialize eglstreams API"; + return false; + } + + return true; } QtWayland::ClientBuffer *WaylandEglStreamClientBufferIntegration::createBufferFor(wl_resource *buffer) diff --git a/src/hardwareintegration/compositor/wayland-eglstream-controller/waylandeglstreamintegration.h b/src/hardwareintegration/compositor/wayland-eglstream-controller/waylandeglstreamintegration.h index 4c4cce257..35d2c80d3 100644 --- a/src/hardwareintegration/compositor/wayland-eglstream-controller/waylandeglstreamintegration.h +++ b/src/hardwareintegration/compositor/wayland-eglstream-controller/waylandeglstreamintegration.h @@ -44,7 +44,7 @@ public: WaylandEglStreamClientBufferIntegration(); ~WaylandEglStreamClientBufferIntegration() override; - void initializeHardware(struct ::wl_display *display) override; + bool initializeHardware(struct ::wl_display *display) override; QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer) override; diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp index 3cf51a8de..3c302c7f6 100644 --- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp +++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp @@ -62,20 +62,26 @@ XCompositeEglClientBufferIntegration::XCompositeEglClientBufferIntegration() } -void XCompositeEglClientBufferIntegration::initializeHardware(struct ::wl_display *) +bool XCompositeEglClientBufferIntegration::initializeHardware(struct ::wl_display *) { QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); if (nativeInterface) { mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForIntegration("Display")); - if (!mDisplay) - qFatal("could not retrieve Display from platform integration"); + if (!mDisplay) { + qCWarning(qLcWaylandCompositorHardwareIntegration) << "could not retrieve Display from platform integration"; + return false; + } mEglDisplay = static_cast<EGLDisplay>(nativeInterface->nativeResourceForIntegration("EGLDisplay")); - if (!mEglDisplay) - qFatal("could not retrieve EGLDisplay from platform integration"); + if (!mEglDisplay) { + qCWarning(qLcWaylandCompositorHardwareIntegration) << "could not retrieve EGLDisplay from platform integration"; + return false; + } } else { - qFatal("Platform integration doesn't have native interface"); + qCWarning(qLcWaylandCompositorHardwareIntegration) << "Platform integration doesn't have native interface"; + return false; } new XCompositeHandler(m_compositor, mDisplay); + return true; } QtWayland::ClientBuffer *XCompositeEglClientBufferIntegration::createBufferFor(wl_resource *buffer) diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h index 80ce88b5f..2c3116df1 100644 --- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h +++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h @@ -45,7 +45,7 @@ class XCompositeEglClientBufferIntegration : public QtWayland::ClientBufferInteg public: XCompositeEglClientBufferIntegration(); - void initializeHardware(struct ::wl_display *display) override; + bool initializeHardware(struct ::wl_display *display) override; QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer) override; inline Display *xDisplay() const { return mDisplay; } inline EGLDisplay eglDisplay() const { return mEglDisplay; } diff --git a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp index 3c8fc9d04..db4390252 100644 --- a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp +++ b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp @@ -70,16 +70,19 @@ XCompositeGLXClientBufferIntegration::~XCompositeGLXClientBufferIntegration() delete mHandler; } -void XCompositeGLXClientBufferIntegration::initializeHardware(struct ::wl_display *) +bool XCompositeGLXClientBufferIntegration::initializeHardware(struct ::wl_display *) { qDebug() << "Initializing GLX integration"; QPlatformNativeInterface *nativeInterface = QGuiApplicationPrivate::platformIntegration()->nativeInterface(); if (nativeInterface) { mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForIntegration("Display")); - if (!mDisplay) - qFatal("could not retrieve Display from platform integration"); + if (!mDisplay) { + qCWarning(qLcWaylandCompositorHardwareIntegration) << "could not retrieve Display from platform integration"; + return false; + } } else { - qFatal("Platform integration doesn't have native interface"); + qCWarning(qLcWaylandCompositorHardwareIntegration) << "Platform integration doesn't have native interface"; + return false; } mScreen = XDefaultScreen(mDisplay); @@ -90,7 +93,8 @@ void XCompositeGLXClientBufferIntegration::initializeHardware(struct ::wl_displa m_glxBindTexImageEXT = reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(glContext->getProcAddress("glXBindTexImageEXT")); if (!m_glxBindTexImageEXT) { - qDebug() << "Did not find glxBindTexImageExt, everything will FAIL!"; + qCWarning(qLcWaylandCompositorHardwareIntegration) << "Did not find glxBindTexImageExt, everything will FAIL!"; + return false; } m_glxReleaseTexImageEXT = reinterpret_cast<PFNGLXRELEASETEXIMAGEEXTPROC>(glContext->getProcAddress("glXReleaseTexImageEXT")); if (!m_glxReleaseTexImageEXT) { @@ -98,6 +102,7 @@ void XCompositeGLXClientBufferIntegration::initializeHardware(struct ::wl_displa } delete glContext; + return true; } QtWayland::ClientBuffer *XCompositeGLXClientBufferIntegration::createBufferFor(wl_resource *buffer) diff --git a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h index e783d41bf..6763d5916 100644 --- a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h +++ b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h @@ -48,7 +48,7 @@ public: XCompositeGLXClientBufferIntegration(); ~XCompositeGLXClientBufferIntegration() override; - void initializeHardware(struct ::wl_display *display) override; + bool initializeHardware(struct ::wl_display *display) override; QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer) override; inline Display *xDisplay() const { return mDisplay; } |