summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2018-04-04 12:48:39 +0200
committerMorten Johan Sørvig <morten.sorvig@qt.io>2018-04-12 12:14:18 +0000
commit0300886c134799c7b3d1331f99cb6777ad568ba8 (patch)
tree6dc5f50b70340a8bfd32036b1058c529a6c3d6c2
parent5c63e6fd7541609c3fadb694c071b42e93b7acf5 (diff)
Cocoa: Add QNSView Metal Layer support
Make sure the layer is updated on window resize and screen change. Add a support test and print a warning if we try to create a Metal layer without Metal system support. This test should ideally be done earlier, before configuring the QWindow to use Metal. Link against the Metal framework: The minimum deployment target is already 10.11 so this does not add additional deployment requirements. Change-Id: I0a38e824d0b6042bb52520dfaf0958ce21bb40b8 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h1
-rw-r--r--src/plugins/platforms/cocoa/qnsview_drawing.mm60
3 files changed, 60 insertions, 3 deletions
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index 2694cb3607..596b6d8b7f 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -78,7 +78,7 @@ qtConfig(opengl.*) {
RESOURCES += qcocoaresources.qrc
-LIBS += -framework AppKit -framework Carbon -framework IOKit -framework QuartzCore -lcups
+LIBS += -framework AppKit -framework Carbon -framework IOKit -framework QuartzCore -framework Metal -lcups
QT += \
core-private gui-private \
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 100f96d27a..ba696f4b5f 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -41,6 +41,7 @@
#define QNSVIEW_H
#include <AppKit/AppKit.h>
+#include <MetalKit/MetalKit.h>
#include "private/qcore_mac_p.h"
diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm
index 27224473f1..d2c204deb4 100644
--- a/src/plugins/platforms/cocoa/qnsview_drawing.mm
+++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm
@@ -148,6 +148,53 @@
"_q_mac_wantsLayer", "QT_MAC_WANTS_LAYER");
}
+- (CALayer *)makeBackingLayer
+{
+ bool makeMetalLayer = false; // TODO: Add/implement enabling API
+ if (makeMetalLayer) {
+ // Check if Metal is supported. If it isn't then it's most likely
+ // too late at this point and the QWindow will be non-functional,
+ // but we can at least print a warning.
+ if (![MTLCreateSystemDefaultDevice() autorelease]) {
+ qWarning() << "QWindow initialization error: Metal is not supported";
+ return [super makeBackingLayer];
+ }
+
+ CAMetalLayer *layer = [CAMetalLayer layer];
+
+ // Set the contentsScale for the layer. This is normally done in
+ // viewDidChangeBackingProperties, however on startup that function
+ // is called before the layer is created here. The layer's drawableSize
+ // is updated from layoutSublayersOfLayer as usual.
+ layer.contentsScale = self.window.backingScaleFactor;
+
+ return layer;
+ }
+
+ return [super makeBackingLayer];
+}
+
+- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy
+{
+ // We need to set this this excplicitly since the super implementation
+ // returns LayerContentsRedrawNever for custom layers like CAMetalLayer.
+ return NSViewLayerContentsRedrawDuringViewResize;
+}
+
+- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
+{
+ CGSize drawableSize = layer.bounds.size;
+ drawableSize.width *= layer.contentsScale;
+ drawableSize.height *= layer.contentsScale;
+ layer.drawableSize = drawableSize;
+}
+
+- (void)layoutSublayersOfLayer:(CALayer *)layer
+{
+ if ([layer isKindOfClass:CAMetalLayer.class])
+ [self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)];
+}
+
- (void)displayLayer:(CALayer *)layer
{
Q_ASSERT(layer == self.layer);
@@ -163,8 +210,17 @@
- (void)viewDidChangeBackingProperties
{
- if (self.layer)
- self.layer.contentsScale = self.window.backingScaleFactor;
+ CALayer *layer = self.layer;
+ if (!layer)
+ return;
+
+ layer.contentsScale = self.window.backingScaleFactor;
+
+ // Metal layers must be manually updated on e.g. screen change
+ if ([layer isKindOfClass:CAMetalLayer.class]) {
+ [self updateMetalLayerDrawableSize:static_cast<CAMetalLayer* >(layer)];
+ [self setNeedsDisplay:YES];
+ }
}
@end