aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/citra/emu_window/emu_window_glfw.cpp5
-rw-r--r--src/citra/emu_window/emu_window_glfw.h5
-rw-r--r--src/citra_qt/bootmanager.cpp24
-rw-r--r--src/citra_qt/bootmanager.hxx1
-rw-r--r--src/common/emu_window.h7
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp36
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h15
7 files changed, 89 insertions, 4 deletions
diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp
index 0c774bbc..d0f6e9a9 100644
--- a/src/citra/emu_window/emu_window_glfw.cpp
+++ b/src/citra/emu_window/emu_window_glfw.cpp
@@ -34,6 +34,10 @@ const bool EmuWindow_GLFW::IsOpen() {
return glfwWindowShouldClose(m_render_window) == 0;
}
+void EmuWindow_GLFW::GetFramebufferSize(int* fbWidth, int* fbHeight) {
+ glfwGetFramebufferSize(m_render_window, fbWidth, fbHeight);
+}
+
/// EmuWindow_GLFW constructor
EmuWindow_GLFW::EmuWindow_GLFW() {
keyboard_id = KeyMap::NewDeviceId();
@@ -64,6 +68,7 @@ EmuWindow_GLFW::EmuWindow_GLFW() {
glfwSetWindowUserPointer(m_render_window, this);
glfwSetKeyCallback(m_render_window, OnKeyEvent);
+
DoneCurrent();
}
diff --git a/src/citra/emu_window/emu_window_glfw.h b/src/citra/emu_window/emu_window_glfw.h
index 7c307214..e9622876 100644
--- a/src/citra/emu_window/emu_window_glfw.h
+++ b/src/citra/emu_window/emu_window_glfw.h
@@ -21,7 +21,7 @@ public:
/// Makes the graphics context current for the caller thread
void MakeCurrent() override;
-
+
/// Releases (dunno if this is the "right" word) the GLFW context from the caller thread
void DoneCurrent() override;
@@ -32,6 +32,9 @@ public:
void ReloadSetKeymaps() override;
+ /// Gets the size of the window in pixels
+ void GetFramebufferSize(int* fbWidth, int* fbHeight);
+
private:
GLFWwindow* m_render_window; ///< Internal GLFW render window
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 20824692..516e115f 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -2,6 +2,12 @@
#include <QKeyEvent>
#include <QApplication>
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+// Required for screen DPI information
+#include <QScreen>
+#include <QWindow>
+#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();
diff --git a/src/citra_qt/bootmanager.hxx b/src/citra_qt/bootmanager.hxx
index f8afc403..ec3e1fe7 100644
--- a/src/citra_qt/bootmanager.hxx
+++ b/src/citra_qt/bootmanager.hxx
@@ -96,6 +96,7 @@ public:
void MakeCurrent() override;
void DoneCurrent() override;
void PollEvents() override;
+ void GetFramebufferSize(int* fbWidth, int* fbHeight) override;
void BackupGeometry();
void RestoreGeometry();
diff --git a/src/common/emu_window.h b/src/common/emu_window.h
index 6c2b598f..ba9d4fa7 100644
--- a/src/common/emu_window.h
+++ b/src/common/emu_window.h
@@ -49,8 +49,11 @@ public:
void SetConfig(const WindowConfig& val) {
m_config = val;
}
-
- int GetClientAreaWidth() const {
+
+ /// Gets the size of the window in pixels
+ virtual void GetFramebufferSize(int* fbWidth, int* fbHeight) = 0;
+
+ int GetClientAreaWidth() const {
return m_client_area_width;
}
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 8483f79b..3757482d 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -191,7 +191,8 @@ void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x
* Draws the emulated screens to the emulator window.
*/
void RendererOpenGL::DrawScreens() {
- glViewport(0, 0, resolution_width, resolution_height);
+ UpdateViewportExtent();
+ glViewport(viewport_extent.x, viewport_extent.y, viewport_extent.width, viewport_extent.height);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program_id);
@@ -228,6 +229,39 @@ void RendererOpenGL::SetWindow(EmuWindow* window) {
render_window = window;
}
+void RendererOpenGL::UpdateViewportExtent() {
+ int width_in_pixels;
+ int height_in_pixels;
+
+ render_window->GetFramebufferSize(&width_in_pixels, &height_in_pixels);
+
+ // No update needed if framebuffer size hasn't changed
+ if (width_in_pixels == framebuffer_size.width && height_in_pixels == framebuffer_size.height) {
+ return;
+ }
+
+ framebuffer_size.width = width_in_pixels;
+ framebuffer_size.height = height_in_pixels;
+
+ float window_aspect_ratio = static_cast<float>(height_in_pixels) / width_in_pixels;
+ float emulation_aspect_ratio = static_cast<float>(resolution_height) / resolution_width;
+
+ if (window_aspect_ratio > emulation_aspect_ratio) {
+ // If the window is more narrow than the emulation content, borders are applied on the
+ // top and bottom of the window.
+ viewport_extent.width = width_in_pixels;
+ viewport_extent.height = emulation_aspect_ratio * viewport_extent.width;
+ viewport_extent.x = 0;
+ viewport_extent.y = (height_in_pixels - viewport_extent.height) / 2;
+ } else {
+ // Otherwise, borders are applied on the left and right sides of the window.
+ viewport_extent.height = height_in_pixels;
+ viewport_extent.width = (1 / emulation_aspect_ratio) * viewport_extent.height;
+ viewport_extent.x = (width_in_pixels - viewport_extent.width) / 2;
+ viewport_extent.y = 0;
+ }
+}
+
/// Initialize the renderer
void RendererOpenGL::Init() {
render_window->MakeCurrent();
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index eed201a9..d440e2bc 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -52,12 +52,27 @@ private:
static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer,
const TextureInfo& texture);
+ /// Updates the viewport rectangle
+ void UpdateViewportExtent();
+
EmuWindow* render_window; ///< Handle to render window
u32 last_mode; ///< Last render mode
int resolution_width; ///< Current resolution width
int resolution_height; ///< Current resolution height
+ struct {
+ int width;
+ int height;
+ } framebuffer_size; ///< Current framebuffer size
+
+ struct {
+ int x;
+ int y;
+ int width;
+ int height;
+ } viewport_extent; ///< Current viewport rectangle
+
// OpenGL object IDs
GLuint vertex_array_handle;
GLuint vertex_buffer_handle;