Skip to content

Commit

Permalink
Fix render resolution at different UI scales (#514)
Browse files Browse the repository at this point in the history
  • Loading branch information
goeiecool9999 committed Nov 30, 2022
1 parent a3476c7 commit d3721c3
Show file tree
Hide file tree
Showing 18 changed files with 128 additions and 57 deletions.
4 changes: 2 additions & 2 deletions src/Cafe/HW/Latte/Core/LatteOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,9 @@ void LatteOverlay_render(bool pad_view)

sint32 w = 0, h = 0;
if (pad_view && gui_isPadWindowOpen())
gui_getPadWindowSize(&w, &h);
gui_getPadWindowPhysSize(w, h);
else
gui_getWindowSize(&w, &h);
gui_getWindowPhysSize(w, h);

if (w == 0 || h == 0)
return;
Expand Down
4 changes: 2 additions & 2 deletions src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,9 +848,9 @@ void LatteRenderTarget_getScreenImageArea(sint32* x, sint32* y, sint32* width, s
{
int w, h;
if(padView && gui_isPadWindowOpen())
gui_getPadWindowSize(&w, &h);
gui_getPadWindowPhysSize(w, h);
else
gui_getWindowSize(&w, &h);
gui_getWindowPhysSize(w, h);

sint32 scaledOutputX;
sint32 scaledOutputY;
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/HW/Latte/Core/LatteShaderCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateF
continue;

int w, h;
gui_getWindowSize(&w, &h);
gui_getWindowPhysSize(w, h);
const Vector2f window_size{ (float)w,(float)h };

ImGui_GetFont(window_size.y / 32.0f); // = 24 by default
Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/HW/Latte/Core/LatteThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ int Latte_ThreadEntry()
{
SetThreadName("LatteThread");
sint32 w,h;
gui_getWindowSize(&w,&h);
gui_getWindowPhysSize(w,h);

// imgui
ImGui::CreateContext();
Expand Down
4 changes: 2 additions & 2 deletions src/Cafe/HW/Latte/Renderer/OpenGL/OpenGLRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,9 +556,9 @@ void OpenGLRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutpu
{
int windowWidth, windowHeight;
if (padView)
gui_getPadWindowSize(&windowWidth, &windowHeight);
gui_getPadWindowPhysSize(windowWidth, windowHeight);
else
gui_getWindowSize(&windowWidth, &windowHeight);
gui_getWindowPhysSize(windowWidth, windowHeight);
g_renderer->renderTarget_setViewport(0, 0, windowWidth, windowHeight, 0.0f, 1.0f);
g_renderer->ClearColorbuffer(padView);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Cafe/HW/Latte/Renderer/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ bool Renderer::ImguiBegin(bool mainWindow)
{
sint32 w = 0, h = 0;
if(mainWindow)
gui_getWindowSize(&w, &h);
gui_getWindowPhysSize(w, h);
else if(gui_isPadWindowOpen())
gui_getPadWindowSize(&w, &h);
gui_getPadWindowPhysSize(w, h);
else
return false;

Expand Down
17 changes: 16 additions & 1 deletion src/Cafe/HW/Latte/Renderer/Vulkan/CocoaSurface.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,23 @@ -(BOOL) wantsUpdateLayer { return YES; }

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

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

-(CALayer*) makeBackingLayer
{
CALayer* layer = [self.class.layerClass layer];
CGSize viewScale = [self convertSizeToBacking: CGSizeMake(1.0, 1.0)];
layer.contentsScale = MIN(viewScale.width, viewScale.height);
return layer;
}

-(BOOL) layer: (CALayer *)layer shouldInheritContentsScale: (CGFloat)newScale fromWindow: (NSWindow *)window
{
if (newScale == layer.contentsScale) { return NO; }

layer.contentsScale = newScale;
return YES;
}
@end

VkSurfaceKHR CreateCocoaSurface(VkInstance instance, void* handle)
Expand Down
18 changes: 6 additions & 12 deletions src/Cafe/HW/Latte/Renderer/Vulkan/SwapchainInfoVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,20 +208,14 @@ bool SwapchainInfoVk::AcquireImage(uint64 timeout)

VkSemaphore acquireSemaphore = m_acquireSemaphores[m_acquireIndex];
VkResult result = vkAcquireNextImageKHR(m_logicalDevice, swapchain, timeout, acquireSemaphore, m_imageAvailableFence, &swapchainImageIndex);
if (result == VK_TIMEOUT)
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
m_shouldRecreate = true;
if (result < 0)
{
return false;
}
else if (result != VK_SUCCESS)
{
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
m_shouldRecreate = true;

if (result == VK_ERROR_OUT_OF_DATE_KHR)
return false;

if (result != VK_ERROR_OUT_OF_DATE_KHR && result != VK_SUBOPTIMAL_KHR)
swapchainImageIndex = -1;
if (result != VK_ERROR_OUT_OF_DATE_KHR)
throw std::runtime_error(fmt::format("Failed to acquire next image: {}", result));
return false;
}
m_currentSemaphore = acquireSemaphore;
m_awaitableFence = m_imageAvailableFence;
Expand Down
17 changes: 8 additions & 9 deletions src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ VulkanRenderer* VulkanRenderer::GetInstance()
return (VulkanRenderer*)g_renderer.get();
}

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

Expand Down Expand Up @@ -2564,20 +2564,20 @@ void VulkanRenderer::RecreateSwapchain(bool mainWindow, bool skipCreate)
if (mainWindow)
{
ImGui_ImplVulkan_Shutdown();
gui_getWindowSize(&size.x, &size.y);
gui_getWindowPhysSize(size.x, size.y);
}
else
{
gui_getPadWindowSize(&size.x, &size.y);
gui_getPadWindowPhysSize(size.x, size.y);
}

chainInfo.swapchainImageIndex = -1;
chainInfo.Cleanup();
chainInfo.m_desiredExtent = size;
if(!skipCreate)
{
chainInfo.Create(m_physicalDevice, m_logicalDevice);
}
chainInfo.swapchainImageIndex = -1;

if (mainWindow)
ImguiInit();
Expand Down Expand Up @@ -2644,13 +2644,12 @@ void VulkanRenderer::SwapBuffer(bool mainWindow)
presentInfo.pWaitSemaphores = &presentSemaphore;

VkResult result = vkQueuePresentKHR(m_presentQueue, &presentInfo);
if (result != VK_SUCCESS)
if (result < 0 && result != VK_ERROR_OUT_OF_DATE_KHR)
{
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
chainInfo.m_shouldRecreate = true;
else
throw std::runtime_error(fmt::format("Failed to present image: {}", result));
throw std::runtime_error(fmt::format("Failed to present image: {}", result));
}
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
chainInfo.m_shouldRecreate = true;

chainInfo.hasDefinedSwapchainImage = false;

Expand Down
2 changes: 1 addition & 1 deletion src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class VulkanRenderer : public Renderer

void GetDeviceFeatures();
void DetermineVendor();
void Initialize(const Vector2i& size, bool mainWindow);
void InitializeSurface(const Vector2i& size, bool mainWindow);

const std::unique_ptr<SwapchainInfoVk>& GetChainInfoPtr(bool mainWindow) const;
SwapchainInfoVk& GetChainInfo(bool mainWindow) const;
Expand Down
25 changes: 21 additions & 4 deletions src/gui/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ wxBEGIN_EVENT_TABLE(MainWindow, wxFrame)
EVT_TIMER(MAINFRAME_ID_TIMER1, MainWindow::OnTimer)
EVT_CLOSE(MainWindow::OnClose)
EVT_SIZE(MainWindow::OnSizeEvent)
EVT_DPI_CHANGED(MainWindow::OnDPIChangedEvent)
EVT_MOVE(MainWindow::OnMove)
// file menu
EVT_MENU(MAINFRAME_MENU_ID_FILE_LOAD, MainWindow::OnFileMenu)
Expand Down Expand Up @@ -1310,7 +1311,8 @@ void MainWindow::OnMouseMove(wxMouseEvent& event)

auto& instance = InputManager::instance();
std::unique_lock lock(instance.m_main_mouse.m_mutex);
instance.m_main_mouse.position = { event.GetPosition().x, event.GetPosition().y };
auto physPos = ToPhys(event.GetPosition());
instance.m_main_mouse.position = { physPos.x, physPos.y };
lock.unlock();

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

std::scoped_lock lock(instance.m_main_mouse.m_mutex);
instance.m_main_mouse.left_down = event.ButtonDown(wxMOUSE_BTN_LEFT);
instance.m_main_mouse.position = { event.GetPosition().x, event.GetPosition().y };
auto physPos = ToPhys(event.GetPosition());
instance.m_main_mouse.position = { physPos.x, physPos.y };
if (event.ButtonDown(wxMOUSE_BTN_LEFT))
instance.m_main_mouse.left_down_toggle = true;

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

std::scoped_lock lock(instance.m_main_mouse.m_mutex);
instance.m_main_mouse.right_down = event.ButtonDown(wxMOUSE_BTN_RIGHT);
instance.m_main_mouse.position = { event.GetPosition().x, event.GetPosition().y };
auto physPos = ToPhys(event.GetPosition());
instance.m_main_mouse.position = { physPos.x, physPos.y };
if(event.ButtonDown(wxMOUSE_BTN_RIGHT))
instance.m_main_mouse.right_down_toggle = true;

Expand Down Expand Up @@ -1441,7 +1445,8 @@ void MainWindow::OnGesturePan(wxPanGestureEvent& event)
{
auto& instance = InputManager::instance();
std::scoped_lock lock(instance.m_main_touch.m_mutex);
instance.m_main_touch.position = { event.GetPosition().x, event.GetPosition().y };
auto physPos = ToPhys(event.GetPosition());
instance.m_main_touch.position = { physPos.x, physPos.y };
instance.m_main_touch.left_down = event.IsGestureStart() || !event.IsGestureEnd();
if (event.IsGestureStart() || !event.IsGestureEnd())
instance.m_main_touch.left_down_toggle = true;
Expand Down Expand Up @@ -1516,6 +1521,8 @@ void MainWindow::OnSizeEvent(wxSizeEvent& event)
const wxSize client_size = GetClientSize();
g_window_info.width = client_size.GetWidth();
g_window_info.height = client_size.GetHeight();
g_window_info.phys_width = ToPhys(client_size.GetWidth());
g_window_info.phys_height = ToPhys(client_size.GetHeight());

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

void MainWindow::OnDPIChangedEvent(wxDPIChangedEvent& event)
{
event.Skip();
const wxSize client_size = GetClientSize();
g_window_info.width = client_size.GetWidth();
g_window_info.height = client_size.GetHeight();
g_window_info.phys_width = ToPhys(client_size.GetWidth());
g_window_info.phys_height = ToPhys(client_size.GetHeight());
}

void MainWindow::OnMove(wxMoveEvent& event)
{
if (!IsMaximized() && !gui_isFullScreen())
Expand Down
3 changes: 2 additions & 1 deletion src/gui/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class MainWindow : public wxFrame
PadViewFrame* GetPadView() const { return m_padView; }

void OnSizeEvent(wxSizeEvent& event);
void OnDPIChangedEvent(wxDPIChangedEvent& event);
void OnMove(wxMoveEvent& event);

void OnDebuggerClose(wxCloseEvent& event);
Expand Down Expand Up @@ -231,4 +232,4 @@ class MainWindow : public wxFrame
wxDECLARE_EVENT_TABLE();
};

extern MainWindow* g_mainFrame;
extern MainWindow* g_mainFrame;
29 changes: 24 additions & 5 deletions src/gui/PadViewFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ PadViewFrame::PadViewFrame(wxFrame* parent)
Maximize();

Bind(wxEVT_SIZE, &PadViewFrame::OnSizeEvent, this);
Bind(wxEVT_DPI_CHANGED, &PadViewFrame::OnDPIChangedEvent, this);
Bind(wxEVT_MOVE, &PadViewFrame::OnMoveEvent, this);
Bind(wxEVT_MOTION, &PadViewFrame::OnMouseMove, this);

Expand All @@ -55,6 +56,8 @@ bool PadViewFrame::Initialize()
const wxSize client_size = GetClientSize();
g_window_info.pad_width = client_size.GetWidth();
g_window_info.pad_height = client_size.GetHeight();
g_window_info.phys_pad_width = ToPhys(client_size.GetWidth());
g_window_info.phys_pad_height = ToPhys(client_size.GetHeight());

return true;
}
Expand Down Expand Up @@ -98,10 +101,22 @@ void PadViewFrame::OnSizeEvent(wxSizeEvent& event)
const wxSize client_size = GetClientSize();
g_window_info.pad_width = client_size.GetWidth();
g_window_info.pad_height = client_size.GetHeight();
g_window_info.phys_pad_width = ToPhys(client_size.GetWidth());
g_window_info.phys_pad_height = ToPhys(client_size.GetHeight());

event.Skip();
}

void PadViewFrame::OnDPIChangedEvent(wxDPIChangedEvent& event)
{
event.Skip();
const wxSize client_size = GetClientSize();
g_window_info.pad_width = client_size.GetWidth();
g_window_info.pad_height = client_size.GetHeight();
g_window_info.phys_pad_width = ToPhys(client_size.GetWidth());
g_window_info.phys_pad_height = ToPhys(client_size.GetHeight());
}

void PadViewFrame::OnMoveEvent(wxMoveEvent& event)
{
if (!IsMaximized() && !IsFullScreen())
Expand Down Expand Up @@ -130,7 +145,8 @@ void PadViewFrame::OnGesturePan(wxPanGestureEvent& event)
auto& instance = InputManager::instance();

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

std::scoped_lock lock(instance.m_pad_touch.m_mutex);
instance.m_pad_mouse.position = { event.GetPosition().x, event.GetPosition().y };
auto physPos = ToPhys(event.GetPosition());
instance.m_pad_mouse.position = { physPos.x, physPos.y };

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

std::scoped_lock lock(instance.m_pad_mouse.m_mutex);
instance.m_pad_mouse.left_down = event.ButtonDown(wxMOUSE_BTN_LEFT);
instance.m_pad_mouse.position = { event.GetPosition().x, event.GetPosition().y };
auto physPos = ToPhys(event.GetPosition());
instance.m_pad_mouse.position = { physPos.x, physPos.y };
if (event.ButtonDown(wxMOUSE_BTN_LEFT))
instance.m_pad_mouse.left_down_toggle = true;

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

std::scoped_lock lock(instance.m_pad_mouse.m_mutex);
instance.m_pad_mouse.right_down = event.ButtonDown(wxMOUSE_BTN_LEFT);
instance.m_pad_mouse.position = { event.GetPosition().x, event.GetPosition().y };
auto physPos = ToPhys(event.GetPosition());
instance.m_pad_mouse.position = { physPos.x, physPos.y };
if (event.ButtonDown(wxMOUSE_BTN_RIGHT))
instance.m_pad_mouse.right_down_toggle = true;
}
Expand All @@ -187,4 +206,4 @@ void PadViewFrame::AsyncSetTitle(std::string_view windowTitle)
wxCommandEvent set_title_event(wxEVT_SET_WINDOW_TITLE);
set_title_event.SetString(wxHelper::FromUtf8(windowTitle));
QueueEvent(set_title_event.Clone());
}
}
3 changes: 2 additions & 1 deletion src/gui/PadViewFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ class PadViewFrame : public wxFrame
void OnMouseLeft(wxMouseEvent& event);
void OnMouseRight(wxMouseEvent& event);
void OnSizeEvent(wxSizeEvent& event);
void OnDPIChangedEvent(wxDPIChangedEvent& event);
void OnMoveEvent(wxMoveEvent& event);
void OnGesturePan(wxPanGestureEvent& event);
void OnSetWindowTitle(wxCommandEvent& event);

wxWindow* m_render_canvas = nullptr;
};
};
2 changes: 1 addition & 1 deletion src/gui/canvas/VulkanCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ VulkanCanvas::VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_wi
g_renderer = std::make_unique<VulkanRenderer>();

auto vulkan_renderer = VulkanRenderer::GetInstance();
vulkan_renderer->Initialize({size.x, size.y}, is_main_window);
vulkan_renderer->InitializeSurface({size.x, size.y}, is_main_window);
}
catch(const std::exception& ex)
{
Expand Down

0 comments on commit d3721c3

Please sign in to comment.