From 0f2ac928f291101bd74aac661cff7d14dfa8c984 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Wed, 1 Aug 2018 20:59:42 -0400
Subject: [PATCH] video_core: Make global EmuWindow instance part of the base
 renderer class

Makes the global a member of the RendererBase class. We also change this
to be a reference. Passing any form of null pointer to these functions
is incorrect entirely, especially given the code itself assumes that the
pointer would always be in a valid state.

This also makes it easier to follow the lifecycle of instances being
used, as we explicitly interact the renderer with the rasterizer, rather
than it just operating on a global pointer.
---
 src/core/core.cpp                             |  4 +--
 src/core/core.h                               | 10 ++++---
 src/core/settings.cpp                         |  8 +++---
 src/video_core/renderer_base.cpp              | 14 +++++++---
 src/video_core/renderer_base.h                | 15 +++++------
 .../renderer_opengl/gl_rasterizer.cpp         |  7 +++--
 .../renderer_opengl/gl_rasterizer.h           |  5 +++-
 .../renderer_opengl/renderer_opengl.cpp       | 26 +++++++------------
 .../renderer_opengl/renderer_opengl.h         | 15 ++++-------
 src/video_core/video_core.cpp                 |  7 ++---
 src/video_core/video_core.h                   |  3 +--
 src/yuzu/main.cpp                             |  2 +-
 src/yuzu_cmd/yuzu.cpp                         |  2 +-
 13 files changed, 54 insertions(+), 64 deletions(-)

diff --git a/src/core/core.cpp b/src/core/core.cpp
index b7f4b45323..be8cf9c2bc 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -86,7 +86,7 @@ System::ResultStatus System::SingleStep() {
     return RunLoop(false);
 }
 
-System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) {
+System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& filepath) {
     app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath));
 
     if (!app_loader) {
@@ -163,7 +163,7 @@ Cpu& System::CpuCore(size_t core_index) {
     return *cpu_cores[core_index];
 }
 
-System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
+System::ResultStatus System::Init(EmuWindow& emu_window, u32 system_mode) {
     LOG_DEBUG(HW_Memory, "initialized OK");
 
     CoreTiming::Init();
diff --git a/src/core/core.h b/src/core/core.h
index c123fe4018..515923a24a 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -81,11 +81,12 @@ public:
 
     /**
      * Load an executable application.
-     * @param emu_window Pointer to the host-system window used for video output and keyboard input.
+     * @param emu_window Reference to the host-system window used for video output and keyboard
+     *                   input.
      * @param filepath String path to the executable application to load on the host file system.
      * @returns ResultStatus code, indicating if the operation succeeded.
      */
-    ResultStatus Load(EmuWindow* emu_window, const std::string& filepath);
+    ResultStatus Load(EmuWindow& emu_window, const std::string& filepath);
 
     /**
      * Indicates if the emulated system is powered on (all subsystems initialized and able to run an
@@ -186,11 +187,12 @@ private:
 
     /**
      * Initialize the emulated system.
-     * @param emu_window Pointer to the host-system window used for video output and keyboard input.
+     * @param emu_window Reference to the host-system window used for video output and keyboard
+     *                   input.
      * @param system_mode The system mode.
      * @return ResultStatus code, indicating if the operation succeeded.
      */
-    ResultStatus Init(EmuWindow* emu_window, u32 system_mode);
+    ResultStatus Init(EmuWindow& emu_window, u32 system_mode);
 
     /// AppLoader used to load the current executing application
     std::unique_ptr<Loader::AppLoader> app_loader;
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 444bcc387d..79e0b347b8 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -5,10 +5,9 @@
 #include "core/gdbstub/gdbstub.h"
 #include "core/hle/service/hid/hid.h"
 #include "core/settings.h"
+#include "video_core/renderer_base.h"
 #include "video_core/video_core.h"
 
-#include "core/frontend/emu_window.h"
-
 namespace Settings {
 
 Values values = {};
@@ -20,9 +19,8 @@ void Apply() {
 
     VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit;
 
-    if (VideoCore::g_emu_window) {
-        auto layout = VideoCore::g_emu_window->GetFramebufferLayout();
-        VideoCore::g_emu_window->UpdateCurrentFramebufferLayout(layout.width, layout.height);
+    if (VideoCore::g_renderer) {
+        VideoCore::g_renderer->UpdateCurrentFramebufferLayout();
     }
 
     Service::HID::ReloadInputDevices();
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp
index 30075b23c1..dbe3edf09a 100644
--- a/src/video_core/renderer_base.cpp
+++ b/src/video_core/renderer_base.cpp
@@ -2,14 +2,22 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
-#include <atomic>
 #include <memory>
+#include "core/frontend/emu_window.h"
 #include "video_core/renderer_base.h"
 #include "video_core/renderer_opengl/gl_rasterizer.h"
-#include "video_core/video_core.h"
+
+RendererBase::RendererBase(EmuWindow& window) : render_window{window} {}
+RendererBase::~RendererBase() = default;
+
+void RendererBase::UpdateCurrentFramebufferLayout() {
+    const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout();
+
+    render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height);
+}
 
 void RendererBase::RefreshRasterizerSetting() {
     if (rasterizer == nullptr) {
-        rasterizer = std::make_unique<RasterizerOpenGL>();
+        rasterizer = std::make_unique<RasterizerOpenGL>(render_window);
     }
 }
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h
index 89a960eaf8..1cb161b7f9 100644
--- a/src/video_core/renderer_base.h
+++ b/src/video_core/renderer_base.h
@@ -18,23 +18,21 @@ public:
     /// Used to reference a framebuffer
     enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture };
 
-    virtual ~RendererBase() {}
+    explicit RendererBase(EmuWindow& window);
+    virtual ~RendererBase();
 
     /// Swap buffers (render frame)
     virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0;
 
-    /**
-     * Set the emulator window to use for renderer
-     * @param window EmuWindow handle to emulator window to use for rendering
-     */
-    virtual void SetWindow(EmuWindow* window) = 0;
-
     /// Initialize the renderer
     virtual bool Init() = 0;
 
     /// Shutdown the renderer
     virtual void ShutDown() = 0;
 
+    /// Updates the framebuffer layout of the contained render window handle.
+    void UpdateCurrentFramebufferLayout();
+
     // Getter/setter functions:
     // ------------------------
 
@@ -53,9 +51,8 @@ public:
     void RefreshRasterizerSetting();
 
 protected:
+    EmuWindow& render_window; ///< Reference to the render window handle.
     std::unique_ptr<VideoCore::RasterizerInterface> rasterizer;
     f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer
     int m_current_frame = 0;  ///< Current frame, should be set by the renderer
-
-private:
 };
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a1c47bae99..6555db5bbb 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -14,7 +14,6 @@
 #include "common/logging/log.h"
 #include "common/math_util.h"
 #include "common/microprofile.h"
-#include "common/scope_exit.h"
 #include "core/core.h"
 #include "core/frontend/emu_window.h"
 #include "core/hle/kernel/process.h"
@@ -37,7 +36,7 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192));
 MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255));
 MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));
 
-RasterizerOpenGL::RasterizerOpenGL() {
+RasterizerOpenGL::RasterizerOpenGL(EmuWindow& window) : emu_window{window} {
     // Create sampler objects
     for (size_t i = 0; i < texture_samplers.size(); ++i) {
         texture_samplers[i].Create();
@@ -395,7 +394,7 @@ void RasterizerOpenGL::Clear() {
     if (clear_mask == 0)
         return;
 
-    ScopeAcquireGLContext acquire_context;
+    ScopeAcquireGLContext acquire_context{emu_window};
 
     auto [dirty_color_surface, dirty_depth_surface] =
         ConfigureFramebuffers(use_color_fb, use_depth_fb);
@@ -425,7 +424,7 @@ void RasterizerOpenGL::DrawArrays() {
     MICROPROFILE_SCOPE(OpenGL_Drawing);
     const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
-    ScopeAcquireGLContext acquire_context;
+    ScopeAcquireGLContext acquire_context{emu_window};
 
     auto [dirty_color_surface, dirty_depth_surface] =
         ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index e150be58f6..6d6d85cc10 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -21,11 +21,12 @@
 #include "video_core/renderer_opengl/gl_state.h"
 #include "video_core/renderer_opengl/gl_stream_buffer.h"
 
+class EmuWindow;
 struct ScreenInfo;
 
 class RasterizerOpenGL : public VideoCore::RasterizerInterface {
 public:
-    RasterizerOpenGL();
+    explicit RasterizerOpenGL(EmuWindow& renderer);
     ~RasterizerOpenGL() override;
 
     void DrawArrays() override;
@@ -144,6 +145,8 @@ private:
 
     RasterizerCacheOpenGL res_cache;
 
+    EmuWindow& emu_window;
+
     std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
     OGLVertexArray sw_vao;
     OGLVertexArray hw_vao;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 7810b9147b..74383c7cfc 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -92,23 +92,23 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
     return matrix;
 }
 
-ScopeAcquireGLContext::ScopeAcquireGLContext() {
+ScopeAcquireGLContext::ScopeAcquireGLContext(EmuWindow& emu_window_) : emu_window{emu_window_} {
     if (Settings::values.use_multi_core) {
-        VideoCore::g_emu_window->MakeCurrent();
+        emu_window.MakeCurrent();
     }
 }
 ScopeAcquireGLContext::~ScopeAcquireGLContext() {
     if (Settings::values.use_multi_core) {
-        VideoCore::g_emu_window->DoneCurrent();
+        emu_window.DoneCurrent();
     }
 }
 
-RendererOpenGL::RendererOpenGL() = default;
+RendererOpenGL::RendererOpenGL(EmuWindow& window) : RendererBase{window} {}
 RendererOpenGL::~RendererOpenGL() = default;
 
 /// Swap buffers (render frame)
 void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) {
-    ScopeAcquireGLContext acquire_context;
+    ScopeAcquireGLContext acquire_context{render_window};
 
     Core::System::GetInstance().perf_stats.EndSystemFrame();
 
@@ -130,10 +130,10 @@ void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&
         // Load the framebuffer from memory, draw it to the screen, and swap buffers
         LoadFBToScreenInfo(*framebuffer, screen_info);
         DrawScreen();
-        render_window->SwapBuffers();
+        render_window.SwapBuffers();
     }
 
-    render_window->PollEvents();
+    render_window.PollEvents();
 
     Core::System::GetInstance().frame_limiter.DoFrameLimiting(CoreTiming::GetGlobalTimeUs());
     Core::System::GetInstance().perf_stats.BeginSystemFrame();
@@ -356,7 +356,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
  * Draws the emulated screens to the emulator window.
  */
 void RendererOpenGL::DrawScreen() {
-    const auto& layout = render_window->GetFramebufferLayout();
+    const auto& layout = render_window.GetFramebufferLayout();
     const auto& screen = layout.screen;
 
     glViewport(0, 0, layout.width, layout.height);
@@ -380,14 +380,6 @@ void RendererOpenGL::DrawScreen() {
 /// Updates the framerate
 void RendererOpenGL::UpdateFramerate() {}
 
-/**
- * Set the emulator window to use for renderer
- * @param window EmuWindow handle to emulator window to use for rendering
- */
-void RendererOpenGL::SetWindow(EmuWindow* window) {
-    render_window = window;
-}
-
 static const char* GetSource(GLenum source) {
 #define RET(s)                                                                                     \
     case GL_DEBUG_SOURCE_##s:                                                                      \
@@ -445,7 +437,7 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum
 
 /// Initialize the renderer
 bool RendererOpenGL::Init() {
-    ScopeAcquireGLContext acquire_context;
+    ScopeAcquireGLContext acquire_context{render_window};
 
     if (GLAD_GL_KHR_debug) {
         glEnable(GL_DEBUG_OUTPUT);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 59d92a3dc8..ab7de41c8b 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -34,24 +34,21 @@ struct ScreenInfo {
 /// Helper class to acquire/release OpenGL context within a given scope
 class ScopeAcquireGLContext : NonCopyable {
 public:
-    ScopeAcquireGLContext();
+    explicit ScopeAcquireGLContext(EmuWindow& window);
     ~ScopeAcquireGLContext();
+
+private:
+    EmuWindow& emu_window;
 };
 
 class RendererOpenGL : public RendererBase {
 public:
-    RendererOpenGL();
+    explicit RendererOpenGL(EmuWindow& window);
     ~RendererOpenGL() override;
 
     /// Swap buffers (render frame)
     void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override;
 
-    /**
-     * Set the emulator window to use for renderer
-     * @param window EmuWindow handle to emulator window to use for rendering
-     */
-    void SetWindow(EmuWindow* window) override;
-
     /// Initialize the renderer
     bool Init() override;
 
@@ -72,8 +69,6 @@ private:
     void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
                                     const TextureInfo& texture);
 
-    EmuWindow* render_window; ///< Handle to render window
-
     OpenGLState state;
 
     // OpenGL object IDs
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp
index 289140f31a..06b13e6817 100644
--- a/src/video_core/video_core.cpp
+++ b/src/video_core/video_core.cpp
@@ -13,16 +13,13 @@
 
 namespace VideoCore {
 
-EmuWindow* g_emu_window = nullptr;        ///< Frontend emulator window
 std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
 
 std::atomic<bool> g_toggle_framelimit_enabled;
 
 /// Initialize the video core
-bool Init(EmuWindow* emu_window) {
-    g_emu_window = emu_window;
-    g_renderer = std::make_unique<RendererOpenGL>();
-    g_renderer->SetWindow(g_emu_window);
+bool Init(EmuWindow& emu_window) {
+    g_renderer = std::make_unique<RendererOpenGL>(emu_window);
     if (g_renderer->Init()) {
         LOG_DEBUG(Render, "initialized OK");
     } else {
diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h
index 37da624369..8707e98813 100644
--- a/src/video_core/video_core.h
+++ b/src/video_core/video_core.h
@@ -18,7 +18,6 @@ namespace VideoCore {
 enum class Renderer { Software, OpenGL };
 
 extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin
-extern EmuWindow* g_emu_window;                  ///< Emu window
 
 // TODO: Wrap these in a user settings struct along with any other graphics settings (often set from
 // qt ui)
@@ -28,7 +27,7 @@ extern std::atomic<bool> g_toggle_framelimit_enabled;
 void Start();
 
 /// Initialize the video core
-bool Init(EmuWindow* emu_window);
+bool Init(EmuWindow& emu_window);
 
 /// Shutdown the video core
 void Shutdown();
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index be38cfa9bc..341867f7b3 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -402,7 +402,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
 
     system.SetGPUDebugContext(debug_context);
 
-    const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())};
+    const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())};
 
     render_window->DoneCurrent();
 
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index b5392c499b..5ff6266bff 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -162,7 +162,7 @@ int main(int argc, char** argv) {
 
     SCOPE_EXIT({ system.Shutdown(); });
 
-    const Core::System::ResultStatus load_result{system.Load(emu_window.get(), filepath)};
+    const Core::System::ResultStatus load_result{system.Load(*emu_window, filepath)};
 
     switch (load_result) {
     case Core::System::ResultStatus::ErrorGetLoader: