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