diff --git a/src/client/protocols/wayland-eglstream-controller.xml b/src/client/protocols/wayland-eglstream-controller.xml new file mode 100644 --- /dev/null +++ b/src/client/protocols/wayland-eglstream-controller.xml @@ -0,0 +1,87 @@ + + + + Copyright (c) 2017-2018, 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. + + + + + + - dont_care: Using this enum will tell the server to make its own + decisions regarding present mode. + + - fifo: Tells the server to use a fifo present mode. The decision to + use fifo synchronous is left up to the server. + + - mailbox: Tells the server to use a mailbox present mode. + + + + + + + + + - present_mode: Must be one of wl_eglstream_controller_present_mode. Tells the + server the desired present mode that should be used. + + - fifo_length: Only valid when the present_mode attrib is provided and its + value is specified as fifo. Tells the server the desired fifo + length to be used when the desired present_mode is fifo. + + + + + + + + Creates the corresponding server side EGLStream from the given wl_buffer + and attaches a consumer to it. + + + + + + + + Creates the corresponding server side EGLStream from the given wl_buffer + and attaches a consumer to it using the given attributes. + + + + + + It contains key-value pairs compatible with intptr_t type. A key must + be one of wl_eglstream_controller_attrib enumeration values. What a value + represents is attribute-specific. + + + + + diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -58,6 +58,7 @@ xdgshell_v6_interface.cpp xdgshell_stable_interface.cpp xdgoutput_interface.cpp + eglstream_controller_interface.cpp ../compat/wayland-xdg-shell-v5-protocol.c ) @@ -202,6 +203,11 @@ BASENAME xdg-decoration ) +ecm_add_wayland_server_protocol(SERVER_LIB_SRCS + PROTOCOL ${KWayland_SOURCE_DIR}/src/client/protocols/wayland-eglstream-controller.xml + BASENAME eglstream-controller +) + set(SERVER_GENERATED_SRCS ${CMAKE_CURRENT_BINARY_DIR}/wayland-output-management-client-protocol.h ${CMAKE_CURRENT_BINARY_DIR}/wayland-output-management-server-protocol.h @@ -257,6 +263,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/wayland-output-unstable-v1-client-protocol.h ${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-decoration-server-protocol.h ${CMAKE_CURRENT_BINARY_DIR}/wayland-xdg-decoration-client-protocol.h + ${CMAKE_CURRENT_BINARY_DIR}/wayland-eglstream-controller-server-protocol.h ) set_source_files_properties(${SERVER_GENERATED_SRCS} PROPERTIES SKIP_AUTOMOC ON) @@ -303,6 +310,7 @@ datasource_interface.h display.h dpms_interface.h + eglstream_controller_interface.h filtered_display.h fakeinput_interface.h global.h diff --git a/src/server/display.h b/src/server/display.h --- a/src/server/display.h +++ b/src/server/display.h @@ -90,6 +90,7 @@ class PlasmaVirtualDesktopManagementInterface; class XdgOutputManagerInterface; class XdgDecorationManagerInterface; +class EglStreamControllerInterface; /** * @brief Class holding the Wayland server display loop. @@ -302,6 +303,14 @@ */ XdgDecorationManagerInterface *createXdgDecorationManager(XdgShellInterface *shellInterface, QObject *parent = nullptr); + /** + * Creates the EglStreamControllerInterface + * + * @return the created EGL Stream controller + * @since 5.58 + */ + EglStreamControllerInterface *createEglStreamControllerInterface(QObject *parent = nullptr); + /** * Gets the ClientConnection for the given @p client. * If there is no ClientConnection yet for the given @p client, it will be created. diff --git a/src/server/display.cpp b/src/server/display.cpp --- a/src/server/display.cpp +++ b/src/server/display.cpp @@ -55,6 +55,7 @@ #include "plasmavirtualdesktop_interface.h" #include "xdgoutput_interface.h" #include "xdgdecoration_interface.h" +#include "eglstream_controller_interface.h" #include #include @@ -514,6 +515,13 @@ return d; } +EglStreamControllerInterface *Display::createEglStreamControllerInterface(QObject *parent) +{ + EglStreamControllerInterface *e = new EglStreamControllerInterface(this, parent); + connect(this, &Display::aboutToTerminate, e, [e] { delete e; }); + return e; +} + void Display::createShm() { Q_ASSERT(d->display); diff --git a/src/server/eglstream_controller_interface.h b/src/server/eglstream_controller_interface.h new file mode 100644 --- /dev/null +++ b/src/server/eglstream_controller_interface.h @@ -0,0 +1,67 @@ +/**************************************************************************** +Copyright 2019 NVIDIA Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +****************************************************************************/ +#ifndef WAYLAND_SERVER_EGLSTREAM_CONTROLLER_INTERFACE_H +#define WAYLAND_SERVER_EGLSTREAM_CONTROLLER_INTERFACE_H + +#include "global.h" +#include "surface_interface.h" + +#include +#include +#include + +namespace KWayland +{ +namespace Server +{ + +class Display; + +/** + * @brief Represents the Global for the wl_eglstream_controller interface. + * + * This class handles requests (typically from the NVIDIA EGL driver) to attach + * a newly created EGL Stream to a Wayland surface, facilitating the sharing + * of buffer contents between client and compositor. + * + */ +class KWAYLANDSERVER_EXPORT EglStreamControllerInterface : public Global +{ + Q_OBJECT +public: + ~EglStreamControllerInterface() override; + void create(); + +Q_SIGNALS: + /** + * Emitted when a new stream attach request is received. + */ + void streamConsumerAttached(SurfaceInterface *surface, void *eglStream, wl_array *attribs); +private: + explicit EglStreamControllerInterface(Display *display, QObject *parent = nullptr); + + class Private; + friend class Display; +}; + +} +} + +#endif diff --git a/src/server/eglstream_controller_interface.cpp b/src/server/eglstream_controller_interface.cpp new file mode 100644 --- /dev/null +++ b/src/server/eglstream_controller_interface.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +Copyright 2019 NVIDIA Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +****************************************************************************/ +#include "eglstream_controller_interface_p.h" +#include "clientconnection.h" +#include "display.h" +#include "logging.h" + +#include +#include + +namespace KWayland +{ +namespace Server +{ + +const quint32 EglStreamControllerInterface::Private::s_version = 1; + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +const struct wl_eglstream_controller_interface EglStreamControllerInterface::Private::s_interface = { + attachStreamConsumer, + attachStreamConsumerAttribs +}; +#endif + +void EglStreamControllerInterface::Private::attachStreamConsumer(wl_client *client, + wl_resource *resource, + wl_resource *surface, + wl_resource *eglStream) +{ + wl_array noAttribs = { 0, 0, nullptr }; + attachStreamConsumerAttribs(client, resource, surface, eglStream, &noAttribs); +} + +void EglStreamControllerInterface::Private::attachStreamConsumerAttribs(wl_client *client, + wl_resource *resource, + wl_resource *surface, + wl_resource *eglStream, + wl_array *attribs) +{ + Q_UNUSED(client); + Private *p = reinterpret_cast(wl_resource_get_user_data(resource)); + emit p->q->streamConsumerAttached(SurfaceInterface::get(surface), eglStream, attribs); +} + +EglStreamControllerInterface::Private::Private(EglStreamControllerInterface *q, Display *display) + // libnvidia-egl-wayland.so.1 may not be present on all systems, so we load it dynamically + : Global::Private(display, + (wl_interface *)QLibrary::resolve(QLatin1String("libnvidia-egl-wayland.so.1"), + "wl_eglstream_controller_interface"), + s_version) + , q(q) +{ +} + +void EglStreamControllerInterface::Private::create() +{ + // bail out early if we were unable to load the interface + if (m_interface == nullptr) { + qCWarning(KWAYLAND_SERVER) << "failed to resolve wl_eglstream_controller_interface"; + return; + } + + Global::Private::create(); +} + +void EglStreamControllerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id) +{ + wl_resource *r = display->getConnection(client)->createResource(m_interface, version, id); + if (r == nullptr) { + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(r, &s_interface, this, nullptr); +} + +EglStreamControllerInterface::~EglStreamControllerInterface() = default; + +EglStreamControllerInterface::EglStreamControllerInterface(Display *display, QObject *parent) + : Global(new Private(this, display), parent) +{ +} + +void EglStreamControllerInterface::create() +{ + static_cast(*d).create(); +} + +} +} diff --git a/src/server/eglstream_controller_interface_p.h b/src/server/eglstream_controller_interface_p.h new file mode 100644 --- /dev/null +++ b/src/server/eglstream_controller_interface_p.h @@ -0,0 +1,58 @@ +/**************************************************************************** +Copyright 2019 NVIDIA Inc. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) version 3, or any +later version accepted by the membership of KDE e.V. (or its +successor approved by the membership of KDE e.V.), which shall +act as a proxy defined in Section 6 of version 3 of the license. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library. If not, see . +****************************************************************************/ +#ifndef WAYLAND_SERVER_EGLSTREAM_CONTROLLER_INTERFACE_P_H +#define WAYLAND_SERVER_EGLSTREAM_CONTROLLER_INTERFACE_P_H + +#include "eglstream_controller_interface.h" +#include "global_p.h" + +#include + +namespace KWayland +{ +namespace Server +{ + +class Q_DECL_HIDDEN EglStreamControllerInterface::Private : public Global::Private +{ +public: + Private(EglStreamControllerInterface *controller, Display *display); + void create(); + +private: + static void attachStreamConsumer(wl_client *client, + wl_resource *resource, + wl_resource *surface, + wl_resource *eglStream); + static void attachStreamConsumerAttribs(wl_client *client, + wl_resource *resource, + wl_resource *surface, + wl_resource *eglStream, + wl_array *attribs); + static const struct wl_eglstream_controller_interface s_interface; + static const quint32 s_version; + void bind(wl_client *client, uint32_t version, uint32_t id) override; + EglStreamControllerInterface *q; +}; + +} +} + +#endif