Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgraphicsframecapturemetal.mm
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <QtCore/qurl.h>
6#include "Metal/Metal.h"
7#include "qglobal.h"
8#include <QtGui/rhi/qrhi.h>
9#include <QtGui/rhi/qrhi_platform.h>
10
12
13Q_LOGGING_CATEGORY(lcGraphicsFrameCapture, "qt.gui.graphicsframecapture")
14
15#if __has_feature(objc_arc)
16#error ARC not supported
17#endif
18
19uint QGraphicsFrameCaptureMetal::frameNumber = 0;
20
22{
23 qputenv("METAL_CAPTURE_ENABLED", QByteArrayLiteral("1"));
24
25 m_captureDescriptor = [MTLCaptureDescriptor new];
26}
27
29{
30#if defined(Q_OS_MACOS) && QT_CONFIG(process)
31 if (m_process) {
32 m_process->terminate();
33 delete m_process;
34 }
35#endif
36 [m_captureDescriptor release];
37}
38
40{
41 if (!rhi)
42 return;
43
44 QRhi::Implementation backend = rhi->backend();
45 const QRhiNativeHandles *nh = rhi->nativeHandles();
46
47 switch (backend) {
49 const QRhiMetalNativeHandles *mtlnh = static_cast<const QRhiMetalNativeHandles *>(nh);
50 if (mtlnh->cmdQueue) {
51 m_captureDescriptor.captureObject = mtlnh->cmdQueue;
52 } else if (mtlnh->dev) {
53 m_captureDescriptor.captureObject = mtlnh->dev;
54 } else {
55 qCWarning(lcGraphicsFrameCapture) << "No valid Metal Device or Metal Command Queue found";
56 m_initialized = false;
57 return;
58 }
59 break;
60 }
61 default: {
62 qCWarning(lcGraphicsFrameCapture) << "Invalid handles were provided. MTLCaptureManager works only with Metal API";
63 m_initialized = false;
64 return;
65 break;
66 }
67 }
68
69 if (!m_captureManager) {
70 m_captureManager = MTLCaptureManager.sharedCaptureManager;
71 bool supportDocs = [m_captureManager supportsDestination:MTLCaptureDestinationGPUTraceDocument];
72 if (supportDocs) {
73 m_captureDescriptor.destination = MTLCaptureDestinationGPUTraceDocument;
74 m_initialized = true;
75 }
76 }
77}
78
80{
81 if (!initialized()) {
82 qCWarning(lcGraphicsFrameCapture) << "Capturing on Metal was not initialized. Starting capturing can not be done.";
83 return;
84 }
85
86 if (isCapturing()) {
87 qCWarning(lcGraphicsFrameCapture) << "A frame capture is already in progress,"
88 "will not initiate another one until QGraphicsFrameCapture::endCaptureFrame is called.";
89 return;
90 }
91
92 updateCaptureFileName();
93 NSError *error;
94 if (![m_captureManager startCaptureWithDescriptor:m_captureDescriptor error:&error]) {
95 QString errorMsg = QString::fromNSString(error.localizedDescription);
96 qCWarning(lcGraphicsFrameCapture, "Failed to start capture : %s", qPrintable(errorMsg));
97 }
98}
99
101{
102 if (!initialized()) {
103 qCWarning(lcGraphicsFrameCapture) << "Capturing on Metal was not initialized. End capturing can not be done.";
104 return;
105 }
106
107 if (!isCapturing()) {
108 qCWarning(lcGraphicsFrameCapture) << "A call to QGraphicsFrameCapture::endCaptureFrame can not be done"
109 " without a call to QGraphicsFrameCapture::startCaptureFrame";
110 return;
111 }
112
113 [m_captureManager stopCapture];
114 m_capturedFilesNames.append(QString::fromNSString(m_traceURL.path));
115 frameNumber++;
116}
117
119{
120 return m_initialized;
121}
122
124{
125 if (!initialized()) {
126 qCWarning(lcGraphicsFrameCapture) << "Capturing on Metal was not initialized. Can not query if capturing is in progress or not.";
127 return false;
128 }
129
130 return [m_captureManager isCapturing];
131}
132
134{
135#if defined(Q_OS_MACOS)
136#if !QT_CONFIG(process)
137 qFatal("QGraphicsFrameCapture requires QProcess on macOS");
138#else
139 if (!initialized()) {
140 qCWarning(lcGraphicsFrameCapture) << "Capturing on Metal was not initialized. Can not open XCode with a valid capture.";
141 return;
142 }
143
144 if (!m_process) {
145 m_process = new QProcess();
146 m_process->setProgram(QStringLiteral("xed"));
148 args.append(QUrl::fromNSURL(m_traceURL).toLocalFile());
149 m_process->setArguments(args);
150 }
151
152 m_process->kill();
153 m_process->start();
154#endif
155#endif
156}
157
158void QGraphicsFrameCaptureMetal::updateCaptureFileName()
159{
160 m_traceURL = QUrl::fromLocalFile(m_capturePath + "/" + m_capturePrefix + "_" + QString::number(frameNumber) + ".gputrace").toNSURL();
161 // We need to remove the trace file if it already existed else MTLCaptureManager
162 // will fail to.
163 if ([NSFileManager.defaultManager fileExistsAtPath:m_traceURL.path])
164 [NSFileManager.defaultManager removeItemAtURL:m_traceURL error:nil];
165
166 m_captureDescriptor.outputURL = m_traceURL;
167}
168
void append(parameter_type t)
Definition qlist.h:458
\inmodule QtRhi
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:1804
Implementation backend() const
Definition qrhi.cpp:8651
Implementation
Describes which graphics API-specific backend gets used by a QRhi instance.
Definition qrhi.h:1806
@ Metal
Definition qrhi.h:1811
const QRhiNativeHandles * nativeHandles()
Definition qrhi.cpp:10137
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition qurl.cpp:3368
Combined button and popup list for selecting options.
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
DBusConnection const char DBusError * error
#define qFatal
Definition qlogging.h:168
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
GLsizei const GLchar *const * path
static QString toLocalFile(const QString &url)
Definition qqmlfile.cpp:708
#define qPrintable(string)
Definition qstring.h:1531
#define QStringLiteral(str)
bool qputenv(const char *varName, QByteArrayView raw)
unsigned int uint
Definition qtypes.h:34
sem release()
QJSValueList args
\variable QRhiReadbackResult::completed
Definition qrhi.h:800