summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Varga <pvarga@inf.u-szeged.hu>2024-04-23 13:01:53 +0200
committerPeter Varga <pvarga@inf.u-szeged.hu>2024-04-25 08:38:21 +0200
commitb46f923e69454fa79d22a5c1c731baf0999e393c (patch)
tree3450500594ce9237f39e83031be01d607da4b94b
parentb5cfe6054e593beb2123d8de36f65b3b14e214ff (diff)
Fix IOSurface memory leak
IOSurface is reference counted by the OS. Chromium wraps it by gfx::ScopedIOSurface to handle reference counter implicitly. Calling gfx::ScopedIOSurface::release() doesn't decrement the counter just release the ownership, see //base/apple/scoped_typeref.h. Without ownership, gfx::ScopedIOSurface cannot decrement the counter at the end of the scope and IOSurface remains in the memory. As a fix, replace the release() call with get() and let the scoper handle the lifetime of the object. Also release MTLTexture during clean-up because it can also hold reference to the IOSurface. Fixes: QTBUG-124353 Pick-to: 6.7 Change-Id: Idf590b1e48f0c988de8fc71556e99a43749d52e5 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Anu Aliyas <anu.aliyas@qt.io>
-rw-r--r--src/core/compositor/native_skia_output_device_mac.mm9
-rw-r--r--src/core/compositor/native_skia_output_device_metal.cpp21
-rw-r--r--src/core/compositor/native_skia_output_device_metal.h3
-rw-r--r--src/core/compositor/native_skia_output_device_opengl.cpp2
4 files changed, 32 insertions, 3 deletions
diff --git a/src/core/compositor/native_skia_output_device_mac.mm b/src/core/compositor/native_skia_output_device_mac.mm
index fd3930a9f..bf21ef8d7 100644
--- a/src/core/compositor/native_skia_output_device_mac.mm
+++ b/src/core/compositor/native_skia_output_device_mac.mm
@@ -36,10 +36,17 @@ QSGTexture *makeMetalTexture(QQuickWindow *win, IOSurfaceRef ioSurface, uint ioS
QSGRendererInterface *ri = win->rendererInterface();
auto device = (__bridge id<MTLDevice>)(ri->getResource(win, QSGRendererInterface::DeviceResource));
- auto texture = [device newTextureWithDescriptor:desc iosurface:ioSurface plane:ioSurfacePlane];
+ id<MTLTexture> texture = [device newTextureWithDescriptor:desc
+ iosurface:ioSurface
+ plane:ioSurfacePlane];
return QNativeInterface::QSGMetalTexture::fromNative(texture, win, size, texOpts);
}
+void releaseMetalTexture(void *texture)
+{
+ [static_cast<id<MTLTexture>>(texture) release];
+}
+
#if QT_CONFIG(opengl)
uint32_t makeCGLTexture(QQuickWindow *win, IOSurfaceRef ioSurface, const QSize &size)
{
diff --git a/src/core/compositor/native_skia_output_device_metal.cpp b/src/core/compositor/native_skia_output_device_metal.cpp
index 95ed02779..a9d6e4fd5 100644
--- a/src/core/compositor/native_skia_output_device_metal.cpp
+++ b/src/core/compositor/native_skia_output_device_metal.cpp
@@ -4,6 +4,7 @@
#include "native_skia_output_device_metal.h"
#include <QtQuick/qquickwindow.h>
+#include <QtQuick/qsgtexture.h>
namespace QtWebEngineCore {
@@ -28,6 +29,7 @@ NativeSkiaOutputDeviceMetal::~NativeSkiaOutputDeviceMetal() { }
QSGTexture *makeMetalTexture(QQuickWindow *win, IOSurfaceRef ioSurface, uint ioSurfacePlane,
const QSize &size, QQuickWindow::CreateTextureOptions texOpts);
+void releaseMetalTexture(void *texture);
QSGTexture *NativeSkiaOutputDeviceMetal::texture(QQuickWindow *win, uint32_t textureOptions)
{
@@ -40,8 +42,25 @@ QSGTexture *NativeSkiaOutputDeviceMetal::texture(QQuickWindow *win, uint32_t tex
return nullptr;
}
+ // This is a workaround to not to release metal texture too early.
+ // In RHI, QMetalTexture wraps MTLTexture. QMetalTexture seems to be only destructed after the
+ // next MTLTexture is imported. The "old" MTLTexture can be still pontentially used by RHI
+ // while QMetalTexture is not destructed. Metal Validation Layer also warns about it.
+ // Delay releasing MTLTexture after the next one is presented.
+ if (m_currentMetalTexture) {
+ m_frontBuffer->textureCleanupCallback = [texture = m_currentMetalTexture]() {
+ releaseMetalTexture(texture);
+ };
+ m_currentMetalTexture = nullptr;
+ }
+
QQuickWindow::CreateTextureOptions texOpts(textureOptions);
- return makeMetalTexture(win, ioSurface.release(), /* plane */ 0, size(), texOpts);
+ QSGTexture *qsgTexture = makeMetalTexture(win, ioSurface.get(), /* plane */ 0, size(), texOpts);
+
+ auto ni = qsgTexture->nativeInterface<QNativeInterface::QSGMetalTexture>();
+ m_currentMetalTexture = ni->nativeTexture();
+
+ return qsgTexture;
}
} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_metal.h b/src/core/compositor/native_skia_output_device_metal.h
index e61665fb5..8e8d0fab8 100644
--- a/src/core/compositor/native_skia_output_device_metal.h
+++ b/src/core/compositor/native_skia_output_device_metal.h
@@ -21,6 +21,9 @@ public:
// Overridden from Compositor:
QSGTexture *texture(QQuickWindow *win, uint32_t textureOptions) override;
+
+private:
+ void *m_currentMetalTexture = nullptr;
};
} // namespace QtWebEngineCore
diff --git a/src/core/compositor/native_skia_output_device_opengl.cpp b/src/core/compositor/native_skia_output_device_opengl.cpp
index ea4c0c500..058573b9e 100644
--- a/src/core/compositor/native_skia_output_device_opengl.cpp
+++ b/src/core/compositor/native_skia_output_device_opengl.cpp
@@ -68,7 +68,7 @@ QSGTexture *NativeSkiaOutputDeviceOpenGL::texture(QQuickWindow *win, uint32_t te
// TODO: Add WGL support over ANGLE.
QT_NOT_YET_IMPLEMENTED
#elif defined(Q_OS_MACOS)
- uint32_t glTexture = makeCGLTexture(win, ioSurface.release(), size());
+ uint32_t glTexture = makeCGLTexture(win, ioSurface.get(), size());
texture = QNativeInterface::QSGOpenGLTexture::fromNative(glTexture, win, size(), texOpts);
m_frontBuffer->textureCleanupCallback = [glTexture]() {