Update macOS Cube demo to demonstrate optimizing swapchain across multiple screens.

- DemoView implements NSViewLayerContentScaleDelegate protocol to update
  [CAMetalLayer contentsScale] property when moved between screens.
- Log contentsScale value during swapchain creation.
- Remove a few unnecessary inline declarations.
diff --git a/Demos/Cube/macOS/DemoViewController.m b/Demos/Cube/macOS/DemoViewController.m
index 5ec96ae..d04697f 100644
--- a/Demos/Cube/macOS/DemoViewController.m
+++ b/Demos/Cube/macOS/DemoViewController.m
@@ -88,4 +88,16 @@
 	return layer;
 }
 
+/**
+ * If this view moves to a screen that has a different resolution scale (eg. Standard <=> Retina),
+ * update the contentsScale of the layer, which will trigger a Vulkan VK_SUBOPTIMAL_KHR result, which
+ * causes this demo to replace the swapchain, in order to optimize rendering for the new resolution.
+ */
+-(BOOL) layer: (CALayer *)layer shouldInheritContentsScale: (CGFloat)newScale fromWindow: (NSWindow *)window {
+	if (newScale == layer.contentsScale) { return NO; }
+
+	layer.contentsScale = newScale;
+	return YES;
+}
+
 @end
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index d5fa9a6..1a6bef6 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -30,6 +30,7 @@
 - Fix query pool wait block when query is not encoded to be written to.
 - Fix `vkUpdateDescriptorSetWithTemplate()` for inline block descriptors.
 - Ignore sampler update in descriptor set bindings that use immutable samplers.
+- Update _macOS Cube_ demo to demonstrate optimizing swapchain across multiple screens.
 - Update `VK_MVK_MOLTENVK_SPEC_VERSION` to version `35`.
 
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
index 250210f..7521e65 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
@@ -73,15 +73,15 @@
 								 uint32_t* pImageIndex);
 
 	/** Returns whether the parent surface is now lost and this swapchain must be recreated. */
-	inline bool getIsSurfaceLost() { return _surfaceLost; }
+	bool getIsSurfaceLost() { return _surfaceLost; }
 
-	/** Returns whether the surface size has changed since the last time this function was called. */
-	inline bool getHasSurfaceSizeChanged() {
+	/** Returns whether the surface size or resolution scale has changed since the last time this function was called. */
+	bool getHasSurfaceSizeChanged() {
 		return !CGSizeEqualToSize(_mtlLayer.naturalDrawableSizeMVK, _mtlLayer.drawableSize);
 	}
 
 	/** Returns the status of the surface. Surface loss takes precedence over out-of-date errors. */
-	inline VkResult getSurfaceStatus() {
+	VkResult getSurfaceStatus() {
 		if (_device->getConfigurationResult() != VK_SUCCESS) { return _device->getConfigurationResult(); }
 		if (getIsSurfaceLost()) { return VK_ERROR_SURFACE_LOST_KHR; }
 		if (getHasSurfaceSizeChanged()) { return VK_SUBOPTIMAL_KHR; }
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
index 68e7e23..137eaa1 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
@@ -409,7 +409,8 @@
 		_presentableImages.push_back(_device->createPresentableSwapchainImage(&imgInfo, this, imgIdx, NULL));
 	}
 
-    MVKLogInfo("Created %d swapchain images with initial size (%d, %d).", imgCnt, imgExtent.width, imgExtent.height);
+    MVKLogInfo("Created %d swapchain images with initial size (%d, %d) and contents scale %.1f.",
+			   imgCnt, imgExtent.width, imgExtent.height, _mtlLayer.contentsScale);
 }
 
 VkResult MVKSwapchain::getRefreshCycleDuration(VkRefreshCycleDurationGOOGLE *pRefreshCycleDuration) {