From 221a9b023d8c9ca55c093823e9efd6d13d0a54a2 Mon Sep 17 00:00:00 2001 From: Kevin Hartman Date: Fri, 29 Aug 2014 22:23:12 -0700 Subject: Viewport scaling and display density independence The view is scaled to be as large as possible, without changing the aspect, within the bounds of the window. On "retina" displays, or other displays where window units != pixels, the view should no longer draw incorrectly. --- src/citra_qt/bootmanager.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/citra_qt/bootmanager.cpp') diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 20824692d..516e115fd 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -2,6 +2,12 @@ #include #include +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) +// Required for screen DPI information +#include +#include +#endif + #include "common/common.h" #include "bootmanager.hxx" @@ -176,6 +182,24 @@ void GRenderWindow::PollEvents() { */ } +// On Qt 5.1+, this correctly gets the size of the framebuffer (pixels). +// +// Older versions get the window size (density independent pixels), +// and hence, do not support DPI scaling ("retina" displays). +// The result will be a viewport that is smaller than the extent of the window. +void GRenderWindow::GetFramebufferSize(int* fbWidth, int* fbHeight) +{ +#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) + int pixelRatio = child->QPaintDevice::devicePixelRatio(); + + *fbWidth = child->QPaintDevice::width() * pixelRatio; + *fbHeight = child->QPaintDevice::height() * pixelRatio; +#else + *fbWidth = child->QPaintDevice::width(); + *fbHeight = child->QPaintDevice::height(); +#endif +} + void GRenderWindow::BackupGeometry() { geometry = ((QGLWidget*)this)->saveGeometry(); -- cgit v1.2.3 From bd8f491e4c08e9b9a7b852de0b50c144da8ac8c8 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 12 Oct 2014 18:14:57 +0200 Subject: Fixup EmuWindow interface and implementations thereof. --- src/citra_qt/bootmanager.cpp | 53 ++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 19 deletions(-) (limited to 'src/citra_qt/bootmanager.cpp') diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 516e115fd..34a79b306 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -88,20 +88,20 @@ void EmuThread::Stop() class GGLWidgetInternal : public QGLWidget { public: - GGLWidgetInternal(QGLFormat fmt, GRenderWindow* parent) : QGLWidget(fmt, parent) - { - parent_ = parent; + GGLWidgetInternal(QGLFormat fmt, GRenderWindow* parent) + : QGLWidget(fmt, parent), parent(parent) { } - void paintEvent(QPaintEvent* ev) override - { + void paintEvent(QPaintEvent* ev) override { } + void resizeEvent(QResizeEvent* ev) override { - parent_->SetClientAreaWidth(size().width()); - parent_->SetClientAreaHeight(size().height()); + parent->OnClientAreaResized(ev->size().width(), ev->size().height()); + parent->OnFramebufferSizeChanged(); } + private: - GRenderWindow* parent_; + GRenderWindow* parent; }; EmuThread& GRenderWindow::GetEmuThread() @@ -120,16 +120,23 @@ GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this fmt.setProfile(QGLFormat::CoreProfile); // Requests a forward-compatible context, which is required to get a 3.2+ context on OS X fmt.setOption(QGL::NoDeprecatedFunctions); - + child = new GGLWidgetInternal(fmt, this); QBoxLayout* layout = new QHBoxLayout(this); resize(VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); layout->addWidget(child); layout->setMargin(0); setLayout(layout); - QObject::connect(&emu_thread, SIGNAL(started()), this, SLOT(moveContext())); + connect(&emu_thread, SIGNAL(started()), this, SLOT(moveContext())); + + OnFramebufferSizeChanged(); + NotifyClientAreaSizeChanged(std::pair(child->width(), child->height())); BackupGeometry(); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(OnFramebufferSizeChanged())); +#endif } void GRenderWindow::moveContext() @@ -182,22 +189,26 @@ void GRenderWindow::PollEvents() { */ } -// On Qt 5.1+, this correctly gets the size of the framebuffer (pixels). +// On Qt 5.0+, this correctly gets the size of the framebuffer (pixels). // // Older versions get the window size (density independent pixels), // and hence, do not support DPI scaling ("retina" displays). // The result will be a viewport that is smaller than the extent of the window. -void GRenderWindow::GetFramebufferSize(int* fbWidth, int* fbHeight) +void GRenderWindow::OnFramebufferSizeChanged() { -#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0) - int pixelRatio = child->QPaintDevice::devicePixelRatio(); - - *fbWidth = child->QPaintDevice::width() * pixelRatio; - *fbHeight = child->QPaintDevice::height() * pixelRatio; + // Screen changes potentially incur a change in screen DPI, hence we should update the framebuffer size +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + // windowHandle() might not be accessible until the window is displayed to screen. + auto pixel_ratio = windowHandle() ? (windowHandle()->screen()->devicePixelRatio()) : 1.0; + + unsigned width = child->QPaintDevice::width() * pixel_ratio; + unsigned height = child->QPaintDevice::height() * pixel_ratio; #else - *fbWidth = child->QPaintDevice::width(); - *fbHeight = child->QPaintDevice::height(); + unsigned width = child->QPaintDevice::width(); + unsigned height = child->QPaintDevice::height(); #endif + + NotifyFramebufferSizeChanged(std::make_pair(width, height)); } void GRenderWindow::BackupGeometry() @@ -260,3 +271,7 @@ void GRenderWindow::ReloadSetKeymaps() KeyMap::SetKeyMapping({Settings::values.pad_sdown_key, keyboard_id}, HID_User::PAD_CIRCLE_DOWN); } +void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) +{ + NotifyClientAreaSizeChanged(std::make_pair(width, height)); +} -- cgit v1.2.3 From 722ce2258949c5edf81c946faedfd040efeb38a6 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Sun, 12 Oct 2014 22:46:33 +0200 Subject: EmuWindow: Add support for specifying minimal client area sizes. --- src/citra_qt/bootmanager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/citra_qt/bootmanager.cpp') diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 34a79b306..8c12cb228 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -129,6 +129,9 @@ GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this setLayout(layout); connect(&emu_thread, SIGNAL(started()), this, SLOT(moveContext())); + setMinimumSize(GetActiveConfig().min_client_area_size.first, + GetActiveConfig().min_client_area_size.second); + OnFramebufferSizeChanged(); NotifyClientAreaSizeChanged(std::pair(child->width(), child->height())); @@ -275,3 +278,7 @@ void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) { NotifyClientAreaSizeChanged(std::make_pair(width, height)); } + +void GRenderWindow::OnMinimalClientAreaChangeRequest(const std::pair& minimal_size) { + setMinimumSize(minimal_size.first, minimal_size.second); +} -- cgit v1.2.3 From 182476c96a6c75e90a90cbb52048bf754fdd786d Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 13 Nov 2014 18:17:39 +0100 Subject: EmuWindow: Remove window title getters/setters. The window title is none of the emulation core's business. The GUI code is free to put whatever it wants there. Providing properly thread-safe window title getters and setters is a mess anyway. --- src/citra_qt/bootmanager.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src/citra_qt/bootmanager.cpp') diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 8c12cb228..ace48a237 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -111,6 +111,9 @@ EmuThread& GRenderWindow::GetEmuThread() GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this), keyboard_id(0) { + std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); + setWindowTitle(QString::fromStdString(window_title)); + keyboard_id = KeyMap::NewDeviceId(); ReloadSetKeymaps(); @@ -182,14 +185,6 @@ void GRenderWindow::DoneCurrent() } void GRenderWindow::PollEvents() { - // TODO(ShizZy): Does this belong here? This is a reasonable place to update the window title - // from the main thread, but this should probably be in an event handler... - /* - static char title[128]; - sprintf(title, "%s (FPS: %02.02f)", window_title_.c_str(), - video_core::g_renderer->current_fps()); - setWindowTitle(title); - */ } // On Qt 5.0+, this correctly gets the size of the framebuffer (pixels). -- cgit v1.2.3 From 688a5c033ec68bb45cde824885ce8d64384c237d Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 13 Nov 2014 20:32:33 +0100 Subject: citra-qt: Small cleanup. --- src/citra_qt/bootmanager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/citra_qt/bootmanager.cpp') diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index ace48a237..758f71fda 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -132,8 +132,7 @@ GRenderWindow::GRenderWindow(QWidget* parent) : QWidget(parent), emu_thread(this setLayout(layout); connect(&emu_thread, SIGNAL(started()), this, SLOT(moveContext())); - setMinimumSize(GetActiveConfig().min_client_area_size.first, - GetActiveConfig().min_client_area_size.second); + OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); OnFramebufferSizeChanged(); NotifyClientAreaSizeChanged(std::pair(child->width(), child->height())); -- cgit v1.2.3