From 2f649d092cda3c54b6899d9ac184b6220f2feda0 Mon Sep 17 00:00:00 2001 From: Reg Tiangha Date: Fri, 19 Jul 2024 15:56:28 -0600 Subject: [PATCH 1/3] Delete duckstation directory --- .../duckstation/duckstation_compat.h | 17 - .../externals/duckstation/gl/context.cpp | 175 ------- .../externals/duckstation/gl/context.h | 77 --- .../externals/duckstation/gl/context_agl.h | 50 -- .../externals/duckstation/gl/context_agl.mm | 214 --------- .../externals/duckstation/gl/context_egl.cpp | 432 ----------------- .../externals/duckstation/gl/context_egl.h | 48 -- .../duckstation/gl/context_egl_wayland.cpp | 86 ---- .../duckstation/gl/context_egl_wayland.h | 33 -- .../duckstation/gl/context_egl_x11.cpp | 69 --- .../duckstation/gl/context_egl_x11.h | 28 -- .../externals/duckstation/gl/context_glx.cpp | 328 ------------- .../externals/duckstation/gl/context_glx.h | 44 -- .../externals/duckstation/gl/context_wgl.cpp | 453 ------------------ .../externals/duckstation/gl/context_wgl.h | 53 -- .../externals/duckstation/gl/loader.h | 8 - .../externals/duckstation/gl/x11_window.cpp | 101 ---- .../externals/duckstation/gl/x11_window.h | 49 -- src/citra_qt/externals/duckstation/log.h | 46 -- .../externals/duckstation/scoped_guard.h | 34 -- .../externals/duckstation/window_info.cpp | 191 -------- .../externals/duckstation/window_info.h | 43 -- .../externals/duckstation/windows_headers.h | 26 - src/citra_qt/externals/types.h | 39 -- 24 files changed, 2644 deletions(-) delete mode 100644 src/citra_qt/externals/duckstation/duckstation_compat.h delete mode 100644 src/citra_qt/externals/duckstation/gl/context.cpp delete mode 100644 src/citra_qt/externals/duckstation/gl/context.h delete mode 100644 src/citra_qt/externals/duckstation/gl/context_agl.h delete mode 100644 src/citra_qt/externals/duckstation/gl/context_agl.mm delete mode 100644 src/citra_qt/externals/duckstation/gl/context_egl.cpp delete mode 100644 src/citra_qt/externals/duckstation/gl/context_egl.h delete mode 100644 src/citra_qt/externals/duckstation/gl/context_egl_wayland.cpp delete mode 100644 src/citra_qt/externals/duckstation/gl/context_egl_wayland.h delete mode 100644 src/citra_qt/externals/duckstation/gl/context_egl_x11.cpp delete mode 100644 src/citra_qt/externals/duckstation/gl/context_egl_x11.h delete mode 100644 src/citra_qt/externals/duckstation/gl/context_glx.cpp delete mode 100644 src/citra_qt/externals/duckstation/gl/context_glx.h delete mode 100644 src/citra_qt/externals/duckstation/gl/context_wgl.cpp delete mode 100644 src/citra_qt/externals/duckstation/gl/context_wgl.h delete mode 100644 src/citra_qt/externals/duckstation/gl/loader.h delete mode 100644 src/citra_qt/externals/duckstation/gl/x11_window.cpp delete mode 100644 src/citra_qt/externals/duckstation/gl/x11_window.h delete mode 100644 src/citra_qt/externals/duckstation/log.h delete mode 100644 src/citra_qt/externals/duckstation/scoped_guard.h delete mode 100644 src/citra_qt/externals/duckstation/window_info.cpp delete mode 100644 src/citra_qt/externals/duckstation/window_info.h delete mode 100644 src/citra_qt/externals/duckstation/windows_headers.h delete mode 100644 src/citra_qt/externals/types.h diff --git a/src/citra_qt/externals/duckstation/duckstation_compat.h b/src/citra_qt/externals/duckstation/duckstation_compat.h deleted file mode 100644 index fed378056c..0000000000 --- a/src/citra_qt/externals/duckstation/duckstation_compat.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef DUCKSTATION_COMPAT_H -#define DUCKSTATION_COMPAT_H - -#include "../types.h" - -#include - -#define ALWAYS_INLINE __attribute__((always_inline)) inline - -#define AssertMsg(cond, msg) assert(cond && msg) -#define Assert(cond) assert(cond) - -#define Panic(msg) assert(false && msg) - -#define UnreachableCode() __builtin_unreachable() - -#endif \ No newline at end of file diff --git a/src/citra_qt/externals/duckstation/gl/context.cpp b/src/citra_qt/externals/duckstation/gl/context.cpp deleted file mode 100644 index 308b3c4065..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "context.h" -#include "../log.h" -#include "loader.h" -#include -#include -#include -Log_SetChannel(GL::Context); - -#if defined(_WIN32) -#include "context_wgl.h" -#elif defined(__APPLE__) -#include "context_agl.h" -#else -#ifdef WAYLAND_ENABLED -#include "context_egl_wayland.h" -#endif -#include "context_egl_x11.h" -#include "context_glx.h" -#endif - -namespace GL { - -static bool ShouldPreferESContext() -{ -#ifndef _MSC_VER - const char* value = std::getenv("PREFER_GLES_CONTEXT"); - return (value && strcmp(value, "1") == 0); -#else - char buffer[2] = {}; - size_t buffer_size = sizeof(buffer); - getenv_s(&buffer_size, buffer, "PREFER_GLES_CONTEXT"); - return (std::strcmp(buffer, "1") == 0); -#endif -} - -Context::Context(const WindowInfo& wi) : m_wi(wi) {} - -Context::~Context() = default; - -std::vector Context::EnumerateFullscreenModes() -{ - return {}; -} - -std::unique_ptr Context::Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try) -{ - if (ShouldPreferESContext()) - { - // move ES versions to the front - Version* new_versions_to_try = static_cast(alloca(sizeof(Version) * num_versions_to_try)); - size_t count = 0; - for (size_t i = 0; i < num_versions_to_try; i++) - { - if (versions_to_try[i].profile == Profile::ES) - new_versions_to_try[count++] = versions_to_try[i]; - } - for (size_t i = 0; i < num_versions_to_try; i++) - { - if (versions_to_try[i].profile != Profile::ES) - new_versions_to_try[count++] = versions_to_try[i]; - } - versions_to_try = new_versions_to_try; - } - - std::unique_ptr context; -#if defined(_WIN32) - context = ContextWGL::Create(wi, versions_to_try, num_versions_to_try); -#elif defined(__APPLE__) - context = ContextAGL::Create(wi, versions_to_try, num_versions_to_try); -#else - if (wi.type == WindowInfo::Type::X11) - { - const char* use_egl_x11 = std::getenv("USE_EGL_X11"); - if (use_egl_x11 && std::strcmp(use_egl_x11, "1") == 0) - context = ContextEGLX11::Create(wi, versions_to_try, num_versions_to_try); - else - context = ContextGLX::Create(wi, versions_to_try, num_versions_to_try); - } - -#ifdef WAYLAND_ENABLED - if (wi.type == WindowInfo::Type::Wayland) - context = ContextEGLWayland::Create(wi, versions_to_try, num_versions_to_try); -#endif -#endif - - if (!context) - return nullptr; - - Log_InfoPrintf("Created a %s context", context->IsGLES() ? "OpenGL ES" : "OpenGL"); - - // TODO: Not thread-safe. - static Context* context_being_created; - context_being_created = context.get(); - - if (!gladLoadGLLoader([](const char* name) { return context_being_created->GetProcAddress(name); })) - { - Log_ErrorPrintf("Failed to load GL functions for GLAD"); - return nullptr; - } - - const char* gl_vendor = reinterpret_cast(glGetString(GL_VENDOR)); - const char* gl_renderer = reinterpret_cast(glGetString(GL_RENDERER)); - const char* gl_version = reinterpret_cast(glGetString(GL_VERSION)); - const char* gl_shading_language_version = reinterpret_cast(glGetString(GL_SHADING_LANGUAGE_VERSION)); - Log_InfoPrintf("GL_VENDOR: %s", gl_vendor); - Log_InfoPrintf("GL_RENDERER: %s", gl_renderer); - Log_InfoPrintf("GL_VERSION: %s", gl_version); - Log_InfoPrintf("GL_SHADING_LANGUAGE_VERSION: %s", gl_shading_language_version); - - return context; -} - -const std::array& Context::GetAllDesktopVersionsList() -{ - static constexpr std::array vlist = {{{Profile::Core, 4, 6}, - {Profile::Core, 4, 5}, - {Profile::Core, 4, 4}, - {Profile::Core, 4, 3}, - {Profile::Core, 4, 2}, - {Profile::Core, 4, 1}, - {Profile::Core, 4, 0}, - {Profile::Core, 3, 3}, - {Profile::Core, 3, 2}, - {Profile::Core, 3, 1}, - {Profile::Core, 3, 0}}}; - return vlist; -} - -const std::array& Context::GetAllDesktopVersionsListWithFallback() -{ - static constexpr std::array vlist = {{{Profile::Core, 4, 6}, - {Profile::Core, 4, 5}, - {Profile::Core, 4, 4}, - {Profile::Core, 4, 3}, - {Profile::Core, 4, 2}, - {Profile::Core, 4, 1}, - {Profile::Core, 4, 0}, - {Profile::Core, 3, 3}, - {Profile::Core, 3, 2}, - {Profile::Core, 3, 1}, - {Profile::Core, 3, 0}, - {Profile::NoProfile, 0, 0}}}; - return vlist; -} - -const std::array& Context::GetAllESVersionsList() -{ - static constexpr std::array vlist = { - {{Profile::ES, 3, 2}, {Profile::ES, 3, 1}, {Profile::ES, 3, 0}, {Profile::ES, 2, 0}}}; - return vlist; -} - -const std::array& Context::GetAllVersionsList() -{ - static constexpr std::array vlist = {{{Profile::Core, 4, 6}, - {Profile::Core, 4, 5}, - {Profile::Core, 4, 4}, - {Profile::Core, 4, 3}, - {Profile::Core, 4, 2}, - {Profile::Core, 4, 1}, - {Profile::Core, 4, 0}, - {Profile::Core, 3, 3}, - {Profile::Core, 3, 2}, - {Profile::Core, 3, 1}, - {Profile::Core, 3, 0}, - {Profile::ES, 3, 2}, - {Profile::ES, 3, 1}, - {Profile::ES, 3, 0}, - {Profile::ES, 2, 0}, - {Profile::NoProfile, 0, 0}}}; - return vlist; -} - -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context.h b/src/citra_qt/externals/duckstation/gl/context.h deleted file mode 100644 index 09c73e660a..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -#include "../duckstation_compat.h" -#include "../window_info.h" -#include -#include -#include - -namespace GL { -using namespace citra; -class Context -{ -public: - Context(const WindowInfo& wi); - virtual ~Context(); - - enum class Profile - { - NoProfile, - Core, - ES - }; - - struct Version - { - Profile profile; - int major_version; - int minor_version; - }; - - struct FullscreenModeInfo - { - u32 width; - u32 height; - float refresh_rate; - }; - - ALWAYS_INLINE const WindowInfo& GetWindowInfo() const { return m_wi; } - ALWAYS_INLINE bool IsGLES() const { return (m_version.profile == Profile::ES); } - ALWAYS_INLINE u32 GetSurfaceWidth() const { return m_wi.surface_width; } - ALWAYS_INLINE u32 GetSurfaceHeight() const { return m_wi.surface_height; } - ALWAYS_INLINE WindowInfo::SurfaceFormat GetSurfaceFormat() const { return m_wi.surface_format; } - - virtual void* GetProcAddress(const char* name) = 0; - virtual bool ChangeSurface(const WindowInfo& new_wi) = 0; - virtual void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) = 0; - virtual bool SwapBuffers() = 0; - virtual bool MakeCurrent() = 0; - virtual bool DoneCurrent() = 0; - virtual bool SetSwapInterval(s32 interval) = 0; - virtual std::unique_ptr CreateSharedContext(const WindowInfo& wi) = 0; - - virtual std::vector EnumerateFullscreenModes(); - - static std::unique_ptr Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try); - - template - static std::unique_ptr Create(const WindowInfo& wi, const std::array& versions_to_try) - { - return Create(wi, versions_to_try.data(), versions_to_try.size()); - } - - static std::unique_ptr Create(const WindowInfo& wi) { return Create(wi, GetAllVersionsList()); } - - static const std::array& GetAllDesktopVersionsList(); - static const std::array& GetAllDesktopVersionsListWithFallback(); - static const std::array& GetAllESVersionsList(); - static const std::array& GetAllVersionsList(); - -protected: -#ifdef _WIN32 -#endif - - WindowInfo m_wi; - Version m_version = {}; -}; -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_agl.h b/src/citra_qt/externals/duckstation/gl/context_agl.h deleted file mode 100644 index 4ae5202d8a..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_agl.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -#include "context.h" -#include "loader.h" - -#if defined(__APPLE__) && defined(__OBJC__) -#import -#else -struct NSOpenGLContext; -struct NSOpenGLPixelFormat; -struct NSView; -#define __bridge -#endif - -namespace GL { - -using namespace melonDS; -class ContextAGL final : public Context -{ -public: - ContextAGL(const WindowInfo& wi); - ~ContextAGL() override; - - static std::unique_ptr Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try); - - void* GetProcAddress(const char* name) override; - bool ChangeSurface(const WindowInfo& new_wi) override; - void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override; - bool SwapBuffers() override; - bool MakeCurrent() override; - bool DoneCurrent() override; - bool SetSwapInterval(s32 interval) override; - std::unique_ptr CreateSharedContext(const WindowInfo& wi) override; - -private: - ALWAYS_INLINE NSView* GetView() const { return static_cast((__bridge NSView*)m_wi.window_handle); } - - bool Initialize(const Version* versions_to_try, size_t num_versions_to_try); - bool CreateContext(NSOpenGLContext* share_context, int profile, bool make_current); - void BindContextToView(); - - // returns true if dimensions have changed - bool UpdateDimensions(); - - NSOpenGLContext* m_context = nullptr; - NSOpenGLPixelFormat* m_pixel_format = nullptr; - void* m_opengl_module_handle = nullptr; -}; - -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_agl.mm b/src/citra_qt/externals/duckstation/gl/context_agl.mm deleted file mode 100644 index f833518349..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_agl.mm +++ /dev/null @@ -1,214 +0,0 @@ -#include "context_agl.h" -#include "../duckstation_compat.h" -#include "../log.h" -#include "loader.h" -#include -Log_SetChannel(GL::ContextAGL); - -namespace GL { -ContextAGL::ContextAGL(const WindowInfo& wi) : Context(wi) -{ - m_opengl_module_handle = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_NOW); - if (!m_opengl_module_handle) - Log_ErrorPrint("Could not open OpenGL.framework, function lookups will probably fail"); -} - -ContextAGL::~ContextAGL() -{ - if ([NSOpenGLContext currentContext] == m_context) - [NSOpenGLContext clearCurrentContext]; - - if (m_context) - [m_context release]; - - if (m_pixel_format) - [m_pixel_format release]; - - if (m_opengl_module_handle) - dlclose(m_opengl_module_handle); -} - -std::unique_ptr ContextAGL::Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try) -{ - std::unique_ptr context = std::make_unique(wi); - if (!context->Initialize(versions_to_try, num_versions_to_try)) - return nullptr; - - return context; -} - -bool ContextAGL::Initialize(const Version* versions_to_try, size_t num_versions_to_try) -{ - for (size_t i = 0; i < num_versions_to_try; i++) - { - const Version& cv = versions_to_try[i]; - if (cv.profile == Profile::NoProfile && CreateContext(nullptr, NSOpenGLProfileVersionLegacy, true)) - { - // we already have the dummy context, so just use that - m_version = cv; - return true; - } - else if (cv.profile == Profile::Core) - { - if (cv.major_version > 4 && cv.minor_version > 1) - continue; - - const NSOpenGLPixelFormatAttribute profile = (cv.major_version > 3 || cv.minor_version > 2) ? NSOpenGLProfileVersion4_1Core : NSOpenGLProfileVersion3_2Core; - if (CreateContext(nullptr, static_cast(profile), true)) - { - m_version = cv; - return true; - } - } - } - - return false; -} - -void* ContextAGL::GetProcAddress(const char* name) -{ - void* addr = m_opengl_module_handle ? dlsym(m_opengl_module_handle, name) : nullptr; - if (addr) - return addr; - - return dlsym(RTLD_NEXT, name); -} - -bool ContextAGL::ChangeSurface(const WindowInfo& new_wi) -{ - m_wi = new_wi; - BindContextToView(); - return true; -} - -void ContextAGL::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/) -{ - UpdateDimensions(); -} - -bool ContextAGL::UpdateDimensions() -{ - const NSSize window_size = [GetView() frame].size; - const CGFloat window_scale = [[GetView() window] backingScaleFactor]; - const u32 new_width = static_cast(static_cast(window_size.width) * window_scale); - const u32 new_height = static_cast(static_cast(window_size.height) * window_scale); - - if (m_wi.surface_width == new_width && m_wi.surface_height == new_height) - return false; - - m_wi.surface_width = new_width; - m_wi.surface_height = new_height; - - dispatch_block_t block = ^{ - [m_context update]; - }; - - if ([NSThread isMainThread]) - block(); - else - dispatch_sync(dispatch_get_main_queue(), block); - - return true; -} - -bool ContextAGL::SwapBuffers() -{ - [m_context flushBuffer]; - return true; -} - -bool ContextAGL::MakeCurrent() -{ - [m_context makeCurrentContext]; - return true; -} - -bool ContextAGL::DoneCurrent() -{ - [NSOpenGLContext clearCurrentContext]; - return true; -} - -bool ContextAGL::SetSwapInterval(s32 interval) -{ - GLint gl_interval = static_cast(interval); - [m_context setValues:&gl_interval forParameter:NSOpenGLCPSwapInterval]; - return true; -} - -std::unique_ptr ContextAGL::CreateSharedContext(const WindowInfo& wi) -{ - std::unique_ptr context = std::make_unique(wi); - - context->m_context = [[NSOpenGLContext alloc] initWithFormat:m_pixel_format shareContext:m_context]; - if (context->m_context == nil) - return nullptr; - - context->m_version = m_version; - context->m_pixel_format = m_pixel_format; - [context->m_pixel_format retain]; - - if (wi.type == WindowInfo::Type::MacOS) - context->BindContextToView(); - - return context; -} - -bool ContextAGL::CreateContext(NSOpenGLContext* share_context, int profile, bool make_current) -{ - if (m_context) - { - [m_context release]; - m_context = nullptr; - } - - if (m_pixel_format) - [m_pixel_format release]; - - const std::array attribs = {{ - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAOpenGLProfile, - static_cast(profile), - NSOpenGLPFAAccelerated, - 0}}; - m_pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs.data()]; - if (m_pixel_format == nil) - { - Log_ErrorPrintf("Failed to initialize pixel format"); - return false; - } - - m_context = [[NSOpenGLContext alloc] initWithFormat:m_pixel_format shareContext:nil]; - if (m_context == nil) - return false; - - if (m_wi.type == WindowInfo::Type::MacOS) - BindContextToView(); - - if (make_current) - [m_context makeCurrentContext]; - - return true; -} - -void ContextAGL::BindContextToView() -{ - NSView* const view = GetView(); - NSWindow* const window = [view window]; - [view setWantsBestResolutionOpenGLSurface:YES]; - - UpdateDimensions(); - - dispatch_block_t block = ^{ - [window makeFirstResponder:view]; - [m_context setView:view]; - [window makeKeyAndOrderFront:nil]; - }; - - if ([NSThread isMainThread]) - block(); - else - dispatch_sync(dispatch_get_main_queue(), block); -} -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_egl.cpp b/src/citra_qt/externals/duckstation/gl/context_egl.cpp deleted file mode 100644 index d251a39cd8..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_egl.cpp +++ /dev/null @@ -1,432 +0,0 @@ -#include "context_egl.h" -#include "../log.h" -#include "../duckstation_compat.h" -#include -#include -#include -Log_SetChannel(GL::ContextEGL); - -namespace GL { -ContextEGL::ContextEGL(const WindowInfo& wi) : Context(wi) {} - -ContextEGL::~ContextEGL() -{ - DestroySurface(); - DestroyContext(); -} - -std::unique_ptr ContextEGL::Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try) -{ - std::unique_ptr context = std::make_unique(wi); - if (!context->Initialize(versions_to_try, num_versions_to_try)) - return nullptr; - - return context; -} - -bool ContextEGL::Initialize(const Version* versions_to_try, size_t num_versions_to_try) -{ - if (!gladLoadEGL()) - { - Log_ErrorPrintf("Loading GLAD EGL functions failed"); - return false; - } - - if (!SetDisplay()) - return false; - - int egl_major, egl_minor; - if (!eglInitialize(m_display, &egl_major, &egl_minor)) - { - Log_ErrorPrintf("eglInitialize() failed: %d", eglGetError()); - return false; - } - Log_InfoPrintf("EGL Version: %d.%d", egl_major, egl_minor); - - const char* extensions = eglQueryString(m_display, EGL_EXTENSIONS); - if (extensions) - { - Log_InfoPrintf("EGL Extensions: %s", extensions); - m_supports_surfaceless = std::strstr(extensions, "EGL_KHR_surfaceless_context") != nullptr; - } - if (!m_supports_surfaceless) - Log_WarningPrint("EGL implementation does not support surfaceless contexts, emulating with pbuffers"); - - for (size_t i = 0; i < num_versions_to_try; i++) - { - if (CreateContextAndSurface(versions_to_try[i], nullptr, true)) - return true; - } - - return false; -} - -bool ContextEGL::SetDisplay() -{ - m_display = eglGetDisplay(static_cast(m_wi.display_connection)); - if (!m_display) - { - Log_ErrorPrintf("eglGetDisplay() failed: %d", eglGetError()); - return false; - } - - return true; -} - -void* ContextEGL::GetProcAddress(const char* name) -{ - return reinterpret_cast(eglGetProcAddress(name)); -} - -bool ContextEGL::ChangeSurface(const WindowInfo& new_wi) -{ - const bool was_current = (eglGetCurrentContext() == m_context); - if (was_current) - eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - if (m_surface != EGL_NO_SURFACE) - { - eglDestroySurface(m_display, m_surface); - m_surface = EGL_NO_SURFACE; - } - - m_wi = new_wi; - if (!CreateSurface()) - return false; - - if (was_current && !eglMakeCurrent(m_display, m_surface, m_surface, m_context)) - { - Log_ErrorPrintf("Failed to make context current again after surface change"); - return false; - } - - return true; -} - -void ContextEGL::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/) -{ - if (new_surface_width == 0 && new_surface_height == 0) - { - EGLint surface_width, surface_height; - if (eglQuerySurface(m_display, m_surface, EGL_WIDTH, &surface_width) && - eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &surface_height)) - { - m_wi.surface_width = static_cast(surface_width); - m_wi.surface_height = static_cast(surface_height); - return; - } - else - { - Log_ErrorPrintf("eglQuerySurface() failed: %d", eglGetError()); - } - } - - m_wi.surface_width = new_surface_width; - m_wi.surface_height = new_surface_height; -} - -bool ContextEGL::SwapBuffers() -{ - return eglSwapBuffers(m_display, m_surface); -} - -bool ContextEGL::MakeCurrent() -{ - if (!eglMakeCurrent(m_display, m_surface, m_surface, m_context)) - { - Log_ErrorPrintf("eglMakeCurrent() failed: %d", eglGetError()); - return false; - } - - return true; -} - -bool ContextEGL::DoneCurrent() -{ - return eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -} - -bool ContextEGL::SetSwapInterval(s32 interval) -{ - return eglSwapInterval(m_display, interval); -} - -std::unique_ptr ContextEGL::CreateSharedContext(const WindowInfo& wi) -{ - std::unique_ptr context = std::make_unique(wi); - context->m_display = m_display; - context->m_supports_surfaceless = m_supports_surfaceless; - - if (!context->CreateContextAndSurface(m_version, m_context, false)) - return nullptr; - - return context; -} - -EGLNativeWindowType ContextEGL::GetNativeWindow(EGLConfig config) -{ - return {}; -} - -bool ContextEGL::CreateSurface() -{ - if (m_wi.type == WindowInfo::Type::Surfaceless) - { - if (m_supports_surfaceless) - return true; - else - return CreatePBufferSurface(); - } - - EGLNativeWindowType native_window = GetNativeWindow(m_config); - m_surface = eglCreateWindowSurface(m_display, m_config, native_window, nullptr); - if (!m_surface) - { - Log_ErrorPrintf("eglCreateWindowSurface() failed: %d", eglGetError()); - return false; - } - - // Some implementations may require the size to be queried at runtime. - EGLint surface_width, surface_height; - if (eglQuerySurface(m_display, m_surface, EGL_WIDTH, &surface_width) && - eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &surface_height)) - { - m_wi.surface_width = static_cast(surface_width); - m_wi.surface_height = static_cast(surface_height); - } - else - { - Log_ErrorPrintf("eglQuerySurface() failed: %d", eglGetError()); - } - - return true; -} - -bool ContextEGL::CreatePBufferSurface() -{ - const u32 width = std::max(m_wi.surface_width, 1); - const u32 height = std::max(m_wi.surface_height, 1); - - // TODO: Format - EGLint attrib_list[] = { - EGL_WIDTH, static_cast(width), EGL_HEIGHT, static_cast(height), EGL_NONE, - }; - - m_surface = eglCreatePbufferSurface(m_display, m_config, attrib_list); - if (!m_surface) - { - Log_ErrorPrintf("eglCreatePbufferSurface() failed: %d", eglGetError()); - return false; - } - - Log_DevPrintf("Created %ux%u pbuffer surface", width, height); - return true; -} - -bool ContextEGL::CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceFormat format) const -{ - int red_size, green_size, blue_size, alpha_size; - if (!eglGetConfigAttrib(m_display, config, EGL_RED_SIZE, &red_size) || - !eglGetConfigAttrib(m_display, config, EGL_GREEN_SIZE, &green_size) || - !eglGetConfigAttrib(m_display, config, EGL_BLUE_SIZE, &blue_size) || - !eglGetConfigAttrib(m_display, config, EGL_ALPHA_SIZE, &alpha_size)) - { - return false; - } - - switch (format) - { - case WindowInfo::SurfaceFormat::Auto: - return true; - - case WindowInfo::SurfaceFormat::RGB8: - return (red_size == 8 && green_size == 8 && blue_size == 8); - - case WindowInfo::SurfaceFormat::RGBA8: - return (red_size == 8 && green_size == 8 && blue_size == 8 && alpha_size == 8); - - case WindowInfo::SurfaceFormat::RGB565: - return (red_size == 5 && green_size == 6 && blue_size == 5); - - default: - return false; - } -} - -void ContextEGL::DestroyContext() -{ - if (eglGetCurrentContext() == m_context) - eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - if (m_context != EGL_NO_CONTEXT) - { - eglDestroyContext(m_display, m_context); - m_context = EGL_NO_CONTEXT; - } -} - -void ContextEGL::DestroySurface() -{ - if (eglGetCurrentSurface(EGL_DRAW) == m_surface) - eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - if (m_surface != EGL_NO_SURFACE) - { - eglDestroySurface(m_display, m_surface); - m_surface = EGL_NO_SURFACE; - } -} - -bool ContextEGL::CreateContext(const Version& version, EGLContext share_context) -{ - Log_DevPrintf( - "Trying version %u.%u (%s)", version.major_version, version.minor_version, - version.profile == Context::Profile::ES ? "ES" : (version.profile == Context::Profile::Core ? "Core" : "None")); - int surface_attribs[16] = { - EGL_RENDERABLE_TYPE, - (version.profile == Profile::ES) ? - ((version.major_version >= 3) ? EGL_OPENGL_ES3_BIT : - ((version.major_version == 2) ? EGL_OPENGL_ES2_BIT : EGL_OPENGL_ES_BIT)) : - EGL_OPENGL_BIT, - EGL_SURFACE_TYPE, - (m_wi.type != WindowInfo::Type::Surfaceless) ? EGL_WINDOW_BIT : 0, - }; - int nsurface_attribs = 4; - - switch (m_wi.surface_format) - { - case WindowInfo::SurfaceFormat::RGB8: - surface_attribs[nsurface_attribs++] = EGL_RED_SIZE; - surface_attribs[nsurface_attribs++] = 8; - surface_attribs[nsurface_attribs++] = EGL_GREEN_SIZE; - surface_attribs[nsurface_attribs++] = 8; - surface_attribs[nsurface_attribs++] = EGL_BLUE_SIZE; - surface_attribs[nsurface_attribs++] = 8; - break; - - case WindowInfo::SurfaceFormat::RGBA8: - surface_attribs[nsurface_attribs++] = EGL_RED_SIZE; - surface_attribs[nsurface_attribs++] = 8; - surface_attribs[nsurface_attribs++] = EGL_GREEN_SIZE; - surface_attribs[nsurface_attribs++] = 8; - surface_attribs[nsurface_attribs++] = EGL_BLUE_SIZE; - surface_attribs[nsurface_attribs++] = 8; - surface_attribs[nsurface_attribs++] = EGL_ALPHA_SIZE; - surface_attribs[nsurface_attribs++] = 8; - break; - - case WindowInfo::SurfaceFormat::RGB565: - surface_attribs[nsurface_attribs++] = EGL_RED_SIZE; - surface_attribs[nsurface_attribs++] = 5; - surface_attribs[nsurface_attribs++] = EGL_GREEN_SIZE; - surface_attribs[nsurface_attribs++] = 6; - surface_attribs[nsurface_attribs++] = EGL_BLUE_SIZE; - surface_attribs[nsurface_attribs++] = 5; - break; - - case WindowInfo::SurfaceFormat::Auto: - break; - - default: - UnreachableCode(); - break; - } - - surface_attribs[nsurface_attribs++] = EGL_NONE; - surface_attribs[nsurface_attribs++] = 0; - - EGLint num_configs; - if (!eglChooseConfig(m_display, surface_attribs, nullptr, 0, &num_configs) || num_configs == 0) - { - Log_ErrorPrintf("eglChooseConfig() failed: %d", eglGetError()); - return false; - } - - std::vector configs(static_cast(num_configs)); - if (!eglChooseConfig(m_display, surface_attribs, configs.data(), num_configs, &num_configs)) - { - Log_ErrorPrintf("eglChooseConfig() failed: %d", eglGetError()); - return false; - } - configs.resize(static_cast(num_configs)); - - std::optional config; - for (EGLConfig check_config : configs) - { - if (CheckConfigSurfaceFormat(check_config, m_wi.surface_format)) - { - config = check_config; - break; - } - } - - if (!config.has_value()) - { - Log_WarningPrintf("No EGL configs matched exactly, using first."); - config = configs.front(); - } - - int attribs[8]; - int nattribs = 0; - if (version.profile != Profile::NoProfile) - { - attribs[nattribs++] = EGL_CONTEXT_MAJOR_VERSION; - attribs[nattribs++] = version.major_version; - attribs[nattribs++] = EGL_CONTEXT_MINOR_VERSION; - attribs[nattribs++] = version.minor_version; - } - attribs[nattribs++] = EGL_NONE; - attribs[nattribs++] = 0; - - if (!eglBindAPI((version.profile == Profile::ES) ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) - { - Log_ErrorPrintf("eglBindAPI(%s) failed", (version.profile == Profile::ES) ? "EGL_OPENGL_ES_API" : "EGL_OPENGL_API"); - return false; - } - - m_context = eglCreateContext(m_display, config.value(), share_context, attribs); - if (!m_context) - { - Log_ErrorPrintf("eglCreateContext() failed: %d", eglGetError()); - return false; - } - - Log_InfoPrintf( - "Got version %u.%u (%s)", version.major_version, version.minor_version, - version.profile == Context::Profile::ES ? "ES" : (version.profile == Context::Profile::Core ? "Core" : "None")); - - m_config = config.value(); - m_version = version; - return true; -} - -bool ContextEGL::CreateContextAndSurface(const Version& version, EGLContext share_context, bool make_current) -{ - if (!CreateContext(version, share_context)) - return false; - - if (!CreateSurface()) - { - Log_ErrorPrintf("Failed to create surface for context"); - eglDestroyContext(m_display, m_context); - m_context = EGL_NO_CONTEXT; - return false; - } - - if (make_current && !eglMakeCurrent(m_display, m_surface, m_surface, m_context)) - { - Log_ErrorPrintf("eglMakeCurrent() failed: %d", eglGetError()); - if (m_surface != EGL_NO_SURFACE) - { - eglDestroySurface(m_display, m_surface); - m_surface = EGL_NO_SURFACE; - } - eglDestroyContext(m_display, m_context); - m_context = EGL_NO_CONTEXT; - return false; - } - - return true; -} -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_egl.h b/src/citra_qt/externals/duckstation/gl/context_egl.h deleted file mode 100644 index 4462736ac2..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_egl.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once -#include "context.h" -#include "../../../../../externals/glad/src/glad_egl.h" - -namespace GL { - -class ContextEGL : public Context -{ -public: - ContextEGL(const WindowInfo& wi); - ~ContextEGL() override; - - static std::unique_ptr Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try); - - void* GetProcAddress(const char* name) override; - virtual bool ChangeSurface(const WindowInfo& new_wi) override; - virtual void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override; - bool SwapBuffers() override; - bool MakeCurrent() override; - bool DoneCurrent() override; - bool SetSwapInterval(s32 interval) override; - virtual std::unique_ptr CreateSharedContext(const WindowInfo& wi) override; - -protected: - virtual bool SetDisplay(); - virtual EGLNativeWindowType GetNativeWindow(EGLConfig config); - - bool Initialize(const Version* versions_to_try, size_t num_versions_to_try); - bool CreateDisplay(); - bool CreateContext(const Version& version, EGLContext share_context); - bool CreateContextAndSurface(const Version& version, EGLContext share_context, bool make_current); - bool CreateSurface(); - bool CreatePBufferSurface(); - bool CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceFormat format) const; - void DestroyContext(); - void DestroySurface(); - - EGLDisplay m_display = EGL_NO_DISPLAY; - EGLSurface m_surface = EGL_NO_SURFACE; - EGLContext m_context = EGL_NO_CONTEXT; - - EGLConfig m_config = {}; - - bool m_supports_surfaceless = false; -}; - -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_egl_wayland.cpp b/src/citra_qt/externals/duckstation/gl/context_egl_wayland.cpp deleted file mode 100644 index 16532e8b18..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_egl_wayland.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "context_egl_wayland.h" -#include "../log.h" -#include -Log_SetChannel(ContextEGLWayland); - -namespace GL { -static const char* WAYLAND_EGL_MODNAME = "libwayland-egl.so.1"; - -ContextEGLWayland::ContextEGLWayland(const WindowInfo& wi) : ContextEGL(wi) {} -ContextEGLWayland::~ContextEGLWayland() -{ - if (m_wl_window) - m_wl_egl_window_destroy(m_wl_window); - if (m_wl_module) - dlclose(m_wl_module); -} - -std::unique_ptr ContextEGLWayland::Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try) -{ - std::unique_ptr context = std::make_unique(wi); - if (!context->LoadModule() || !context->Initialize(versions_to_try, num_versions_to_try)) - return nullptr; - - return context; -} - -std::unique_ptr ContextEGLWayland::CreateSharedContext(const WindowInfo& wi) -{ - std::unique_ptr context = std::make_unique(wi); - context->m_display = m_display; - - if (!context->LoadModule() || !context->CreateContextAndSurface(m_version, m_context, false)) - return nullptr; - - return context; -} - -void ContextEGLWayland::ResizeSurface(u32 new_surface_width, u32 new_surface_height) -{ - if (m_wl_window) - m_wl_egl_window_resize(m_wl_window, new_surface_width, new_surface_height, 0, 0); - - ContextEGL::ResizeSurface(new_surface_width, new_surface_height); -} - -EGLNativeWindowType ContextEGLWayland::GetNativeWindow(EGLConfig config) -{ - if (m_wl_window) - { - m_wl_egl_window_destroy(m_wl_window); - m_wl_window = nullptr; - } - - m_wl_window = - m_wl_egl_window_create(static_cast(m_wi.window_handle), m_wi.surface_width, m_wi.surface_height); - if (!m_wl_window) - return {}; - - return reinterpret_cast(m_wl_window); -} - -bool ContextEGLWayland::LoadModule() -{ - m_wl_module = dlopen(WAYLAND_EGL_MODNAME, RTLD_NOW | RTLD_GLOBAL); - if (!m_wl_module) - { - Log_ErrorPrintf("Failed to load %s.", WAYLAND_EGL_MODNAME); - return false; - } - - m_wl_egl_window_create = - reinterpret_cast(dlsym(m_wl_module, "wl_egl_window_create")); - m_wl_egl_window_destroy = - reinterpret_cast(dlsym(m_wl_module, "wl_egl_window_destroy")); - m_wl_egl_window_resize = - reinterpret_cast(dlsym(m_wl_module, "wl_egl_window_resize")); - if (!m_wl_egl_window_create || !m_wl_egl_window_destroy || !m_wl_egl_window_resize) - { - Log_ErrorPrintf("Failed to load one or more functions from %s.", WAYLAND_EGL_MODNAME); - return false; - } - - return true; -} -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_egl_wayland.h b/src/citra_qt/externals/duckstation/gl/context_egl_wayland.h deleted file mode 100644 index 4682f4244b..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_egl_wayland.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include "context_egl.h" -#include - -namespace GL { - -class ContextEGLWayland final : public ContextEGL -{ -public: - ContextEGLWayland(const WindowInfo& wi); - ~ContextEGLWayland() override; - - static std::unique_ptr Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try); - - std::unique_ptr CreateSharedContext(const WindowInfo& wi) override; - void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override; - -protected: - EGLNativeWindowType GetNativeWindow(EGLConfig config) override; - -private: - bool LoadModule(); - - wl_egl_window* m_wl_window = nullptr; - - void* m_wl_module = nullptr; - wl_egl_window* (*m_wl_egl_window_create)(struct wl_surface* surface, int width, int height); - void (*m_wl_egl_window_destroy)(struct wl_egl_window* egl_window); - void (*m_wl_egl_window_resize)(struct wl_egl_window* egl_window, int width, int height, int dx, int dy); -}; - -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_egl_x11.cpp b/src/citra_qt/externals/duckstation/gl/context_egl_x11.cpp deleted file mode 100644 index c7310e3126..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_egl_x11.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "context_egl_x11.h" -#include "../log.h" -Log_SetChannel(GL::ContextEGLX11); - -namespace GL { -ContextEGLX11::ContextEGLX11(const WindowInfo& wi) : ContextEGL(wi) {} -ContextEGLX11::~ContextEGLX11() = default; - -std::unique_ptr ContextEGLX11::Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try) -{ - std::unique_ptr context = std::make_unique(wi); - if (!context->Initialize(versions_to_try, num_versions_to_try)) - return nullptr; - - return context; -} - -std::unique_ptr ContextEGLX11::CreateSharedContext(const WindowInfo& wi) -{ - std::unique_ptr context = std::make_unique(wi); - context->m_display = m_display; - - if (!context->CreateContextAndSurface(m_version, m_context, false)) - return nullptr; - - return context; -} - -void ContextEGLX11::ResizeSurface(u32 new_surface_width, u32 new_surface_height) -{ - m_window.Resize(); - ContextEGL::ResizeSurface(new_surface_width, new_surface_height); -} - -EGLNativeWindowType ContextEGLX11::GetNativeWindow(EGLConfig config) -{ - X11InhibitErrors ei; - - EGLint native_visual_id = 0; - if (!eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &native_visual_id)) - { - Log_ErrorPrintf("Failed to get X11 visual ID"); - return false; - } - - XVisualInfo vi_query = {}; - vi_query.visualid = native_visual_id; - - int num_vis; - XVisualInfo* vi = XGetVisualInfo(static_cast(m_wi.display_connection), VisualIDMask, &vi_query, &num_vis); - if (num_vis <= 0 || !vi) - { - Log_ErrorPrintf("Failed to query visual from X11"); - return false; - } - - m_window.Destroy(); - if (!m_window.Create(GetDisplay(), static_cast(reinterpret_cast(m_wi.window_handle)), vi)) - { - Log_ErrorPrintf("Faild to create X11 child window"); - XFree(vi); - return false; - } - - XFree(vi); - return static_cast(m_window.GetWindow()); -} -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_egl_x11.h b/src/citra_qt/externals/duckstation/gl/context_egl_x11.h deleted file mode 100644 index 7def8bfbc0..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_egl_x11.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include "context_egl.h" -#include "x11_window.h" - -namespace GL { - -class ContextEGLX11 final : public ContextEGL -{ -public: - ContextEGLX11(const WindowInfo& wi); - ~ContextEGLX11() override; - - static std::unique_ptr Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try); - - std::unique_ptr CreateSharedContext(const WindowInfo& wi) override; - void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override; - -protected: - EGLNativeWindowType GetNativeWindow(EGLConfig config) override; - -private: - ALWAYS_INLINE Display* GetDisplay() const { return static_cast(m_wi.display_connection); } - - X11Window m_window; -}; - -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_glx.cpp b/src/citra_qt/externals/duckstation/gl/context_glx.cpp deleted file mode 100644 index bd32039ffa..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_glx.cpp +++ /dev/null @@ -1,328 +0,0 @@ -#include "context_glx.h" -#include "../duckstation_compat.h" -#include "../log.h" -#include -Log_SetChannel(GL::ContextGLX); - -namespace GL { -ContextGLX::ContextGLX(const WindowInfo& wi) : Context(wi) {} - -ContextGLX::~ContextGLX() -{ - if (glXGetCurrentContext() == m_context) - glXMakeCurrent(GetDisplay(), None, nullptr); - - if (m_context) - glXDestroyContext(GetDisplay(), m_context); - - if (m_vi) - XFree(m_vi); - - if (m_libGL_handle) - dlclose(m_libGL_handle); -} - -std::unique_ptr ContextGLX::Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try) -{ - std::unique_ptr context = std::make_unique(wi); - if (!context->Initialize(versions_to_try, num_versions_to_try)) - return nullptr; - - return context; -} - -bool ContextGLX::Initialize(const Version* versions_to_try, size_t num_versions_to_try) -{ - // We need libGL loaded, because GLAD loads its own, then releases it. - m_libGL_handle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL); - if (!m_libGL_handle) - { - m_libGL_handle = dlopen("libGL.so", RTLD_NOW | RTLD_GLOBAL); - if (!m_libGL_handle) - { - Log_ErrorPrintf("Failed to load libGL.so: %s", dlerror()); - return false; - } - } - - const int screen = DefaultScreen(GetDisplay()); - if (!gladLoadGLX(GetDisplay(), screen)) - { - Log_ErrorPrintf("Loading GLAD GLX functions failed"); - return false; - } - - if (m_wi.type == WindowInfo::Type::X11) - { - if (!CreateWindow(screen)) - return false; - } - else - { - Panic("Create pbuffer"); - } - - for (size_t i = 0; i < num_versions_to_try; i++) - { - const Version& cv = versions_to_try[i]; - if (cv.profile == Profile::NoProfile && CreateAnyContext(nullptr, true)) - { - m_version = cv; - return true; - } - else if (cv.profile != Profile::NoProfile && CreateVersionContext(cv, nullptr, true)) - { - m_version = cv; - return true; - } - } - - return false; -} - -void* ContextGLX::GetProcAddress(const char* name) -{ - return reinterpret_cast(glXGetProcAddress(reinterpret_cast(name))); -} - -bool ContextGLX::ChangeSurface(const WindowInfo& new_wi) -{ - const bool was_current = (glXGetCurrentContext() == m_context); - if (was_current) - glXMakeCurrent(GetDisplay(), None, nullptr); - - m_window.Destroy(); - m_wi = new_wi; - - if (new_wi.type == WindowInfo::Type::X11) - { - const int screen = DefaultScreen(GetDisplay()); - if (!CreateWindow(screen)) - return false; - } - - if (was_current && !glXMakeCurrent(GetDisplay(), GetDrawable(), m_context)) - { - Log_ErrorPrintf("Failed to make context current again after surface change"); - return false; - } - - return true; -} - -void ContextGLX::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/) -{ - m_window.Resize(new_surface_width, new_surface_height); - m_wi.surface_width = m_window.GetWidth(); - m_wi.surface_height = m_window.GetHeight(); -} - -bool ContextGLX::SwapBuffers() -{ - glXSwapBuffers(GetDisplay(), GetDrawable()); - return true; -} - -bool ContextGLX::MakeCurrent() -{ - return (glXMakeCurrent(GetDisplay(), GetDrawable(), m_context) == True); -} - -bool ContextGLX::DoneCurrent() -{ - return (glXMakeCurrent(GetDisplay(), None, nullptr) == True); -} - -bool ContextGLX::SetSwapInterval(s32 interval) -{ - if (GLAD_GLX_EXT_swap_control) - { - glXSwapIntervalEXT(GetDisplay(), GetDrawable(), interval); - return true; - } - else if (GLAD_GLX_MESA_swap_control) - { - return (glXSwapIntervalMESA(static_cast(std::max(interval, 0))) != 0); - } - else if (GLAD_GLX_SGI_swap_control) - { - return (glXSwapIntervalSGI(interval) != 0); - } - else - { - return false; - } -} - -std::unique_ptr ContextGLX::CreateSharedContext(const WindowInfo& wi) -{ - std::unique_ptr context = std::make_unique(wi); - if (wi.type == WindowInfo::Type::X11) - { - const int screen = DefaultScreen(context->GetDisplay()); - if (!context->CreateWindow(screen)) - return nullptr; - } - else - { - Panic("Create pbuffer"); - } - - if (m_version.profile == Profile::NoProfile) - { - if (!context->CreateAnyContext(m_context, false)) - return nullptr; - } - else - { - if (!context->CreateVersionContext(m_version, m_context, false)) - return nullptr; - } - - context->m_version = m_version; - return context; -} - -bool ContextGLX::CreateWindow(int screen) -{ - int attribs[32] = {GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_DOUBLEBUFFER, True}; - int nattribs = 8; - - switch (m_wi.surface_format) - { - case WindowInfo::SurfaceFormat::RGB8: - attribs[nattribs++] = GLX_RED_SIZE; - attribs[nattribs++] = 8; - attribs[nattribs++] = GLX_GREEN_SIZE; - attribs[nattribs++] = 8; - attribs[nattribs++] = GLX_BLUE_SIZE; - attribs[nattribs++] = 8; - break; - - case WindowInfo::SurfaceFormat::RGBA8: - attribs[nattribs++] = GLX_RED_SIZE; - attribs[nattribs++] = 8; - attribs[nattribs++] = GLX_GREEN_SIZE; - attribs[nattribs++] = 8; - attribs[nattribs++] = GLX_BLUE_SIZE; - attribs[nattribs++] = 8; - attribs[nattribs++] = GLX_ALPHA_SIZE; - attribs[nattribs++] = 8; - break; - - case WindowInfo::SurfaceFormat::RGB565: - attribs[nattribs++] = GLX_RED_SIZE; - attribs[nattribs++] = 5; - attribs[nattribs++] = GLX_GREEN_SIZE; - attribs[nattribs++] = 6; - attribs[nattribs++] = GLX_BLUE_SIZE; - attribs[nattribs++] = 5; - break; - - case WindowInfo::SurfaceFormat::Auto: - break; - - default: - UnreachableCode(); - break; - } - - attribs[nattribs++] = None; - attribs[nattribs++] = 0; - - int fbcount = 0; - GLXFBConfig* fbc = glXChooseFBConfig(GetDisplay(), screen, attribs, &fbcount); - if (!fbc || !fbcount) - { - Log_ErrorPrintf("glXChooseFBConfig() failed"); - return false; - } - m_fb_config = *fbc; - XFree(fbc); - - if (!GLAD_GLX_VERSION_1_3) - { - Log_ErrorPrintf("GLX Version 1.3 is required"); - return false; - } - - m_vi = glXGetVisualFromFBConfig(GetDisplay(), m_fb_config); - if (!m_vi) - { - Log_ErrorPrintf("glXGetVisualFromFBConfig() failed"); - return false; - } - - return m_window.Create(GetDisplay(), static_cast(reinterpret_cast(m_wi.window_handle)), m_vi); -} - -bool ContextGLX::CreateAnyContext(GLXContext share_context, bool make_current) -{ - X11InhibitErrors ie; - - m_context = glXCreateContext(GetDisplay(), m_vi, share_context, True); - if (!m_context || ie.HadError()) - { - Log_ErrorPrintf("glxCreateContext() failed"); - return false; - } - - if (make_current) - { - if (!glXMakeCurrent(GetDisplay(), GetDrawable(), m_context)) - { - Log_ErrorPrintf("glXMakeCurrent() failed"); - return false; - } - } - - return true; -} - -bool ContextGLX::CreateVersionContext(const Version& version, GLXContext share_context, bool make_current) -{ - // we need create context attribs - if (!GLAD_GLX_VERSION_1_3) - { - Log_ErrorPrint("Missing GLX version 1.3."); - return false; - } - - int attribs[32]; - int nattribs = 0; - attribs[nattribs++] = GLX_CONTEXT_PROFILE_MASK_ARB; - attribs[nattribs++] = - ((version.profile == Profile::ES) ? - ((version.major_version >= 2) ? GLX_CONTEXT_ES2_PROFILE_BIT_EXT : GLX_CONTEXT_ES_PROFILE_BIT_EXT) : - GLX_CONTEXT_CORE_PROFILE_BIT_ARB); - attribs[nattribs++] = GLX_CONTEXT_MAJOR_VERSION_ARB; - attribs[nattribs++] = version.major_version; - attribs[nattribs++] = GLX_CONTEXT_MINOR_VERSION_ARB; - attribs[nattribs++] = version.minor_version; - attribs[nattribs++] = None; - attribs[nattribs++] = 0; - - X11InhibitErrors ie; - m_context = glXCreateContextAttribsARB(GetDisplay(), m_fb_config, share_context, True, attribs); - XSync(GetDisplay(), False); - if (ie.HadError()) - m_context = nullptr; - if (!m_context) - return false; - - if (make_current) - { - if (!glXMakeCurrent(GetDisplay(), GetDrawable(), m_context)) - { - Log_ErrorPrint("glXMakeCurrent() failed"); - glXDestroyContext(GetDisplay(), m_context); - m_context = nullptr; - return false; - } - } - - return true; -} -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_glx.h b/src/citra_qt/externals/duckstation/gl/context_glx.h deleted file mode 100644 index 1f386fe9da..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_glx.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -#include "context.h" -#include "../../../../../externals/glad/src/glad_glx.h" -#include "x11_window.h" - -namespace GL { - -class ContextGLX final : public Context -{ -public: - ContextGLX(const WindowInfo& wi); - ~ContextGLX() override; - - static std::unique_ptr Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try); - - void* GetProcAddress(const char* name) override; - bool ChangeSurface(const WindowInfo& new_wi) override; - void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override; - bool SwapBuffers() override; - bool MakeCurrent() override; - bool DoneCurrent() override; - bool SetSwapInterval(s32 interval) override; - std::unique_ptr CreateSharedContext(const WindowInfo& wi) override; - -private: - ALWAYS_INLINE Display* GetDisplay() const { return static_cast(m_wi.display_connection); } - ALWAYS_INLINE GLXDrawable GetDrawable() const { return static_cast(m_window.GetWindow()); } - - bool Initialize(const Version* versions_to_try, size_t num_versions_to_try); - bool CreateWindow(int screen); - bool CreateAnyContext(GLXContext share_context, bool make_current); - bool CreateVersionContext(const Version& version, GLXContext share_context, bool make_current); - - GLXContext m_context = nullptr; - GLXFBConfig m_fb_config = {}; - XVisualInfo* m_vi = nullptr; - X11Window m_window; - - // GLAD releases its reference to libGL.so, so we need to maintain our own. - void* m_libGL_handle = nullptr; -}; - -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_wgl.cpp b/src/citra_qt/externals/duckstation/gl/context_wgl.cpp deleted file mode 100644 index 09f994c920..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_wgl.cpp +++ /dev/null @@ -1,453 +0,0 @@ -#include "context_wgl.h" -#include "../duckstation_compat.h" -#include "../log.h" -#include "../scoped_guard.h" -#include "loader.h" -using namespace melonDS; -Log_SetChannel(GL::ContextWGL); - -// TODO: get rid of this -#pragma comment(lib, "opengl32.lib") - -static void* GetProcAddressCallback(const char* name) -{ - void* addr = reinterpret_cast(wglGetProcAddress(name)); - if (addr) - return addr; - - // try opengl32.dll - return reinterpret_cast(::GetProcAddress(GetModuleHandleA("opengl32.dll"), name)); -} - -namespace GL { -ContextWGL::ContextWGL(const WindowInfo& wi) : Context(wi) {} - -ContextWGL::~ContextWGL() -{ - if (wglGetCurrentContext() == m_rc) - wglMakeCurrent(m_dc, nullptr); - - if (m_rc) - wglDeleteContext(m_rc); - - ReleaseDC(); -} - -std::unique_ptr ContextWGL::Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try) -{ - std::unique_ptr context = std::make_unique(wi); - if (!context->Initialize(versions_to_try, num_versions_to_try)) - return nullptr; - - return context; -} - -bool ContextWGL::Initialize(const Version* versions_to_try, size_t num_versions_to_try) -{ - if (m_wi.type == WindowInfo::Type::Win32) - { - if (!InitializeDC()) - return false; - } - else - { - Log_ErrorPrint("ContextWGL must always start with a valid surface."); - return false; - } - - // Everything including core/ES requires a dummy profile to load the WGL extensions. - if (!CreateAnyContext(nullptr, true)) - return false; - - for (size_t i = 0; i < num_versions_to_try; i++) - { - const Version& cv = versions_to_try[i]; - if (cv.profile == Profile::NoProfile) - { - // we already have the dummy context, so just use that - m_version = cv; - return true; - } - else if (CreateVersionContext(cv, nullptr, true)) - { - m_version = cv; - return true; - } - } - - return false; -} - -void* ContextWGL::GetProcAddress(const char* name) -{ - return GetProcAddressCallback(name); -} - -bool ContextWGL::ChangeSurface(const WindowInfo& new_wi) -{ - const bool was_current = (wglGetCurrentContext() == m_rc); - - ReleaseDC(); - - m_wi = new_wi; - if (!InitializeDC()) - return false; - - if (was_current && !wglMakeCurrent(m_dc, m_rc)) - { - Log_ErrorPrintf("Failed to make context current again after surface change: 0x%08X", GetLastError()); - return false; - } - - return true; -} - -void ContextWGL::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/) -{ - RECT client_rc = {}; - GetClientRect(GetHWND(), &client_rc); - m_wi.surface_width = static_cast(client_rc.right - client_rc.left); - m_wi.surface_height = static_cast(client_rc.bottom - client_rc.top); -} - -bool ContextWGL::SwapBuffers() -{ - return ::SwapBuffers(m_dc); -} - -bool ContextWGL::MakeCurrent() -{ - if (!wglMakeCurrent(m_dc, m_rc)) - { - Log_ErrorPrintf("wglMakeCurrent() failed: 0x%08X", GetLastError()); - return false; - } - - return true; -} - -bool ContextWGL::DoneCurrent() -{ - return wglMakeCurrent(m_dc, nullptr); -} - -bool ContextWGL::SetSwapInterval(s32 interval) -{ - if (!GLAD_WGL_EXT_swap_control) - return false; - - return wglSwapIntervalEXT(interval); -} - -std::unique_ptr ContextWGL::CreateSharedContext(const WindowInfo& wi) -{ - std::unique_ptr context = std::make_unique(wi); - if (wi.type == WindowInfo::Type::Win32) - { - if (!context->InitializeDC()) - return nullptr; - } - else - { - Log_ErrorPrint("PBuffer not implemented"); - return nullptr; - } - - if (m_version.profile == Profile::NoProfile) - { - if (!context->CreateAnyContext(m_rc, false)) - return nullptr; - } - else - { - if (!context->CreateVersionContext(m_version, m_rc, false)) - return nullptr; - } - - context->m_version = m_version; - return context; -} - -HDC ContextWGL::GetDCAndSetPixelFormat(HWND hwnd) -{ - PIXELFORMATDESCRIPTOR pfd = {}; - pfd.nSize = sizeof(pfd); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.dwLayerMask = PFD_MAIN_PLANE; - pfd.cRedBits = 8; - pfd.cGreenBits = 8; - pfd.cBlueBits = 8; - pfd.cColorBits = 24; - - HDC hDC = ::GetDC(hwnd); - if (!hDC) - { - Log_ErrorPrintf("GetDC() failed: 0x%08X", GetLastError()); - return {}; - } - - if (!m_pixel_format.has_value()) - { - const int pf = ChoosePixelFormat(hDC, &pfd); - if (pf == 0) - { - Log_ErrorPrintf("ChoosePixelFormat() failed: 0x%08X", GetLastError()); - ::ReleaseDC(hwnd, hDC); - return {}; - } - - m_pixel_format = pf; - } - - if (!SetPixelFormat(hDC, m_pixel_format.value(), &pfd)) - { - Log_ErrorPrintf("SetPixelFormat() failed: 0x%08X", GetLastError()); - ::ReleaseDC(hwnd, hDC); - return {}; - } - - return hDC; -} - -bool ContextWGL::InitializeDC() -{ - if (m_wi.type == WindowInfo::Type::Win32) - { - m_dc = GetDCAndSetPixelFormat(GetHWND()); - if (!m_dc) - { - Log_ErrorPrint("Failed to get DC for window"); - return false; - } - - return true; - } - else if (m_wi.type == WindowInfo::Type::Surfaceless) - { - return CreatePBuffer(); - } - else - { - Log_ErrorPrintf("Unknown window info type %u", static_cast(m_wi.type)); - return false; - } -} - -void ContextWGL::ReleaseDC() -{ - if (m_pbuffer) - { - wglReleasePbufferDCARB(m_pbuffer, m_dc); - m_dc = {}; - - wglDestroyPbufferARB(m_pbuffer); - m_pbuffer = {}; - - ::ReleaseDC(m_dummy_window, m_dummy_dc); - m_dummy_dc = {}; - - DestroyWindow(m_dummy_window); - m_dummy_window = {}; - } - else if (m_dc) - { - ::ReleaseDC(GetHWND(), m_dc); - m_dc = {}; - } -} - -bool ContextWGL::CreatePBuffer() -{ - static bool window_class_registered = false; - static const wchar_t* window_class_name = L"ContextWGLPBuffer"; - - if (!window_class_registered) - { - WNDCLASSEXW wc = {}; - wc.cbSize = sizeof(WNDCLASSEXW); - wc.style = 0; - wc.lpfnWndProc = DefWindowProcW; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle(nullptr); - wc.hIcon = NULL; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - wc.lpszMenuName = NULL; - wc.lpszClassName = window_class_name; - wc.hIconSm = NULL; - - if (!RegisterClassExW(&wc)) - { - Log_ErrorPrint("(ContextWGL::CreatePBuffer) RegisterClassExW() failed"); - return false; - } - - window_class_registered = true; - } - - HWND hwnd = CreateWindowExW(0, window_class_name, window_class_name, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); - if (!hwnd) - { - Log_ErrorPrint("(ContextWGL::CreatePBuffer) CreateWindowEx() failed"); - return false; - } - - ScopedGuard hwnd_guard([hwnd]() { DestroyWindow(hwnd); }); - - HDC hdc = GetDCAndSetPixelFormat(hwnd); - if (!hdc) - return false; - - ScopedGuard hdc_guard([hdc, hwnd]() { ::ReleaseDC(hwnd, hdc); }); - - static constexpr const int pb_attribs[] = {0, 0}; - - AssertMsg(m_pixel_format.has_value(), "Has pixel format for pbuffer"); - HPBUFFERARB pbuffer = wglCreatePbufferARB(hdc, m_pixel_format.value(), 1, 1, pb_attribs); - if (!pbuffer) - { - Log_ErrorPrint("(ContextWGL::CreatePBuffer) wglCreatePbufferARB() failed"); - return false; - } - - ScopedGuard pbuffer_guard([pbuffer]() { wglDestroyPbufferARB(pbuffer); }); - - m_dc = wglGetPbufferDCARB(pbuffer); - if (!m_dc) - { - Log_ErrorPrint("(ContextWGL::CreatePbuffer) wglGetPbufferDCARB() failed"); - return false; - } - - m_dummy_window = hwnd; - m_dummy_dc = hdc; - m_pbuffer = pbuffer; - - pbuffer_guard.Cancel(); - hdc_guard.Cancel(); - hwnd_guard.Cancel(); - return true; -} - -bool ContextWGL::CreateAnyContext(HGLRC share_context, bool make_current) -{ - m_rc = wglCreateContext(m_dc); - if (!m_rc) - { - Log_ErrorPrintf("wglCreateContext() failed: 0x%08X", GetLastError()); - return false; - } - - if (make_current) - { - if (!wglMakeCurrent(m_dc, m_rc)) - { - Log_ErrorPrintf("wglMakeCurrent() failed: 0x%08X", GetLastError()); - return false; - } - - // re-init glad-wgl - if (!gladLoadWGLLoader([](const char* name) -> void* { return reinterpret_cast(wglGetProcAddress(name)); }, m_dc)) - { - Log_ErrorPrint("Loading GLAD WGL functions failed"); - return false; - } - } - - if (share_context && !wglShareLists(share_context, m_rc)) - { - Log_ErrorPrintf("wglShareLists() failed: 0x%08X", GetLastError()); - return false; - } - - return true; -} - -bool ContextWGL::CreateVersionContext(const Version& version, HGLRC share_context, bool make_current) -{ - // we need create context attribs - if (!GLAD_WGL_ARB_create_context) - { - Log_ErrorPrint("Missing GLAD_WGL_ARB_create_context."); - return false; - } - - HGLRC new_rc; - if (version.profile == Profile::Core) - { - const int attribs[] = {WGL_CONTEXT_PROFILE_MASK_ARB, - WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - WGL_CONTEXT_MAJOR_VERSION_ARB, - version.major_version, - WGL_CONTEXT_MINOR_VERSION_ARB, - version.minor_version, -#ifdef _DEBUG - WGL_CONTEXT_FLAGS_ARB, - WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | WGL_CONTEXT_DEBUG_BIT_ARB, -#else - WGL_CONTEXT_FLAGS_ARB, - WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, -#endif - 0, - 0}; - - new_rc = wglCreateContextAttribsARB(m_dc, share_context, attribs); - } - else if (version.profile == Profile::ES) - { - if ((version.major_version >= 2 && !GLAD_WGL_EXT_create_context_es2_profile) || - (version.major_version < 2 && !GLAD_WGL_EXT_create_context_es_profile)) - { - Log_ErrorPrint("WGL_EXT_create_context_es_profile not supported"); - return false; - } - - const int attribs[] = { - WGL_CONTEXT_PROFILE_MASK_ARB, - ((version.major_version >= 2) ? WGL_CONTEXT_ES2_PROFILE_BIT_EXT : WGL_CONTEXT_ES_PROFILE_BIT_EXT), - WGL_CONTEXT_MAJOR_VERSION_ARB, - version.major_version, - WGL_CONTEXT_MINOR_VERSION_ARB, - version.minor_version, - 0, - 0}; - - new_rc = wglCreateContextAttribsARB(m_dc, share_context, attribs); - } - else - { - Log_ErrorPrint("Unknown profile"); - return false; - } - - if (!new_rc) - return false; - - // destroy and swap contexts - if (m_rc) - { - if (!wglMakeCurrent(m_dc, make_current ? new_rc : nullptr)) - { - Log_ErrorPrintf("wglMakeCurrent() failed: 0x%08X", GetLastError()); - wglDeleteContext(new_rc); - return false; - } - - // re-init glad-wgl - if (make_current && !gladLoadWGLLoader([](const char* name) -> void* { return reinterpret_cast(wglGetProcAddress(name)); }, m_dc)) - { - Log_ErrorPrint("Loading GLAD WGL functions failed"); - return false; - } - - wglDeleteContext(m_rc); - } - - m_rc = new_rc; - return true; -} -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/context_wgl.h b/src/citra_qt/externals/duckstation/gl/context_wgl.h deleted file mode 100644 index c90845ebb7..0000000000 --- a/src/citra_qt/externals/duckstation/gl/context_wgl.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once -#include "../windows_headers.h" - -#include "context.h" -#include "../../../../../externals/glad/src/glad_wgl.h" -#include "loader.h" -#include - -namespace GL { - -class ContextWGL final : public Context -{ -public: - ContextWGL(const WindowInfo& wi); - ~ContextWGL() override; - - static std::unique_ptr Create(const WindowInfo& wi, const Version* versions_to_try, - size_t num_versions_to_try); - - void* GetProcAddress(const char* name) override; - bool ChangeSurface(const WindowInfo& new_wi) override; - void ResizeSurface(u32 new_surface_width = 0, u32 new_surface_height = 0) override; - bool SwapBuffers() override; - bool MakeCurrent() override; - bool DoneCurrent() override; - bool SetSwapInterval(s32 interval) override; - std::unique_ptr CreateSharedContext(const WindowInfo& wi) override; - -private: - ALWAYS_INLINE HWND GetHWND() const { return static_cast(m_wi.window_handle); } - - HDC GetDCAndSetPixelFormat(HWND hwnd); - - bool Initialize(const Version* versions_to_try, size_t num_versions_to_try); - bool InitializeDC(); - void ReleaseDC(); - bool CreatePBuffer(); - bool CreateAnyContext(HGLRC share_context, bool make_current); - bool CreateVersionContext(const Version& version, HGLRC share_context, bool make_current); - - HDC m_dc = {}; - HGLRC m_rc = {}; - - // Can't change pixel format once it's set for a RC. - std::optional m_pixel_format; - - // Dummy window for creating a PBuffer off when we're surfaceless. - HWND m_dummy_window = {}; - HDC m_dummy_dc = {}; - HPBUFFERARB m_pbuffer = {}; -}; - -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/loader.h b/src/citra_qt/externals/duckstation/gl/loader.h deleted file mode 100644 index 4aefd97f4c..0000000000 --- a/src/citra_qt/externals/duckstation/gl/loader.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Fix glad.h including windows.h -#ifdef _WIN32 -#include "../windows_headers.h" -#endif - -#include "../../../../../externals/glad/src/glad.h" diff --git a/src/citra_qt/externals/duckstation/gl/x11_window.cpp b/src/citra_qt/externals/duckstation/gl/x11_window.cpp deleted file mode 100644 index bf09fcc61b..0000000000 --- a/src/citra_qt/externals/duckstation/gl/x11_window.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include "x11_window.h" -#include "../log.h" -#include "../duckstation_compat.h" -#include -Log_SetChannel(X11Window); - -namespace GL { -X11Window::X11Window() = default; - -X11Window::~X11Window() -{ - Destroy(); -} - -bool X11Window::Create(Display* display, Window parent_window, const XVisualInfo* vi) -{ - m_display = display; - m_parent_window = parent_window; - XSync(m_display, True); - - XWindowAttributes parent_wa = {}; - XGetWindowAttributes(m_display, m_parent_window, &parent_wa); - m_width = static_cast(parent_wa.width); - m_height = static_cast(parent_wa.height); - - // Failed X calls terminate the process so no need to check for errors. - // We could swap the error handler out here as well. - m_colormap = XCreateColormap(m_display, m_parent_window, vi->visual, AllocNone); - - XSetWindowAttributes wa = {}; - wa.colormap = m_colormap; - - m_window = XCreateWindow(m_display, m_parent_window, 0, 0, m_width, m_height, 0, vi->depth, InputOutput, vi->visual, - CWColormap, &wa); - XMapWindow(m_display, m_window); - XSync(m_display, True); - - return true; -} - -void X11Window::Destroy() -{ - if (m_window) - { - XUnmapWindow(m_display, m_window); - XDestroyWindow(m_display, m_window); - m_window = {}; - } - - if (m_colormap) - { - XFreeColormap(m_display, m_colormap); - m_colormap = {}; - } -} - -void X11Window::Resize(u32 width, u32 height) -{ - if (width != 0 && height != 0) - { - m_width = width; - m_height = height; - } - else - { - XWindowAttributes parent_wa = {}; - XGetWindowAttributes(m_display, m_parent_window, &parent_wa); - m_width = static_cast(parent_wa.width); - m_height = static_cast(parent_wa.height); - } - - XResizeWindow(m_display, m_window, m_width, m_height); -} - -static X11InhibitErrors* s_current_error_inhibiter; - -X11InhibitErrors::X11InhibitErrors() -{ - Assert(!s_current_error_inhibiter); - m_old_handler = XSetErrorHandler(ErrorHandler); - s_current_error_inhibiter = this; -} - -X11InhibitErrors::~X11InhibitErrors() -{ - Assert(s_current_error_inhibiter == this); - s_current_error_inhibiter = nullptr; - XSetErrorHandler(m_old_handler); -} - -int X11InhibitErrors::ErrorHandler(Display* display, XErrorEvent* ee) -{ - char error_string[256] = {}; - XGetErrorText(display, ee->error_code, error_string, sizeof(error_string)); - Log_WarningPrintf("X11 Error: %s (Error %u Minor %u Request %u)", error_string, ee->error_code, ee->minor_code, - ee->request_code); - - s_current_error_inhibiter->m_had_error = true; - return 0; -} -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/gl/x11_window.h b/src/citra_qt/externals/duckstation/gl/x11_window.h deleted file mode 100644 index 9fa896f33f..0000000000 --- a/src/citra_qt/externals/duckstation/gl/x11_window.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once -#include "../duckstation_compat.h" -#include -#include - -namespace GL { -using namespace citra; -class X11Window -{ -public: - X11Window(); - ~X11Window(); - - ALWAYS_INLINE Window GetWindow() const { return m_window; } - ALWAYS_INLINE u32 GetWidth() const { return m_width; } - ALWAYS_INLINE u32 GetHeight() const { return m_height; } - - bool Create(Display* display, Window parent_window, const XVisualInfo* vi); - void Destroy(); - - // Setting a width/height of 0 will use parent dimensions. - void Resize(u32 width = 0, u32 height = 0); - -private: - Display* m_display = nullptr; - Window m_parent_window = {}; - Window m_window = {}; - Colormap m_colormap = {}; - u32 m_width = 0; - u32 m_height = 0; -}; - -// Helper class for managing X errors -class X11InhibitErrors -{ -public: - X11InhibitErrors(); - ~X11InhibitErrors(); - - ALWAYS_INLINE bool HadError() const { return m_had_error; } - -private: - static int ErrorHandler(Display* display, XErrorEvent* ee); - - XErrorHandler m_old_handler = {}; - bool m_had_error = false; -}; - -} // namespace GL diff --git a/src/citra_qt/externals/duckstation/log.h b/src/citra_qt/externals/duckstation/log.h deleted file mode 100644 index a945bb35cd..0000000000 --- a/src/citra_qt/externals/duckstation/log.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef LOG_H -#define LOG_H - -#include - -#define Log_SetChannel(ChannelName) -#define Log_ErrorPrint(msg) puts(msg "\n"); -#define Log_ErrorPrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0) -#define Log_WarningPrint(msg) puts(msg) -#define Log_WarningPrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0) -#define Log_PerfPrint(msg) puts(msg) -#define Log_PerfPrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0) -#define Log_InfoPrint(msg) puts(msg) -#define Log_InfoPrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0) -#define Log_VerbosePrint(msg) puts(msg) -#define Log_VerbosePrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0) -#define Log_DevPrint(msg) puts(msg) -#define Log_DevPrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0) -#define Log_ProfilePrint(msg) puts(msg) -#define Log_ProfilePrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0) - -#ifdef _DEBUG -#define Log_DebugPrint(msg) puts(msg) -#define Log_DebugPrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0) -#define Log_TracePrint(msg) puts(msg) -#define Log_TracePrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0) -#else -#define Log_DebugPrint(msg) \ - do \ - { \ - } while (0) -#define Log_DebugPrintf(...) \ - do \ - { \ - } while (0) -#define Log_TracePrint(msg) \ - do \ - { \ - } while (0) -#define Log_TracePrintf(...) \ - do \ - { \ - } while (0) -#endif - -#endif \ No newline at end of file diff --git a/src/citra_qt/externals/duckstation/scoped_guard.h b/src/citra_qt/externals/duckstation/scoped_guard.h deleted file mode 100644 index 89f35d92f9..0000000000 --- a/src/citra_qt/externals/duckstation/scoped_guard.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include -#include - -/// ScopedGuard provides an object which runs a function (usually a lambda) when -/// it goes out of scope. This can be useful for releasing resources or handles -/// which do not normally have C++ types to automatically release. -template -class ScopedGuard final -{ -public: - ALWAYS_INLINE ScopedGuard(T&& func) : m_func(std::forward(func)) {} - ALWAYS_INLINE ScopedGuard(ScopedGuard&& other) : m_func(std::move(other.m_func)) { other.m_func = nullptr; } - ALWAYS_INLINE ~ScopedGuard() { Invoke(); } - - ScopedGuard(const ScopedGuard&) = delete; - void operator=(const ScopedGuard&) = delete; - - /// Prevents the function from being invoked when we go out of scope. - ALWAYS_INLINE void Cancel() { m_func.reset(); } - - /// Explicitly fires the function. - ALWAYS_INLINE void Invoke() - { - if (!m_func.has_value()) - return; - - m_func.value()(); - m_func.reset(); - } - -private: - std::optional m_func; -}; diff --git a/src/citra_qt/externals/duckstation/window_info.cpp b/src/citra_qt/externals/duckstation/window_info.cpp deleted file mode 100644 index 5176dad62a..0000000000 --- a/src/citra_qt/externals/duckstation/window_info.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "window_info.h" -#include "common/log.h" -Log_SetChannel(WindowInfo); - -#if defined(_WIN32) - -#include "common/windows_headers.h" -#include - -static bool GetRefreshRateFromDWM(HWND hwnd, float* refresh_rate) -{ - static HMODULE dwm_module = nullptr; - static HRESULT(STDAPICALLTYPE * is_composition_enabled)(BOOL * pfEnabled) = nullptr; - static HRESULT(STDAPICALLTYPE * get_timing_info)(HWND hwnd, DWM_TIMING_INFO * pTimingInfo) = nullptr; - static bool load_tried = false; - if (!load_tried) - { - load_tried = true; - dwm_module = LoadLibrary("dwmapi.dll"); - if (dwm_module) - { - std::atexit([]() { - FreeLibrary(dwm_module); - dwm_module = nullptr; - }); - is_composition_enabled = - reinterpret_cast(GetProcAddress(dwm_module, "DwmIsCompositionEnabled")); - get_timing_info = - reinterpret_cast(GetProcAddress(dwm_module, "DwmGetCompositionTimingInfo")); - } - } - - BOOL composition_enabled; - if (!is_composition_enabled || FAILED(is_composition_enabled(&composition_enabled) || !get_timing_info)) - return false; - - DWM_TIMING_INFO ti = {}; - ti.cbSize = sizeof(ti); - HRESULT hr = get_timing_info(nullptr, &ti); - if (SUCCEEDED(hr)) - { - if (ti.rateRefresh.uiNumerator == 0 || ti.rateRefresh.uiDenominator == 0) - return false; - - *refresh_rate = static_cast(ti.rateRefresh.uiNumerator) / static_cast(ti.rateRefresh.uiDenominator); - return true; - } - - return false; -} - -static bool GetRefreshRateFromMonitor(HWND hwnd, float* refresh_rate) -{ - HMONITOR mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); - if (!mon) - return false; - - MONITORINFOEXW mi = {}; - mi.cbSize = sizeof(mi); - if (GetMonitorInfoW(mon, &mi)) - { - DEVMODEW dm = {}; - dm.dmSize = sizeof(dm); - - // 0/1 are reserved for "defaults". - if (EnumDisplaySettingsW(mi.szDevice, ENUM_CURRENT_SETTINGS, &dm) && dm.dmDisplayFrequency > 1) - { - *refresh_rate = static_cast(dm.dmDisplayFrequency); - return true; - } - } - - return false; -} - -bool WindowInfo::QueryRefreshRateForWindow(const WindowInfo& wi, float* refresh_rate) -{ - if (wi.type != Type::Win32 || !wi.window_handle) - return false; - - // Try DWM first, then fall back to integer values. - const HWND hwnd = static_cast(wi.window_handle); - return GetRefreshRateFromDWM(hwnd, refresh_rate) || GetRefreshRateFromMonitor(hwnd, refresh_rate); -} - -#else - -#ifdef USE_X11 - -#include "common/scoped_guard.h" -#include "gl/x11_window.h" -#include - -static bool GetRefreshRateFromXRandR(const WindowInfo& wi, float* refresh_rate) -{ - Display* display = static_cast(wi.display_connection); - Window window = static_cast(reinterpret_cast(wi.window_handle)); - if (!display || !window) - return false; - - GL::X11InhibitErrors inhibiter; - - XRRScreenResources* res = XRRGetScreenResources(display, window); - if (!res) - { - Log_ErrorPrint("XRRGetScreenResources() failed"); - return false; - } - - ScopedGuard res_guard([res]() { XRRFreeScreenResources(res); }); - - int num_monitors; - XRRMonitorInfo* mi = XRRGetMonitors(display, window, True, &num_monitors); - if (num_monitors < 0) - { - Log_ErrorPrint("XRRGetMonitors() failed"); - return false; - } - else if (num_monitors > 1) - { - Log_WarningPrintf("XRRGetMonitors() returned %d monitors, using first", num_monitors); - } - - ScopedGuard mi_guard([mi]() { XRRFreeMonitors(mi); }); - if (mi->noutput <= 0) - { - Log_ErrorPrint("Monitor has no outputs"); - return false; - } - else if (mi->noutput > 1) - { - Log_WarningPrintf("Monitor has %d outputs, using first", mi->noutput); - } - - XRROutputInfo* oi = XRRGetOutputInfo(display, res, mi->outputs[0]); - if (!oi) - { - Log_ErrorPrint("XRRGetOutputInfo() failed"); - return false; - } - - ScopedGuard oi_guard([oi]() { XRRFreeOutputInfo(oi); }); - - XRRCrtcInfo* ci = XRRGetCrtcInfo(display, res, oi->crtc); - if (!ci) - { - Log_ErrorPrint("XRRGetCrtcInfo() failed"); - return false; - } - - ScopedGuard ci_guard([ci]() { XRRFreeCrtcInfo(ci); }); - - XRRModeInfo* mode = nullptr; - for (int i = 0; i < res->nmode; i++) - { - if (res->modes[i].id == ci->mode) - { - mode = &res->modes[i]; - break; - } - } - if (!mode) - { - Log_ErrorPrintf("Failed to look up mode %d (of %d)", static_cast(ci->mode), res->nmode); - return false; - } - - if (mode->dotClock == 0 || mode->hTotal == 0 || mode->vTotal == 0) - { - Log_ErrorPrintf("Modeline is invalid: %ld/%d/%d", mode->dotClock, mode->hTotal, mode->vTotal); - return false; - } - - *refresh_rate = - static_cast(mode->dotClock) / (static_cast(mode->hTotal) * static_cast(mode->vTotal)); - return true; -} - -#endif // USE_X11 - -bool WindowInfo::QueryRefreshRateForWindow(const WindowInfo& wi, float* refresh_rate) -{ -#if defined(USE_X11) - if (wi.type == WindowInfo::Type::X11) - return GetRefreshRateFromXRandR(wi, refresh_rate); -#endif - - return false; -} - -#endif \ No newline at end of file diff --git a/src/citra_qt/externals/duckstation/window_info.h b/src/citra_qt/externals/duckstation/window_info.h deleted file mode 100644 index 0a92a2dd83..0000000000 --- a/src/citra_qt/externals/duckstation/window_info.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "../types.h" - -// Contains the information required to create a graphics context in a window. -struct WindowInfo -{ - enum class Type - { - Surfaceless, - Win32, - X11, - Wayland, - MacOS, - Android, - Display, - }; - - enum class SurfaceFormat - { - None, - Auto, - RGB8, - RGBA8, - RGB565, - Count - }; - - Type type = Type::Surfaceless; - void* display_connection = nullptr; - void* window_handle = nullptr; - citra::u32 surface_width = 0; - citra::u32 surface_height = 0; - float surface_refresh_rate = 0.0f; - float surface_scale = 1.0f; - SurfaceFormat surface_format = SurfaceFormat::RGB8; - - // Needed for macOS. -#ifdef __APPLE__ - void* surface_handle = nullptr; -#endif - - static bool QueryRefreshRateForWindow(const WindowInfo& wi, float* refresh_rate); -}; diff --git a/src/citra_qt/externals/duckstation/windows_headers.h b/src/citra_qt/externals/duckstation/windows_headers.h deleted file mode 100644 index 6ff6ed3070..0000000000 --- a/src/citra_qt/externals/duckstation/windows_headers.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif -#ifndef NOMINMAX -#define NOMINMAX 1 -#endif - -// require vista+ -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT _WIN32_WINNT_VISTA - -#include - -#if defined(CreateDirectory) -#undef CreateDirectory -#endif -#if defined(CopyFile) -#undef CopyFile -#endif -#if defined(DeleteFile) -#undef DeleteFile -#endif diff --git a/src/citra_qt/externals/types.h b/src/citra_qt/externals/types.h deleted file mode 100644 index a6cc1b46c3..0000000000 --- a/src/citra_qt/externals/types.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright 2016-2023 melonDS team - - This file is part of melonDS. - - melonDS is free software: you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation, either version 3 of the License, or (at your option) - any later version. - - melonDS is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with melonDS. If not, see http://www.gnu.org/licenses/. -*/ - -#ifndef TYPES_H -#define TYPES_H - -#include -#include - -namespace citra -{ -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; - -template -using array2d = std::array, A>; -} -#endif // TYPES_H From 215a25c05ab3bce6ee9153fe71148acb312f4e0c Mon Sep 17 00:00:00 2001 From: Reg Tiangha Date: Fri, 19 Jul 2024 16:22:26 -0600 Subject: [PATCH 2/3] Remove references to duckstation folder --- src/citra_qt/CMakeLists.txt | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index 4e67d84c4b..88a08c344d 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -290,36 +290,6 @@ elseif (WIN32) set_target_properties(citra-qt PROPERTIES LINK_FLAGS_RELEASE "-mwindows") endif() -elseif(UNIX) - find_package(X11 REQUIRED) - find_package(EGL REQUIRED) - - option(ENABLE_WAYLAND "Enable Wayland support" ON) - - if (ENABLE_WAYLAND) - - find_package(Wayland REQUIRED Client) - - target_compile_definitions(citra PRIVATE WAYLAND_ENABLED) - - target_sources(citra PRIVATE - externals/duckstation/gl/context_egl_wayland.cpp - ) - endif() - - target_sources(citra PRIVATE - externals/duckstation/gl/context.cpp - externals/duckstation/gl/context_egl.cpp - externals/duckstation/gl/context_egl_x11.cpp - externals/duckstation/gl/context_glx.cpp - externals/duckstation/gl/x11_window.cpp - - ../../externals/glad/src/glad_egl.c - ../../externals/glad/src/glad_glx.c - ) - target_link_libraries(citra PRIVATE "${X11_LIBRARIES}" "${EGL_LIBRARIES}") - target_include_directories(citra PRIVATE "${X11_INCLUDE_DIR}") - add_compile_definitions(QAPPLICATION_CLASS=QApplication) endif() if(ENABLE_SDL2) From 973ff5f2d1da43b3aa8f2b8d528536e3f90d495f Mon Sep 17 00:00:00 2001 From: Reg Tiangha Date: Sat, 20 Jul 2024 11:02:32 -0600 Subject: [PATCH 3/3] ci: Bundle QT Wayland libraries into Linux AppImage --- .ci/linux.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ci/linux.sh b/.ci/linux.sh index ee971f4bc0..7dd860604e 100755 --- a/.ci/linux.sh +++ b/.ci/linux.sh @@ -3,6 +3,9 @@ if [ "$TARGET" = "appimage" ]; then # Compile the AppImage we distribute with Clang. export EXTRA_CMAKE_FLAGS=(-DCITRA_USE_PRECOMPILED_HEADERS=OFF -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_LINKER=/etc/bin/ld.lld) + # Bundle required QT wayland libraries + export EXTRA_QT_PLUGINS="waylandcompositor" + export EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so" else # For the linux-fresh verification target, verify compilation without PCH as well. export EXTRA_CMAKE_FLAGS=(-DCITRA_USE_PRECOMPILED_HEADERS=OFF)