From 846a4e1d792d8dd7836177b61ff5ffddc99d3d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Tue, 3 Mar 2015 09:43:30 +0100 Subject: [PATCH] [server] BufferInterface can resolve size through egl extension Uses eglQueryWaylandBufferWL (if available) to determine the size of the buffer. In order to do so, the server library links against egl (1) and one needs to register the EGLDisplay in Server::Display by the user of the library. For this a new method Display::setEglDisplay is added. 1: not using epoxy as it doesn't wrap the Wayland interfaces yet. --- src/wayland/CMakeLists.txt | 4 +++- src/wayland/display.cpp | 17 ++++++++++++++++ src/wayland/display.h | 17 ++++++++++++++++ src/wayland/server/buffer_interface.cpp | 27 +++++++++++++++++++++++++ src/wayland/server/buffer_interface.h | 4 +++- 5 files changed, 67 insertions(+), 2 deletions(-) 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;