summaryrefslogtreecommitdiffstats
path: root/src/core/compositor/native_skia_output_device_metal.cpp
blob: a9d6e4fd53b1e0499cb963c5afc9638543d03a19 (plain)
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