macOS retina scaling fixes, M1 Vulkan vsync workaround, CMakeLists OpenMP path fix for Apple

This commit is contained in:
Stephen Saunders 2022-06-20 16:44:34 -04:00
parent 279c95422d
commit 8bc8d14cf2
10 changed files with 33 additions and 21 deletions

View file

@ -291,8 +291,12 @@ void VulkanSwapChain::create(uint32_t *width, uint32_t *height, bool vsync, bool
// Determine the number of images
uint32_t desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1;
#if (defined(VK_USE_PLATFORM_MACOS_MVK) && defined(VK_EXAMPLE_XCODE_GENERATED))
// SRS - Work around known MoltenVK issue re 2x frame rate when vsync (VK_PRESENT_MODE_FIFO_KHR) enabled in windowed mode
if (vsync && !fullscreen)
// SRS - Work around known MoltenVK issue re 2x frame rate when vsync (VK_PRESENT_MODE_FIFO_KHR) enabled
struct utsname sysInfo;
uname(&sysInfo);
// SRS - When vsync is on, use minImageCount when not in fullscreen or when running on Apple Silcon
// This forces swapchain image acquire frame rate to match display vsync frame rate
if (vsync && (!fullscreen || strcmp(sysInfo.machine, "arm64") == 0))
{
desiredNumberOfSwapchainImages = surfCaps.minImageCount;
}

View file

@ -23,6 +23,10 @@
#include "VulkanAndroid.h"
#endif
#ifdef __APPLE__
#include <sys/utsname.h>
#endif
typedef struct _SwapChainBuffers {
VkImage image;
VkImageView view;

View file

@ -78,7 +78,9 @@ namespace vks
}
#else
const std::string filename = getAssetPath() + "Roboto-Medium.ttf";
io.Fonts->AddFontFromFileTTF(filename.c_str(), 16.0f);
io.Fonts->AddFontFromFileTTF(filename.c_str(), 16.0f * scale);
ImGuiStyle& style = ImGui::GetStyle();
style.ScaleAllSizes(scale);
#endif
io.Fonts->GetTexDataAsRGBA32(&fontData, &texWidth, &texHeight);
VkDeviceSize uploadSize = texWidth*texHeight * 4 * sizeof(char);

View file

@ -688,7 +688,7 @@ void VulkanExampleBase::updateOverlay()
ImGui::NewFrame();
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
ImGui::SetNextWindowPos(ImVec2(10, 10));
ImGui::SetNextWindowPos(ImVec2(10 * UIOverlay.scale, 10 * UIOverlay.scale));
ImGui::SetNextWindowSize(ImVec2(0, 0), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Vulkan Example", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);
ImGui::TextUnformatted(title.c_str());

View file

@ -12,21 +12,21 @@ function(buildExample EXAMPLE_NAME)
SET(MAIN_HEADER ${EXAMPLE_FOLDER}/${EXAMPLE_NAME}.h)
ENDIF()
if(APPLE)
# SRS - Use MacPorts paths as default since they are the same on x86 and Apple Silicon, can override on cmake command line
if(NOT OpenMP_omp_LIBRARY)
# SRS - Use MacPorts paths as default since the same on x86 and Apple Silicon, can override for homebrew on cmake command line
if(NOT OpenMP_omp_LIBRARY AND EXISTS /opt/local/lib/libomp/libomp.dylib)
set(OpenMP_omp_LIBRARY /opt/local/lib/libomp/libomp.dylib)
endif()
if(CMAKE_C_COMPILER_ID MATCHES "Clang\$")
set(OpenMP_C_FLAGS "-Xclang -fopenmp")
set(OpenMP_C_LIB_NAMES "omp")
if(NOT OpenMP_C_INCLUDE_DIR)
if(NOT OpenMP_C_INCLUDE_DIR AND EXISTS /opt/local/include/libomp)
set(OpenMP_C_INCLUDE_DIR /opt/local/include/libomp)
endif()
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang\$")
set(OpenMP_CXX_FLAGS "-Xclang -fopenmp")
set(OpenMP_CXX_LIB_NAMES "omp")
if(NOT OpenMP_CXX_INCLUDE_DIR)
if(NOT OpenMP_CXX_INCLUDE_DIR AND EXISTS /opt/local/include/libomp)
set(OpenMP_CXX_INCLUDE_DIR /opt/local/include/libomp)
endif()
endif()

View file

@ -652,7 +652,7 @@ void VulkanExample::OnUpdateUIOverlay(vks::UIOverlay* overlay)
ImGui::NewLine();
// POI: Create a list of glTF nodes for visibility toggle
ImGui::BeginChild("#nodelist", ImVec2(200.0f, 340.0f), false);
ImGui::BeginChild("#nodelist", ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * (glTFScene.nodes.size() + 4)), false);
for (auto &node : glTFScene.nodes)
{
if (overlay->checkBox(node.name.c_str(), &node.visible))

View file

@ -113,11 +113,12 @@ void MVKExample::fullScreen(bool fullscreen) {
_vulkanExample->settings.fullscreen = fullscreen;
}
MVKExample::MVKExample(void* view) {
MVKExample::MVKExample(void* view, double scaleUI) {
_vulkanExample = new VulkanExample();
_vulkanExample->settings.vsync = true; // SRS - this iOS/macOS example uses displayLink vsync rendering - set before calling prepare()
_vulkanExample->initVulkan();
_vulkanExample->setupWindow(view);
_vulkanExample->settings.vsync = true; // SRS - set vsync flag since this iOS/macOS example app uses displayLink vsync rendering
_vulkanExample->UIOverlay.scale = scaleUI; // SRS - set UIOverlay scale to maintain relative proportions/readability on retina displays
_vulkanExample->prepare();
_vulkanExample->renderLoop(); // SRS - this inits destWidth/destHeight/lastTimestamp/tPrevEnd, then falls through and returns
}

View file

@ -31,7 +31,7 @@ public:
void fullScreen(bool fullscreen); // SRS - expose VulkanExampleBase::settings.fullscreen to DemoView (macOS only)
MVKExample(void* view);
MVKExample(void* view, double scaleUI); // SRS - support UIOverlay scaling parameter based on device and display type
~MVKExample();
protected:

View file

@ -32,7 +32,7 @@ const std::string getAssetPath() {
self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale;
_mvkExample = new MVKExample(self.view);
_mvkExample = new MVKExample(self.view, 1.0f); // SRS - Use 1x scale factor for UIOverlay on iOS
// SRS - Enable AppDelegate to call into DemoViewController for handling app lifecycle events (e.g. termination)
auto appDelegate = (AppDelegate *)UIApplication.sharedApplication.delegate;

View file

@ -27,6 +27,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink,
return kCVReturnSuccess;
}
CALayer* layer;
MVKExample* _mvkExample;
#pragma mark -
@ -40,9 +41,9 @@ MVKExample* _mvkExample;
-(void) viewDidLoad {
[super viewDidLoad];
self.view.wantsLayer = YES; // Back the view with a layer created by the makeBackingLayer method.
self.view.wantsLayer = YES; // Back the view with a layer created by the makeBackingLayer method (called immediately on set)
_mvkExample = new MVKExample(self.view);
_mvkExample = new MVKExample(self.view, layer.contentsScale); // SRS - Use backing layer scale factor for UIOverlay on macOS
// SRS - Enable AppDelegate to call into DemoViewController for handling application lifecycle events (e.g. termination)
auto appDelegate = (AppDelegate *)NSApplication.sharedApplication.delegate;
@ -75,7 +76,7 @@ MVKExample* _mvkExample;
/** If the wantsLayer property is set to YES, this method will be invoked to return a layer instance. */
-(CALayer*) makeBackingLayer {
CALayer* layer = [self.class.layerClass layer];
layer = [self.class.layerClass layer];
CGSize viewScale = [self convertSizeToBacking: CGSizeMake(1.0, 1.0)];
layer.contentsScale = MIN(viewScale.width, viewScale.height);
return layer;
@ -108,8 +109,8 @@ MVKExample* _mvkExample;
// SRS - Handle mouse events
-(NSPoint) getMouseLocalPoint:(NSEvent*) theEvent {
NSPoint location = [theEvent locationInWindow];
NSPoint point = [self convertPoint:location fromView:nil];
point.y = self.frame.size.height - point.y;
NSPoint point = [self convertPointToBacking:location];
point.y = self.frame.size.height*self.window.backingScaleFactor - point.y;
return point;
}