1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "native_skia_output_device_metal.h"
#include <QtQuick/qquickwindow.h>
#include <QtQuick/qsgtexture.h>
namespace QtWebEngineCore {
NativeSkiaOutputDeviceMetal::NativeSkiaOutputDeviceMetal(
scoped_refptr<gpu::SharedContextState> contextState, bool requiresAlpha,
gpu::MemoryTracker *memoryTracker, viz::SkiaOutputSurfaceDependency *dependency,
gpu::SharedImageFactory *shared_image_factory,
gpu::SharedImageRepresentationFactory *shared_image_representation_factory,
DidSwapBufferCompleteCallback didSwapBufferCompleteCallback)
: NativeSkiaOutputDevice(contextState, requiresAlpha, memoryTracker, dependency,
shared_image_factory, shared_image_representation_factory,
didSwapBufferCompleteCallback)
{
SkColorType skColorType = kRGBA_8888_SkColorType;
capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBA_8888)] = skColorType;
capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::RGBX_8888)] = skColorType;
capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRA_8888)] = skColorType;
capabilities_.sk_color_types[static_cast<int>(gfx::BufferFormat::BGRX_8888)] = skColorType;
}
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)
{
if (!m_frontBuffer || !m_readyWithTexture)
return nullptr;
gfx::ScopedIOSurface ioSurface = m_frontBuffer->ioSurface();
if (!ioSurface) {
qWarning("No IOSurface.");
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);
QSGTexture *qsgTexture = makeMetalTexture(win, ioSurface.get(), /* plane */ 0, size(), texOpts);
auto ni = qsgTexture->nativeInterface<QNativeInterface::QSGMetalTexture>();
m_currentMetalTexture = ni->nativeTexture();
return qsgTexture;
}
} // namespace QtWebEngineCore
|