summaryrefslogtreecommitdiff
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 0c774bbc5..d0f6e9a9e 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() {
34 return glfwWindowShouldClose(m_render_window) == 0; 34 return glfwWindowShouldClose(m_render_window) == 0;
35} 35}
36 36
37void EmuWindow_GLFW::GetFramebufferSize(int* fbWidth, int* fbHeight) {
38 glfwGetFramebufferSize(m_render_window, fbWidth, fbHeight);
39}
40
37/// EmuWindow_GLFW constructor 41/// EmuWindow_GLFW constructor
38EmuWindow_GLFW::EmuWindow_GLFW() { 42EmuWindow_GLFW::EmuWindow_GLFW() {
39 keyboard_id = KeyMap::NewDeviceId(); 43 keyboard_id = KeyMap::NewDeviceId();
@@ -64,6 +68,7 @@ EmuWindow_GLFW::EmuWindow_GLFW() {
64 glfwSetWindowUserPointer(m_render_window, this); 68 glfwSetWindowUserPointer(m_render_window, this);
65 glfwSetKeyCallback(m_render_window, OnKeyEvent); 69 glfwSetKeyCallback(m_render_window, OnKeyEvent);
66 70
71
67 DoneCurrent(); 72 DoneCurrent();
68} 73}
69 74
diff --git a/src/citra/emu_window/emu_window_glfw.h b/src/citra/emu_window/emu_window_glfw.h
index 7c3072145..e96228765 100644
--- a/src/citra/emu_window/emu_window_glfw.h
+++ b/src/citra/emu_window/emu_window_glfw.h
@@ -21,7 +21,7 @@ public:
21 21
22 /// Makes the graphics context current for the caller thread 22 /// Makes the graphics context current for the caller thread
23 void MakeCurrent() override; 23 void MakeCurrent() override;
24 24
25 /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread 25 /// Releases (dunno if this is the "right" word) the GLFW context from the caller thread
26 void DoneCurrent() override; 26 void DoneCurrent() override;
27 27
@@ -32,6 +32,9 @@ public:
32 32
33 void ReloadSetKeymaps() override; 33 void ReloadSetKeymaps() override;
34 34
35 /// Gets the size of the window in pixels
36 void GetFramebufferSize(int* fbWidth, int* fbHeight);
37
35private: 38private:
36 GLFWwindow* m_render_window; ///< Internal GLFW render window 39 GLFWwindow* m_render_window; ///< Internal GLFW render window
37 40
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 @@
2#include <QKeyEvent> 2#include <QKeyEvent>
3#include <QApplication> 3#include <QApplication>
4 4
5#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
6// Required for screen DPI information
7#include <QScreen>
8#include <QWindow>
9#endif
10
5#include "common/common.h" 11#include "common/common.h"
6#include "bootmanager.hxx" 12#include "bootmanager.hxx"
7 13
@@ -176,6 +182,24 @@ void GRenderWindow::PollEvents() {
176 */ 182 */
177} 183}
178 184
185// On Qt 5.1+, this correctly gets the size of the framebuffer (pixels).
186//
187// Older versions get the window size (density independent pixels),
188// and hence, do not support DPI scaling ("retina" displays).
189// The result will be a viewport that is smaller than the extent of the window.
190void GRenderWindow::GetFramebufferSize(int* fbWidth, int* fbHeight)
191{
192#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
193 int pixelRatio = child->QPaintDevice::devicePixelRatio();
194
195 *fbWidth = child->QPaintDevice::width() * pixelRatio;
196 *fbHeight = child->QPaintDevice::height() * pixelRatio;
197#else
198 *fbWidth = child->QPaintDevice::width();
199 *fbHeight = child->QPaintDevice::height();
200#endif
201}
202
179void GRenderWindow::BackupGeometry() 203void GRenderWindow::BackupGeometry()
180{ 204{
181 geometry = ((QGLWidget*)this)->saveGeometry(); 205 geometry = ((QGLWidget*)this)->saveGeometry();
diff --git a/src/citra_qt/bootmanager.hxx b/src/citra_qt/bootmanager.hxx
index f8afc403e..ec3e1fe71 100644
--- a/src/citra_qt/bootmanager.hxx
+++ b/src/citra_qt/bootmanager.hxx
@@ -96,6 +96,7 @@ public:
96 void MakeCurrent() override; 96 void MakeCurrent() override;
97 void DoneCurrent() override; 97 void DoneCurrent() override;
98 void PollEvents() override; 98 void PollEvents() override;
99 void GetFramebufferSize(int* fbWidth, int* fbHeight) override;
99 100
100 void BackupGeometry(); 101 void BackupGeometry();
101 void RestoreGeometry(); 102 void RestoreGeometry();
diff --git a/src/common/emu_window.h b/src/common/emu_window.h
index 6c2b598f6..ba9d4fa76 100644
--- a/src/common/emu_window.h
+++ b/src/common/emu_window.h
@@ -49,8 +49,11 @@ public:
49 void SetConfig(const WindowConfig& val) { 49 void SetConfig(const WindowConfig& val) {
50 m_config = val; 50 m_config = val;
51 } 51 }
52 52
53 int GetClientAreaWidth() const { 53 /// Gets the size of the window in pixels
54 virtual void GetFramebufferSize(int* fbWidth, int* fbHeight) = 0;
55
56 int GetClientAreaWidth() const {
54 return m_client_area_width; 57 return m_client_area_width;
55 } 58 }
56 59
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 8483f79be..3757482db 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
191 * Draws the emulated screens to the emulator window. 191 * Draws the emulated screens to the emulator window.
192 */ 192 */
193void RendererOpenGL::DrawScreens() { 193void RendererOpenGL::DrawScreens() {
194 glViewport(0, 0, resolution_width, resolution_height); 194 UpdateViewportExtent();
195 glViewport(viewport_extent.x, viewport_extent.y, viewport_extent.width, viewport_extent.height);
195 glClear(GL_COLOR_BUFFER_BIT); 196 glClear(GL_COLOR_BUFFER_BIT);
196 197
197 glUseProgram(program_id); 198 glUseProgram(program_id);
@@ -228,6 +229,39 @@ void RendererOpenGL::SetWindow(EmuWindow* window) {
228 render_window = window; 229 render_window = window;
229} 230}
230 231
232void RendererOpenGL::UpdateViewportExtent() {
233 int width_in_pixels;
234 int height_in_pixels;
235
236 render_window->GetFramebufferSize(&width_in_pixels, &height_in_pixels);
237
238 // No update needed if framebuffer size hasn't changed
239 if (width_in_pixels == framebuffer_size.width && height_in_pixels == framebuffer_size.height) {
240 return;
241 }
242
243 framebuffer_size.width = width_in_pixels;
244 framebuffer_size.height = height_in_pixels;
245
246 float window_aspect_ratio = static_cast<float>(height_in_pixels) / width_in_pixels;
247 float emulation_aspect_ratio = static_cast<float>(resolution_height) / resolution_width;
248
249 if (window_aspect_ratio > emulation_aspect_ratio) {
250 // If the window is more narrow than the emulation content, borders are applied on the
251 // top and bottom of the window.
252 viewport_extent.width = width_in_pixels;
253 viewport_extent.height = emulation_aspect_ratio * viewport_extent.width;
254 viewport_extent.x = 0;
255 viewport_extent.y = (height_in_pixels - viewport_extent.height) / 2;
256 } else {
257 // Otherwise, borders are applied on the left and right sides of the window.
258 viewport_extent.height = height_in_pixels;
259 viewport_extent.width = (1 / emulation_aspect_ratio) * viewport_extent.height;
260 viewport_extent.x = (width_in_pixels - viewport_extent.width) / 2;
261 viewport_extent.y = 0;
262 }
263}
264
231/// Initialize the renderer 265/// Initialize the renderer
232void RendererOpenGL::Init() { 266void RendererOpenGL::Init() {
233 render_window->MakeCurrent(); 267 render_window->MakeCurrent();
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index eed201a95..d440e2bc7 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -52,12 +52,27 @@ private:
52 static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer, 52 static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer,
53 const TextureInfo& texture); 53 const TextureInfo& texture);
54 54
55 /// Updates the viewport rectangle
56 void UpdateViewportExtent();
57
55 EmuWindow* render_window; ///< Handle to render window 58 EmuWindow* render_window; ///< Handle to render window
56 u32 last_mode; ///< Last render mode 59 u32 last_mode; ///< Last render mode
57 60
58 int resolution_width; ///< Current resolution width 61 int resolution_width; ///< Current resolution width
59 int resolution_height; ///< Current resolution height 62 int resolution_height; ///< Current resolution height
60 63
64 struct {
65 int width;
66 int height;
67 } framebuffer_size; ///< Current framebuffer size
68
69 struct {
70 int x;
71 int y;
72 int width;
73 int height;
74 } viewport_extent; ///< Current viewport rectangle
75
61 // OpenGL object IDs 76 // OpenGL object IDs
62 GLuint vertex_array_handle; 77 GLuint vertex_array_handle;
63 GLuint vertex_buffer_handle; 78 GLuint vertex_buffer_handle;