Skip to content

Commit d3721c3

Browse files
Fix render resolution at different UI scales (#514)
1 parent a3476c7 commit d3721c3

18 files changed

+128
-57
lines changed

src/Cafe/HW/Latte/Core/LatteOverlay.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -513,9 +513,9 @@ void LatteOverlay_render(bool pad_view)
513513

514514
sint32 w = 0, h = 0;
515515
if (pad_view && gui_isPadWindowOpen())
516-
gui_getPadWindowSize(&w, &h);
516+
gui_getPadWindowPhysSize(w, h);
517517
else
518-
gui_getWindowSize(&w, &h);
518+
gui_getWindowPhysSize(w, h);
519519

520520
if (w == 0 || h == 0)
521521
return;

src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -848,9 +848,9 @@ void LatteRenderTarget_getScreenImageArea(sint32* x, sint32* y, sint32* width, s
848848
{
849849
int w, h;
850850
if(padView && gui_isPadWindowOpen())
851-
gui_getPadWindowSize(&w, &h);
851+
gui_getPadWindowPhysSize(w, h);
852852
else
853-
gui_getWindowSize(&w, &h);
853+
gui_getWindowPhysSize(w, h);
854854

855855
sint32 scaledOutputX;
856856
sint32 scaledOutputY;

src/Cafe/HW/Latte/Core/LatteShaderCache.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateF
418418
continue;
419419

420420
int w, h;
421-
gui_getWindowSize(&w, &h);
421+
gui_getWindowPhysSize(w, h);
422422
const Vector2f window_size{ (float)w,(float)h };
423423

424424
ImGui_GetFont(window_size.y / 32.0f); // = 24 by default

src/Cafe/HW/Latte/Core/LatteThread.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ int Latte_ThreadEntry()
117117
{
118118
SetThreadName("LatteThread");
119119
sint32 w,h;
120-
gui_getWindowSize(&w,&h);
120+
gui_getWindowPhysSize(w,h);
121121

122122
// imgui
123123
ImGui::CreateContext();

src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -556,9 +556,9 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
556556
{
557557
int windowWidth, windowHeight;
558558
if (padView)
559-
gui_getPadWindowSize(&windowWidth, &windowHeight);
559+
gui_getPadWindowPhysSize(windowWidth, windowHeight);
560560
else
561-
gui_getWindowSize(&windowWidth, &windowHeight);
561+
gui_getWindowPhysSize(windowWidth, windowHeight);
562562
g_renderer->renderTarget_setViewport(0, 0, windowWidth, windowHeight, 0.0f, 1.0f);
563563
g_renderer->ClearColorbuffer(padView);
564564
}

src/Cafe/HW/Latte/Renderer/Renderer.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ bool Renderer::ImguiBegin(bool mainWindow)
3636
{
3737
sint32 w = 0, h = 0;
3838
if(mainWindow)
39-
gui_getWindowSize(&w, &h);
39+
gui_getWindowPhysSize(w, h);
4040
else if(gui_isPadWindowOpen())
41-
gui_getPadWindowSize(&w, &h);
41+
gui_getPadWindowPhysSize(w, h);
4242
else
4343
return false;
4444

src/Cafe/HW/Latte/Renderer/Vulkan/CocoaSurface.mm

+16-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,23 @@ -(BOOL) wantsUpdateLayer { return YES; }
1313

1414
+(Class) layerClass { return [CAMetalLayer class]; }
1515

16-
-(CALayer*) makeBackingLayer { return [self.class.layerClass layer]; }
16+
// copied from https://github.com/KhronosGroup/MoltenVK/blob/master/Demos/Cube/macOS/DemoViewController.m
1717

18+
-(CALayer*) makeBackingLayer
19+
{
20+
CALayer* layer = [self.class.layerClass layer];
21+
CGSize viewScale = [self convertSizeToBacking: CGSizeMake(1.0, 1.0)];
22+
layer.contentsScale = MIN(viewScale.width, viewScale.height);
23+
return layer;
24+
}
25+
26+
-(BOOL) layer: (CALayer *)layer shouldInheritContentsScale: (CGFloat)newScale fromWindow: (NSWindow *)window
27+
{
28+
if (newScale == layer.contentsScale) { return NO; }
29+
30+
layer.contentsScale = newScale;
31+
return YES;
32+
}
1833
@end
1934

2035
VkSurfaceKHR CreateCocoaSurface(VkInstance instance, void* handle)

src/Cafe/HW/Latte/Renderer/Vulkan/SwapchainInfoVk.cpp

+6-12
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,14 @@ bool SwapchainInfoVk::AcquireImage(uint64 timeout)
208208

209209
VkSemaphore acquireSemaphore = m_acquireSemaphores[m_acquireIndex];
210210
VkResult result = vkAcquireNextImageKHR(m_logicalDevice, swapchain, timeout, acquireSemaphore, m_imageAvailableFence, &swapchainImageIndex);
211-
if (result == VK_TIMEOUT)
211+
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
212+
m_shouldRecreate = true;
213+
if (result < 0)
212214
{
213-
return false;
214-
}
215-
else if (result != VK_SUCCESS)
216-
{
217-
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
218-
m_shouldRecreate = true;
219-
220-
if (result == VK_ERROR_OUT_OF_DATE_KHR)
221-
return false;
222-
223-
if (result != VK_ERROR_OUT_OF_DATE_KHR && result != VK_SUBOPTIMAL_KHR)
215+
swapchainImageIndex = -1;
216+
if (result != VK_ERROR_OUT_OF_DATE_KHR)
224217
throw std::runtime_error(fmt::format("Failed to acquire next image: {}", result));
218+
return false;
225219
}
226220
m_currentSemaphore = acquireSemaphore;
227221
m_awaitableFence = m_imageAvailableFence;

src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp

+8-9
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ VulkanRenderer* VulkanRenderer::GetInstance()
643643
return (VulkanRenderer*)g_renderer.get();
644644
}
645645

646-
void VulkanRenderer::Initialize(const Vector2i& size, bool mainWindow)
646+
void VulkanRenderer::InitializeSurface(const Vector2i& size, bool mainWindow)
647647
{
648648
auto& windowHandleInfo = mainWindow ? gui_getWindowInfo().canvas_main : gui_getWindowInfo().canvas_pad;
649649

@@ -2564,20 +2564,20 @@ void VulkanRenderer::RecreateSwapchain(bool mainWindow, bool skipCreate)
25642564
if (mainWindow)
25652565
{
25662566
ImGui_ImplVulkan_Shutdown();
2567-
gui_getWindowSize(&size.x, &size.y);
2567+
gui_getWindowPhysSize(size.x, size.y);
25682568
}
25692569
else
25702570
{
2571-
gui_getPadWindowSize(&size.x, &size.y);
2571+
gui_getPadWindowPhysSize(size.x, size.y);
25722572
}
25732573

2574+
chainInfo.swapchainImageIndex = -1;
25742575
chainInfo.Cleanup();
25752576
chainInfo.m_desiredExtent = size;
25762577
if(!skipCreate)
25772578
{
25782579
chainInfo.Create(m_physicalDevice, m_logicalDevice);
25792580
}
2580-
chainInfo.swapchainImageIndex = -1;
25812581

25822582
if (mainWindow)
25832583
ImguiInit();
@@ -2644,13 +2644,12 @@ void VulkanRenderer::SwapBuffer(bool mainWindow)
26442644
presentInfo.pWaitSemaphores = &presentSemaphore;
26452645

26462646
VkResult result = vkQueuePresentKHR(m_presentQueue, &presentInfo);
2647-
if (result != VK_SUCCESS)
2647+
if (result < 0 && result != VK_ERROR_OUT_OF_DATE_KHR)
26482648
{
2649-
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
2650-
chainInfo.m_shouldRecreate = true;
2651-
else
2652-
throw std::runtime_error(fmt::format("Failed to present image: {}", result));
2649+
throw std::runtime_error(fmt::format("Failed to present image: {}", result));
26532650
}
2651+
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
2652+
chainInfo.m_shouldRecreate = true;
26542653

26552654
chainInfo.hasDefinedSwapchainImage = false;
26562655

src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class VulkanRenderer : public Renderer
182182

183183
void GetDeviceFeatures();
184184
void DetermineVendor();
185-
void Initialize(const Vector2i& size, bool mainWindow);
185+
void InitializeSurface(const Vector2i& size, bool mainWindow);
186186

187187
const std::unique_ptr<SwapchainInfoVk>& GetChainInfoPtr(bool mainWindow) const;
188188
SwapchainInfoVk& GetChainInfo(bool mainWindow) const;

src/gui/MainWindow.cpp

+21-4
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ wxBEGIN_EVENT_TABLE(MainWindow, wxFrame)
157157
EVT_TIMER(MAINFRAME_ID_TIMER1, MainWindow::OnTimer)
158158
EVT_CLOSE(MainWindow::OnClose)
159159
EVT_SIZE(MainWindow::OnSizeEvent)
160+
EVT_DPI_CHANGED(MainWindow::OnDPIChangedEvent)
160161
EVT_MOVE(MainWindow::OnMove)
161162
// file menu
162163
EVT_MENU(MAINFRAME_MENU_ID_FILE_LOAD, MainWindow::OnFileMenu)
@@ -1310,7 +1311,8 @@ void MainWindow::OnMouseMove(wxMouseEvent& event)
13101311

13111312
auto& instance = InputManager::instance();
13121313
std::unique_lock lock(instance.m_main_mouse.m_mutex);
1313-
instance.m_main_mouse.position = { event.GetPosition().x, event.GetPosition().y };
1314+
auto physPos = ToPhys(event.GetPosition());
1315+
instance.m_main_mouse.position = { physPos.x, physPos.y };
13141316
lock.unlock();
13151317

13161318
if (!IsFullScreen())
@@ -1328,7 +1330,8 @@ void MainWindow::OnMouseLeft(wxMouseEvent& event)
13281330

13291331
std::scoped_lock lock(instance.m_main_mouse.m_mutex);
13301332
instance.m_main_mouse.left_down = event.ButtonDown(wxMOUSE_BTN_LEFT);
1331-
instance.m_main_mouse.position = { event.GetPosition().x, event.GetPosition().y };
1333+
auto physPos = ToPhys(event.GetPosition());
1334+
instance.m_main_mouse.position = { physPos.x, physPos.y };
13321335
if (event.ButtonDown(wxMOUSE_BTN_LEFT))
13331336
instance.m_main_mouse.left_down_toggle = true;
13341337

@@ -1341,7 +1344,8 @@ void MainWindow::OnMouseRight(wxMouseEvent& event)
13411344

13421345
std::scoped_lock lock(instance.m_main_mouse.m_mutex);
13431346
instance.m_main_mouse.right_down = event.ButtonDown(wxMOUSE_BTN_RIGHT);
1344-
instance.m_main_mouse.position = { event.GetPosition().x, event.GetPosition().y };
1347+
auto physPos = ToPhys(event.GetPosition());
1348+
instance.m_main_mouse.position = { physPos.x, physPos.y };
13451349
if(event.ButtonDown(wxMOUSE_BTN_RIGHT))
13461350
instance.m_main_mouse.right_down_toggle = true;
13471351

@@ -1441,7 +1445,8 @@ void MainWindow::OnGesturePan(wxPanGestureEvent& event)
14411445
{
14421446
auto& instance = InputManager::instance();
14431447
std::scoped_lock lock(instance.m_main_touch.m_mutex);
1444-
instance.m_main_touch.position = { event.GetPosition().x, event.GetPosition().y };
1448+
auto physPos = ToPhys(event.GetPosition());
1449+
instance.m_main_touch.position = { physPos.x, physPos.y };
14451450
instance.m_main_touch.left_down = event.IsGestureStart() || !event.IsGestureEnd();
14461451
if (event.IsGestureStart() || !event.IsGestureEnd())
14471452
instance.m_main_touch.left_down_toggle = true;
@@ -1516,6 +1521,8 @@ void MainWindow::OnSizeEvent(wxSizeEvent& event)
15161521
const wxSize client_size = GetClientSize();
15171522
g_window_info.width = client_size.GetWidth();
15181523
g_window_info.height = client_size.GetHeight();
1524+
g_window_info.phys_width = ToPhys(client_size.GetWidth());
1525+
g_window_info.phys_height = ToPhys(client_size.GetHeight());
15191526

15201527
if (m_debugger_window && m_debugger_window->IsShown())
15211528
m_debugger_window->OnParentMove(GetPosition(), event.GetSize());
@@ -1525,6 +1532,16 @@ void MainWindow::OnSizeEvent(wxSizeEvent& event)
15251532
VsyncDriver_notifyWindowPosChanged();
15261533
}
15271534

1535+
void MainWindow::OnDPIChangedEvent(wxDPIChangedEvent& event)
1536+
{
1537+
event.Skip();
1538+
const wxSize client_size = GetClientSize();
1539+
g_window_info.width = client_size.GetWidth();
1540+
g_window_info.height = client_size.GetHeight();
1541+
g_window_info.phys_width = ToPhys(client_size.GetWidth());
1542+
g_window_info.phys_height = ToPhys(client_size.GetHeight());
1543+
}
1544+
15281545
void MainWindow::OnMove(wxMoveEvent& event)
15291546
{
15301547
if (!IsMaximized() && !gui_isFullScreen())

src/gui/MainWindow.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class MainWindow : public wxFrame
7878
PadViewFrame* GetPadView() const { return m_padView; }
7979

8080
void OnSizeEvent(wxSizeEvent& event);
81+
void OnDPIChangedEvent(wxDPIChangedEvent& event);
8182
void OnMove(wxMoveEvent& event);
8283

8384
void OnDebuggerClose(wxCloseEvent& event);
@@ -231,4 +232,4 @@ class MainWindow : public wxFrame
231232
wxDECLARE_EVENT_TABLE();
232233
};
233234

234-
extern MainWindow* g_mainFrame;
235+
extern MainWindow* g_mainFrame;

src/gui/PadViewFrame.cpp

+24-5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ PadViewFrame::PadViewFrame(wxFrame* parent)
3737
Maximize();
3838

3939
Bind(wxEVT_SIZE, &PadViewFrame::OnSizeEvent, this);
40+
Bind(wxEVT_DPI_CHANGED, &PadViewFrame::OnDPIChangedEvent, this);
4041
Bind(wxEVT_MOVE, &PadViewFrame::OnMoveEvent, this);
4142
Bind(wxEVT_MOTION, &PadViewFrame::OnMouseMove, this);
4243

@@ -55,6 +56,8 @@ bool PadViewFrame::Initialize()
5556
const wxSize client_size = GetClientSize();
5657
g_window_info.pad_width = client_size.GetWidth();
5758
g_window_info.pad_height = client_size.GetHeight();
59+
g_window_info.phys_pad_width = ToPhys(client_size.GetWidth());
60+
g_window_info.phys_pad_height = ToPhys(client_size.GetHeight());
5861

5962
return true;
6063
}
@@ -98,10 +101,22 @@ void PadViewFrame::OnSizeEvent(wxSizeEvent& event)
98101
const wxSize client_size = GetClientSize();
99102
g_window_info.pad_width = client_size.GetWidth();
100103
g_window_info.pad_height = client_size.GetHeight();
104+
g_window_info.phys_pad_width = ToPhys(client_size.GetWidth());
105+
g_window_info.phys_pad_height = ToPhys(client_size.GetHeight());
101106

102107
event.Skip();
103108
}
104109

110+
void PadViewFrame::OnDPIChangedEvent(wxDPIChangedEvent& event)
111+
{
112+
event.Skip();
113+
const wxSize client_size = GetClientSize();
114+
g_window_info.pad_width = client_size.GetWidth();
115+
g_window_info.pad_height = client_size.GetHeight();
116+
g_window_info.phys_pad_width = ToPhys(client_size.GetWidth());
117+
g_window_info.phys_pad_height = ToPhys(client_size.GetHeight());
118+
}
119+
105120
void PadViewFrame::OnMoveEvent(wxMoveEvent& event)
106121
{
107122
if (!IsMaximized() && !IsFullScreen())
@@ -130,7 +145,8 @@ void PadViewFrame::OnGesturePan(wxPanGestureEvent& event)
130145
auto& instance = InputManager::instance();
131146

132147
std::scoped_lock lock(instance.m_pad_touch.m_mutex);
133-
instance.m_pad_touch.position = { event.GetPosition().x, event.GetPosition().y };
148+
auto physPos = ToPhys(event.GetPosition());
149+
instance.m_pad_touch.position = { physPos.x, physPos.y };
134150
instance.m_pad_touch.left_down = event.IsGestureStart() || !event.IsGestureEnd();
135151
if (event.IsGestureStart() || !event.IsGestureEnd())
136152
instance.m_pad_touch.left_down_toggle = true;
@@ -149,7 +165,8 @@ void PadViewFrame::OnMouseMove(wxMouseEvent& event)
149165
auto& instance = InputManager::instance();
150166

151167
std::scoped_lock lock(instance.m_pad_touch.m_mutex);
152-
instance.m_pad_mouse.position = { event.GetPosition().x, event.GetPosition().y };
168+
auto physPos = ToPhys(event.GetPosition());
169+
instance.m_pad_mouse.position = { physPos.x, physPos.y };
153170

154171
event.Skip();
155172
}
@@ -160,7 +177,8 @@ void PadViewFrame::OnMouseLeft(wxMouseEvent& event)
160177

161178
std::scoped_lock lock(instance.m_pad_mouse.m_mutex);
162179
instance.m_pad_mouse.left_down = event.ButtonDown(wxMOUSE_BTN_LEFT);
163-
instance.m_pad_mouse.position = { event.GetPosition().x, event.GetPosition().y };
180+
auto physPos = ToPhys(event.GetPosition());
181+
instance.m_pad_mouse.position = { physPos.x, physPos.y };
164182
if (event.ButtonDown(wxMOUSE_BTN_LEFT))
165183
instance.m_pad_mouse.left_down_toggle = true;
166184

@@ -172,7 +190,8 @@ void PadViewFrame::OnMouseRight(wxMouseEvent& event)
172190

173191
std::scoped_lock lock(instance.m_pad_mouse.m_mutex);
174192
instance.m_pad_mouse.right_down = event.ButtonDown(wxMOUSE_BTN_LEFT);
175-
instance.m_pad_mouse.position = { event.GetPosition().x, event.GetPosition().y };
193+
auto physPos = ToPhys(event.GetPosition());
194+
instance.m_pad_mouse.position = { physPos.x, physPos.y };
176195
if (event.ButtonDown(wxMOUSE_BTN_RIGHT))
177196
instance.m_pad_mouse.right_down_toggle = true;
178197
}
@@ -187,4 +206,4 @@ void PadViewFrame::AsyncSetTitle(std::string_view windowTitle)
187206
wxCommandEvent set_title_event(wxEVT_SET_WINDOW_TITLE);
188207
set_title_event.SetString(wxHelper::FromUtf8(windowTitle));
189208
QueueEvent(set_title_event.Clone());
190-
}
209+
}

src/gui/PadViewFrame.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ class PadViewFrame : public wxFrame
2626
void OnMouseLeft(wxMouseEvent& event);
2727
void OnMouseRight(wxMouseEvent& event);
2828
void OnSizeEvent(wxSizeEvent& event);
29+
void OnDPIChangedEvent(wxDPIChangedEvent& event);
2930
void OnMoveEvent(wxMoveEvent& event);
3031
void OnGesturePan(wxPanGestureEvent& event);
3132
void OnSetWindowTitle(wxCommandEvent& event);
3233

3334
wxWindow* m_render_canvas = nullptr;
34-
};
35+
};

src/gui/canvas/VulkanCanvas.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ VulkanCanvas::VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_wi
2323
g_renderer = std::make_unique<VulkanRenderer>();
2424

2525
auto vulkan_renderer = VulkanRenderer::GetInstance();
26-
vulkan_renderer->Initialize({size.x, size.y}, is_main_window);
26+
vulkan_renderer->InitializeSurface({size.x, size.y}, is_main_window);
2727
}
2828
catch(const std::exception& ex)
2929
{

0 commit comments

Comments
 (0)