From c5c6e095f037a0128de156103f5b98d5bf2b417c Mon Sep 17 00:00:00 2001
From: Tony Wasserka <NeoBrainX@gmail.com>
Date: Thu, 13 Nov 2014 19:33:29 +0100
Subject: [PATCH] OpenGL Renderer: Cleanup viewport extent calculation.

---
 .../renderer_opengl/renderer_opengl.cpp       | 49 +++++++++----------
 .../renderer_opengl/renderer_opengl.h         | 26 +++-------
 2 files changed, 30 insertions(+), 45 deletions(-)

diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 082a464b32..729e8e73d1 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -191,8 +191,8 @@ void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x
  * Draws the emulated screens to the emulator window.
  */
 void RendererOpenGL::DrawScreens() {
-    UpdateViewportExtent();
-    glViewport(viewport_extent.x, viewport_extent.y, viewport_extent.width, viewport_extent.height);
+    auto viewport_extent = GetViewportExtent();
+    glViewport(viewport_extent.left, viewport_extent.top, viewport_extent.GetWidth(), viewport_extent.GetHeight()); // TODO: Or bottom?
     glClear(GL_COLOR_BUFFER_BIT);
 
     glUseProgram(program_id);
@@ -229,37 +229,32 @@ void RendererOpenGL::SetWindow(EmuWindow* window) {
     render_window = window;
 }
 
-void RendererOpenGL::UpdateViewportExtent() {
-    unsigned width_in_pixels;
-    unsigned height_in_pixels;
+MathUtil::Rectangle<unsigned> RendererOpenGL::GetViewportExtent() {
+    unsigned framebuffer_width;
+    unsigned framebuffer_height;
+    std::tie(framebuffer_width, framebuffer_height) = render_window->GetFramebufferSize();
 
-    std::tie(width_in_pixels, height_in_pixels) = render_window->GetFramebufferSize();
-
-    // 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 window_aspect_ratio = static_cast<float>(framebuffer_height) / framebuffer_width;
     float emulation_aspect_ratio = static_cast<float>(resolution_height) / resolution_width;
 
+    MathUtil::Rectangle<unsigned> viewport_extent;
     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;
+		// Window is narrower than the emulation content => apply borders to the top and bottom
+        unsigned viewport_height = emulation_aspect_ratio * framebuffer_width;
+        viewport_extent.left = 0;
+        viewport_extent.top = (framebuffer_height - viewport_height) / 2;
+        viewport_extent.right = viewport_extent.left + framebuffer_width;
+        viewport_extent.bottom = viewport_extent.top + viewport_height;
     } 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;
+        // Otherwise, apply borders to the left and right sides of the window.
+        unsigned viewport_width = framebuffer_height / emulation_aspect_ratio;
+        viewport_extent.left = (framebuffer_width - viewport_width) / 2;
+        viewport_extent.top = 0;
+        viewport_extent.right = viewport_extent.left + viewport_width;
+        viewport_extent.bottom = viewport_extent.top + framebuffer_height;
     }
+
+    return viewport_extent;
 }
 
 /// Initialize the renderer
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index d440e2bc79..7fdcec7319 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -4,13 +4,15 @@
 
 #pragma once
 
+#include <array>
+
 #include "generated/gl_3_2_core.h"
 
-#include "common/common.h"
-#include "core/hw/gpu.h"
-#include "video_core/renderer_base.h"
+#include "common/math_util.h"
 
-#include <array>
+#include "core/hw/gpu.h"
+
+#include "video_core/renderer_base.h"
 
 class EmuWindow;
 
@@ -52,8 +54,8 @@ private:
     static void LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer,
                                         const TextureInfo& texture);
 
-    /// Updates the viewport rectangle
-    void UpdateViewportExtent();
+    /// Computes the viewport rectangle
+    MathUtil::Rectangle<unsigned> GetViewportExtent();
 
     EmuWindow*  render_window;                    ///< Handle to render window
     u32         last_mode;                        ///< Last render mode
@@ -61,18 +63,6 @@ private:
     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;