diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp index da3e47aa26..d56d048d1b 100644 --- a/Source/Core/Common/GL/GLContext.cpp +++ b/Source/Core/Common/GL/GLContext.cpp @@ -23,8 +23,6 @@ #error Platform doesnt have a GLInterface #endif -std::unique_ptr g_main_gl_context; - GLContext::~GLContext() = default; bool GLContext::Initialize(void* display_handle, void* window_handle, bool stereo, bool core) diff --git a/Source/Core/Common/GL/GLContext.h b/Source/Core/Common/GL/GLContext.h index c9e1d8c457..89dba55286 100644 --- a/Source/Core/Common/GL/GLContext.h +++ b/Source/Core/Common/GL/GLContext.h @@ -60,5 +60,3 @@ protected: bool m_is_core_context = false; bool m_is_shared = false; }; - -extern std::unique_ptr g_main_gl_context; diff --git a/Source/Core/Common/GL/GLExtensions/GLExtensions.cpp b/Source/Core/Common/GL/GLExtensions/GLExtensions.cpp index 18c4dc2f39..641559a29a 100644 --- a/Source/Core/Common/GL/GLExtensions/GLExtensions.cpp +++ b/Source/Core/Common/GL/GLExtensions/GLExtensions.cpp @@ -2148,12 +2148,11 @@ const GLFunc gl_function_array[] = { namespace GLExtensions { // Private members and functions -static bool _isES; -static u32 _GLVersion; -static std::unordered_map m_extension_list; +static u32 s_gl_version; +static std::unordered_map s_extension_list; // Private initialization functions -bool InitFunctionPointers(); +bool InitFunctionPointers(GLContext* context); // Initializes the extension list the old way static void InitExtensionList21() @@ -2163,28 +2162,28 @@ static void InitExtensionList21() std::istringstream buffer(tmp); while (buffer >> tmp) - m_extension_list[tmp] = true; + s_extension_list[tmp] = true; } -static void InitExtensionList() +static void InitExtensionList(GLContext* context) { - m_extension_list.clear(); - if (_isES) + s_extension_list.clear(); + if (context->IsGLES()) { - switch (_GLVersion) + switch (s_gl_version) { default: case 320: - m_extension_list["VERSION_GLES_3_2"] = true; + s_extension_list["VERSION_GLES_3_2"] = true; case 310: - m_extension_list["VERSION_GLES_3_1"] = true; + s_extension_list["VERSION_GLES_3_1"] = true; case 300: - m_extension_list["VERSION_GLES_3"] = true; + s_extension_list["VERSION_GLES_3"] = true; break; } // We always have ES 2.0 - m_extension_list["VERSION_GLES_2"] = true; + s_extension_list["VERSION_GLES_2"] = true; } else { @@ -2194,7 +2193,7 @@ static void InitExtensionList() // When an extension got merged in to core, the naming may have changed // This has intentional fall through - switch (_GLVersion) + switch (s_gl_version) { default: case 450: @@ -2213,7 +2212,7 @@ static void InitExtensionList() "VERSION_4_5", }; for (auto it : gl450exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 440: { @@ -2229,7 +2228,7 @@ static void InitExtensionList() "VERSION_4_4", }; for (auto it : gl440exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 430: { @@ -2257,7 +2256,7 @@ static void InitExtensionList() "VERSION_4_3", }; for (auto it : gl430exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 420: { @@ -2277,7 +2276,7 @@ static void InitExtensionList() "VERSION_4_2", }; for (auto it : gl420exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 410: { @@ -2291,7 +2290,7 @@ static void InitExtensionList() "VERSION_4_1", }; for (auto it : gl410exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 400: { @@ -2311,7 +2310,7 @@ static void InitExtensionList() "VERSION_4_0", }; for (auto it : gl400exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 330: { @@ -2329,7 +2328,7 @@ static void InitExtensionList() "VERSION_3_3", }; for (auto it : gl330exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 320: { @@ -2346,7 +2345,7 @@ static void InitExtensionList() "VERSION_3_2", }; for (auto it : gl320exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 310: { @@ -2361,7 +2360,7 @@ static void InitExtensionList() "VERSION_3_1", }; for (auto it : gl310exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 300: { @@ -2392,7 +2391,7 @@ static void InitExtensionList() "VERSION_3_0", }; for (auto it : gl300exts) - m_extension_list[it] = true; + s_extension_list[it] = true; } case 210: case 200: @@ -2406,10 +2405,10 @@ static void InitExtensionList() break; } // So we can easily determine if we are running dekstop GL - m_extension_list["VERSION_GL"] = true; + s_extension_list["VERSION_GL"] = true; } - if (_GLVersion < 300) + if (s_gl_version < 300) { InitExtensionList21(); return; @@ -2417,7 +2416,7 @@ static void InitExtensionList() GLint NumExtension = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &NumExtension); for (GLint i = 0; i < NumExtension; ++i) - m_extension_list[std::string((const char*)glGetStringi(GL_EXTENSIONS, i))] = true; + s_extension_list[std::string((const char*)glGetStringi(GL_EXTENSIONS, i))] = true; } static void InitVersion() { @@ -2425,14 +2424,14 @@ static void InitVersion() glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor); if (glGetError() == GL_NO_ERROR) - _GLVersion = major * 100 + minor * 10; + s_gl_version = major * 100 + minor * 10; else - _GLVersion = 210; + s_gl_version = 210; } -static void* GetFuncAddress(const std::string& name, void** func) +static void* GetFuncAddress(GLContext* context, const std::string& name, void** func) { - *func = g_main_gl_context->GetFuncAddress(name); + *func = context->GetFuncAddress(name); if (*func == nullptr) { #if defined(__linux__) || defined(__APPLE__) @@ -2448,37 +2447,36 @@ static void* GetFuncAddress(const std::string& name, void** func) // Public members u32 Version() { - return _GLVersion; + return s_gl_version; } bool Supports(const std::string& name) { - return m_extension_list[name]; + return s_extension_list[name]; } -bool Init() +bool Init(GLContext* context) { - _isES = g_main_gl_context->GetMode() == GLContext::Mode::OpenGLES; - // Grab a few functions for initial checking // We need them to grab the extension list // Also to check if there is an error grabbing the version - if (GetFuncAddress("glGetIntegerv", (void**)&glGetIntegerv) == nullptr) + if (GetFuncAddress(context, "glGetIntegerv", (void**)&glGetIntegerv) == nullptr) return false; - if (GetFuncAddress("glGetString", (void**)&glGetString) == nullptr) + if (GetFuncAddress(context, "glGetString", (void**)&glGetString) == nullptr) return false; - if (GetFuncAddress("glGetError", (void**)&glGetError) == nullptr) + if (GetFuncAddress(context, "glGetError", (void**)&glGetError) == nullptr) return false; InitVersion(); // We need to use glGetStringi to get the extension list // if we are using GLES3 or a GL version greater than 2.1 - if (_GLVersion > 210 && GetFuncAddress("glGetStringi", (void**)&glGetStringi) == nullptr) + if (s_gl_version > 210 && + GetFuncAddress(context, "glGetStringi", (void**)&glGetStringi) == nullptr) return false; - InitExtensionList(); + InitExtensionList(context); - return InitFunctionPointers(); + return InitFunctionPointers(context); } // Private initialization functions @@ -2491,20 +2489,20 @@ static bool HasFeatures(const std::string& extensions) while (buffer >> tmp) { if (tmp[0] == '!') - result &= !m_extension_list[tmp.erase(0, 1)]; + result &= !s_extension_list[tmp.erase(0, 1)]; else if (tmp[0] == '|') - result |= m_extension_list[tmp.erase(0, 1)]; + result |= s_extension_list[tmp.erase(0, 1)]; else - result &= m_extension_list[tmp]; + result &= s_extension_list[tmp]; } return result; } -bool InitFunctionPointers() +bool InitFunctionPointers(GLContext* context) { bool result = true; for (const auto& it : gl_function_array) if (HasFeatures(it.requirements)) - result &= !!GetFuncAddress(it.function_name, it.function_ptr); + result &= !!GetFuncAddress(context, it.function_name, it.function_ptr); return result; } } // namespace GLExtensions diff --git a/Source/Core/Common/GL/GLExtensions/GLExtensions.h b/Source/Core/Common/GL/GLExtensions/GLExtensions.h index 2c0364da48..f1e258f98e 100644 --- a/Source/Core/Common/GL/GLExtensions/GLExtensions.h +++ b/Source/Core/Common/GL/GLExtensions/GLExtensions.h @@ -54,10 +54,12 @@ #include "Common/GL/GLExtensions/gl_4_4.h" #include "Common/GL/GLExtensions/gl_4_5.h" +class GLContext; + namespace GLExtensions { // Initializes the interface -bool Init(); +bool Init(GLContext* context); // Function for checking if the hardware supports an extension // example: if (GLExtensions::Supports("GL_ARB_multi_map")) @@ -65,4 +67,4 @@ bool Supports(const std::string& name); // Returns OpenGL version in format 430 u32 Version(); -} +} // namespace GLExtensions diff --git a/Source/Core/Common/GL/GLUtil.cpp b/Source/Core/Common/GL/GLUtil.cpp index 729cc2c25d..ba0f76b9b0 100644 --- a/Source/Core/Common/GL/GLUtil.cpp +++ b/Source/Core/Common/GL/GLUtil.cpp @@ -96,11 +96,11 @@ GLuint CompileProgram(const std::string& vertexShader, const std::string& fragme return programID; } -void EnablePrimitiveRestart() +void EnablePrimitiveRestart(const GLContext* context) { constexpr GLuint PRIMITIVE_RESTART_INDEX = 65535; - if (g_main_gl_context->GetMode() == GLContext::Mode::OpenGLES) + if (context->IsGLES()) { glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); } diff --git a/Source/Core/Common/GL/GLUtil.h b/Source/Core/Common/GL/GLUtil.h index 62605585f3..1ec63ebad0 100644 --- a/Source/Core/Common/GL/GLUtil.h +++ b/Source/Core/Common/GL/GLUtil.h @@ -8,8 +8,10 @@ #include "Common/GL/GLExtensions/GLExtensions.h" +class GLContext; + namespace GLUtil { GLuint CompileProgram(const std::string& vertexShader, const std::string& fragmentShader); -void EnablePrimitiveRestart(); +void EnablePrimitiveRestart(const GLContext* context); } // namespace GLUtil diff --git a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp index 1c1c976f70..12de898ff5 100644 --- a/Source/Core/VideoBackends/OGL/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/OGL/FramebufferManager.cpp @@ -9,7 +9,6 @@ #include "Common/Common.h" #include "Common/CommonTypes.h" -#include "Common/GL/GLContext.h" #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" @@ -414,7 +413,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms glBindBuffer(GL_ARRAY_BUFFER, static_cast(g_vertex_manager.get())->GetVertexBufferHandle()); - if (!g_main_gl_context->IsGLES()) + if (!static_cast(g_renderer.get())->IsGLES()) glEnable(GL_PROGRAM_POINT_SIZE); } diff --git a/Source/Core/VideoBackends/OGL/PerfQuery.cpp b/Source/Core/VideoBackends/OGL/PerfQuery.cpp index 30a6e1781b..77471cee19 100644 --- a/Source/Core/VideoBackends/OGL/PerfQuery.cpp +++ b/Source/Core/VideoBackends/OGL/PerfQuery.cpp @@ -6,24 +6,23 @@ #include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" -#include "Common/GL/GLContext.h" -#include "Common/GL/GLUtil.h" +#include "Common/GL/GLExtensions/GLExtensions.h" #include "VideoBackends/OGL/PerfQuery.h" -#include "VideoCommon/RenderBase.h" +#include "VideoBackends/OGL/Render.h" #include "VideoCommon/VideoConfig.h" namespace OGL { std::unique_ptr GetPerfQuery() { - if (g_main_gl_context->IsGLES() && GLExtensions::Supports("GL_NV_occlusion_query_samples")) + const bool is_gles = static_cast(g_renderer.get())->IsGLES(); + if (is_gles && GLExtensions::Supports("GL_NV_occlusion_query_samples")) return std::make_unique(); - - if (g_main_gl_context->IsGLES()) + else if (is_gles) return std::make_unique(GL_ANY_SAMPLES_PASSED); - - return std::make_unique(GL_SAMPLES_PASSED); + else + return std::make_unique(GL_SAMPLES_PASSED); } PerfQuery::PerfQuery() : m_query_read_pos() diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index ae930dddab..78458aa3fe 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -805,7 +805,8 @@ void ProgramShaderCache::CreateHeader() bool SharedContextAsyncShaderCompiler::WorkerThreadInitMainThread(void** param) { - std::unique_ptr context = g_main_gl_context->CreateSharedContext(); + std::unique_ptr context = + static_cast(g_renderer.get())->GetMainGLContext()->CreateSharedContext(); if (!context) { PanicAlert("Failed to create shared context for shader compiling."); @@ -824,7 +825,7 @@ bool SharedContextAsyncShaderCompiler::WorkerThreadInitWorkerThread(void* param) s_is_shared_context = true; if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart) - GLUtil::EnablePrimitiveRestart(); + GLUtil::EnablePrimitiveRestart(context); return true; } diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index be08541f97..b28df12c6a 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -353,9 +353,10 @@ static void InitDriverInfo() } // Init functions -Renderer::Renderer() - : ::Renderer(static_cast(std::max(g_main_gl_context->GetBackBufferWidth(), 1u)), - static_cast(std::max(g_main_gl_context->GetBackBufferHeight(), 1u))) +Renderer::Renderer(std::unique_ptr main_gl_context) + : ::Renderer(static_cast(std::max(main_gl_context->GetBackBufferWidth(), 1u)), + static_cast(std::max(main_gl_context->GetBackBufferHeight(), 1u))), + m_main_gl_context(std::move(main_gl_context)) { bool bSuccess = true; @@ -365,7 +366,7 @@ Renderer::Renderer() InitDriverInfo(); - if (!g_main_gl_context->IsGLES()) + if (!m_main_gl_context->IsGLES()) { if (!GLExtensions::Supports("GL_ARB_framebuffer_object")) { @@ -500,7 +501,7 @@ Renderer::Renderer() g_Config.backend_info.bSupportsBPTCTextures = GLExtensions::Supports("GL_ARB_texture_compression_bptc"); - if (g_main_gl_context->IsGLES()) + if (m_main_gl_context->IsGLES()) { g_ogl_config.SupportedESPointSize = GLExtensions::Supports("GL_OES_geometry_point_size") ? @@ -731,7 +732,7 @@ Renderer::Renderer() if (!g_ogl_config.bSupportsGLBufferStorage && !g_ogl_config.bSupportsGLPinnedMemory) { OSD::AddMessage(StringFromFormat("Your OpenGL driver does not support %s_buffer_storage.", - g_main_gl_context->IsGLES() ? "EXT" : "ARB"), + m_main_gl_context->IsGLES() ? "EXT" : "ARB"), 60000); OSD::AddMessage("This device's performance will be terrible.", 60000); OSD::AddMessage("Please ask your device vendor for an updated OpenGL driver.", 60000); @@ -760,7 +761,7 @@ Renderer::Renderer() // Handle VSync on/off s_vsync = g_ActiveConfig.IsVSync(); if (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC)) - g_main_gl_context->SwapInterval(s_vsync); + m_main_gl_context->SwapInterval(s_vsync); // Because of the fixed framebuffer size we need to disable the resolution // options while running @@ -795,18 +796,22 @@ Renderer::Renderer() glClearDepthf(1.0f); if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart) - GLUtil::EnablePrimitiveRestart(); + GLUtil::EnablePrimitiveRestart(m_main_gl_context.get()); IndexGenerator::Init(); UpdateActiveConfig(); ClearEFBCache(); } -Renderer::~Renderer() = default; +Renderer::~Renderer() +{ + m_main_gl_context->ClearCurrent(); + m_main_gl_context->Shutdown(); +} bool Renderer::IsHeadless() const { - return g_main_gl_context->IsHeadless(); + return m_main_gl_context->IsHeadless(); } void Renderer::Shutdown() @@ -1048,7 +1053,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) std::unique_ptr colorMap(new u32[targetPixelRcWidth * targetPixelRcHeight]); - if (g_main_gl_context->IsGLES()) + if (IsGLES()) // XXX: Swap colours glReadPixels(targetPixelRc.left, targetPixelRc.bottom, targetPixelRcWidth, targetPixelRcHeight, GL_RGBA, GL_UNSIGNED_BYTE, colorMap.get()); @@ -1355,7 +1360,7 @@ void Renderer::ApplyBlendingState(const BlendingState state, bool force) GL_XOR, GL_OR, GL_NOR, GL_EQUIV, GL_INVERT, GL_OR_REVERSE, GL_COPY_INVERTED, GL_OR_INVERTED, GL_NAND, GL_SET}; - if (g_main_gl_context->IsGLES()) + if (IsGLES()) { // Logic ops aren't available in GLES3 } @@ -1425,7 +1430,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region OSD::DrawMessages(); // Swap the back and front buffers, presenting the image. - g_main_gl_context->Swap(); + m_main_gl_context->Swap(); } else { @@ -1470,7 +1475,7 @@ void Renderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_region { s_vsync = g_ActiveConfig.IsVSync(); if (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VSYNC)) - g_main_gl_context->SwapInterval(s_vsync); + m_main_gl_context->SwapInterval(s_vsync); } // Clean out old stuff from caches. It's not worth it to clean out the shader caches. @@ -1504,12 +1509,12 @@ void Renderer::CheckForSurfaceChange() if (!m_surface_changed.TestAndClear()) return; - g_main_gl_context->UpdateSurface(m_new_surface_handle); + m_main_gl_context->UpdateSurface(m_new_surface_handle); m_new_surface_handle = nullptr; // With a surface change, the window likely has new dimensions. - m_backbuffer_width = g_main_gl_context->GetBackBufferWidth(); - m_backbuffer_height = g_main_gl_context->GetBackBufferHeight(); + m_backbuffer_width = m_main_gl_context->GetBackBufferWidth(); + m_backbuffer_height = m_main_gl_context->GetBackBufferHeight(); } void Renderer::CheckForSurfaceResize() @@ -1517,9 +1522,9 @@ void Renderer::CheckForSurfaceResize() if (!m_surface_resized.TestAndClear()) return; - g_main_gl_context->Update(); - m_backbuffer_width = g_main_gl_context->GetBackBufferWidth(); - m_backbuffer_height = g_main_gl_context->GetBackBufferHeight(); + m_main_gl_context->Update(); + m_backbuffer_width = m_main_gl_context->GetBackBufferWidth(); + m_backbuffer_height = m_main_gl_context->GetBackBufferHeight(); } void Renderer::DrawEFB(GLuint framebuffer, const TargetRectangle& target_rc, @@ -1540,7 +1545,7 @@ void Renderer::ResetAPIState() glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glDisable(GL_BLEND); - if (!g_main_gl_context->IsGLES()) + if (!IsGLES()) glDisable(GL_COLOR_LOGIC_OP); if (g_ActiveConfig.backend_info.bSupportsDepthClamp) { diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index 7662900624..5beb4ecd75 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -7,7 +7,8 @@ #include #include -#include "Common/GL/GLUtil.h" +#include "Common/GL/GLContext.h" +#include "Common/GL/GLExtensions/GLExtensions.h" #include "VideoCommon/RenderBase.h" struct XFBSourceBase; @@ -81,7 +82,7 @@ extern VideoConfig g_ogl_config; class Renderer : public ::Renderer { public: - Renderer(); + Renderer(std::unique_ptr main_gl_context); ~Renderer() override; bool IsHeadless() const override; @@ -143,6 +144,10 @@ public: std::unique_ptr CreateAsyncShaderCompiler() override; + // Only call methods from this on the GPU thread. + GLContext* GetMainGLContext() const { return m_main_gl_context.get(); } + bool IsGLES() const { return m_main_gl_context->IsGLES(); } + private: void UpdateEFBCache(EFBAccessType type, u32 cacheRectIdx, const EFBRectangle& efbPixelRc, const TargetRectangle& targetPixelRc, const void* data); @@ -161,10 +166,11 @@ private: void ApplyDepthState(const DepthState state, bool force = false); void UploadUtilityUniforms(const void* uniforms, u32 uniforms_size); + std::unique_ptr m_main_gl_context; std::array m_bound_textures{}; const OGLPipeline* m_graphics_pipeline = nullptr; RasterizationState m_current_rasterization_state = {}; DepthState m_current_depth_state = {}; BlendingState m_current_blend_state = {}; }; -} +} // namespace OGL diff --git a/Source/Core/VideoBackends/OGL/SamplerCache.cpp b/Source/Core/VideoBackends/OGL/SamplerCache.cpp index ae848e8d29..364ec51c99 100644 --- a/Source/Core/VideoBackends/OGL/SamplerCache.cpp +++ b/Source/Core/VideoBackends/OGL/SamplerCache.cpp @@ -3,11 +3,11 @@ // Refer to the license.txt file included. #include "VideoBackends/OGL/SamplerCache.h" +#include "VideoBackends/OGL/Render.h" #include #include "Common/CommonTypes.h" -#include "Common/GL/GLContext.h" #include "VideoCommon/SamplerCommon.h" #include "VideoCommon/VideoConfig.h" @@ -99,7 +99,7 @@ void SamplerCache::SetParameters(GLuint sampler_id, const SamplerState& params) glSamplerParameterf(sampler_id, GL_TEXTURE_MIN_LOD, params.min_lod / 16.f); glSamplerParameterf(sampler_id, GL_TEXTURE_MAX_LOD, params.max_lod / 16.f); - if (!g_main_gl_context->IsGLES()) + if (!static_cast(g_renderer.get())->IsGLES()) glSamplerParameterf(sampler_id, GL_TEXTURE_LOD_BIAS, params.lod_bias / 256.f); if (params.anisotropic_filtering && g_ogl_config.bSupportsAniso) diff --git a/Source/Core/VideoBackends/OGL/VideoBackend.h b/Source/Core/VideoBackends/OGL/VideoBackend.h index 2a1360542f..74bc929e85 100644 --- a/Source/Core/VideoBackends/OGL/VideoBackend.h +++ b/Source/Core/VideoBackends/OGL/VideoBackend.h @@ -7,6 +7,8 @@ #include #include "VideoCommon/VideoBackendBase.h" +class GLContext; + namespace OGL { class VideoBackend : public VideoBackendBase @@ -20,7 +22,7 @@ class VideoBackend : public VideoBackendBase void InitBackendInfo() override; private: - bool InitializeGLExtensions(); + bool InitializeGLExtensions(GLContext* context); bool FillBackendInfo(); }; } // namespace OGL diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp index 56cd60fc47..2c38986aa9 100644 --- a/Source/Core/VideoBackends/OGL/main.cpp +++ b/Source/Core/VideoBackends/OGL/main.cpp @@ -66,7 +66,7 @@ std::string VideoBackend::GetName() const std::string VideoBackend::GetDisplayName() const { - if (g_main_gl_context && g_main_gl_context->GetMode() == GLContext::Mode::OpenGLES) + if (g_renderer && static_cast(g_renderer.get())->IsGLES()) return _trans("OpenGL ES"); else return _trans("OpenGL"); @@ -108,10 +108,10 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.AAModes = {1, 2, 4, 8}; } -bool VideoBackend::InitializeGLExtensions() +bool VideoBackend::InitializeGLExtensions(GLContext* context) { // Init extension support. - if (!GLExtensions::Init()) + if (!GLExtensions::Init(context)) { // OpenGL 2.0 is required for all shader based drawings. There is no way to get this by // extensions @@ -161,15 +161,16 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi) { InitializeShared(); - g_main_gl_context = GLContext::Create(wsi, g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer); - if (!g_main_gl_context) + std::unique_ptr main_gl_context = + GLContext::Create(wsi, g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer); + if (!main_gl_context) return false; - g_main_gl_context->MakeCurrent(); - if (!InitializeGLExtensions() || !FillBackendInfo()) + main_gl_context->MakeCurrent(); + if (!InitializeGLExtensions(main_gl_context.get()) || !FillBackendInfo()) return false; - g_renderer = std::make_unique(); + g_renderer = std::make_unique(std::move(main_gl_context)); g_vertex_manager = std::make_unique(); g_perf_query = GetPerfQuery(); ProgramShaderCache::Init(); @@ -195,9 +196,6 @@ void VideoBackend::Shutdown() g_perf_query.reset(); g_vertex_manager.reset(); g_renderer.reset(); - g_main_gl_context->ClearCurrent(); - g_main_gl_context->Shutdown(); - g_main_gl_context.reset(); ShutdownShared(); } } // namespace OGL diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp index d9694c17aa..4936d1a13c 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp @@ -7,48 +7,58 @@ #include "Common/GL/GLContext.h" #include "Common/GL/GLUtil.h" #include "Common/Logging/Log.h" +#include "Common/MsgHandler.h" #include "VideoBackends/Software/SWOGLWindow.h" #include "VideoBackends/Software/SWTexture.h" -std::unique_ptr SWOGLWindow::s_instance; +SWOGLWindow::SWOGLWindow() = default; -void SWOGLWindow::Init(const WindowSystemInfo& wsi) +SWOGLWindow::~SWOGLWindow() { - g_main_gl_context = GLContext::Create(wsi); - if (!g_main_gl_context) + if (m_gl_context) { - ERROR_LOG(VIDEO, "GLInterface::Create failed."); + m_gl_context->ClearCurrent(); + m_gl_context->Shutdown(); + } +} + +std::unique_ptr SWOGLWindow::Create(const WindowSystemInfo& wsi) +{ + std::unique_ptr window = std::unique_ptr(new SWOGLWindow()); + if (!window->Initialize(wsi)) + { + PanicAlert("Failed to create OpenGL window"); + return nullptr; } - s_instance.reset(new SWOGLWindow()); + return window; } -void SWOGLWindow::Shutdown() +bool SWOGLWindow::IsHeadless() const { - g_main_gl_context->Shutdown(); - g_main_gl_context.reset(); - - s_instance.reset(); + return m_gl_context->IsHeadless(); } -void SWOGLWindow::Prepare() +bool SWOGLWindow::Initialize(const WindowSystemInfo& wsi) { - if (m_init) - return; - m_init = true; + m_gl_context = GLContext::Create(wsi); + if (!m_gl_context) + return false; + + m_gl_context->MakeCurrent(); // Init extension support. - if (!GLExtensions::Init()) + if (!GLExtensions::Init(m_gl_context.get())) { ERROR_LOG(VIDEO, "GLExtensions::Init failed!Does your video card support OpenGL 2.0?"); - return; + return false; } else if (GLExtensions::Version() < 310) { ERROR_LOG(VIDEO, "OpenGL Version %d detected, but at least 3.1 is required.", GLExtensions::Version()); - return; + return false; } std::string frag_shader = "in vec2 TexCoord;\n" @@ -65,9 +75,9 @@ void SWOGLWindow::Prepare() " TexCoord = vec2(rawpos.x, -rawpos.y);\n" "}\n"; - std::string header = g_main_gl_context->IsGLES() ? "#version 300 es\n" - "precision highp float;\n" : - "#version 140\n"; + std::string header = m_gl_context->IsGLES() ? "#version 300 es\n" + "precision highp float;\n" : + "#version 140\n"; m_image_program = GLUtil::CompileProgram(header + vertex_shader, header + frag_shader); @@ -81,6 +91,7 @@ void SWOGLWindow::Prepare() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glGenVertexArrays(1, &m_image_vao); + return true; } void SWOGLWindow::PrintText(const std::string& text, int x, int y, u32 color) @@ -91,10 +102,10 @@ void SWOGLWindow::PrintText(const std::string& text, int x, int y, u32 color) void SWOGLWindow::ShowImage(AbstractTexture* image, const EFBRectangle& xfb_region) { SW::SWTexture* sw_image = static_cast(image); - g_main_gl_context->Update(); // just updates the render window position and the backbuffer size + m_gl_context->Update(); // just updates the render window position and the backbuffer size - GLsizei glWidth = (GLsizei)g_main_gl_context->GetBackBufferWidth(); - GLsizei glHeight = (GLsizei)g_main_gl_context->GetBackBufferHeight(); + GLsizei glWidth = (GLsizei)m_gl_context->GetBackBufferWidth(); + GLsizei glHeight = (GLsizei)m_gl_context->GetBackBufferHeight(); glViewport(0, 0, glWidth, glHeight); @@ -121,5 +132,5 @@ void SWOGLWindow::ShowImage(AbstractTexture* image, const EFBRectangle& xfb_regi // } m_text.clear(); - g_main_gl_context->Swap(); + m_gl_context->Swap(); } diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.h b/Source/Core/VideoBackends/Software/SWOGLWindow.h index 2d85770e61..38ae316d07 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.h +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.h @@ -11,15 +11,18 @@ #include "Common/CommonTypes.h" #include "VideoCommon/VideoCommon.h" +class GLContext; + class AbstractTexture; struct WindowSystemInfo; class SWOGLWindow { public: - static void Init(const WindowSystemInfo& wsi); - static void Shutdown(); - void Prepare(); + ~SWOGLWindow(); + + GLContext* GetContext() const { return m_gl_context.get(); } + bool IsHeadless() const; // Will be printed on the *next* image void PrintText(const std::string& text, int x, int y, u32 color); @@ -27,10 +30,13 @@ public: // Image to show, will be swapped immediately void ShowImage(AbstractTexture* image, const EFBRectangle& xfb_region); - static std::unique_ptr s_instance; + static std::unique_ptr Create(const WindowSystemInfo& wsi); private: - SWOGLWindow() {} + SWOGLWindow(); + + bool Initialize(const WindowSystemInfo& wsi); + struct TextData { std::string text; @@ -39,7 +45,9 @@ private: }; std::vector m_text; - bool m_init{false}; + u32 m_image_program = 0; + u32 m_image_texture = 0; + u32 m_image_vao = 0; - u32 m_image_program, m_image_texture, m_image_vao; + std::unique_ptr m_gl_context; }; diff --git a/Source/Core/VideoBackends/Software/SWRenderer.cpp b/Source/Core/VideoBackends/Software/SWRenderer.cpp index 5e76cdd296..2c6a97027b 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.cpp +++ b/Source/Core/VideoBackends/Software/SWRenderer.cpp @@ -24,14 +24,15 @@ #include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoConfig.h" -SWRenderer::SWRenderer() - : ::Renderer(static_cast(MAX_XFB_WIDTH), static_cast(MAX_XFB_HEIGHT)) +SWRenderer::SWRenderer(std::unique_ptr window) + : ::Renderer(static_cast(MAX_XFB_WIDTH), static_cast(MAX_XFB_HEIGHT)), + m_window(std::move(window)) { } bool SWRenderer::IsHeadless() const { - return g_main_gl_context->IsHeadless(); + return m_window->IsHeadless(); } std::unique_ptr SWRenderer::CreateTexture(const TextureConfig& config) @@ -55,7 +56,7 @@ SWRenderer::CreateFramebuffer(const AbstractTexture* color_attachment, void SWRenderer::RenderText(const std::string& pstr, int left, int top, u32 color) { - SWOGLWindow::s_instance->PrintText(pstr, left, top, color); + m_window->PrintText(pstr, left, top, color); } class SWShader final : public AbstractShader @@ -100,7 +101,7 @@ void SWRenderer::SwapImpl(AbstractTexture* texture, const EFBRectangle& xfb_regi if (!IsHeadless()) { DrawDebugText(); - SWOGLWindow::s_instance->ShowImage(texture, xfb_region); + m_window->ShowImage(texture, xfb_region); } UpdateActiveConfig(); diff --git a/Source/Core/VideoBackends/Software/SWRenderer.h b/Source/Core/VideoBackends/Software/SWRenderer.h index 6b2a3f0795..936139516f 100644 --- a/Source/Core/VideoBackends/Software/SWRenderer.h +++ b/Source/Core/VideoBackends/Software/SWRenderer.h @@ -4,14 +4,18 @@ #pragma once +#include + #include "Common/CommonTypes.h" #include "VideoCommon/RenderBase.h" +class SWOGLWindow; + class SWRenderer : public Renderer { public: - SWRenderer(); + SWRenderer(std::unique_ptr window); bool IsHeadless() const override; @@ -42,4 +46,7 @@ public: u32 color, u32 z) override; void ReinterpretPixelData(unsigned int convtype) override {} + +private: + std::unique_ptr m_window; }; diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index 070cf74b69..a0ad349849 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -82,16 +82,15 @@ bool VideoSoftware::Initialize(const WindowSystemInfo& wsi) { InitializeShared(); - SWOGLWindow::Init(wsi); + std::unique_ptr window = SWOGLWindow::Create(wsi); + if (!window) + return false; Clipper::Init(); Rasterizer::Init(); DebugUtil::Init(); - g_main_gl_context->MakeCurrent(); - SWOGLWindow::s_instance->Prepare(); - - g_renderer = std::make_unique(); + g_renderer = std::make_unique(std::move(window)); g_vertex_manager = std::make_unique(); g_perf_query = std::make_unique(); g_texture_cache = std::make_unique(); @@ -108,7 +107,6 @@ void VideoSoftware::Shutdown() g_renderer->Shutdown(); DebugUtil::Shutdown(); - SWOGLWindow::Shutdown(); g_framebuffer_manager.reset(); g_texture_cache.reset(); g_perf_query.reset();