mirror of
https://github.com/PabloMK7/citra.git
synced 2025-09-09 04:10:05 +00:00
Apply clang-format-15
This commit is contained in:
parent
3193775201
commit
99b9cec967
21 changed files with 1623 additions and 1779 deletions
|
@ -7,7 +7,7 @@
|
|||
|
||||
#define ALWAYS_INLINE __attribute__((always_inline)) inline
|
||||
|
||||
#define AssertMsg(cond, msg) assert(cond && msg)
|
||||
#define AssertMsg(cond, msg) assert(cond&& msg)
|
||||
#define Assert(cond) assert(cond)
|
||||
|
||||
#define Panic(msg) assert(false && msg)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "context.h"
|
||||
#include "../log.h"
|
||||
#include "loader.h"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
#include "../log.h"
|
||||
#include "context.h"
|
||||
#include "loader.h"
|
||||
Log_SetChannel(GL::Context);
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
@ -20,8 +20,7 @@ Log_SetChannel(GL::Context);
|
|||
|
||||
namespace GL {
|
||||
|
||||
static bool ShouldPreferESContext()
|
||||
{
|
||||
static bool ShouldPreferESContext() {
|
||||
#ifndef _MSC_VER
|
||||
const char* value = std::getenv("PREFER_GLES_CONTEXT");
|
||||
return (value && strcmp(value, "1") == 0);
|
||||
|
@ -37,26 +36,22 @@ Context::Context(const WindowInfo& wi) : m_wi(wi) {}
|
|||
|
||||
Context::~Context() = default;
|
||||
|
||||
std::vector<Context::FullscreenModeInfo> Context::EnumerateFullscreenModes()
|
||||
{
|
||||
std::vector<Context::FullscreenModeInfo> Context::EnumerateFullscreenModes() {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<GL::Context> Context::Create(const WindowInfo& wi, const Version* versions_to_try,
|
||||
size_t num_versions_to_try)
|
||||
{
|
||||
if (ShouldPreferESContext())
|
||||
{
|
||||
size_t num_versions_to_try) {
|
||||
if (ShouldPreferESContext()) {
|
||||
// move ES versions to the front
|
||||
Version* new_versions_to_try = static_cast<Version*>(alloca(sizeof(Version) * num_versions_to_try));
|
||||
Version* new_versions_to_try =
|
||||
static_cast<Version*>(alloca(sizeof(Version) * num_versions_to_try));
|
||||
size_t count = 0;
|
||||
for (size_t i = 0; i < num_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];
|
||||
}
|
||||
for (size_t i = 0; i < num_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];
|
||||
}
|
||||
|
@ -69,8 +64,7 @@ std::unique_ptr<GL::Context> Context::Create(const WindowInfo& wi, const Version
|
|||
#elif defined(__APPLE__)
|
||||
context = ContextAGL::Create(wi, versions_to_try, num_versions_to_try);
|
||||
#else
|
||||
if (wi.type == WindowInfo::Type::X11)
|
||||
{
|
||||
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);
|
||||
|
@ -93,8 +87,8 @@ std::unique_ptr<GL::Context> Context::Create(const WindowInfo& wi, const Version
|
|||
static Context* context_being_created;
|
||||
context_being_created = context.get();
|
||||
|
||||
if (!gladLoadGLLoader([](const char* name) { return context_being_created->GetProcAddress(name); }))
|
||||
{
|
||||
if (!gladLoadGLLoader(
|
||||
[](const char* name) { return context_being_created->GetProcAddress(name); })) {
|
||||
Log_ErrorPrintf("Failed to load GL functions for GLAD");
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -102,7 +96,8 @@ std::unique_ptr<GL::Context> Context::Create(const WindowInfo& wi, const Version
|
|||
const char* gl_vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
|
||||
const char* gl_renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
const char* gl_version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||
const char* gl_shading_language_version = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
const char* gl_shading_language_version =
|
||||
reinterpret_cast<const char*>(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);
|
||||
|
@ -111,8 +106,7 @@ std::unique_ptr<GL::Context> Context::Create(const WindowInfo& wi, const Version
|
|||
return context;
|
||||
}
|
||||
|
||||
const std::array<Context::Version, 11>& Context::GetAllDesktopVersionsList()
|
||||
{
|
||||
const std::array<Context::Version, 11>& Context::GetAllDesktopVersionsList() {
|
||||
static constexpr std::array<Version, 11> vlist = {{{Profile::Core, 4, 6},
|
||||
{Profile::Core, 4, 5},
|
||||
{Profile::Core, 4, 4},
|
||||
|
@ -127,8 +121,7 @@ const std::array<Context::Version, 11>& Context::GetAllDesktopVersionsList()
|
|||
return vlist;
|
||||
}
|
||||
|
||||
const std::array<Context::Version, 12>& Context::GetAllDesktopVersionsListWithFallback()
|
||||
{
|
||||
const std::array<Context::Version, 12>& Context::GetAllDesktopVersionsListWithFallback() {
|
||||
static constexpr std::array<Version, 12> vlist = {{{Profile::Core, 4, 6},
|
||||
{Profile::Core, 4, 5},
|
||||
{Profile::Core, 4, 4},
|
||||
|
@ -144,15 +137,13 @@ const std::array<Context::Version, 12>& Context::GetAllDesktopVersionsListWithFa
|
|||
return vlist;
|
||||
}
|
||||
|
||||
const std::array<Context::Version, 4>& Context::GetAllESVersionsList()
|
||||
{
|
||||
const std::array<Context::Version, 4>& Context::GetAllESVersionsList() {
|
||||
static constexpr std::array<Version, 4> vlist = {
|
||||
{{Profile::ES, 3, 2}, {Profile::ES, 3, 1}, {Profile::ES, 3, 0}, {Profile::ES, 2, 0}}};
|
||||
return vlist;
|
||||
}
|
||||
|
||||
const std::array<Context::Version, 16>& Context::GetAllVersionsList()
|
||||
{
|
||||
const std::array<Context::Version, 16>& Context::GetAllVersionsList() {
|
||||
static constexpr std::array<Version, 16> vlist = {{{Profile::Core, 4, 6},
|
||||
{Profile::Core, 4, 5},
|
||||
{Profile::Core, 4, 4},
|
||||
|
|
50
src/citra_qt/externals/duckstation/gl/context.h
vendored
50
src/citra_qt/externals/duckstation/gl/context.h
vendored
|
@ -1,44 +1,46 @@
|
|||
#pragma once
|
||||
#include "../duckstation_compat.h"
|
||||
#include "../window_info.h"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "../duckstation_compat.h"
|
||||
#include "../window_info.h"
|
||||
|
||||
namespace GL {
|
||||
using namespace citra;
|
||||
class Context
|
||||
{
|
||||
class Context {
|
||||
public:
|
||||
Context(const WindowInfo& wi);
|
||||
virtual ~Context();
|
||||
|
||||
enum class Profile
|
||||
{
|
||||
NoProfile,
|
||||
Core,
|
||||
ES
|
||||
};
|
||||
enum class Profile { NoProfile, Core, ES };
|
||||
|
||||
struct Version
|
||||
{
|
||||
struct Version {
|
||||
Profile profile;
|
||||
int major_version;
|
||||
int minor_version;
|
||||
};
|
||||
|
||||
struct FullscreenModeInfo
|
||||
{
|
||||
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; }
|
||||
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;
|
||||
|
@ -54,13 +56,15 @@ public:
|
|||
static std::unique_ptr<Context> Create(const WindowInfo& wi, const Version* versions_to_try,
|
||||
size_t num_versions_to_try);
|
||||
|
||||
template<size_t N>
|
||||
static std::unique_ptr<Context> Create(const WindowInfo& wi, const std::array<Version, N>& versions_to_try)
|
||||
{
|
||||
template <size_t N>
|
||||
static std::unique_ptr<Context> Create(const WindowInfo& wi,
|
||||
const std::array<Version, N>& versions_to_try) {
|
||||
return Create(wi, versions_to_try.data(), versions_to_try.size());
|
||||
}
|
||||
|
||||
static std::unique_ptr<Context> Create(const WindowInfo& wi) { return Create(wi, GetAllVersionsList()); }
|
||||
static std::unique_ptr<Context> Create(const WindowInfo& wi) {
|
||||
return Create(wi, GetAllVersionsList());
|
||||
}
|
||||
|
||||
static const std::array<Version, 11>& GetAllDesktopVersionsList();
|
||||
static const std::array<Version, 12>& GetAllDesktopVersionsListWithFallback();
|
||||
|
|
|
@ -14,8 +14,7 @@ struct NSView;
|
|||
namespace GL {
|
||||
|
||||
using namespace melonDS;
|
||||
class ContextAGL final : public Context
|
||||
{
|
||||
class ContextAGL final : public Context {
|
||||
public:
|
||||
ContextAGL(const WindowInfo& wi);
|
||||
~ContextAGL() override;
|
||||
|
@ -33,7 +32,9 @@ public:
|
|||
std::unique_ptr<Context> CreateSharedContext(const WindowInfo& wi) override;
|
||||
|
||||
private:
|
||||
ALWAYS_INLINE NSView* GetView() const { return static_cast<NSView*>((__bridge NSView*)m_wi.window_handle); }
|
||||
ALWAYS_INLINE NSView* GetView() const {
|
||||
return static_cast<NSView*>((__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);
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
#include "context_egl.h"
|
||||
#include "../log.h"
|
||||
#include "../duckstation_compat.h"
|
||||
#include <cstring>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include "../duckstation_compat.h"
|
||||
#include "../log.h"
|
||||
#include "context_egl.h"
|
||||
Log_SetChannel(GL::ContextEGL);
|
||||
|
||||
namespace GL {
|
||||
ContextEGL::ContextEGL(const WindowInfo& wi) : Context(wi) {}
|
||||
|
||||
ContextEGL::~ContextEGL()
|
||||
{
|
||||
ContextEGL::~ContextEGL() {
|
||||
DestroySurface();
|
||||
DestroyContext();
|
||||
}
|
||||
|
||||
std::unique_ptr<Context> ContextEGL::Create(const WindowInfo& wi, const Version* versions_to_try,
|
||||
size_t num_versions_to_try)
|
||||
{
|
||||
size_t num_versions_to_try) {
|
||||
std::unique_ptr<ContextEGL> context = std::make_unique<ContextEGL>(wi);
|
||||
if (!context->Initialize(versions_to_try, num_versions_to_try))
|
||||
return nullptr;
|
||||
|
@ -25,10 +23,8 @@ std::unique_ptr<Context> ContextEGL::Create(const WindowInfo& wi, const Version*
|
|||
return context;
|
||||
}
|
||||
|
||||
bool ContextEGL::Initialize(const Version* versions_to_try, size_t num_versions_to_try)
|
||||
{
|
||||
if (!gladLoadEGL())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -37,24 +33,22 @@ bool ContextEGL::Initialize(const Version* versions_to_try, size_t num_versions_
|
|||
return false;
|
||||
|
||||
int egl_major, egl_minor;
|
||||
if (!eglInitialize(m_display, &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)
|
||||
{
|
||||
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");
|
||||
Log_WarningPrint(
|
||||
"EGL implementation does not support surfaceless contexts, emulating with pbuffers");
|
||||
|
||||
for (size_t i = 0; i < num_versions_to_try; i++)
|
||||
{
|
||||
for (size_t i = 0; i < num_versions_to_try; i++) {
|
||||
if (CreateContextAndSurface(versions_to_try[i], nullptr, true))
|
||||
return true;
|
||||
}
|
||||
|
@ -62,11 +56,9 @@ bool ContextEGL::Initialize(const Version* versions_to_try, size_t num_versions_
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ContextEGL::SetDisplay()
|
||||
{
|
||||
bool ContextEGL::SetDisplay() {
|
||||
m_display = eglGetDisplay(static_cast<EGLNativeDisplayType>(m_wi.display_connection));
|
||||
if (!m_display)
|
||||
{
|
||||
if (!m_display) {
|
||||
Log_ErrorPrintf("eglGetDisplay() failed: %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
@ -74,19 +66,16 @@ bool ContextEGL::SetDisplay()
|
|||
return true;
|
||||
}
|
||||
|
||||
void* ContextEGL::GetProcAddress(const char* name)
|
||||
{
|
||||
void* ContextEGL::GetProcAddress(const char* name) {
|
||||
return reinterpret_cast<void*>(eglGetProcAddress(name));
|
||||
}
|
||||
|
||||
bool ContextEGL::ChangeSurface(const WindowInfo& new_wi)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (m_surface != EGL_NO_SURFACE) {
|
||||
eglDestroySurface(m_display, m_surface);
|
||||
m_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
@ -95,8 +84,7 @@ bool ContextEGL::ChangeSurface(const WindowInfo& new_wi)
|
|||
if (!CreateSurface())
|
||||
return false;
|
||||
|
||||
if (was_current && !eglMakeCurrent(m_display, m_surface, m_surface, m_context))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -104,20 +92,15 @@ bool ContextEGL::ChangeSurface(const WindowInfo& new_wi)
|
|||
return true;
|
||||
}
|
||||
|
||||
void ContextEGL::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/)
|
||||
{
|
||||
if (new_surface_width == 0 && new_surface_height == 0)
|
||||
{
|
||||
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))
|
||||
{
|
||||
eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &surface_height)) {
|
||||
m_wi.surface_width = static_cast<u32>(surface_width);
|
||||
m_wi.surface_height = static_cast<u32>(surface_height);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Log_ErrorPrintf("eglQuerySurface() failed: %d", eglGetError());
|
||||
}
|
||||
}
|
||||
|
@ -126,15 +109,12 @@ void ContextEGL::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_he
|
|||
m_wi.surface_height = new_surface_height;
|
||||
}
|
||||
|
||||
bool ContextEGL::SwapBuffers()
|
||||
{
|
||||
bool ContextEGL::SwapBuffers() {
|
||||
return eglSwapBuffers(m_display, m_surface);
|
||||
}
|
||||
|
||||
bool ContextEGL::MakeCurrent()
|
||||
{
|
||||
if (!eglMakeCurrent(m_display, m_surface, m_surface, m_context))
|
||||
{
|
||||
bool ContextEGL::MakeCurrent() {
|
||||
if (!eglMakeCurrent(m_display, m_surface, m_surface, m_context)) {
|
||||
Log_ErrorPrintf("eglMakeCurrent() failed: %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
@ -142,18 +122,15 @@ bool ContextEGL::MakeCurrent()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContextEGL::DoneCurrent()
|
||||
{
|
||||
bool ContextEGL::DoneCurrent() {
|
||||
return eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
bool ContextEGL::SetSwapInterval(s32 interval)
|
||||
{
|
||||
bool ContextEGL::SetSwapInterval(s32 interval) {
|
||||
return eglSwapInterval(m_display, interval);
|
||||
}
|
||||
|
||||
std::unique_ptr<Context> ContextEGL::CreateSharedContext(const WindowInfo& wi)
|
||||
{
|
||||
std::unique_ptr<Context> ContextEGL::CreateSharedContext(const WindowInfo& wi) {
|
||||
std::unique_ptr<ContextEGL> context = std::make_unique<ContextEGL>(wi);
|
||||
context->m_display = m_display;
|
||||
context->m_supports_surfaceless = m_supports_surfaceless;
|
||||
|
@ -164,15 +141,12 @@ std::unique_ptr<Context> ContextEGL::CreateSharedContext(const WindowInfo& wi)
|
|||
return context;
|
||||
}
|
||||
|
||||
EGLNativeWindowType ContextEGL::GetNativeWindow(EGLConfig config)
|
||||
{
|
||||
EGLNativeWindowType ContextEGL::GetNativeWindow(EGLConfig config) {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ContextEGL::CreateSurface()
|
||||
{
|
||||
if (m_wi.type == WindowInfo::Type::Surfaceless)
|
||||
{
|
||||
bool ContextEGL::CreateSurface() {
|
||||
if (m_wi.type == WindowInfo::Type::Surfaceless) {
|
||||
if (m_supports_surfaceless)
|
||||
return true;
|
||||
else
|
||||
|
@ -181,8 +155,7 @@ bool ContextEGL::CreateSurface()
|
|||
|
||||
EGLNativeWindowType native_window = GetNativeWindow(m_config);
|
||||
m_surface = eglCreateWindowSurface(m_display, m_config, native_window, nullptr);
|
||||
if (!m_surface)
|
||||
{
|
||||
if (!m_surface) {
|
||||
Log_ErrorPrintf("eglCreateWindowSurface() failed: %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
@ -190,21 +163,17 @@ bool ContextEGL::CreateSurface()
|
|||
// 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))
|
||||
{
|
||||
eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &surface_height)) {
|
||||
m_wi.surface_width = static_cast<u32>(surface_width);
|
||||
m_wi.surface_height = static_cast<u32>(surface_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Log_ErrorPrintf("eglQuerySurface() failed: %d", eglGetError());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContextEGL::CreatePBufferSurface()
|
||||
{
|
||||
bool ContextEGL::CreatePBufferSurface() {
|
||||
const u32 width = std::max<u32>(m_wi.surface_width, 1);
|
||||
const u32 height = std::max<u32>(m_wi.surface_height, 1);
|
||||
|
||||
|
@ -214,8 +183,7 @@ bool ContextEGL::CreatePBufferSurface()
|
|||
};
|
||||
|
||||
m_surface = eglCreatePbufferSurface(m_display, m_config, attrib_list);
|
||||
if (!m_surface)
|
||||
{
|
||||
if (!m_surface) {
|
||||
Log_ErrorPrintf("eglCreatePbufferSurface() failed: %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
@ -224,19 +192,17 @@ bool ContextEGL::CreatePBufferSurface()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContextEGL::CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceFormat format) const
|
||||
{
|
||||
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))
|
||||
{
|
||||
!eglGetConfigAttrib(m_display, config, EGL_ALPHA_SIZE, &alpha_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (format)
|
||||
{
|
||||
switch (format) {
|
||||
case WindowInfo::SurfaceFormat::Auto:
|
||||
return true;
|
||||
|
||||
|
@ -254,48 +220,44 @@ bool ContextEGL::CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceF
|
|||
}
|
||||
}
|
||||
|
||||
void ContextEGL::DestroyContext()
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (m_context != EGL_NO_CONTEXT) {
|
||||
eglDestroyContext(m_display, m_context);
|
||||
m_context = EGL_NO_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
void ContextEGL::DestroySurface()
|
||||
{
|
||||
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)
|
||||
{
|
||||
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"));
|
||||
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,
|
||||
(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)
|
||||
{
|
||||
switch (m_wi.surface_format) {
|
||||
case WindowInfo::SurfaceFormat::RGB8:
|
||||
surface_attribs[nsurface_attribs++] = EGL_RED_SIZE;
|
||||
surface_attribs[nsurface_attribs++] = 8;
|
||||
|
@ -337,40 +299,35 @@ bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
|
|||
surface_attribs[nsurface_attribs++] = 0;
|
||||
|
||||
EGLint num_configs;
|
||||
if (!eglChooseConfig(m_display, surface_attribs, nullptr, 0, &num_configs) || num_configs == 0)
|
||||
{
|
||||
if (!eglChooseConfig(m_display, surface_attribs, nullptr, 0, &num_configs) ||
|
||||
num_configs == 0) {
|
||||
Log_ErrorPrintf("eglChooseConfig() failed: %d", eglGetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<EGLConfig> configs(static_cast<u32>(num_configs));
|
||||
if (!eglChooseConfig(m_display, surface_attribs, configs.data(), num_configs, &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<u32>(num_configs));
|
||||
|
||||
std::optional<EGLConfig> config;
|
||||
for (EGLConfig check_config : configs)
|
||||
{
|
||||
if (CheckConfigSurfaceFormat(check_config, m_wi.surface_format))
|
||||
{
|
||||
for (EGLConfig check_config : configs) {
|
||||
if (CheckConfigSurfaceFormat(check_config, m_wi.surface_format)) {
|
||||
config = check_config;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.has_value())
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (version.profile != Profile::NoProfile) {
|
||||
attribs[nattribs++] = EGL_CONTEXT_MAJOR_VERSION;
|
||||
attribs[nattribs++] = version.major_version;
|
||||
attribs[nattribs++] = EGL_CONTEXT_MINOR_VERSION;
|
||||
|
@ -379,46 +336,43 @@ bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
|
|||
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");
|
||||
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)
|
||||
{
|
||||
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"));
|
||||
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)
|
||||
{
|
||||
bool ContextEGL::CreateContextAndSurface(const Version& version, EGLContext share_context,
|
||||
bool make_current) {
|
||||
if (!CreateContext(version, share_context))
|
||||
return false;
|
||||
|
||||
if (!CreateSurface())
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (make_current && !eglMakeCurrent(m_display, m_surface, m_surface, m_context)) {
|
||||
Log_ErrorPrintf("eglMakeCurrent() failed: %d", eglGetError());
|
||||
if (m_surface != EGL_NO_SURFACE)
|
||||
{
|
||||
if (m_surface != EGL_NO_SURFACE) {
|
||||
eglDestroySurface(m_display, m_surface);
|
||||
m_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#pragma once
|
||||
#include "context.h"
|
||||
#include "../../../../../externals/glad/src/glad_egl.h"
|
||||
#include "context.h"
|
||||
|
||||
namespace GL {
|
||||
|
||||
class ContextEGL : public Context
|
||||
{
|
||||
class ContextEGL : public Context {
|
||||
public:
|
||||
ContextEGL(const WindowInfo& wi);
|
||||
~ContextEGL() override;
|
||||
|
@ -29,7 +28,8 @@ protected:
|
|||
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 CreateContextAndSurface(const Version& version, EGLContext share_context,
|
||||
bool make_current);
|
||||
bool CreateSurface();
|
||||
bool CreatePBufferSurface();
|
||||
bool CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceFormat format) const;
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
#include "context_egl_wayland.h"
|
||||
#include "../log.h"
|
||||
#include <dlfcn.h>
|
||||
#include "../log.h"
|
||||
#include "context_egl_wayland.h"
|
||||
Log_SetChannel(ContextEGLWayland);
|
||||
|
||||
namespace GL {
|
||||
static const char* WAYLAND_EGL_MODNAME = "libwayland-egl.so.1";
|
||||
|
||||
ContextEGLWayland::ContextEGLWayland(const WindowInfo& wi) : ContextEGL(wi) {}
|
||||
ContextEGLWayland::~ContextEGLWayland()
|
||||
{
|
||||
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<Context> ContextEGLWayland::Create(const WindowInfo& wi, const Version* versions_to_try,
|
||||
size_t num_versions_to_try)
|
||||
{
|
||||
std::unique_ptr<Context> ContextEGLWayland::Create(const WindowInfo& wi,
|
||||
const Version* versions_to_try,
|
||||
size_t num_versions_to_try) {
|
||||
std::unique_ptr<ContextEGLWayland> context = std::make_unique<ContextEGLWayland>(wi);
|
||||
if (!context->LoadModule() || !context->Initialize(versions_to_try, num_versions_to_try))
|
||||
return nullptr;
|
||||
|
@ -25,8 +24,7 @@ std::unique_ptr<Context> ContextEGLWayland::Create(const WindowInfo& wi, const V
|
|||
return context;
|
||||
}
|
||||
|
||||
std::unique_ptr<Context> ContextEGLWayland::CreateSharedContext(const WindowInfo& wi)
|
||||
{
|
||||
std::unique_ptr<Context> ContextEGLWayland::CreateSharedContext(const WindowInfo& wi) {
|
||||
std::unique_ptr<ContextEGLWayland> context = std::make_unique<ContextEGLWayland>(wi);
|
||||
context->m_display = m_display;
|
||||
|
||||
|
@ -36,47 +34,41 @@ std::unique_ptr<Context> ContextEGLWayland::CreateSharedContext(const WindowInfo
|
|||
return context;
|
||||
}
|
||||
|
||||
void ContextEGLWayland::ResizeSurface(u32 new_surface_width, u32 new_surface_height)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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<wl_surface*>(m_wi.window_handle), m_wi.surface_width, m_wi.surface_height);
|
||||
m_wl_window = m_wl_egl_window_create(static_cast<wl_surface*>(m_wi.window_handle),
|
||||
m_wi.surface_width, m_wi.surface_height);
|
||||
if (!m_wl_window)
|
||||
return {};
|
||||
|
||||
return reinterpret_cast<EGLNativeWindowType>(m_wl_window);
|
||||
}
|
||||
|
||||
bool ContextEGLWayland::LoadModule()
|
||||
{
|
||||
bool ContextEGLWayland::LoadModule() {
|
||||
m_wl_module = dlopen(WAYLAND_EGL_MODNAME, RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!m_wl_module)
|
||||
{
|
||||
if (!m_wl_module) {
|
||||
Log_ErrorPrintf("Failed to load %s.", WAYLAND_EGL_MODNAME);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_wl_egl_window_create =
|
||||
reinterpret_cast<decltype(m_wl_egl_window_create)>(dlsym(m_wl_module, "wl_egl_window_create"));
|
||||
m_wl_egl_window_destroy =
|
||||
reinterpret_cast<decltype(m_wl_egl_window_destroy)>(dlsym(m_wl_module, "wl_egl_window_destroy"));
|
||||
m_wl_egl_window_resize =
|
||||
reinterpret_cast<decltype(m_wl_egl_window_resize)>(dlsym(m_wl_module, "wl_egl_window_resize"));
|
||||
if (!m_wl_egl_window_create || !m_wl_egl_window_destroy || !m_wl_egl_window_resize)
|
||||
{
|
||||
m_wl_egl_window_create = reinterpret_cast<decltype(m_wl_egl_window_create)>(
|
||||
dlsym(m_wl_module, "wl_egl_window_create"));
|
||||
m_wl_egl_window_destroy = reinterpret_cast<decltype(m_wl_egl_window_destroy)>(
|
||||
dlsym(m_wl_module, "wl_egl_window_destroy"));
|
||||
m_wl_egl_window_resize = reinterpret_cast<decltype(m_wl_egl_window_resize)>(
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
#pragma once
|
||||
#include "context_egl.h"
|
||||
#include <wayland-egl.h>
|
||||
#include "context_egl.h"
|
||||
|
||||
namespace GL {
|
||||
|
||||
class ContextEGLWayland final : public ContextEGL
|
||||
{
|
||||
class ContextEGLWayland final : public ContextEGL {
|
||||
public:
|
||||
ContextEGLWayland(const WindowInfo& wi);
|
||||
~ContextEGLWayland() override;
|
||||
|
@ -27,7 +26,8 @@ private:
|
|||
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);
|
||||
void (*m_wl_egl_window_resize)(struct wl_egl_window* egl_window, int width, int height, int dx,
|
||||
int dy);
|
||||
};
|
||||
|
||||
} // namespace GL
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "context_egl_x11.h"
|
||||
#include "../log.h"
|
||||
#include "context_egl_x11.h"
|
||||
Log_SetChannel(GL::ContextEGLX11);
|
||||
|
||||
namespace GL {
|
||||
|
@ -7,8 +7,7 @@ ContextEGLX11::ContextEGLX11(const WindowInfo& wi) : ContextEGL(wi) {}
|
|||
ContextEGLX11::~ContextEGLX11() = default;
|
||||
|
||||
std::unique_ptr<Context> ContextEGLX11::Create(const WindowInfo& wi, const Version* versions_to_try,
|
||||
size_t num_versions_to_try)
|
||||
{
|
||||
size_t num_versions_to_try) {
|
||||
std::unique_ptr<ContextEGLX11> context = std::make_unique<ContextEGLX11>(wi);
|
||||
if (!context->Initialize(versions_to_try, num_versions_to_try))
|
||||
return nullptr;
|
||||
|
@ -16,8 +15,7 @@ std::unique_ptr<Context> ContextEGLX11::Create(const WindowInfo& wi, const Versi
|
|||
return context;
|
||||
}
|
||||
|
||||
std::unique_ptr<Context> ContextEGLX11::CreateSharedContext(const WindowInfo& wi)
|
||||
{
|
||||
std::unique_ptr<Context> ContextEGLX11::CreateSharedContext(const WindowInfo& wi) {
|
||||
std::unique_ptr<ContextEGLX11> context = std::make_unique<ContextEGLX11>(wi);
|
||||
context->m_display = m_display;
|
||||
|
||||
|
@ -27,19 +25,16 @@ std::unique_ptr<Context> ContextEGLX11::CreateSharedContext(const WindowInfo& wi
|
|||
return context;
|
||||
}
|
||||
|
||||
void ContextEGLX11::ResizeSurface(u32 new_surface_width, u32 new_surface_height)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (!eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &native_visual_id)) {
|
||||
Log_ErrorPrintf("Failed to get X11 visual ID");
|
||||
return false;
|
||||
}
|
||||
|
@ -48,16 +43,17 @@ EGLNativeWindowType ContextEGLX11::GetNativeWindow(EGLConfig config)
|
|||
vi_query.visualid = native_visual_id;
|
||||
|
||||
int num_vis;
|
||||
XVisualInfo* vi = XGetVisualInfo(static_cast<Display*>(m_wi.display_connection), VisualIDMask, &vi_query, &num_vis);
|
||||
if (num_vis <= 0 || !vi)
|
||||
{
|
||||
XVisualInfo* vi = XGetVisualInfo(static_cast<Display*>(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<Window>(reinterpret_cast<uintptr_t>(m_wi.window_handle)), vi))
|
||||
{
|
||||
if (!m_window.Create(GetDisplay(),
|
||||
static_cast<Window>(reinterpret_cast<uintptr_t>(m_wi.window_handle)),
|
||||
vi)) {
|
||||
Log_ErrorPrintf("Faild to create X11 child window");
|
||||
XFree(vi);
|
||||
return false;
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
namespace GL {
|
||||
|
||||
class ContextEGLX11 final : public ContextEGL
|
||||
{
|
||||
class ContextEGLX11 final : public ContextEGL {
|
||||
public:
|
||||
ContextEGLX11(const WindowInfo& wi);
|
||||
~ContextEGLX11() override;
|
||||
|
@ -20,7 +19,9 @@ protected:
|
|||
EGLNativeWindowType GetNativeWindow(EGLConfig config) override;
|
||||
|
||||
private:
|
||||
ALWAYS_INLINE Display* GetDisplay() const { return static_cast<Display*>(m_wi.display_connection); }
|
||||
ALWAYS_INLINE Display* GetDisplay() const {
|
||||
return static_cast<Display*>(m_wi.display_connection);
|
||||
}
|
||||
|
||||
X11Window m_window;
|
||||
};
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
#include "context_glx.h"
|
||||
#include <dlfcn.h>
|
||||
#include "../duckstation_compat.h"
|
||||
#include "../log.h"
|
||||
#include <dlfcn.h>
|
||||
#include "context_glx.h"
|
||||
Log_SetChannel(GL::ContextGLX);
|
||||
|
||||
namespace GL {
|
||||
ContextGLX::ContextGLX(const WindowInfo& wi) : Context(wi) {}
|
||||
|
||||
ContextGLX::~ContextGLX()
|
||||
{
|
||||
ContextGLX::~ContextGLX() {
|
||||
if (glXGetCurrentContext() == m_context)
|
||||
glXMakeCurrent(GetDisplay(), None, nullptr);
|
||||
|
||||
|
@ -23,8 +22,7 @@ ContextGLX::~ContextGLX()
|
|||
}
|
||||
|
||||
std::unique_ptr<Context> ContextGLX::Create(const WindowInfo& wi, const Version* versions_to_try,
|
||||
size_t num_versions_to_try)
|
||||
{
|
||||
size_t num_versions_to_try) {
|
||||
std::unique_ptr<ContextGLX> context = std::make_unique<ContextGLX>(wi);
|
||||
if (!context->Initialize(versions_to_try, num_versions_to_try))
|
||||
return nullptr;
|
||||
|
@ -32,47 +30,36 @@ std::unique_ptr<Context> ContextGLX::Create(const WindowInfo& wi, const Version*
|
|||
return context;
|
||||
}
|
||||
|
||||
bool ContextGLX::Initialize(const Version* versions_to_try, size_t num_versions_to_try)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!m_libGL_handle) {
|
||||
m_libGL_handle = dlopen("libGL.so", RTLD_NOW | RTLD_GLOBAL);
|
||||
if (!m_libGL_handle)
|
||||
{
|
||||
if (!m_libGL_handle) {
|
||||
Log_ErrorPrintf("Failed to load libGL.so: %s", dlerror());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const int screen = DefaultScreen(GetDisplay());
|
||||
if (!gladLoadGLX(GetDisplay(), screen))
|
||||
{
|
||||
if (!gladLoadGLX(GetDisplay(), screen)) {
|
||||
Log_ErrorPrintf("Loading GLAD GLX functions failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_wi.type == WindowInfo::Type::X11)
|
||||
{
|
||||
if (m_wi.type == WindowInfo::Type::X11) {
|
||||
if (!CreateWindow(screen))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Panic("Create pbuffer");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_versions_to_try; i++)
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (cv.profile == Profile::NoProfile && CreateAnyContext(nullptr, true)) {
|
||||
m_version = cv;
|
||||
return true;
|
||||
}
|
||||
else if (cv.profile != Profile::NoProfile && CreateVersionContext(cv, nullptr, true))
|
||||
{
|
||||
} else if (cv.profile != Profile::NoProfile && CreateVersionContext(cv, nullptr, true)) {
|
||||
m_version = cv;
|
||||
return true;
|
||||
}
|
||||
|
@ -81,13 +68,11 @@ bool ContextGLX::Initialize(const Version* versions_to_try, size_t num_versions_
|
|||
return false;
|
||||
}
|
||||
|
||||
void* ContextGLX::GetProcAddress(const char* name)
|
||||
{
|
||||
void* ContextGLX::GetProcAddress(const char* name) {
|
||||
return reinterpret_cast<void*>(glXGetProcAddress(reinterpret_cast<const GLubyte*>(name)));
|
||||
}
|
||||
|
||||
bool ContextGLX::ChangeSurface(const WindowInfo& new_wi)
|
||||
{
|
||||
bool ContextGLX::ChangeSurface(const WindowInfo& new_wi) {
|
||||
const bool was_current = (glXGetCurrentContext() == m_context);
|
||||
if (was_current)
|
||||
glXMakeCurrent(GetDisplay(), None, nullptr);
|
||||
|
@ -95,15 +80,13 @@ bool ContextGLX::ChangeSurface(const WindowInfo& new_wi)
|
|||
m_window.Destroy();
|
||||
m_wi = new_wi;
|
||||
|
||||
if (new_wi.type == WindowInfo::Type::X11)
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (was_current && !glXMakeCurrent(GetDisplay(), GetDrawable(), m_context)) {
|
||||
Log_ErrorPrintf("Failed to make context current again after surface change");
|
||||
return false;
|
||||
}
|
||||
|
@ -111,71 +94,52 @@ bool ContextGLX::ChangeSurface(const WindowInfo& new_wi)
|
|||
return true;
|
||||
}
|
||||
|
||||
void ContextGLX::ResizeSurface(u32 new_surface_width /*= 0*/, u32 new_surface_height /*= 0*/)
|
||||
{
|
||||
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()
|
||||
{
|
||||
bool ContextGLX::SwapBuffers() {
|
||||
glXSwapBuffers(GetDisplay(), GetDrawable());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContextGLX::MakeCurrent()
|
||||
{
|
||||
bool ContextGLX::MakeCurrent() {
|
||||
return (glXMakeCurrent(GetDisplay(), GetDrawable(), m_context) == True);
|
||||
}
|
||||
|
||||
bool ContextGLX::DoneCurrent()
|
||||
{
|
||||
bool ContextGLX::DoneCurrent() {
|
||||
return (glXMakeCurrent(GetDisplay(), None, nullptr) == True);
|
||||
}
|
||||
|
||||
bool ContextGLX::SetSwapInterval(s32 interval)
|
||||
{
|
||||
if (GLAD_GLX_EXT_swap_control)
|
||||
{
|
||||
bool ContextGLX::SetSwapInterval(s32 interval) {
|
||||
if (GLAD_GLX_EXT_swap_control) {
|
||||
glXSwapIntervalEXT(GetDisplay(), GetDrawable(), interval);
|
||||
return true;
|
||||
}
|
||||
else if (GLAD_GLX_MESA_swap_control)
|
||||
{
|
||||
} else if (GLAD_GLX_MESA_swap_control) {
|
||||
return (glXSwapIntervalMESA(static_cast<u32>(std::max(interval, 0))) != 0);
|
||||
}
|
||||
else if (GLAD_GLX_SGI_swap_control)
|
||||
{
|
||||
} else if (GLAD_GLX_SGI_swap_control) {
|
||||
return (glXSwapIntervalSGI(interval) != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Context> ContextGLX::CreateSharedContext(const WindowInfo& wi)
|
||||
{
|
||||
std::unique_ptr<Context> ContextGLX::CreateSharedContext(const WindowInfo& wi) {
|
||||
std::unique_ptr<ContextGLX> context = std::make_unique<ContextGLX>(wi);
|
||||
if (wi.type == WindowInfo::Type::X11)
|
||||
{
|
||||
if (wi.type == WindowInfo::Type::X11) {
|
||||
const int screen = DefaultScreen(context->GetDisplay());
|
||||
if (!context->CreateWindow(screen))
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Panic("Create pbuffer");
|
||||
}
|
||||
|
||||
if (m_version.profile == Profile::NoProfile)
|
||||
{
|
||||
if (m_version.profile == Profile::NoProfile) {
|
||||
if (!context->CreateAnyContext(m_context, false))
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (!context->CreateVersionContext(m_version, m_context, false))
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -184,14 +148,12 @@ std::unique_ptr<Context> ContextGLX::CreateSharedContext(const WindowInfo& wi)
|
|||
return context;
|
||||
}
|
||||
|
||||
bool ContextGLX::CreateWindow(int screen)
|
||||
{
|
||||
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)
|
||||
{
|
||||
switch (m_wi.surface_format) {
|
||||
case WindowInfo::SurfaceFormat::RGB8:
|
||||
attribs[nattribs++] = GLX_RED_SIZE;
|
||||
attribs[nattribs++] = 8;
|
||||
|
@ -234,45 +196,39 @@ bool ContextGLX::CreateWindow(int screen)
|
|||
|
||||
int fbcount = 0;
|
||||
GLXFBConfig* fbc = glXChooseFBConfig(GetDisplay(), screen, attribs, &fbcount);
|
||||
if (!fbc || !fbcount)
|
||||
{
|
||||
if (!fbc || !fbcount) {
|
||||
Log_ErrorPrintf("glXChooseFBConfig() failed");
|
||||
return false;
|
||||
}
|
||||
m_fb_config = *fbc;
|
||||
XFree(fbc);
|
||||
|
||||
if (!GLAD_GLX_VERSION_1_3)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!m_vi) {
|
||||
Log_ErrorPrintf("glXGetVisualFromFBConfig() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_window.Create(GetDisplay(), static_cast<Window>(reinterpret_cast<uintptr_t>(m_wi.window_handle)), m_vi);
|
||||
return m_window.Create(
|
||||
GetDisplay(), static_cast<Window>(reinterpret_cast<uintptr_t>(m_wi.window_handle)), m_vi);
|
||||
}
|
||||
|
||||
bool ContextGLX::CreateAnyContext(GLXContext share_context, bool make_current)
|
||||
{
|
||||
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())
|
||||
{
|
||||
if (!m_context || ie.HadError()) {
|
||||
Log_ErrorPrintf("glxCreateContext() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (make_current)
|
||||
{
|
||||
if (!glXMakeCurrent(GetDisplay(), GetDrawable(), m_context))
|
||||
{
|
||||
if (make_current) {
|
||||
if (!glXMakeCurrent(GetDisplay(), GetDrawable(), m_context)) {
|
||||
Log_ErrorPrintf("glXMakeCurrent() failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -281,11 +237,10 @@ bool ContextGLX::CreateAnyContext(GLXContext share_context, bool make_current)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContextGLX::CreateVersionContext(const Version& version, GLXContext share_context, bool make_current)
|
||||
{
|
||||
bool ContextGLX::CreateVersionContext(const Version& version, GLXContext share_context,
|
||||
bool make_current) {
|
||||
// we need create context attribs
|
||||
if (!GLAD_GLX_VERSION_1_3)
|
||||
{
|
||||
if (!GLAD_GLX_VERSION_1_3) {
|
||||
Log_ErrorPrint("Missing GLX version 1.3.");
|
||||
return false;
|
||||
}
|
||||
|
@ -293,10 +248,10 @@ bool ContextGLX::CreateVersionContext(const Version& version, GLXContext share_c
|
|||
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++] = ((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;
|
||||
|
@ -312,10 +267,8 @@ bool ContextGLX::CreateVersionContext(const Version& version, GLXContext share_c
|
|||
if (!m_context)
|
||||
return false;
|
||||
|
||||
if (make_current)
|
||||
{
|
||||
if (!glXMakeCurrent(GetDisplay(), GetDrawable(), m_context))
|
||||
{
|
||||
if (make_current) {
|
||||
if (!glXMakeCurrent(GetDisplay(), GetDrawable(), m_context)) {
|
||||
Log_ErrorPrint("glXMakeCurrent() failed");
|
||||
glXDestroyContext(GetDisplay(), m_context);
|
||||
m_context = nullptr;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
#pragma once
|
||||
#include "context.h"
|
||||
#include "../../../../../externals/glad/src/glad_glx.h"
|
||||
#include "context.h"
|
||||
#include "x11_window.h"
|
||||
|
||||
namespace GL {
|
||||
|
||||
class ContextGLX final : public Context
|
||||
{
|
||||
class ContextGLX final : public Context {
|
||||
public:
|
||||
ContextGLX(const WindowInfo& wi);
|
||||
~ContextGLX() override;
|
||||
|
@ -24,8 +23,12 @@ public:
|
|||
std::unique_ptr<Context> CreateSharedContext(const WindowInfo& wi) override;
|
||||
|
||||
private:
|
||||
ALWAYS_INLINE Display* GetDisplay() const { return static_cast<Display*>(m_wi.display_connection); }
|
||||
ALWAYS_INLINE GLXDrawable GetDrawable() const { return static_cast<GLXDrawable>(m_window.GetWindow()); }
|
||||
ALWAYS_INLINE Display* GetDisplay() const {
|
||||
return static_cast<Display*>(m_wi.display_connection);
|
||||
}
|
||||
ALWAYS_INLINE GLXDrawable GetDrawable() const {
|
||||
return static_cast<GLXDrawable>(m_window.GetWindow());
|
||||
}
|
||||
|
||||
bool Initialize(const Version* versions_to_try, size_t num_versions_to_try);
|
||||
bool CreateWindow(int screen);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "context_wgl.h"
|
||||
#include "../duckstation_compat.h"
|
||||
#include "../log.h"
|
||||
#include "../scoped_guard.h"
|
||||
#include "context_wgl.h"
|
||||
#include "loader.h"
|
||||
using namespace melonDS;
|
||||
Log_SetChannel(GL::ContextWGL);
|
||||
|
@ -9,8 +9,7 @@ Log_SetChannel(GL::ContextWGL);
|
|||
// TODO: get rid of this
|
||||
#pragma comment(lib, "opengl32.lib")
|
||||
|
||||
static void* GetProcAddressCallback(const char* name)
|
||||
{
|
||||
static void* GetProcAddressCallback(const char* name) {
|
||||
void* addr = reinterpret_cast<void*>(wglGetProcAddress(name));
|
||||
if (addr)
|
||||
return addr;
|
||||
|
@ -22,8 +21,7 @@ static void* GetProcAddressCallback(const char* name)
|
|||
namespace GL {
|
||||
ContextWGL::ContextWGL(const WindowInfo& wi) : Context(wi) {}
|
||||
|
||||
ContextWGL::~ContextWGL()
|
||||
{
|
||||
ContextWGL::~ContextWGL() {
|
||||
if (wglGetCurrentContext() == m_rc)
|
||||
wglMakeCurrent(m_dc, nullptr);
|
||||
|
||||
|
@ -34,8 +32,7 @@ ContextWGL::~ContextWGL()
|
|||
}
|
||||
|
||||
std::unique_ptr<Context> ContextWGL::Create(const WindowInfo& wi, const Version* versions_to_try,
|
||||
size_t num_versions_to_try)
|
||||
{
|
||||
size_t num_versions_to_try) {
|
||||
std::unique_ptr<ContextWGL> context = std::make_unique<ContextWGL>(wi);
|
||||
if (!context->Initialize(versions_to_try, num_versions_to_try))
|
||||
return nullptr;
|
||||
|
@ -43,15 +40,11 @@ std::unique_ptr<Context> ContextWGL::Create(const WindowInfo& wi, const Version*
|
|||
return context;
|
||||
}
|
||||
|
||||
bool ContextWGL::Initialize(const Version* versions_to_try, size_t num_versions_to_try)
|
||||
{
|
||||
if (m_wi.type == WindowInfo::Type::Win32)
|
||||
{
|
||||
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
|
||||
{
|
||||
} else {
|
||||
Log_ErrorPrint("ContextWGL must always start with a valid surface.");
|
||||
return false;
|
||||
}
|
||||
|
@ -60,17 +53,13 @@ bool ContextWGL::Initialize(const Version* versions_to_try, size_t num_versions_
|
|||
if (!CreateAnyContext(nullptr, true))
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < num_versions_to_try; i++)
|
||||
{
|
||||
for (size_t i = 0; i < num_versions_to_try; i++) {
|
||||
const Version& cv = versions_to_try[i];
|
||||
if (cv.profile == Profile::NoProfile)
|
||||
{
|
||||
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))
|
||||
{
|
||||
} else if (CreateVersionContext(cv, nullptr, true)) {
|
||||
m_version = cv;
|
||||
return true;
|
||||
}
|
||||
|
@ -79,13 +68,11 @@ bool ContextWGL::Initialize(const Version* versions_to_try, size_t num_versions_
|
|||
return false;
|
||||
}
|
||||
|
||||
void* ContextWGL::GetProcAddress(const char* name)
|
||||
{
|
||||
void* ContextWGL::GetProcAddress(const char* name) {
|
||||
return GetProcAddressCallback(name);
|
||||
}
|
||||
|
||||
bool ContextWGL::ChangeSurface(const WindowInfo& new_wi)
|
||||
{
|
||||
bool ContextWGL::ChangeSurface(const WindowInfo& new_wi) {
|
||||
const bool was_current = (wglGetCurrentContext() == m_rc);
|
||||
|
||||
ReleaseDC();
|
||||
|
@ -94,32 +81,28 @@ bool ContextWGL::ChangeSurface(const WindowInfo& 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());
|
||||
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*/)
|
||||
{
|
||||
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<u32>(client_rc.right - client_rc.left);
|
||||
m_wi.surface_height = static_cast<u32>(client_rc.bottom - client_rc.top);
|
||||
}
|
||||
|
||||
bool ContextWGL::SwapBuffers()
|
||||
{
|
||||
bool ContextWGL::SwapBuffers() {
|
||||
return ::SwapBuffers(m_dc);
|
||||
}
|
||||
|
||||
bool ContextWGL::MakeCurrent()
|
||||
{
|
||||
if (!wglMakeCurrent(m_dc, m_rc))
|
||||
{
|
||||
bool ContextWGL::MakeCurrent() {
|
||||
if (!wglMakeCurrent(m_dc, m_rc)) {
|
||||
Log_ErrorPrintf("wglMakeCurrent() failed: 0x%08X", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
@ -127,40 +110,31 @@ bool ContextWGL::MakeCurrent()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContextWGL::DoneCurrent()
|
||||
{
|
||||
bool ContextWGL::DoneCurrent() {
|
||||
return wglMakeCurrent(m_dc, nullptr);
|
||||
}
|
||||
|
||||
bool ContextWGL::SetSwapInterval(s32 interval)
|
||||
{
|
||||
bool ContextWGL::SetSwapInterval(s32 interval) {
|
||||
if (!GLAD_WGL_EXT_swap_control)
|
||||
return false;
|
||||
|
||||
return wglSwapIntervalEXT(interval);
|
||||
}
|
||||
|
||||
std::unique_ptr<Context> ContextWGL::CreateSharedContext(const WindowInfo& wi)
|
||||
{
|
||||
std::unique_ptr<Context> ContextWGL::CreateSharedContext(const WindowInfo& wi) {
|
||||
std::unique_ptr<ContextWGL> context = std::make_unique<ContextWGL>(wi);
|
||||
if (wi.type == WindowInfo::Type::Win32)
|
||||
{
|
||||
if (wi.type == WindowInfo::Type::Win32) {
|
||||
if (!context->InitializeDC())
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Log_ErrorPrint("PBuffer not implemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (m_version.profile == Profile::NoProfile)
|
||||
{
|
||||
if (m_version.profile == Profile::NoProfile) {
|
||||
if (!context->CreateAnyContext(m_rc, false))
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (!context->CreateVersionContext(m_version, m_rc, false))
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -169,8 +143,7 @@ std::unique_ptr<Context> ContextWGL::CreateSharedContext(const WindowInfo& wi)
|
|||
return context;
|
||||
}
|
||||
|
||||
HDC ContextWGL::GetDCAndSetPixelFormat(HWND hwnd)
|
||||
{
|
||||
HDC ContextWGL::GetDCAndSetPixelFormat(HWND hwnd) {
|
||||
PIXELFORMATDESCRIPTOR pfd = {};
|
||||
pfd.nSize = sizeof(pfd);
|
||||
pfd.nVersion = 1;
|
||||
|
@ -183,17 +156,14 @@ HDC ContextWGL::GetDCAndSetPixelFormat(HWND hwnd)
|
|||
pfd.cColorBits = 24;
|
||||
|
||||
HDC hDC = ::GetDC(hwnd);
|
||||
if (!hDC)
|
||||
{
|
||||
if (!hDC) {
|
||||
Log_ErrorPrintf("GetDC() failed: 0x%08X", GetLastError());
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!m_pixel_format.has_value())
|
||||
{
|
||||
if (!m_pixel_format.has_value()) {
|
||||
const int pf = ChoosePixelFormat(hDC, &pfd);
|
||||
if (pf == 0)
|
||||
{
|
||||
if (pf == 0) {
|
||||
Log_ErrorPrintf("ChoosePixelFormat() failed: 0x%08X", GetLastError());
|
||||
::ReleaseDC(hwnd, hDC);
|
||||
return {};
|
||||
|
@ -202,8 +172,7 @@ HDC ContextWGL::GetDCAndSetPixelFormat(HWND hwnd)
|
|||
m_pixel_format = pf;
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(hDC, m_pixel_format.value(), &pfd))
|
||||
{
|
||||
if (!SetPixelFormat(hDC, m_pixel_format.value(), &pfd)) {
|
||||
Log_ErrorPrintf("SetPixelFormat() failed: 0x%08X", GetLastError());
|
||||
::ReleaseDC(hwnd, hDC);
|
||||
return {};
|
||||
|
@ -212,34 +181,25 @@ HDC ContextWGL::GetDCAndSetPixelFormat(HWND hwnd)
|
|||
return hDC;
|
||||
}
|
||||
|
||||
bool ContextWGL::InitializeDC()
|
||||
{
|
||||
if (m_wi.type == WindowInfo::Type::Win32)
|
||||
{
|
||||
bool ContextWGL::InitializeDC() {
|
||||
if (m_wi.type == WindowInfo::Type::Win32) {
|
||||
m_dc = GetDCAndSetPixelFormat(GetHWND());
|
||||
if (!m_dc)
|
||||
{
|
||||
if (!m_dc) {
|
||||
Log_ErrorPrint("Failed to get DC for window");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (m_wi.type == WindowInfo::Type::Surfaceless)
|
||||
{
|
||||
} else if (m_wi.type == WindowInfo::Type::Surfaceless) {
|
||||
return CreatePBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Log_ErrorPrintf("Unknown window info type %u", static_cast<unsigned>(m_wi.type));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ContextWGL::ReleaseDC()
|
||||
{
|
||||
if (m_pbuffer)
|
||||
{
|
||||
void ContextWGL::ReleaseDC() {
|
||||
if (m_pbuffer) {
|
||||
wglReleasePbufferDCARB(m_pbuffer, m_dc);
|
||||
m_dc = {};
|
||||
|
||||
|
@ -251,21 +211,17 @@ void ContextWGL::ReleaseDC()
|
|||
|
||||
DestroyWindow(m_dummy_window);
|
||||
m_dummy_window = {};
|
||||
}
|
||||
else if (m_dc)
|
||||
{
|
||||
} else if (m_dc) {
|
||||
::ReleaseDC(GetHWND(), m_dc);
|
||||
m_dc = {};
|
||||
}
|
||||
}
|
||||
|
||||
bool ContextWGL::CreatePBuffer()
|
||||
{
|
||||
bool ContextWGL::CreatePBuffer() {
|
||||
static bool window_class_registered = false;
|
||||
static const wchar_t* window_class_name = L"ContextWGLPBuffer";
|
||||
|
||||
if (!window_class_registered)
|
||||
{
|
||||
if (!window_class_registered) {
|
||||
WNDCLASSEXW wc = {};
|
||||
wc.cbSize = sizeof(WNDCLASSEXW);
|
||||
wc.style = 0;
|
||||
|
@ -280,8 +236,7 @@ bool ContextWGL::CreatePBuffer()
|
|||
wc.lpszClassName = window_class_name;
|
||||
wc.hIconSm = NULL;
|
||||
|
||||
if (!RegisterClassExW(&wc))
|
||||
{
|
||||
if (!RegisterClassExW(&wc)) {
|
||||
Log_ErrorPrint("(ContextWGL::CreatePBuffer) RegisterClassExW() failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -289,9 +244,9 @@ bool ContextWGL::CreatePBuffer()
|
|||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -308,8 +263,7 @@ bool ContextWGL::CreatePBuffer()
|
|||
|
||||
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)
|
||||
{
|
||||
if (!pbuffer) {
|
||||
Log_ErrorPrint("(ContextWGL::CreatePBuffer) wglCreatePbufferARB() failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -317,8 +271,7 @@ bool ContextWGL::CreatePBuffer()
|
|||
ScopedGuard pbuffer_guard([pbuffer]() { wglDestroyPbufferARB(pbuffer); });
|
||||
|
||||
m_dc = wglGetPbufferDCARB(pbuffer);
|
||||
if (!m_dc)
|
||||
{
|
||||
if (!m_dc) {
|
||||
Log_ErrorPrint("(ContextWGL::CreatePbuffer) wglGetPbufferDCARB() failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -333,33 +286,31 @@ bool ContextWGL::CreatePBuffer()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContextWGL::CreateAnyContext(HGLRC share_context, bool make_current)
|
||||
{
|
||||
bool ContextWGL::CreateAnyContext(HGLRC share_context, bool make_current) {
|
||||
m_rc = wglCreateContext(m_dc);
|
||||
if (!m_rc)
|
||||
{
|
||||
if (!m_rc) {
|
||||
Log_ErrorPrintf("wglCreateContext() failed: 0x%08X", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (make_current)
|
||||
{
|
||||
if (!wglMakeCurrent(m_dc, m_rc))
|
||||
{
|
||||
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<void*>(wglGetProcAddress(name)); }, m_dc))
|
||||
{
|
||||
if (!gladLoadWGLLoader(
|
||||
[](const char* name) -> void* {
|
||||
return reinterpret_cast<void*>(wglGetProcAddress(name));
|
||||
},
|
||||
m_dc)) {
|
||||
Log_ErrorPrint("Loading GLAD WGL functions failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (share_context && !wglShareLists(share_context, m_rc))
|
||||
{
|
||||
if (share_context && !wglShareLists(share_context, m_rc)) {
|
||||
Log_ErrorPrintf("wglShareLists() failed: 0x%08X", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
@ -367,18 +318,16 @@ bool ContextWGL::CreateAnyContext(HGLRC share_context, bool make_current)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ContextWGL::CreateVersionContext(const Version& version, HGLRC share_context, bool make_current)
|
||||
{
|
||||
bool ContextWGL::CreateVersionContext(const Version& version, HGLRC share_context,
|
||||
bool make_current) {
|
||||
// we need create context attribs
|
||||
if (!GLAD_WGL_ARB_create_context)
|
||||
{
|
||||
if (!GLAD_WGL_ARB_create_context) {
|
||||
Log_ErrorPrint("Missing GLAD_WGL_ARB_create_context.");
|
||||
return false;
|
||||
}
|
||||
|
||||
HGLRC new_rc;
|
||||
if (version.profile == Profile::Core)
|
||||
{
|
||||
if (version.profile == Profile::Core) {
|
||||
const int attribs[] = {WGL_CONTEXT_PROFILE_MASK_ARB,
|
||||
WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB,
|
||||
|
@ -396,19 +345,16 @@ bool ContextWGL::CreateVersionContext(const Version& version, HGLRC share_contex
|
|||
0};
|
||||
|
||||
new_rc = wglCreateContextAttribsARB(m_dc, share_context, attribs);
|
||||
}
|
||||
else if (version.profile == Profile::ES)
|
||||
{
|
||||
} 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))
|
||||
{
|
||||
(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),
|
||||
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,
|
||||
|
@ -417,9 +363,7 @@ bool ContextWGL::CreateVersionContext(const Version& version, HGLRC share_contex
|
|||
0};
|
||||
|
||||
new_rc = wglCreateContextAttribsARB(m_dc, share_context, attribs);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Log_ErrorPrint("Unknown profile");
|
||||
return false;
|
||||
}
|
||||
|
@ -428,18 +372,19 @@ bool ContextWGL::CreateVersionContext(const Version& version, HGLRC share_contex
|
|||
return false;
|
||||
|
||||
// destroy and swap contexts
|
||||
if (m_rc)
|
||||
{
|
||||
if (!wglMakeCurrent(m_dc, make_current ? new_rc : nullptr))
|
||||
{
|
||||
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<void*>(wglGetProcAddress(name)); }, m_dc))
|
||||
{
|
||||
if (make_current && !gladLoadWGLLoader(
|
||||
[](const char* name) -> void* {
|
||||
return reinterpret_cast<void*>(wglGetProcAddress(name));
|
||||
},
|
||||
m_dc)) {
|
||||
Log_ErrorPrint("Loading GLAD WGL functions failed");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
#pragma once
|
||||
#include "../windows_headers.h"
|
||||
|
||||
#include "context.h"
|
||||
#include "../../../../../externals/glad/src/glad_wgl.h"
|
||||
#include "loader.h"
|
||||
#include <optional>
|
||||
#include "../../../../../externals/glad/src/glad_wgl.h"
|
||||
#include "context.h"
|
||||
#include "loader.h"
|
||||
|
||||
namespace GL {
|
||||
|
||||
class ContextWGL final : public Context
|
||||
{
|
||||
class ContextWGL final : public Context {
|
||||
public:
|
||||
ContextWGL(const WindowInfo& wi);
|
||||
~ContextWGL() override;
|
||||
|
@ -27,7 +26,9 @@ public:
|
|||
std::unique_ptr<Context> CreateSharedContext(const WindowInfo& wi) override;
|
||||
|
||||
private:
|
||||
ALWAYS_INLINE HWND GetHWND() const { return static_cast<HWND>(m_wi.window_handle); }
|
||||
ALWAYS_INLINE HWND GetHWND() const {
|
||||
return static_cast<HWND>(m_wi.window_handle);
|
||||
}
|
||||
|
||||
HDC GetDCAndSetPixelFormat(HWND hwnd);
|
||||
|
||||
|
|
|
@ -1,19 +1,17 @@
|
|||
#include "x11_window.h"
|
||||
#include "../log.h"
|
||||
#include "../duckstation_compat.h"
|
||||
#include <cstdio>
|
||||
#include "../duckstation_compat.h"
|
||||
#include "../log.h"
|
||||
#include "x11_window.h"
|
||||
Log_SetChannel(X11Window);
|
||||
|
||||
namespace GL {
|
||||
X11Window::X11Window() = default;
|
||||
|
||||
X11Window::~X11Window()
|
||||
{
|
||||
X11Window::~X11Window() {
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool X11Window::Create(Display* display, Window parent_window, const XVisualInfo* vi)
|
||||
{
|
||||
bool X11Window::Create(Display* display, Window parent_window, const XVisualInfo* vi) {
|
||||
m_display = display;
|
||||
m_parent_window = parent_window;
|
||||
XSync(m_display, True);
|
||||
|
@ -30,39 +28,32 @@ bool X11Window::Create(Display* display, Window parent_window, const XVisualInfo
|
|||
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);
|
||||
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)
|
||||
{
|
||||
void X11Window::Destroy() {
|
||||
if (m_window) {
|
||||
XUnmapWindow(m_display, m_window);
|
||||
XDestroyWindow(m_display, m_window);
|
||||
m_window = {};
|
||||
}
|
||||
|
||||
if (m_colormap)
|
||||
{
|
||||
if (m_colormap) {
|
||||
XFreeColormap(m_display, m_colormap);
|
||||
m_colormap = {};
|
||||
}
|
||||
}
|
||||
|
||||
void X11Window::Resize(u32 width, u32 height)
|
||||
{
|
||||
if (width != 0 && height != 0)
|
||||
{
|
||||
void X11Window::Resize(u32 width, u32 height) {
|
||||
if (width != 0 && height != 0) {
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
XWindowAttributes parent_wa = {};
|
||||
XGetWindowAttributes(m_display, m_parent_window, &parent_wa);
|
||||
m_width = static_cast<u32>(parent_wa.width);
|
||||
|
@ -74,26 +65,23 @@ void X11Window::Resize(u32 width, u32 height)
|
|||
|
||||
static X11InhibitErrors* s_current_error_inhibiter;
|
||||
|
||||
X11InhibitErrors::X11InhibitErrors()
|
||||
{
|
||||
X11InhibitErrors::X11InhibitErrors() {
|
||||
Assert(!s_current_error_inhibiter);
|
||||
m_old_handler = XSetErrorHandler(ErrorHandler);
|
||||
s_current_error_inhibiter = this;
|
||||
}
|
||||
|
||||
X11InhibitErrors::~X11InhibitErrors()
|
||||
{
|
||||
X11InhibitErrors::~X11InhibitErrors() {
|
||||
Assert(s_current_error_inhibiter == this);
|
||||
s_current_error_inhibiter = nullptr;
|
||||
XSetErrorHandler(m_old_handler);
|
||||
}
|
||||
|
||||
int X11InhibitErrors::ErrorHandler(Display* display, XErrorEvent* ee)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
#pragma once
|
||||
#include "../duckstation_compat.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include "../duckstation_compat.h"
|
||||
|
||||
namespace GL {
|
||||
using namespace citra;
|
||||
class X11Window
|
||||
{
|
||||
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; }
|
||||
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();
|
||||
|
@ -31,13 +36,14 @@ private:
|
|||
};
|
||||
|
||||
// Helper class for managing X errors
|
||||
class X11InhibitErrors
|
||||
{
|
||||
class X11InhibitErrors {
|
||||
public:
|
||||
X11InhibitErrors();
|
||||
~X11InhibitErrors();
|
||||
|
||||
ALWAYS_INLINE bool HadError() const { return m_had_error; }
|
||||
ALWAYS_INLINE bool HadError() const {
|
||||
return m_had_error;
|
||||
}
|
||||
|
||||
private:
|
||||
static int ErrorHandler(Display* display, XErrorEvent* ee);
|
||||
|
|
66
src/citra_qt/externals/duckstation/log.h
vendored
66
src/citra_qt/externals/duckstation/log.h
vendored
|
@ -5,41 +5,73 @@
|
|||
|
||||
#define Log_SetChannel(ChannelName)
|
||||
#define Log_ErrorPrint(msg) puts(msg "\n");
|
||||
#define Log_ErrorPrintf(...) do { printf(__VA_ARGS__); putchar('\n'); } while (0)
|
||||
#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_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_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_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_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_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)
|
||||
#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_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)
|
||||
#define Log_TracePrintf(...) \
|
||||
do { \
|
||||
printf(__VA_ARGS__); \
|
||||
putchar('\n'); \
|
||||
} while (0)
|
||||
#else
|
||||
#define Log_DebugPrint(msg) \
|
||||
do \
|
||||
{ \
|
||||
do { \
|
||||
} while (0)
|
||||
#define Log_DebugPrintf(...) \
|
||||
do \
|
||||
{ \
|
||||
do { \
|
||||
} while (0)
|
||||
#define Log_TracePrint(msg) \
|
||||
do \
|
||||
{ \
|
||||
do { \
|
||||
} while (0)
|
||||
#define Log_TracePrintf(...) \
|
||||
do \
|
||||
{ \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -5,23 +5,27 @@
|
|||
/// 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<typename T>
|
||||
class ScopedGuard final
|
||||
{
|
||||
template <typename T>
|
||||
class ScopedGuard final {
|
||||
public:
|
||||
ALWAYS_INLINE ScopedGuard(T&& func) : m_func(std::forward<T>(func)) {}
|
||||
ALWAYS_INLINE ScopedGuard(ScopedGuard&& other) : m_func(std::move(other.m_func)) { other.m_func = nullptr; }
|
||||
ALWAYS_INLINE ~ScopedGuard() { Invoke(); }
|
||||
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(); }
|
||||
ALWAYS_INLINE void Cancel() {
|
||||
m_func.reset();
|
||||
}
|
||||
|
||||
/// Explicitly fires the function.
|
||||
ALWAYS_INLINE void Invoke()
|
||||
{
|
||||
ALWAYS_INLINE void Invoke() {
|
||||
if (!m_func.has_value())
|
||||
return;
|
||||
|
||||
|
|
102
src/citra_qt/externals/duckstation/window_info.cpp
vendored
102
src/citra_qt/externals/duckstation/window_info.cpp
vendored
|
@ -1,70 +1,67 @@
|
|||
#include "window_info.h"
|
||||
#include "common/log.h"
|
||||
#include "window_info.h"
|
||||
Log_SetChannel(WindowInfo);
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include "common/windows_headers.h"
|
||||
#include <dwmapi.h>
|
||||
#include "common/windows_headers.h"
|
||||
|
||||
static bool GetRefreshRateFromDWM(HWND hwnd, float* refresh_rate)
|
||||
{
|
||||
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 HRESULT(STDAPICALLTYPE * get_timing_info)(HWND hwnd, DWM_TIMING_INFO * pTimingInfo) =
|
||||
nullptr;
|
||||
static bool load_tried = false;
|
||||
if (!load_tried)
|
||||
{
|
||||
if (!load_tried) {
|
||||
load_tried = true;
|
||||
dwm_module = LoadLibrary("dwmapi.dll");
|
||||
if (dwm_module)
|
||||
{
|
||||
if (dwm_module) {
|
||||
std::atexit([]() {
|
||||
FreeLibrary(dwm_module);
|
||||
dwm_module = nullptr;
|
||||
});
|
||||
is_composition_enabled =
|
||||
reinterpret_cast<decltype(is_composition_enabled)>(GetProcAddress(dwm_module, "DwmIsCompositionEnabled"));
|
||||
get_timing_info =
|
||||
reinterpret_cast<decltype(get_timing_info)>(GetProcAddress(dwm_module, "DwmGetCompositionTimingInfo"));
|
||||
is_composition_enabled = reinterpret_cast<decltype(is_composition_enabled)>(
|
||||
GetProcAddress(dwm_module, "DwmIsCompositionEnabled"));
|
||||
get_timing_info = reinterpret_cast<decltype(get_timing_info)>(
|
||||
GetProcAddress(dwm_module, "DwmGetCompositionTimingInfo"));
|
||||
}
|
||||
}
|
||||
|
||||
BOOL composition_enabled;
|
||||
if (!is_composition_enabled || FAILED(is_composition_enabled(&composition_enabled) || !get_timing_info))
|
||||
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 (SUCCEEDED(hr)) {
|
||||
if (ti.rateRefresh.uiNumerator == 0 || ti.rateRefresh.uiDenominator == 0)
|
||||
return false;
|
||||
|
||||
*refresh_rate = static_cast<float>(ti.rateRefresh.uiNumerator) / static_cast<float>(ti.rateRefresh.uiDenominator);
|
||||
*refresh_rate = static_cast<float>(ti.rateRefresh.uiNumerator) /
|
||||
static_cast<float>(ti.rateRefresh.uiDenominator);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GetRefreshRateFromMonitor(HWND hwnd, float* refresh_rate)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (EnumDisplaySettingsW(mi.szDevice, ENUM_CURRENT_SETTINGS, &dm) &&
|
||||
dm.dmDisplayFrequency > 1) {
|
||||
*refresh_rate = static_cast<float>(dm.dmDisplayFrequency);
|
||||
return true;
|
||||
}
|
||||
|
@ -73,26 +70,25 @@ static bool GetRefreshRateFromMonitor(HWND hwnd, float* refresh_rate)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool WindowInfo::QueryRefreshRateForWindow(const WindowInfo& wi, float* refresh_rate)
|
||||
{
|
||||
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<HWND>(wi.window_handle);
|
||||
return GetRefreshRateFromDWM(hwnd, refresh_rate) || GetRefreshRateFromMonitor(hwnd, refresh_rate);
|
||||
return GetRefreshRateFromDWM(hwnd, refresh_rate) ||
|
||||
GetRefreshRateFromMonitor(hwnd, refresh_rate);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef USE_X11
|
||||
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include "common/scoped_guard.h"
|
||||
#include "gl/x11_window.h"
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
|
||||
static bool GetRefreshRateFromXRandR(const WindowInfo& wi, float* refresh_rate)
|
||||
{
|
||||
static bool GetRefreshRateFromXRandR(const WindowInfo& wi, float* refresh_rate) {
|
||||
Display* display = static_cast<Display*>(wi.display_connection);
|
||||
Window window = static_cast<Window>(reinterpret_cast<uintptr_t>(wi.window_handle));
|
||||
if (!display || !window)
|
||||
|
@ -101,8 +97,7 @@ static bool GetRefreshRateFromXRandR(const WindowInfo& wi, float* refresh_rate)
|
|||
GL::X11InhibitErrors inhibiter;
|
||||
|
||||
XRRScreenResources* res = XRRGetScreenResources(display, window);
|
||||
if (!res)
|
||||
{
|
||||
if (!res) {
|
||||
Log_ErrorPrint("XRRGetScreenResources() failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -111,30 +106,23 @@ static bool GetRefreshRateFromXRandR(const WindowInfo& wi, float* refresh_rate)
|
|||
|
||||
int num_monitors;
|
||||
XRRMonitorInfo* mi = XRRGetMonitors(display, window, True, &num_monitors);
|
||||
if (num_monitors < 0)
|
||||
{
|
||||
if (num_monitors < 0) {
|
||||
Log_ErrorPrint("XRRGetMonitors() failed");
|
||||
return false;
|
||||
}
|
||||
else if (num_monitors > 1)
|
||||
{
|
||||
} 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)
|
||||
{
|
||||
if (mi->noutput <= 0) {
|
||||
Log_ErrorPrint("Monitor has no outputs");
|
||||
return false;
|
||||
}
|
||||
else if (mi->noutput > 1)
|
||||
{
|
||||
} 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)
|
||||
{
|
||||
if (!oi) {
|
||||
Log_ErrorPrint("XRRGetOutputInfo() failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -142,8 +130,7 @@ static bool GetRefreshRateFromXRandR(const WindowInfo& wi, float* refresh_rate)
|
|||
ScopedGuard oi_guard([oi]() { XRRFreeOutputInfo(oi); });
|
||||
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(display, res, oi->crtc);
|
||||
if (!ci)
|
||||
{
|
||||
if (!ci) {
|
||||
Log_ErrorPrint("XRRGetCrtcInfo() failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -151,35 +138,32 @@ static bool GetRefreshRateFromXRandR(const WindowInfo& wi, float* refresh_rate)
|
|||
ScopedGuard ci_guard([ci]() { XRRFreeCrtcInfo(ci); });
|
||||
|
||||
XRRModeInfo* mode = nullptr;
|
||||
for (int i = 0; i < res->nmode; i++)
|
||||
{
|
||||
if (res->modes[i].id == ci->mode)
|
||||
{
|
||||
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<int>(ci->mode), res->nmode);
|
||||
if (!mode) {
|
||||
Log_ErrorPrintf("Failed to look up mode %d (of %d)", static_cast<int>(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);
|
||||
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<double>(mode->dotClock) / (static_cast<double>(mode->hTotal) * static_cast<double>(mode->vTotal));
|
||||
*refresh_rate = static_cast<double>(mode->dotClock) /
|
||||
(static_cast<double>(mode->hTotal) * static_cast<double>(mode->vTotal));
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // USE_X11
|
||||
|
||||
bool WindowInfo::QueryRefreshRateForWindow(const WindowInfo& wi, float* refresh_rate)
|
||||
{
|
||||
bool WindowInfo::QueryRefreshRateForWindow(const WindowInfo& wi, float* refresh_rate) {
|
||||
#if defined(USE_X11)
|
||||
if (wi.type == WindowInfo::Type::X11)
|
||||
return GetRefreshRateFromXRandR(wi, refresh_rate);
|
||||
|
|
16
src/citra_qt/externals/duckstation/window_info.h
vendored
16
src/citra_qt/externals/duckstation/window_info.h
vendored
|
@ -2,10 +2,8 @@
|
|||
#include "../types.h"
|
||||
|
||||
// Contains the information required to create a graphics context in a window.
|
||||
struct WindowInfo
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
struct WindowInfo {
|
||||
enum class Type {
|
||||
Surfaceless,
|
||||
Win32,
|
||||
X11,
|
||||
|
@ -15,15 +13,7 @@ struct WindowInfo
|
|||
Display,
|
||||
};
|
||||
|
||||
enum class SurfaceFormat
|
||||
{
|
||||
None,
|
||||
Auto,
|
||||
RGB8,
|
||||
RGBA8,
|
||||
RGB565,
|
||||
Count
|
||||
};
|
||||
enum class SurfaceFormat { None, Auto, RGB8, RGBA8, RGB565, Count };
|
||||
|
||||
Type type = Type::Surfaceless;
|
||||
void* display_connection = nullptr;
|
||||
|
|
9
src/citra_qt/externals/types.h
vendored
9
src/citra_qt/externals/types.h
vendored
|
@ -19,11 +19,10 @@
|
|||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <array>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace citra
|
||||
{
|
||||
namespace citra {
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
|
@ -33,7 +32,7 @@ typedef int16_t s16;
|
|||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
template<class T, std::size_t A, std::size_t B>
|
||||
template <class T, std::size_t A, std::size_t B>
|
||||
using array2d = std::array<std::array<T, B>, A>;
|
||||
}
|
||||
} // namespace citra
|
||||
#endif // TYPES_H
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue