From 154bdf45dd51a521058c820e7b871008ce8508ae Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Thu, 14 Dec 2017 17:40:43 +0100 Subject: Fix for big memory leak in Qt based compositors The system would leak a complete buffer every time the client attached a new Wayland buffer. For QML applications this will normally happen every time a new animation is started. Change-Id: Ie4981ccbb2e09d702ee291f1144e3b8aa84c0d1d Reviewed-by: Paul Olav Tvete --- .../waylandeglclientbufferintegration.cpp | 29 +++++++++++++++++++++- .../waylandeglclientbufferintegration.h | 3 +++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp index 453800c18..f5e63aec5 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp @@ -198,10 +198,14 @@ public: QEGLStreamConvenience *funcs; static WaylandEglClientBufferIntegrationPrivate *get(WaylandEglClientBufferIntegration *integration) { - return integration->d_ptr.data(); + return shuttingDown ? nullptr : integration->d_ptr.data(); } + + static bool shuttingDown; }; +bool WaylandEglClientBufferIntegrationPrivate::shuttingDown = false; + BufferState::BufferState() : egl_format(EGL_TEXTURE_RGBA) , egl_stream(EGL_NO_STREAM_KHR) @@ -395,6 +399,11 @@ WaylandEglClientBufferIntegration::WaylandEglClientBufferIntegration() { } +WaylandEglClientBufferIntegration::~WaylandEglClientBufferIntegration() +{ + WaylandEglClientBufferIntegrationPrivate::shuttingDown = true; +} + void WaylandEglClientBufferIntegration::initializeHardware(struct wl_display *display) { Q_D(WaylandEglClientBufferIntegration); @@ -480,6 +489,24 @@ WaylandEglClientBuffer::WaylandEglClientBuffer(WaylandEglClientBufferIntegration } } + +WaylandEglClientBuffer::~WaylandEglClientBuffer() +{ + auto *p = WaylandEglClientBufferIntegrationPrivate::get(m_integration); + + if (p) { + for (auto image : d->egl_images) + p->egl_destroy_image(p->egl_display, image); + + if (d->egl_stream) + p->funcs->destroy_stream(p->egl_display, d->egl_stream); + + for (auto *texture : d->textures) + delete texture; + } + delete d; +} + static QWaylandBufferRef::BufferFormatEgl formatFromEglFormat(EGLint format) { switch (format) { case EGL_TEXTURE_RGB: diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h index 5217039d8..60ce814de 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h @@ -53,6 +53,7 @@ class WaylandEglClientBufferIntegration : public QtWayland::ClientBufferIntegrat Q_DECLARE_PRIVATE(WaylandEglClientBufferIntegration) public: WaylandEglClientBufferIntegration(); + ~WaylandEglClientBufferIntegration(); void initializeHardware(struct ::wl_display *display) override; @@ -68,6 +69,8 @@ struct BufferState; class WaylandEglClientBuffer : public QtWayland::ClientBuffer { public: + ~WaylandEglClientBuffer(); + QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const override; QSize size() const override; QWaylandSurface::Origin origin() const override; -- cgit v1.2.3