diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 989c64f656..0360eb1f0a 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -35,7 +35,9 @@ target_include_directories(KF5WaylandServer INTERFACE "$. #include +#include + namespace KWayland { namespace Server @@ -53,6 +55,7 @@ public: bool running = false; QList outputs; QVector clients; + EGLDisplay eglDisplay = EGL_NO_DISPLAY; private: Display *q; @@ -294,5 +297,19 @@ ClientConnection *Display::createClient(int fd) return getConnection(c); } +void Display::setEglDisplay(void *display) +{ + if (d->eglDisplay != EGL_NO_DISPLAY) { + qCWarning(KWAYLAND_SERVER) << "EGLDisplay cannot be changed"; + return; + } + d->eglDisplay = (EGLDisplay)display; +} + +void *Display::eglDisplay() const +{ + return d->eglDisplay; +} + } } diff --git a/src/wayland/display.h b/src/wayland/display.h index f115229fde..4c92d5d568 100644 --- a/src/wayland/display.h +++ b/src/wayland/display.h @@ -123,6 +123,23 @@ public: ClientConnection *getConnection(wl_client *client); QVector connections() const; + /** + * Set the EGL @p display for this Wayland display. + * The EGLDisplay can only be set once and must be alive as long as the Wayland display + * is alive. The user should have set up the binding between the EGLDisplay and the + * Wayland display prior to calling this method. + * + * @see eglDisplay + * @since 5.3 + **/ + void setEglDisplay(void *display); + /** + * @returns the EGLDisplay used for this Wayland display or EGL_NO_DISPLAY if not set. + * @see setEglDisplay + * @since 5.3 + **/ + void *eglDisplay() const; + Q_SIGNALS: void socketNameChanged(const QString&); void runningChanged(bool); diff --git a/src/wayland/server/buffer_interface.cpp b/src/wayland/server/buffer_interface.cpp index bdd679dd7c..621605edb9 100644 --- a/src/wayland/server/buffer_interface.cpp +++ b/src/wayland/server/buffer_interface.cpp @@ -18,15 +18,25 @@ You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . *********************************************************************/ #include "buffer_interface.h" +#include "display.h" #include "surface_interface.h" // Wayland #include +// EGL +#include +#include namespace KWayland { namespace Server { +namespace EGL +{ +typedef GLboolean(*eglQueryWaylandBufferWL_func)(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +eglQueryWaylandBufferWL_func eglQueryWaylandBufferWL = nullptr; +} + class BufferInterface::Private { public: @@ -89,6 +99,23 @@ BufferInterface::Private::Private(BufferInterface *q, wl_resource *resource, Sur wl_resource_add_destroy_listener(resource, &listener); if (shmBuffer) { size = QSize(wl_shm_buffer_get_width(shmBuffer), wl_shm_buffer_get_height(shmBuffer)); + } else if (parent) { + EGLDisplay eglDisplay = parent->global()->display()->eglDisplay(); + static bool resolved = false; + using namespace EGL; + if (!resolved && eglDisplay != EGL_NO_DISPLAY) { + eglQueryWaylandBufferWL = (eglQueryWaylandBufferWL_func)eglGetProcAddress("eglQueryWaylandBufferWL"); + resolved = true; + } + if (eglQueryWaylandBufferWL) { + EGLint width, height; + bool valid = false; + valid = eglQueryWaylandBufferWL(eglDisplay, buffer, EGL_WIDTH, &width); + valid = valid && eglQueryWaylandBufferWL(eglDisplay, buffer, EGL_HEIGHT, &height); + if (valid) { + size = QSize(width, height); + } + } } } diff --git a/src/wayland/server/buffer_interface.h b/src/wayland/server/buffer_interface.h index c200d9b851..8b0ba544a0 100644 --- a/src/wayland/server/buffer_interface.h +++ b/src/wayland/server/buffer_interface.h @@ -73,9 +73,11 @@ public: /** * Returns the size of this BufferInterface. * Note: only for shared memory buffers (shmBuffer) the size can be derived, - * for other buffers the user of the BufferInterface has to use setSize to + * for other buffers it might be possible to derive the size if an EGL display + * is set on Display otherwise the user of the BufferInterface has to use setSize to * provide the proper size. * @see setSize + * @see Display::setEglDisplay * @since 5.3 **/ QSize size() const;