Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ set (SIMPLEGRAPHIC_PLATFORM_SOURCES)
if (APPLE)
set (SIMPLEGRAPHIC_PLATFORM_SOURCES
"engine/system/win/sys_macos.mm"
"engine/system/win/sys_platform_macos.h"
)
endif()

Expand Down
1 change: 1 addition & 0 deletions engine/render/r_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,7 @@ void r_renderer_c::BeginFrame()
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
{
sys->video->SyncSurfaceScale();
auto& vid = sys->video->vid;
int wNew = VirtualScreenWidth();
int hNew = VirtualScreenHeight();
Expand Down
1 change: 1 addition & 0 deletions engine/system/sys_video.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class sys_IVideo {
virtual void SetForeground() = 0; // Activate the window if shown
virtual bool IsActive() = 0; // Get activated status
virtual void FramebufferSizeChanged(int width, int height) = 0; // Respond to framebuffer size change
virtual void SyncSurfaceScale() = 0; // Keep the drawing surface density matched to the display
virtual void SizeChanged(int width, int height, bool max) = 0; // Respond to window size change
virtual void PosChanged(int x, int y) = 0; // Respond to window position change
virtual void GetMinSize(int &width, int &height) = 0; // Get minimum window size
Expand Down
33 changes: 33 additions & 0 deletions engine/system/win/sys_macos.mm
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
#include <string_view>
#include <CoreFoundation/CFBundle.h>
#include <ApplicationServices/ApplicationServices.h>
#include <Cocoa/Cocoa.h>

#define GLFW_EXPOSE_NATIVE_COCOA
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>

#include "sys_platform_macos.h"

const char* PlatformOpenURL(const char* textUrl)
{
Expand All @@ -10,3 +17,29 @@
CFRelease(url);
return nullptr;
}

bool Platform_SyncLayerScale(GLFWwindow* window)
{
// The layer the renderer draws into can be left at a pixel density that
// doesn't match the display the window is on, which makes the drawing
// surface larger than the size the window system reports. Everything then
// renders into a fraction of the window.
NSWindow* w = glfwGetCocoaWindow(window);
if (!w) {
return false;
}
NSView* v = [w contentView];
CALayer* layer = [v layer];
if (!layer) {
return false;
}
CGFloat want = [w backingScaleFactor];
if (want <= 0.0 || fabs([layer contentsScale] - want) < 0.01) {
return false;
}
[layer setContentsScale:want];
for (CALayer* sub in [layer sublayers]) {
[sub setContentsScale:want];
}
return true;
}
12 changes: 12 additions & 0 deletions engine/system/win/sys_platform_macos.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SimpleGraphic Engine
//
// macOS platform helpers
//

#pragma once

struct GLFWwindow;

// Keep the layer being rendered into at the same pixel density as the display
// the window is on. Returns true when it had to be corrected.
bool Platform_SyncLayerScale(GLFWwindow* window);
23 changes: 23 additions & 0 deletions engine/system/win/sys_video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
#include <glad/gles2.h>

#include "sys_local.h"
#ifdef __APPLE__
#include "sys_platform_macos.h"
#endif
#include "core.h"

#include <GLFW/glfw3.h>
Expand All @@ -32,6 +35,7 @@ class sys_video_c : public sys_IVideo {
void SetForeground();
bool IsActive();
void FramebufferSizeChanged(int width, int height);
void SyncSurfaceScale();
void SizeChanged(int width, int height, bool max);
void PosChanged(int x, int y);
void GetMinSize(int& width, int& height);
Expand Down Expand Up @@ -677,6 +681,25 @@ void sys_video_c::FramebufferSizeChanged(int width, int height)
}
}

void sys_video_c::SyncSurfaceScale()
{
#ifdef __APPLE__
if (!wnd) {
return;
}
if (Platform_SyncLayerScale(wnd)) {
// The surface was rebuilt at the correct density; re-read the size
// that describes it.
int fbW = 0, fbH = 0;
glfwGetFramebufferSize(wnd, &fbW, &fbH);
if (fbW > 0 && fbH > 0) {
vid.fbSize[0] = fbW;
vid.fbSize[1] = fbH;
}
}
#endif
}

void sys_video_c::SizeChanged(int width, int height, bool max)
{
// Avoid persisting an invalid window size from being minimized.
Expand Down