Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qmetallayer.mm
Go to the documentation of this file.
1// Copyright (C) 2024 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
6#include <QtCore/qreadwritelock.h>
7#include <QtCore/qrect.h>
8
9using namespace std::chrono_literals;
10
12Q_LOGGING_CATEGORY(lcMetalLayer, "qt.gui.metal")
13QT_END_NAMESPACE
14
15QT_USE_NAMESPACE
16
17@implementation QMetalLayer
18{
19 std::unique_ptr<QReadWriteLock> m_displayLock;
20}
21
22- (instancetype)init
23{
24 if ((self = [super init])) {
25 m_displayLock.reset(new QReadWriteLock(QReadWriteLock::Recursive));
26 self.mainThreadPresentation = nil;
27 }
28
29 return self;
30}
31
32- (QReadWriteLock &)displayLock
33{
34 return *m_displayLock.get();
35}
36
37- (void)setNeedsDisplay
38{
39 [self setNeedsDisplayInRect:CGRectInfinite];
40}
41
42- (void)setNeedsDisplayInRect:(CGRect)rect
43{
44 if (!self.needsDisplay) {
45 // We lock for writing here, blocking in case a secondary thread is in
46 // the middle of presenting to the layer, as we want the main thread's
47 // display to happen after the secondary thread finishes presenting.
48 qCDebug(lcMetalLayer) << "Locking" << self << "for writing"
49 << "due to needing display in rect" << QRectF::fromCGRect(rect);
50
51 // For added safety, we use a 5 second timeout, and try to fail
52 // gracefully by not marking the layer as needing display, as
53 // doing so would lead us to unlock and unheld lock in displayLayer.
54 if (!self.displayLock.tryLockForWrite(5s)) {
55 qCWarning(lcMetalLayer) << "Timed out waiting for display lock";
56 return;
57 }
58 }
59
60 [super setNeedsDisplayInRect:rect];
61}
62
63- (id<CAMetalDrawable>)nextDrawable
64{
65 {
66 // Drop the presentation block early, so that if the main thread for
67 // some reason doesn't handle the presentation, the block won't hold on
68 // to a drawable unnecessarily.
69 QMacAutoReleasePool pool;
70 self.mainThreadPresentation = nil;
71 }
72
73 return [super nextDrawable];
74}
75
76@end
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")