Skip to content

Commit fb6eda9

Browse files
committed
Track window physical size instead of logical size for dynamic dpi scaling
1 parent de84d48 commit fb6eda9

File tree

9 files changed

+45
-39
lines changed

9 files changed

+45
-39
lines changed

pathfinder/gpu/gl/window_builder.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ bool is_extension_supported(const char *name) {
2828
}
2929

3030
#ifndef __ANDROID__
31-
WindowBuilderGl::WindowBuilderGl(const Vec2I &size) {
31+
WindowBuilderGl::WindowBuilderGl(const Vec2I &logical_size) {
3232
glfwInit();
3333

3434
// Major GL version.
@@ -48,16 +48,19 @@ WindowBuilderGl::WindowBuilderGl(const Vec2I &size) {
4848
#endif
4949

5050
float dpi_scaling_factor;
51-
auto glfw_window = glfw_window_init(size, PRIMARY_WINDOW_TITLE, dpi_scaling_factor, false, nullptr);
51+
auto glfw_window = glfw_window_init(logical_size, PRIMARY_WINDOW_TITLE, dpi_scaling_factor, false, nullptr);
5252

53-
primary_window_ = std::make_shared<WindowGl>(size, glfw_window);
53+
auto physical_size = (logical_size.to_f32() * dpi_scaling_factor).to_i32();
54+
55+
primary_window_ = std::make_shared<WindowGl>(physical_size, glfw_window);
5456
primary_window_->set_dpi_scaling_factor(dpi_scaling_factor);
5557

5658
// Set user data.
5759
primary_window_->window_index = 0;
5860

5961
std::ostringstream ss;
60-
ss << "Window created:\n Size: " << size << "\n DPI Scaling: " << dpi_scaling_factor;
62+
ss << "Window created:\n Physical Size: " << physical_size << "\n Logical Size: " << logical_size
63+
<< "\n DPI Scaling: " << dpi_scaling_factor;
6164
Logger::info(ss.str());
6265

6366
// Have to make the window context current before calling gladLoadGL().

pathfinder/gpu/gl/window_builder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ class WindowBuilderGl : public WindowBuilder {
1414
#ifdef __ANDROID__
1515
WindowBuilderGl(ANativeWindow *native_window, const Vec2I &window_size);
1616
#else
17-
explicit WindowBuilderGl(const Vec2I &size);
17+
explicit WindowBuilderGl(const Vec2I &logical_size);
1818
#endif
1919

2020
~WindowBuilderGl() override;
2121

22-
uint8_t create_window(const Vec2I &size, const std::string &title) override;
22+
uint8_t create_window(const Vec2I &logical_size, const std::string &title) override;
2323

2424
std::shared_ptr<Device> request_device() override;
2525

pathfinder/gpu/vk/window.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ VkExtent2D WindowVk::choose_swap_extent(const VkSurfaceCapabilitiesKHR& capabili
4949
std::shared_ptr<SwapChain> WindowVk::get_swap_chain(const std::shared_ptr<Device>& device) {
5050
if (!swapchain_) {
5151
auto device_vk = static_cast<DeviceVk*>(device.get());
52-
swapchain_ = std::make_shared<SwapChainVk>(logical_size_, this, device_vk);
52+
swapchain_ = std::make_shared<SwapChainVk>(get_physical_size(), this, device_vk);
5353
}
5454

5555
return swapchain_;

pathfinder/gpu/vk/window_builder.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void destroy_debug_utils_messenger_ext(VkInstance instance,
2929
}
3030

3131
#ifndef __ANDROID__
32-
WindowBuilderVk::WindowBuilderVk(const Vec2I &size) {
32+
WindowBuilderVk::WindowBuilderVk(const Vec2I &logical_size) {
3333
glfwInit();
3434

3535
// To not create an OpenGL context (as we're using Vulkan).
@@ -40,18 +40,20 @@ WindowBuilderVk::WindowBuilderVk(const Vec2I &size) {
4040
setup_debug_messenger();
4141

4242
float dpi_scaling_factor;
43-
auto glfw_window = glfw_window_init(size, PRIMARY_WINDOW_TITLE, dpi_scaling_factor, false, nullptr);
43+
auto glfw_window = glfw_window_init(logical_size, PRIMARY_WINDOW_TITLE, dpi_scaling_factor, false, nullptr);
44+
45+
auto physical_size = (logical_size.to_f32() * dpi_scaling_factor).to_i32();
4446

4547
VkSurfaceKHR surface{};
4648
VK_CHECK_RESULT(glfwCreateWindowSurface(instance_, glfw_window, nullptr, &surface))
4749

4850
initialize_after_surface_creation(surface);
4951

50-
primary_window_ = std::make_shared<WindowVk>(size, glfw_window, surface, instance_);
52+
primary_window_ = std::make_shared<WindowVk>(physical_size, glfw_window, surface, instance_);
5153
primary_window_->set_dpi_scaling_factor(dpi_scaling_factor);
5254
}
5355
#else
54-
WindowBuilderVk::WindowBuilderVk(ANativeWindow *native_window, const Vec2I &window_size) {
56+
WindowBuilderVk::WindowBuilderVk(ANativeWindow *native_window, const Vec2I &physical_size) {
5557
native_window_ = native_window;
5658

5759
create_instance();
@@ -68,7 +70,7 @@ WindowBuilderVk::WindowBuilderVk(ANativeWindow *native_window, const Vec2I &wind
6870

6971
initialize_after_surface_creation(surface);
7072

71-
primary_window_ = std::make_shared<WindowVk>(window_size, surface, instance_);
73+
primary_window_ = std::make_shared<WindowVk>(physical_size, surface, instance_);
7274
}
7375
#endif
7476

pathfinder/gpu/vk/window_builder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ class Window;
5454
class WindowBuilderVk : public WindowBuilder {
5555
public:
5656
#ifndef __ANDROID__
57-
explicit WindowBuilderVk(const Vec2I &size);
57+
explicit WindowBuilderVk(const Vec2I &logical_size);
5858
#else
59-
explicit WindowBuilderVk(ANativeWindow *native_window, const Vec2I &window_size);
59+
explicit WindowBuilderVk(ANativeWindow *native_window, const Vec2I &physical_size);
6060
#endif
6161

6262
~WindowBuilderVk() override;

pathfinder/gpu/window.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@
55
namespace Pathfinder {
66

77
#ifdef __ANDROID__
8-
Window::Window(const Vec2I& size) : logical_size_(size) {}
8+
Window::Window(const Vec2I& size) : physical_size_(size) {}
99
#else
10-
Window::Window(const Vec2I& size, GLFWwindow* window_handle) : logical_size_(size), glfw_window_(window_handle) {
10+
Window::Window(const Vec2I& size, GLFWwindow* window_handle) : physical_size_(size), glfw_window_(window_handle) {
1111
// Assign this to window user, so we can fetch it when window size changes.
1212
glfwSetWindowUserPointer(glfw_window_, this);
1313
glfwSetFramebufferSizeCallback(glfw_window_, framebuffer_resize_callback);
1414
}
1515
#endif
1616

1717
Vec2I Window::get_physical_size() const {
18-
return (logical_size_.to_f32() * dpi_scaling_factor_).to_i32();
18+
return physical_size_;
1919
}
2020

2121
Vec2I Window::get_logical_size() const {
22-
return logical_size_;
22+
return (physical_size_.to_f32() / dpi_scaling_factor_).to_i32();
2323
}
2424

2525
Vec2I Window::get_position() const {
@@ -48,7 +48,7 @@ void Window::set_dpi_scaling_factor(float scale) {
4848

4949
#ifndef __ANDROID__
5050
void Window::framebuffer_resize_callback(GLFWwindow* glfw_window, int width, int height) {
51-
auto window = reinterpret_cast<Window*>(glfwGetWindowUserPointer(glfw_window));
51+
auto window = static_cast<Window*>(glfwGetWindowUserPointer(glfw_window));
5252

5353
if (window) {
5454
// Get the size of window decorations.
@@ -57,11 +57,11 @@ void Window::framebuffer_resize_callback(GLFWwindow* glfw_window, int width, int
5757

5858
// TODO: consider window decorations.
5959
window->just_resized_ = true;
60-
window->logical_size_ = (Vec2F(width, height) / window->get_dpi_scaling_factor()).to_i32();
61-
window->minimized_ = window->logical_size_.area() == 0;
60+
window->physical_size_ = Vec2I(width, height);
61+
window->minimized_ = window->physical_size_.area() == 0;
6262

63-
Logger::info("Window resized to physical" + Vec2I(width, height).to_string() + ", logical" +
64-
window->logical_size_.to_string());
63+
Logger::info("Window resized to physical" + window->get_physical_size().to_string() + ", logical" +
64+
window->get_logical_size().to_string());
6565
} else {
6666
Logger::error("glfwGetWindowUserPointer is NULL!");
6767
}

pathfinder/gpu/window.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class Window {
5959
uint8_t window_index{};
6060

6161
protected:
62-
Vec2I logical_size_;
62+
Vec2I physical_size_;
6363

6464
bool just_resized_ = false;
6565
bool fullscreen_ = false;

pathfinder/gpu/window_builder.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ float WindowBuilder::get_dpi_scaling_factor(uint8_t window_index) const {
5757
return get_window(window_index).lock()->get_dpi_scaling_factor();
5858
}
5959

60+
void WindowBuilder::set_dpi_scaling_factor(uint8_t window_index, float new_scale) {
61+
get_window(window_index).lock()->set_dpi_scaling_factor(new_scale);
62+
}
63+
6064
void WindowBuilder::poll_events() {
6165
// Reset window flags.
6266
{
@@ -81,35 +85,30 @@ void WindowBuilder::set_fullscreen(bool fullscreen) {
8185
primary_window_->fullscreen_ = fullscreen;
8286

8387
if (fullscreen) {
84-
reserved_window_logical_size_ = primary_window_->get_logical_size();
88+
reserved_window_physical_size_ = primary_window_->get_physical_size();
8589
reserved_window_position_ = primary_window_->get_position();
8690

8791
const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
8892

89-
auto physical_size = Vec2I(mode->width, mode->height);
90-
9193
glfwSetWindowMonitor(primary_window_->glfw_window_,
9294
glfwGetPrimaryMonitor(),
9395
0,
9496
0,
95-
physical_size.x,
96-
physical_size.y,
97+
mode->width,
98+
mode->height,
9799
GLFW_DONT_CARE);
98100

99-
auto logical_size = (physical_size.to_f32() / get_dpi_scaling_factor(0)).to_i32();
100-
primary_window_->logical_size_ = logical_size;
101+
primary_window_->physical_size_ = Vec2I(mode->width, mode->height);
101102
} else {
102-
auto physical_size = (reserved_window_logical_size_.to_f32() * get_dpi_scaling_factor(0)).to_i32();
103-
104103
glfwSetWindowMonitor(primary_window_->glfw_window_,
105-
NULL,
104+
nullptr,
106105
reserved_window_position_.x,
107106
reserved_window_position_.y,
108-
physical_size.x,
109-
physical_size.y,
107+
reserved_window_physical_size_.x,
108+
reserved_window_physical_size_.y,
110109
GLFW_DONT_CARE);
111110

112-
primary_window_->logical_size_ = reserved_window_logical_size_;
111+
primary_window_->physical_size_ = reserved_window_physical_size_;
113112
}
114113
#endif
115114
}

pathfinder/gpu/window_builder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ class WindowBuilder {
3131
/// Create a new sub-window.
3232
virtual uint8_t create_window(const Vec2I &size, const std::string &title) = 0;
3333

34-
[[nodiscard]] std::weak_ptr<Window> get_window(uint8_t window_index) const;
34+
std::weak_ptr<Window> get_window(uint8_t window_index) const;
3535

3636
float get_dpi_scaling_factor(uint8_t window_index) const;
3737

38+
void set_dpi_scaling_factor(uint8_t window_index, float new_scale);
39+
3840
virtual std::shared_ptr<Device> request_device() = 0;
3941

4042
virtual std::shared_ptr<Queue> create_queue() = 0;
@@ -60,7 +62,7 @@ class WindowBuilder {
6062
bool primary_window_fullscreen_ = false;
6163

6264
// Size before going fullscreen or being minimized.
63-
Vec2I reserved_window_logical_size_;
65+
Vec2I reserved_window_physical_size_;
6466

6567
Vec2I reserved_window_position_;
6668
};

0 commit comments

Comments
 (0)