mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-24 21:55:09 +00:00
Add platform service enhancements and logging capabilities
- Introduced IPlatformService interface with methods for retrieving platform information, current video driver, and available video/render drivers. - Implemented PlatformService to gather and log detailed system information, including CPU capabilities, environment variables, and SDL video driver support. - Updated BgfxGraphicsBackend to utilize IPlatformService for platform-specific data. - Enhanced SdlWindowService to log system information upon window creation. - Added utility functions for string formatting and feature value retrieval.
This commit is contained in:
@@ -271,6 +271,7 @@ void ServiceBasedApp::RegisterServices() {
|
||||
|
||||
auto graphicsBackend = std::make_shared<services::impl::BgfxGraphicsBackend>(
|
||||
registry_.GetService<services::IConfigService>(),
|
||||
registry_.GetService<services::IPlatformService>(),
|
||||
registry_.GetService<services::ILogger>());
|
||||
|
||||
// Graphics service (facade)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <glm/gtc/matrix_inverse.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
@@ -54,15 +55,41 @@ void SetUniformIfValid(bgfx::UniformHandle handle, const void* data, uint16_t co
|
||||
}
|
||||
}
|
||||
|
||||
bgfx::RendererType::Enum RendererFromString(const std::string& value) {
|
||||
bool TryParseRendererType(const std::string& value, bgfx::RendererType::Enum& out) {
|
||||
const std::string lower = ToLower(value);
|
||||
if (lower == "vulkan") {
|
||||
return bgfx::RendererType::Vulkan;
|
||||
}
|
||||
if (lower == "auto") {
|
||||
return bgfx::RendererType::Count;
|
||||
out = bgfx::RendererType::Count;
|
||||
return true;
|
||||
}
|
||||
return bgfx::RendererType::Vulkan;
|
||||
if (lower == "vulkan") {
|
||||
out = bgfx::RendererType::Vulkan;
|
||||
return true;
|
||||
}
|
||||
if (lower == "opengl") {
|
||||
out = bgfx::RendererType::OpenGL;
|
||||
return true;
|
||||
}
|
||||
if (lower == "opengles" || lower == "opengles2") {
|
||||
out = bgfx::RendererType::OpenGLES;
|
||||
return true;
|
||||
}
|
||||
if (lower == "direct3d11" || lower == "d3d11") {
|
||||
out = bgfx::RendererType::Direct3D11;
|
||||
return true;
|
||||
}
|
||||
if (lower == "direct3d12" || lower == "d3d12") {
|
||||
out = bgfx::RendererType::Direct3D12;
|
||||
return true;
|
||||
}
|
||||
if (lower == "metal") {
|
||||
out = bgfx::RendererType::Metal;
|
||||
return true;
|
||||
}
|
||||
if (lower == "noop") {
|
||||
out = bgfx::RendererType::Noop;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string RendererTypeName(bgfx::RendererType::Enum type) {
|
||||
@@ -100,15 +127,148 @@ std::string JoinRendererNames(const std::vector<bgfx::RendererType::Enum>& rende
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* HandleTypeName(bgfx::NativeWindowHandleType::Enum type) {
|
||||
switch (type) {
|
||||
case bgfx::NativeWindowHandleType::Default:
|
||||
return "default";
|
||||
case bgfx::NativeWindowHandleType::Wayland:
|
||||
return "wayland";
|
||||
case bgfx::NativeWindowHandleType::Count:
|
||||
return "count";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char* RendererConfigName(bgfx::RendererType::Enum type) {
|
||||
switch (type) {
|
||||
case bgfx::RendererType::Vulkan:
|
||||
return "vulkan";
|
||||
case bgfx::RendererType::OpenGL:
|
||||
return "opengl";
|
||||
case bgfx::RendererType::OpenGLES:
|
||||
return "opengles";
|
||||
case bgfx::RendererType::Direct3D11:
|
||||
return "direct3d11";
|
||||
case bgfx::RendererType::Direct3D12:
|
||||
return "direct3d12";
|
||||
case bgfx::RendererType::Metal:
|
||||
return "metal";
|
||||
case bgfx::RendererType::Noop:
|
||||
return "noop";
|
||||
case bgfx::RendererType::Count:
|
||||
default:
|
||||
return "auto";
|
||||
}
|
||||
}
|
||||
|
||||
bool IsNoopRenderer(bgfx::RendererType::Enum type) {
|
||||
return type == bgfx::RendererType::Noop;
|
||||
}
|
||||
|
||||
bool ContainsRenderer(const std::vector<bgfx::RendererType::Enum>& renderers,
|
||||
bgfx::RendererType::Enum type) {
|
||||
return std::find(renderers.begin(), renderers.end(), type) != renderers.end();
|
||||
}
|
||||
|
||||
bool IsRendererAllowedOnPlatform(bgfx::RendererType::Enum type, const std::string& platformName) {
|
||||
if (type == bgfx::RendererType::Count || type == bgfx::RendererType::Noop) {
|
||||
return true;
|
||||
}
|
||||
const std::string platformLower = ToLower(platformName);
|
||||
if (platformLower.find("windows") != std::string::npos) {
|
||||
return type == bgfx::RendererType::Direct3D11 ||
|
||||
type == bgfx::RendererType::Direct3D12 ||
|
||||
type == bgfx::RendererType::Vulkan ||
|
||||
type == bgfx::RendererType::OpenGL ||
|
||||
type == bgfx::RendererType::OpenGLES;
|
||||
}
|
||||
if (platformLower.find("mac") != std::string::npos ||
|
||||
platformLower.find("darwin") != std::string::npos) {
|
||||
return type == bgfx::RendererType::Metal ||
|
||||
type == bgfx::RendererType::OpenGL ||
|
||||
type == bgfx::RendererType::Vulkan;
|
||||
}
|
||||
return type == bgfx::RendererType::Vulkan ||
|
||||
type == bgfx::RendererType::OpenGL ||
|
||||
type == bgfx::RendererType::OpenGLES;
|
||||
}
|
||||
|
||||
void AddRendererIfSupported(std::vector<bgfx::RendererType::Enum>& ordered,
|
||||
const std::vector<bgfx::RendererType::Enum>& supported,
|
||||
bgfx::RendererType::Enum type) {
|
||||
if (IsNoopRenderer(type) || type == bgfx::RendererType::Count) {
|
||||
return;
|
||||
}
|
||||
if (!ContainsRenderer(supported, type)) {
|
||||
return;
|
||||
}
|
||||
if (!ContainsRenderer(ordered, type)) {
|
||||
ordered.push_back(type);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<bgfx::RendererType::Enum> BuildPreferredRenderers(
|
||||
const std::vector<bgfx::RendererType::Enum>& supportedRenderers,
|
||||
const std::string& platformName,
|
||||
const std::string& videoDriverName) {
|
||||
std::vector<bgfx::RendererType::Enum> preferred;
|
||||
const std::string platformLower = ToLower(platformName);
|
||||
const std::string videoLower = ToLower(videoDriverName);
|
||||
|
||||
if (platformLower.find("windows") != std::string::npos) {
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::Direct3D12);
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::Direct3D11);
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::Vulkan);
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::OpenGL);
|
||||
} else if (platformLower.find("mac") != std::string::npos ||
|
||||
platformLower.find("darwin") != std::string::npos) {
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::Metal);
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::OpenGL);
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::Vulkan);
|
||||
} else {
|
||||
const bool waylandOrX11 = (videoLower == "wayland") || (videoLower == "x11");
|
||||
const bool kmsdrm = (videoLower == "kmsdrm");
|
||||
if (waylandOrX11 || kmsdrm) {
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::Vulkan);
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::OpenGL);
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::OpenGLES);
|
||||
} else {
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::Vulkan);
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::OpenGL);
|
||||
AddRendererIfSupported(preferred, supportedRenderers, bgfx::RendererType::OpenGLES);
|
||||
}
|
||||
}
|
||||
|
||||
return preferred;
|
||||
}
|
||||
|
||||
std::optional<bgfx::RendererType::Enum> RecommendFallbackRenderer(
|
||||
bgfx::RendererType::Enum requested,
|
||||
const std::vector<bgfx::RendererType::Enum>& supportedRenderers,
|
||||
const std::string& platformName,
|
||||
const std::string& videoDriverName) {
|
||||
const auto preferred = BuildPreferredRenderers(supportedRenderers, platformName, videoDriverName);
|
||||
for (bgfx::RendererType::Enum type : preferred) {
|
||||
if (type != requested) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BgfxGraphicsBackend::BgfxGraphicsBackend(std::shared_ptr<IConfigService> configService,
|
||||
std::shared_ptr<IPlatformService> platformService,
|
||||
std::shared_ptr<ILogger> logger)
|
||||
: configService_(std::move(configService)),
|
||||
platformService_(std::move(platformService)),
|
||||
logger_(std::move(logger)) {
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "BgfxGraphicsBackend",
|
||||
"configService=" + std::string(configService_ ? "set" : "null"));
|
||||
"configService=" + std::string(configService_ ? "set" : "null") +
|
||||
", platformService=" + std::string(platformService_ ? "set" : "null"));
|
||||
}
|
||||
vertexLayout_.begin()
|
||||
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
|
||||
@@ -139,8 +299,15 @@ BgfxGraphicsBackend::~BgfxGraphicsBackend() {
|
||||
|
||||
void BgfxGraphicsBackend::SetupPlatformData(void* window) {
|
||||
bgfx::PlatformData pd{};
|
||||
platformHandleInfo_ = PlatformHandleInfo{};
|
||||
platformHandleInfo_.handleType = bgfx::NativeWindowHandleType::Default;
|
||||
SDL_Window* sdlWindow = static_cast<SDL_Window*>(window);
|
||||
if (!sdlWindow) {
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "SetupPlatformData", "windowIsNull=true");
|
||||
}
|
||||
platformHandleInfo_.hasWindowHandle = false;
|
||||
platformHandleInfo_.hasDisplayHandle = false;
|
||||
bgfx::setPlatformData(pd);
|
||||
return;
|
||||
}
|
||||
@@ -153,20 +320,45 @@ void BgfxGraphicsBackend::SetupPlatformData(void* window) {
|
||||
#elif defined(__linux__)
|
||||
void* wlDisplay = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr);
|
||||
void* wlSurface = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr);
|
||||
if (wlDisplay && wlSurface) {
|
||||
void* x11Display = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr);
|
||||
Sint64 x11Window = SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
const bool hasWayland = wlDisplay && wlSurface;
|
||||
const bool hasX11 = x11Display && x11Window != 0;
|
||||
platformHandleInfo_.hasWayland = hasWayland;
|
||||
platformHandleInfo_.hasX11 = hasX11;
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "SetupPlatformData",
|
||||
"waylandAvailable=" + std::string(hasWayland ? "true" : "false") +
|
||||
", x11Available=" + std::string(hasX11 ? "true" : "false"));
|
||||
}
|
||||
if (hasWayland) {
|
||||
pd.ndt = wlDisplay;
|
||||
pd.nwh = wlSurface;
|
||||
} else {
|
||||
void* x11Display = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr);
|
||||
Sint64 x11Window = SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
if (x11Display && x11Window != 0) {
|
||||
pd.ndt = x11Display;
|
||||
pd.nwh = reinterpret_cast<void*>(static_cast<uintptr_t>(x11Window));
|
||||
pd.type = bgfx::NativeWindowHandleType::Wayland;
|
||||
platformHandleInfo_.handleType = bgfx::NativeWindowHandleType::Wayland;
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "SetupPlatformData", "selectedHandleType=Wayland");
|
||||
}
|
||||
} else if (hasX11) {
|
||||
pd.ndt = x11Display;
|
||||
pd.nwh = reinterpret_cast<void*>(static_cast<uintptr_t>(x11Window));
|
||||
pd.type = bgfx::NativeWindowHandleType::Default;
|
||||
platformHandleInfo_.handleType = bgfx::NativeWindowHandleType::Default;
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "SetupPlatformData", "selectedHandleType=X11");
|
||||
}
|
||||
}
|
||||
#else
|
||||
pd.nwh = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr);
|
||||
#endif
|
||||
platformHandleInfo_.hasWindowHandle = pd.nwh != nullptr;
|
||||
platformHandleInfo_.hasDisplayHandle = pd.ndt != nullptr;
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "SetupPlatformData",
|
||||
"nwh=" + std::to_string(reinterpret_cast<uintptr_t>(pd.nwh)) +
|
||||
", ndt=" + std::to_string(reinterpret_cast<uintptr_t>(pd.ndt)) +
|
||||
", handleType=" + std::string(HandleTypeName(platformHandleInfo_.handleType)));
|
||||
}
|
||||
bgfx::setPlatformData(pd);
|
||||
}
|
||||
|
||||
@@ -175,7 +367,67 @@ bgfx::RendererType::Enum BgfxGraphicsBackend::ResolveRendererType() const {
|
||||
return bgfx::RendererType::Vulkan;
|
||||
}
|
||||
const auto& config = configService_->GetBgfxConfig();
|
||||
return RendererFromString(config.renderer);
|
||||
bgfx::RendererType::Enum resolved = bgfx::RendererType::Vulkan;
|
||||
const bool parsed = TryParseRendererType(config.renderer, resolved);
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "ResolveRendererType",
|
||||
"renderer=" + config.renderer +
|
||||
", resolved=" + RendererTypeName(resolved) +
|
||||
", parsed=" + std::string(parsed ? "true" : "false"));
|
||||
}
|
||||
if (!parsed && logger_) {
|
||||
logger_->Warn("BgfxGraphicsBackend::ResolveRendererType: Unknown renderer '" +
|
||||
config.renderer + "', defaulting to Vulkan");
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
void BgfxGraphicsBackend::LogRendererFailureDetails(
|
||||
bgfx::RendererType::Enum renderer,
|
||||
const std::vector<bgfx::RendererType::Enum>& supportedRenderers,
|
||||
const std::string& platformName,
|
||||
const std::string& videoDriverName) {
|
||||
if (!logger_) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: Renderer " +
|
||||
RendererTypeName(renderer) + " failed (platform=" +
|
||||
platformName + ", videoDriver=" + videoDriverName +
|
||||
", handleType=" +
|
||||
std::string(HandleTypeName(platformHandleInfo_.handleType)) +
|
||||
", windowHandle=" +
|
||||
std::string(platformHandleInfo_.hasWindowHandle ? "set" : "null") +
|
||||
", displayHandle=" +
|
||||
std::string(platformHandleInfo_.hasDisplayHandle ? "set" : "null") +
|
||||
", supportedRenderers=" + JoinRendererNames(supportedRenderers) + ")");
|
||||
|
||||
const auto fallback = RecommendFallbackRenderer(renderer, supportedRenderers,
|
||||
platformName, videoDriverName);
|
||||
if (fallback.has_value()) {
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: Recommended fallback renderer=" +
|
||||
RendererTypeName(fallback.value()) +
|
||||
" (set bgfx.renderer=" + std::string(RendererConfigName(fallback.value())) + ")");
|
||||
}
|
||||
|
||||
if (renderer == bgfx::RendererType::Vulkan) {
|
||||
if (!platformHandleInfo_.hasWindowHandle) {
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: Vulkan requires a native window handle");
|
||||
}
|
||||
if (videoDriverName == "wayland" && !platformHandleInfo_.hasWayland) {
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: SDL reports Wayland, but no Wayland "
|
||||
"window handle was provided");
|
||||
}
|
||||
if (videoDriverName == "x11" && !platformHandleInfo_.hasX11) {
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: SDL reports X11, but no X11 "
|
||||
"window handle was provided");
|
||||
}
|
||||
}
|
||||
|
||||
if (platformService_ && !loggedInitFailureDiagnostics_) {
|
||||
platformService_->LogSystemInfo();
|
||||
loggedInitFailureDiagnostics_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void BgfxGraphicsBackend::Initialize(void* window, const GraphicsConfig& config) {
|
||||
@@ -200,10 +452,32 @@ void BgfxGraphicsBackend::Initialize(void* window, const GraphicsConfig& config)
|
||||
|
||||
const auto requestedRenderer = ResolveRendererType();
|
||||
const auto supportedRenderers = GetSupportedRenderers();
|
||||
const std::string platformName = platformService_
|
||||
? platformService_->GetPlatformName()
|
||||
: "unknown";
|
||||
const std::string videoDriverName = platformService_
|
||||
? platformService_->GetCurrentVideoDriverName()
|
||||
: "unknown";
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "Initialize",
|
||||
"requestedRenderer=" + RendererTypeName(requestedRenderer) +
|
||||
", supportedRenderers=" + JoinRendererNames(supportedRenderers));
|
||||
", supportedRenderers=" + JoinRendererNames(supportedRenderers) +
|
||||
", platform=" + platformName +
|
||||
", videoDriver=" + videoDriverName);
|
||||
}
|
||||
if (requestedRenderer != bgfx::RendererType::Count &&
|
||||
!ContainsRenderer(supportedRenderers, requestedRenderer) &&
|
||||
logger_) {
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: Requested renderer=" +
|
||||
RendererTypeName(requestedRenderer) +
|
||||
" is not in the supported renderers list");
|
||||
}
|
||||
if (requestedRenderer != bgfx::RendererType::Count &&
|
||||
!IsRendererAllowedOnPlatform(requestedRenderer, platformName) &&
|
||||
logger_) {
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: Requested renderer=" +
|
||||
RendererTypeName(requestedRenderer) +
|
||||
" is not recommended for platform=" + platformName);
|
||||
}
|
||||
|
||||
bgfx::Init init{};
|
||||
@@ -218,17 +492,38 @@ void BgfxGraphicsBackend::Initialize(void* window, const GraphicsConfig& config)
|
||||
}
|
||||
};
|
||||
|
||||
if (requestedRenderer == bgfx::RendererType::Count) {
|
||||
addCandidate(bgfx::RendererType::Count);
|
||||
} else {
|
||||
const auto preferredRenderers =
|
||||
BuildPreferredRenderers(supportedRenderers, platformName, videoDriverName);
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "Initialize",
|
||||
"preferredRenderers=" + JoinRendererNames(preferredRenderers));
|
||||
}
|
||||
|
||||
if (requestedRenderer != bgfx::RendererType::Count) {
|
||||
addCandidate(requestedRenderer);
|
||||
}
|
||||
for (bgfx::RendererType::Enum renderer : supportedRenderers) {
|
||||
for (bgfx::RendererType::Enum renderer : preferredRenderers) {
|
||||
addCandidate(renderer);
|
||||
}
|
||||
for (bgfx::RendererType::Enum renderer : supportedRenderers) {
|
||||
if (!IsNoopRenderer(renderer) && renderer != bgfx::RendererType::Count &&
|
||||
IsRendererAllowedOnPlatform(renderer, platformName)) {
|
||||
addCandidate(renderer);
|
||||
}
|
||||
}
|
||||
addCandidate(bgfx::RendererType::Count);
|
||||
if (ContainsRenderer(supportedRenderers, bgfx::RendererType::Noop) ||
|
||||
requestedRenderer == bgfx::RendererType::Noop) {
|
||||
addCandidate(bgfx::RendererType::Noop);
|
||||
}
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "Initialize",
|
||||
"candidateRenderers=" + JoinRendererNames(candidates));
|
||||
}
|
||||
|
||||
bool initialized = false;
|
||||
bool requestedFailed = false;
|
||||
const bool requestedExplicit = requestedRenderer != bgfx::RendererType::Count;
|
||||
for (bgfx::RendererType::Enum renderer : candidates) {
|
||||
init.type = renderer;
|
||||
if (logger_) {
|
||||
@@ -243,15 +538,31 @@ void BgfxGraphicsBackend::Initialize(void* window, const GraphicsConfig& config)
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: bgfx init failed for renderer=" +
|
||||
RendererTypeName(renderer));
|
||||
}
|
||||
if (renderer == requestedRenderer && !requestedFailed) {
|
||||
requestedFailed = true;
|
||||
LogRendererFailureDetails(renderer, supportedRenderers, platformName, videoDriverName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!initialized) {
|
||||
if (platformService_ && !loggedInitFailureDiagnostics_) {
|
||||
platformService_->LogSystemInfo();
|
||||
loggedInitFailureDiagnostics_ = true;
|
||||
}
|
||||
throw std::runtime_error("Failed to initialize bgfx");
|
||||
}
|
||||
if (logger_) {
|
||||
logger_->Trace("BgfxGraphicsBackend", "Initialize",
|
||||
"selectedRenderer=" + RendererTypeName(bgfx::getRendererType()));
|
||||
}
|
||||
if (requestedExplicit && bgfx::getRendererType() != requestedRenderer && logger_) {
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: Requested renderer=" +
|
||||
RendererTypeName(requestedRenderer) + ", using=" +
|
||||
RendererTypeName(bgfx::getRendererType()));
|
||||
}
|
||||
if (bgfx::getRendererType() == bgfx::RendererType::Noop && logger_) {
|
||||
logger_->Warn("BgfxGraphicsBackend::Initialize: Noop renderer selected; rendering disabled");
|
||||
}
|
||||
|
||||
bgfx::setViewClear(viewId_, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x1f1f1fff, 1.0f, 0);
|
||||
bgfx::setDebug(BGFX_DEBUG_TEXT);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "../interfaces/i_config_service.hpp"
|
||||
#include "../interfaces/i_graphics_backend.hpp"
|
||||
#include "../interfaces/i_logger.hpp"
|
||||
#include "../interfaces/i_platform_service.hpp"
|
||||
#include "../../core/vertex.hpp"
|
||||
#include <bgfx/bgfx.h>
|
||||
#include <array>
|
||||
@@ -15,6 +16,7 @@ namespace sdl3cpp::services::impl {
|
||||
class BgfxGraphicsBackend : public IGraphicsBackend {
|
||||
public:
|
||||
BgfxGraphicsBackend(std::shared_ptr<IConfigService> configService,
|
||||
std::shared_ptr<IPlatformService> platformService,
|
||||
std::shared_ptr<ILogger> logger);
|
||||
~BgfxGraphicsBackend() override;
|
||||
|
||||
@@ -72,8 +74,20 @@ private:
|
||||
bgfx::UniformHandle viewPosition = BGFX_INVALID_HANDLE;
|
||||
};
|
||||
|
||||
struct PlatformHandleInfo {
|
||||
bool hasWayland = false;
|
||||
bool hasX11 = false;
|
||||
bool hasWindowHandle = false;
|
||||
bool hasDisplayHandle = false;
|
||||
bgfx::NativeWindowHandleType::Enum handleType = bgfx::NativeWindowHandleType::Default;
|
||||
};
|
||||
|
||||
void SetupPlatformData(void* window);
|
||||
bgfx::RendererType::Enum ResolveRendererType() const;
|
||||
void LogRendererFailureDetails(bgfx::RendererType::Enum renderer,
|
||||
const std::vector<bgfx::RendererType::Enum>& supportedRenderers,
|
||||
const std::string& platformName,
|
||||
const std::string& videoDriverName);
|
||||
std::vector<uint8_t> ReadShaderSource(const std::string& path,
|
||||
const std::string& source) const;
|
||||
bgfx::ShaderHandle CreateShader(const std::string& label,
|
||||
@@ -86,6 +100,7 @@ private:
|
||||
void DestroyBuffers();
|
||||
|
||||
std::shared_ptr<IConfigService> configService_;
|
||||
std::shared_ptr<IPlatformService> platformService_;
|
||||
std::shared_ptr<ILogger> logger_;
|
||||
bgfx::VertexLayout vertexLayout_;
|
||||
std::unordered_map<GraphicsPipelineHandle, std::unique_ptr<PipelineEntry>> pipelines_;
|
||||
@@ -97,6 +112,8 @@ private:
|
||||
uint32_t viewportHeight_ = 0;
|
||||
bool initialized_ = false;
|
||||
bgfx::ViewId viewId_ = 0;
|
||||
PlatformHandleInfo platformHandleInfo_{};
|
||||
bool loggedInitFailureDiagnostics_ = false;
|
||||
};
|
||||
|
||||
} // namespace sdl3cpp::services::impl
|
||||
|
||||
@@ -1,13 +1,451 @@
|
||||
#include "platform_service.hpp"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
namespace sdl3cpp::services::impl {
|
||||
namespace {
|
||||
|
||||
std::string EnvValueOrUnset(const char* name) {
|
||||
const char* value = std::getenv(name);
|
||||
if (!value || *value == '\0') {
|
||||
return "unset";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string HintValueOrUnset(const char* name) {
|
||||
const char* value = SDL_GetHint(name);
|
||||
if (!value || *value == '\0') {
|
||||
return "unset";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string SystemThemeName(SDL_SystemTheme theme) {
|
||||
switch (theme) {
|
||||
case SDL_SYSTEM_THEME_LIGHT:
|
||||
return "light";
|
||||
case SDL_SYSTEM_THEME_DARK:
|
||||
return "dark";
|
||||
case SDL_SYSTEM_THEME_UNKNOWN:
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string JoinStrings(const std::vector<std::string>& values) {
|
||||
if (values.empty()) {
|
||||
return "none";
|
||||
}
|
||||
std::string result;
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
if (i > 0) {
|
||||
result += ", ";
|
||||
}
|
||||
result += values[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ContainsDriver(const std::vector<std::string>& drivers, const char* name) {
|
||||
if (!name || *name == '\0') {
|
||||
return false;
|
||||
}
|
||||
for (const auto& driver : drivers) {
|
||||
if (driver == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string FormatBounds(const SDL_Rect& bounds) {
|
||||
return std::to_string(bounds.w) + "x" + std::to_string(bounds.h) +
|
||||
"+" + std::to_string(bounds.x) + "+" + std::to_string(bounds.y);
|
||||
}
|
||||
|
||||
enum class FeatureKey {
|
||||
PointerBits,
|
||||
PlatformName,
|
||||
SdlVersion,
|
||||
SdlVersionMajor,
|
||||
SdlVersionMinor,
|
||||
SdlVersionMicro,
|
||||
SdlRevision,
|
||||
CpuCount,
|
||||
CpuCacheLineSize,
|
||||
SystemRamMb,
|
||||
CpuHasSse,
|
||||
CpuHasSse2,
|
||||
CpuHasSse3,
|
||||
CpuHasSse41,
|
||||
CpuHasSse42,
|
||||
CpuHasAvx,
|
||||
CpuHasAvx2,
|
||||
CpuHasAvx512f,
|
||||
CpuHasNeon,
|
||||
CpuHasArmSimd,
|
||||
CpuHasAltivec,
|
||||
CpuHasLsx,
|
||||
CpuHasLasx,
|
||||
EnvXdgSessionType,
|
||||
EnvWaylandDisplay,
|
||||
EnvX11Display,
|
||||
EnvDesktopSession,
|
||||
EnvXdgCurrentDesktop,
|
||||
EnvXdgRuntimeDir,
|
||||
EnvSdlVideoDriver,
|
||||
EnvSdlRenderDriver,
|
||||
HintVideoDriver,
|
||||
HintRenderDriver,
|
||||
HintWaylandPreferLibdecor,
|
||||
SdlVideoDriverCount,
|
||||
SdlVideoDrivers,
|
||||
SdlVideoInitialized,
|
||||
SdlVideoBackendSupportsWayland,
|
||||
SdlVideoBackendSupportsX11,
|
||||
SdlVideoBackendSupportsKmsdrm,
|
||||
SdlVideoBackendSupportsWindows,
|
||||
SdlVideoBackendSupportsCocoa,
|
||||
SdlVideoBackendIsWayland,
|
||||
SdlVideoBackendIsX11,
|
||||
SdlVideoBackendIsKmsdrm,
|
||||
SdlVideoBackendIsWindows,
|
||||
SdlVideoBackendIsCocoa,
|
||||
SdlCurrentVideoDriver,
|
||||
SdlSystemTheme,
|
||||
SdlRenderDriverCount,
|
||||
SdlRenderDrivers,
|
||||
SdlRenderSupportsOpenGL,
|
||||
SdlRenderSupportsOpenGLES2,
|
||||
SdlRenderSupportsDirect3D11,
|
||||
SdlRenderSupportsDirect3D12,
|
||||
SdlRenderSupportsMetal,
|
||||
SdlRenderSupportsSoftware,
|
||||
SdlDisplayCount,
|
||||
SdlPrimaryDisplayId,
|
||||
SdlDisplaySummary,
|
||||
SdlDisplayError,
|
||||
UnameSysname,
|
||||
UnameRelease,
|
||||
UnameVersion,
|
||||
UnameMachine
|
||||
};
|
||||
|
||||
struct FeatureDefinition {
|
||||
FeatureKey key;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
struct FeatureValues {
|
||||
int pointerBits = 0;
|
||||
std::string platformName;
|
||||
int sdlVersion = 0;
|
||||
int sdlVersionMajor = 0;
|
||||
int sdlVersionMinor = 0;
|
||||
int sdlVersionMicro = 0;
|
||||
std::string sdlRevision;
|
||||
int cpuCount = 0;
|
||||
int cpuCacheLineSize = 0;
|
||||
int systemRamMb = 0;
|
||||
bool cpuHasSse = false;
|
||||
bool cpuHasSse2 = false;
|
||||
bool cpuHasSse3 = false;
|
||||
bool cpuHasSse41 = false;
|
||||
bool cpuHasSse42 = false;
|
||||
bool cpuHasAvx = false;
|
||||
bool cpuHasAvx2 = false;
|
||||
bool cpuHasAvx512f = false;
|
||||
bool cpuHasNeon = false;
|
||||
bool cpuHasArmSimd = false;
|
||||
bool cpuHasAltivec = false;
|
||||
bool cpuHasLsx = false;
|
||||
bool cpuHasLasx = false;
|
||||
std::string envXdgSessionType;
|
||||
std::string envWaylandDisplay;
|
||||
std::string envX11Display;
|
||||
std::string envDesktopSession;
|
||||
std::string envXdgCurrentDesktop;
|
||||
std::string envXdgRuntimeDir;
|
||||
std::string envSdlVideoDriver;
|
||||
std::string envSdlRenderDriver;
|
||||
std::string hintVideoDriver;
|
||||
std::string hintRenderDriver;
|
||||
std::string hintWaylandPreferLibdecor;
|
||||
int sdlVideoDriverCount = 0;
|
||||
std::string sdlVideoDrivers;
|
||||
bool sdlVideoInitialized = false;
|
||||
bool sdlVideoBackendSupportsWayland = false;
|
||||
bool sdlVideoBackendSupportsX11 = false;
|
||||
bool sdlVideoBackendSupportsKmsdrm = false;
|
||||
bool sdlVideoBackendSupportsWindows = false;
|
||||
bool sdlVideoBackendSupportsCocoa = false;
|
||||
bool sdlVideoBackendIsWayland = false;
|
||||
bool sdlVideoBackendIsX11 = false;
|
||||
bool sdlVideoBackendIsKmsdrm = false;
|
||||
bool sdlVideoBackendIsWindows = false;
|
||||
bool sdlVideoBackendIsCocoa = false;
|
||||
std::string sdlCurrentVideoDriver;
|
||||
std::string sdlSystemTheme;
|
||||
int sdlRenderDriverCount = 0;
|
||||
std::string sdlRenderDrivers;
|
||||
bool sdlRenderSupportsOpenGL = false;
|
||||
bool sdlRenderSupportsOpenGLES2 = false;
|
||||
bool sdlRenderSupportsDirect3D11 = false;
|
||||
bool sdlRenderSupportsDirect3D12 = false;
|
||||
bool sdlRenderSupportsMetal = false;
|
||||
bool sdlRenderSupportsSoftware = false;
|
||||
int sdlDisplayCount = 0;
|
||||
int sdlPrimaryDisplayId = 0;
|
||||
std::string sdlDisplaySummary = "none";
|
||||
std::string sdlDisplayError = "none";
|
||||
std::string unameSysname;
|
||||
std::string unameRelease;
|
||||
std::string unameVersion;
|
||||
std::string unameMachine;
|
||||
};
|
||||
|
||||
std::string BoolToString(bool value) {
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
|
||||
std::string StringOrUnset(const std::string& value) {
|
||||
if (value.empty()) {
|
||||
return "unset";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string FeatureValue(FeatureKey key, const FeatureValues& values) {
|
||||
switch (key) {
|
||||
case FeatureKey::PointerBits:
|
||||
return std::to_string(values.pointerBits);
|
||||
case FeatureKey::PlatformName:
|
||||
return StringOrUnset(values.platformName);
|
||||
case FeatureKey::SdlVersion:
|
||||
return std::to_string(values.sdlVersion);
|
||||
case FeatureKey::SdlVersionMajor:
|
||||
return std::to_string(values.sdlVersionMajor);
|
||||
case FeatureKey::SdlVersionMinor:
|
||||
return std::to_string(values.sdlVersionMinor);
|
||||
case FeatureKey::SdlVersionMicro:
|
||||
return std::to_string(values.sdlVersionMicro);
|
||||
case FeatureKey::SdlRevision:
|
||||
return StringOrUnset(values.sdlRevision);
|
||||
case FeatureKey::CpuCount:
|
||||
return std::to_string(values.cpuCount);
|
||||
case FeatureKey::CpuCacheLineSize:
|
||||
return std::to_string(values.cpuCacheLineSize);
|
||||
case FeatureKey::SystemRamMb:
|
||||
return std::to_string(values.systemRamMb);
|
||||
case FeatureKey::CpuHasSse:
|
||||
return BoolToString(values.cpuHasSse);
|
||||
case FeatureKey::CpuHasSse2:
|
||||
return BoolToString(values.cpuHasSse2);
|
||||
case FeatureKey::CpuHasSse3:
|
||||
return BoolToString(values.cpuHasSse3);
|
||||
case FeatureKey::CpuHasSse41:
|
||||
return BoolToString(values.cpuHasSse41);
|
||||
case FeatureKey::CpuHasSse42:
|
||||
return BoolToString(values.cpuHasSse42);
|
||||
case FeatureKey::CpuHasAvx:
|
||||
return BoolToString(values.cpuHasAvx);
|
||||
case FeatureKey::CpuHasAvx2:
|
||||
return BoolToString(values.cpuHasAvx2);
|
||||
case FeatureKey::CpuHasAvx512f:
|
||||
return BoolToString(values.cpuHasAvx512f);
|
||||
case FeatureKey::CpuHasNeon:
|
||||
return BoolToString(values.cpuHasNeon);
|
||||
case FeatureKey::CpuHasArmSimd:
|
||||
return BoolToString(values.cpuHasArmSimd);
|
||||
case FeatureKey::CpuHasAltivec:
|
||||
return BoolToString(values.cpuHasAltivec);
|
||||
case FeatureKey::CpuHasLsx:
|
||||
return BoolToString(values.cpuHasLsx);
|
||||
case FeatureKey::CpuHasLasx:
|
||||
return BoolToString(values.cpuHasLasx);
|
||||
case FeatureKey::EnvXdgSessionType:
|
||||
return StringOrUnset(values.envXdgSessionType);
|
||||
case FeatureKey::EnvWaylandDisplay:
|
||||
return StringOrUnset(values.envWaylandDisplay);
|
||||
case FeatureKey::EnvX11Display:
|
||||
return StringOrUnset(values.envX11Display);
|
||||
case FeatureKey::EnvDesktopSession:
|
||||
return StringOrUnset(values.envDesktopSession);
|
||||
case FeatureKey::EnvXdgCurrentDesktop:
|
||||
return StringOrUnset(values.envXdgCurrentDesktop);
|
||||
case FeatureKey::EnvXdgRuntimeDir:
|
||||
return StringOrUnset(values.envXdgRuntimeDir);
|
||||
case FeatureKey::EnvSdlVideoDriver:
|
||||
return StringOrUnset(values.envSdlVideoDriver);
|
||||
case FeatureKey::EnvSdlRenderDriver:
|
||||
return StringOrUnset(values.envSdlRenderDriver);
|
||||
case FeatureKey::HintVideoDriver:
|
||||
return StringOrUnset(values.hintVideoDriver);
|
||||
case FeatureKey::HintRenderDriver:
|
||||
return StringOrUnset(values.hintRenderDriver);
|
||||
case FeatureKey::HintWaylandPreferLibdecor:
|
||||
return StringOrUnset(values.hintWaylandPreferLibdecor);
|
||||
case FeatureKey::SdlVideoDriverCount:
|
||||
return std::to_string(values.sdlVideoDriverCount);
|
||||
case FeatureKey::SdlVideoDrivers:
|
||||
return StringOrUnset(values.sdlVideoDrivers);
|
||||
case FeatureKey::SdlVideoInitialized:
|
||||
return BoolToString(values.sdlVideoInitialized);
|
||||
case FeatureKey::SdlVideoBackendSupportsWayland:
|
||||
return BoolToString(values.sdlVideoBackendSupportsWayland);
|
||||
case FeatureKey::SdlVideoBackendSupportsX11:
|
||||
return BoolToString(values.sdlVideoBackendSupportsX11);
|
||||
case FeatureKey::SdlVideoBackendSupportsKmsdrm:
|
||||
return BoolToString(values.sdlVideoBackendSupportsKmsdrm);
|
||||
case FeatureKey::SdlVideoBackendSupportsWindows:
|
||||
return BoolToString(values.sdlVideoBackendSupportsWindows);
|
||||
case FeatureKey::SdlVideoBackendSupportsCocoa:
|
||||
return BoolToString(values.sdlVideoBackendSupportsCocoa);
|
||||
case FeatureKey::SdlVideoBackendIsWayland:
|
||||
return BoolToString(values.sdlVideoBackendIsWayland);
|
||||
case FeatureKey::SdlVideoBackendIsX11:
|
||||
return BoolToString(values.sdlVideoBackendIsX11);
|
||||
case FeatureKey::SdlVideoBackendIsKmsdrm:
|
||||
return BoolToString(values.sdlVideoBackendIsKmsdrm);
|
||||
case FeatureKey::SdlVideoBackendIsWindows:
|
||||
return BoolToString(values.sdlVideoBackendIsWindows);
|
||||
case FeatureKey::SdlVideoBackendIsCocoa:
|
||||
return BoolToString(values.sdlVideoBackendIsCocoa);
|
||||
case FeatureKey::SdlCurrentVideoDriver:
|
||||
return StringOrUnset(values.sdlCurrentVideoDriver);
|
||||
case FeatureKey::SdlSystemTheme:
|
||||
return StringOrUnset(values.sdlSystemTheme);
|
||||
case FeatureKey::SdlRenderDriverCount:
|
||||
return std::to_string(values.sdlRenderDriverCount);
|
||||
case FeatureKey::SdlRenderDrivers:
|
||||
return StringOrUnset(values.sdlRenderDrivers);
|
||||
case FeatureKey::SdlRenderSupportsOpenGL:
|
||||
return BoolToString(values.sdlRenderSupportsOpenGL);
|
||||
case FeatureKey::SdlRenderSupportsOpenGLES2:
|
||||
return BoolToString(values.sdlRenderSupportsOpenGLES2);
|
||||
case FeatureKey::SdlRenderSupportsDirect3D11:
|
||||
return BoolToString(values.sdlRenderSupportsDirect3D11);
|
||||
case FeatureKey::SdlRenderSupportsDirect3D12:
|
||||
return BoolToString(values.sdlRenderSupportsDirect3D12);
|
||||
case FeatureKey::SdlRenderSupportsMetal:
|
||||
return BoolToString(values.sdlRenderSupportsMetal);
|
||||
case FeatureKey::SdlRenderSupportsSoftware:
|
||||
return BoolToString(values.sdlRenderSupportsSoftware);
|
||||
case FeatureKey::SdlDisplayCount:
|
||||
return std::to_string(values.sdlDisplayCount);
|
||||
case FeatureKey::SdlPrimaryDisplayId:
|
||||
return std::to_string(values.sdlPrimaryDisplayId);
|
||||
case FeatureKey::SdlDisplaySummary:
|
||||
return StringOrUnset(values.sdlDisplaySummary);
|
||||
case FeatureKey::SdlDisplayError:
|
||||
return StringOrUnset(values.sdlDisplayError);
|
||||
case FeatureKey::UnameSysname:
|
||||
return StringOrUnset(values.unameSysname);
|
||||
case FeatureKey::UnameRelease:
|
||||
return StringOrUnset(values.unameRelease);
|
||||
case FeatureKey::UnameVersion:
|
||||
return StringOrUnset(values.unameVersion);
|
||||
case FeatureKey::UnameMachine:
|
||||
return StringOrUnset(values.unameMachine);
|
||||
default:
|
||||
return "unset";
|
||||
}
|
||||
}
|
||||
|
||||
std::string BuildFeatureTable(const FeatureValues& values) {
|
||||
static constexpr FeatureDefinition kFeatures[] = {
|
||||
{FeatureKey::PointerBits, "platform.pointerBits"},
|
||||
{FeatureKey::PlatformName, "platform.name"},
|
||||
{FeatureKey::SdlVersion, "platform.sdl.version"},
|
||||
{FeatureKey::SdlVersionMajor, "platform.sdl.version.major"},
|
||||
{FeatureKey::SdlVersionMinor, "platform.sdl.version.minor"},
|
||||
{FeatureKey::SdlVersionMicro, "platform.sdl.version.micro"},
|
||||
{FeatureKey::SdlRevision, "platform.sdl.revision"},
|
||||
{FeatureKey::CpuCount, "platform.cpu.count"},
|
||||
{FeatureKey::CpuCacheLineSize, "platform.cpu.cacheLineSize"},
|
||||
{FeatureKey::SystemRamMb, "platform.systemRamMB"},
|
||||
{FeatureKey::CpuHasSse, "platform.cpu.hasSSE"},
|
||||
{FeatureKey::CpuHasSse2, "platform.cpu.hasSSE2"},
|
||||
{FeatureKey::CpuHasSse3, "platform.cpu.hasSSE3"},
|
||||
{FeatureKey::CpuHasSse41, "platform.cpu.hasSSE41"},
|
||||
{FeatureKey::CpuHasSse42, "platform.cpu.hasSSE42"},
|
||||
{FeatureKey::CpuHasAvx, "platform.cpu.hasAVX"},
|
||||
{FeatureKey::CpuHasAvx2, "platform.cpu.hasAVX2"},
|
||||
{FeatureKey::CpuHasAvx512f, "platform.cpu.hasAVX512F"},
|
||||
{FeatureKey::CpuHasNeon, "platform.cpu.hasNEON"},
|
||||
{FeatureKey::CpuHasArmSimd, "platform.cpu.hasARMSIMD"},
|
||||
{FeatureKey::CpuHasAltivec, "platform.cpu.hasAltiVec"},
|
||||
{FeatureKey::CpuHasLsx, "platform.cpu.hasLSX"},
|
||||
{FeatureKey::CpuHasLasx, "platform.cpu.hasLASX"},
|
||||
{FeatureKey::EnvXdgSessionType, "env.xdgSessionType"},
|
||||
{FeatureKey::EnvWaylandDisplay, "env.waylandDisplay"},
|
||||
{FeatureKey::EnvX11Display, "env.x11Display"},
|
||||
{FeatureKey::EnvDesktopSession, "env.desktopSession"},
|
||||
{FeatureKey::EnvXdgCurrentDesktop, "env.xdgCurrentDesktop"},
|
||||
{FeatureKey::EnvXdgRuntimeDir, "env.xdgRuntimeDir"},
|
||||
{FeatureKey::EnvSdlVideoDriver, "env.sdlVideoDriver"},
|
||||
{FeatureKey::EnvSdlRenderDriver, "env.sdlRenderDriver"},
|
||||
{FeatureKey::HintVideoDriver, "sdl.hint.videoDriver"},
|
||||
{FeatureKey::HintRenderDriver, "sdl.hint.renderDriver"},
|
||||
{FeatureKey::HintWaylandPreferLibdecor, "sdl.hint.waylandPreferLibdecor"},
|
||||
{FeatureKey::SdlVideoDriverCount, "sdl.videoDriverCount"},
|
||||
{FeatureKey::SdlVideoDrivers, "sdl.videoDrivers"},
|
||||
{FeatureKey::SdlVideoInitialized, "sdl.videoInitialized"},
|
||||
{FeatureKey::SdlVideoBackendSupportsWayland, "sdl.videoBackend.supportsWayland"},
|
||||
{FeatureKey::SdlVideoBackendSupportsX11, "sdl.videoBackend.supportsX11"},
|
||||
{FeatureKey::SdlVideoBackendSupportsKmsdrm, "sdl.videoBackend.supportsKmsdrm"},
|
||||
{FeatureKey::SdlVideoBackendSupportsWindows, "sdl.videoBackend.supportsWindows"},
|
||||
{FeatureKey::SdlVideoBackendSupportsCocoa, "sdl.videoBackend.supportsCocoa"},
|
||||
{FeatureKey::SdlVideoBackendIsWayland, "sdl.videoBackend.isWayland"},
|
||||
{FeatureKey::SdlVideoBackendIsX11, "sdl.videoBackend.isX11"},
|
||||
{FeatureKey::SdlVideoBackendIsKmsdrm, "sdl.videoBackend.isKmsdrm"},
|
||||
{FeatureKey::SdlVideoBackendIsWindows, "sdl.videoBackend.isWindows"},
|
||||
{FeatureKey::SdlVideoBackendIsCocoa, "sdl.videoBackend.isCocoa"},
|
||||
{FeatureKey::SdlCurrentVideoDriver, "sdl.currentVideoDriver"},
|
||||
{FeatureKey::SdlSystemTheme, "sdl.systemTheme"},
|
||||
{FeatureKey::SdlRenderDriverCount, "sdl.renderDriverCount"},
|
||||
{FeatureKey::SdlRenderDrivers, "sdl.renderDrivers"},
|
||||
{FeatureKey::SdlRenderSupportsOpenGL, "sdl.render.supportsOpenGL"},
|
||||
{FeatureKey::SdlRenderSupportsOpenGLES2, "sdl.render.supportsOpenGLES2"},
|
||||
{FeatureKey::SdlRenderSupportsDirect3D11, "sdl.render.supportsDirect3D11"},
|
||||
{FeatureKey::SdlRenderSupportsDirect3D12, "sdl.render.supportsDirect3D12"},
|
||||
{FeatureKey::SdlRenderSupportsMetal, "sdl.render.supportsMetal"},
|
||||
{FeatureKey::SdlRenderSupportsSoftware, "sdl.render.supportsSoftware"},
|
||||
{FeatureKey::SdlDisplayCount, "sdl.displayCount"},
|
||||
{FeatureKey::SdlPrimaryDisplayId, "sdl.primaryDisplayId"},
|
||||
{FeatureKey::SdlDisplaySummary, "sdl.displaySummary"},
|
||||
{FeatureKey::SdlDisplayError, "sdl.displayError"},
|
||||
{FeatureKey::UnameSysname, "platform.uname.sysname"},
|
||||
{FeatureKey::UnameRelease, "platform.uname.release"},
|
||||
{FeatureKey::UnameVersion, "platform.uname.version"},
|
||||
{FeatureKey::UnameMachine, "platform.uname.machine"}
|
||||
};
|
||||
|
||||
std::string table = "feature\tvalue\n";
|
||||
for (const auto& feature : kFeatures) {
|
||||
table += feature.name;
|
||||
table += "\t";
|
||||
table += FeatureValue(feature.key, values);
|
||||
table += "\n";
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PlatformService::PlatformService(std::shared_ptr<ILogger> logger)
|
||||
: logger_(std::move(logger)) {
|
||||
@@ -84,4 +522,301 @@ std::string PlatformService::GetPlatformError() const {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string PlatformService::GetPlatformName() const {
|
||||
if (logger_) {
|
||||
logger_->Trace("PlatformService", "GetPlatformName");
|
||||
}
|
||||
const char* platformName = SDL_GetPlatform();
|
||||
if (platformName && *platformName != '\0') {
|
||||
return platformName;
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
std::string PlatformService::GetCurrentVideoDriverName() const {
|
||||
if (logger_) {
|
||||
logger_->Trace("PlatformService", "GetCurrentVideoDriverName");
|
||||
}
|
||||
const char* driver = SDL_GetCurrentVideoDriver();
|
||||
if (driver && *driver != '\0') {
|
||||
return driver;
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
std::vector<std::string> PlatformService::GetAvailableVideoDrivers() const {
|
||||
if (logger_) {
|
||||
logger_->Trace("PlatformService", "GetAvailableVideoDrivers");
|
||||
}
|
||||
const int count = SDL_GetNumVideoDrivers();
|
||||
std::vector<std::string> drivers;
|
||||
if (count <= 0) {
|
||||
return drivers;
|
||||
}
|
||||
drivers.reserve(static_cast<size_t>(count));
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const char* driver = SDL_GetVideoDriver(i);
|
||||
if (driver && *driver != '\0') {
|
||||
drivers.emplace_back(driver);
|
||||
}
|
||||
}
|
||||
return drivers;
|
||||
}
|
||||
|
||||
std::vector<std::string> PlatformService::GetAvailableRenderDrivers() const {
|
||||
if (logger_) {
|
||||
logger_->Trace("PlatformService", "GetAvailableRenderDrivers");
|
||||
}
|
||||
const int count = SDL_GetNumRenderDrivers();
|
||||
std::vector<std::string> drivers;
|
||||
if (count <= 0) {
|
||||
return drivers;
|
||||
}
|
||||
drivers.reserve(static_cast<size_t>(count));
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const char* driver = SDL_GetRenderDriver(i);
|
||||
if (driver && *driver != '\0') {
|
||||
drivers.emplace_back(driver);
|
||||
}
|
||||
}
|
||||
return drivers;
|
||||
}
|
||||
|
||||
void PlatformService::LogSystemInfo() const {
|
||||
if (!logger_) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger_->Trace("PlatformService", "LogSystemInfo");
|
||||
FeatureValues values;
|
||||
const int pointerBits = static_cast<int>(sizeof(void*) * 8);
|
||||
logger_->TraceVariable("platform.pointerBits", pointerBits);
|
||||
values.pointerBits = pointerBits;
|
||||
|
||||
const std::string platformName = GetPlatformName();
|
||||
values.platformName = platformName;
|
||||
logger_->TraceVariable("platform.name", values.platformName);
|
||||
|
||||
const int sdlVersion = SDL_GetVersion();
|
||||
logger_->TraceVariable("platform.sdl.version", sdlVersion);
|
||||
values.sdlVersion = sdlVersion;
|
||||
values.sdlVersionMajor = SDL_VERSIONNUM_MAJOR(sdlVersion);
|
||||
values.sdlVersionMinor = SDL_VERSIONNUM_MINOR(sdlVersion);
|
||||
values.sdlVersionMicro = SDL_VERSIONNUM_MICRO(sdlVersion);
|
||||
|
||||
const char* revision = SDL_GetRevision();
|
||||
if (revision && *revision != '\0') {
|
||||
logger_->TraceVariable("platform.sdl.revision", std::string(revision));
|
||||
values.sdlRevision = revision;
|
||||
}
|
||||
|
||||
const int cpuCount = SDL_GetCPUCount();
|
||||
const int cpuCacheLineSize = SDL_GetCPUCacheLineSize();
|
||||
const int systemRamMb = SDL_GetSystemRAM();
|
||||
logger_->TraceVariable("platform.cpu.count", cpuCount);
|
||||
logger_->TraceVariable("platform.cpu.cacheLineSize", cpuCacheLineSize);
|
||||
logger_->TraceVariable("platform.systemRamMB", systemRamMb);
|
||||
values.cpuCount = cpuCount;
|
||||
values.cpuCacheLineSize = cpuCacheLineSize;
|
||||
values.systemRamMb = systemRamMb;
|
||||
|
||||
const bool hasSse = SDL_HasSSE();
|
||||
const bool hasSse2 = SDL_HasSSE2();
|
||||
const bool hasSse3 = SDL_HasSSE3();
|
||||
const bool hasSse41 = SDL_HasSSE41();
|
||||
const bool hasSse42 = SDL_HasSSE42();
|
||||
const bool hasAvx = SDL_HasAVX();
|
||||
const bool hasAvx2 = SDL_HasAVX2();
|
||||
const bool hasAvx512f = SDL_HasAVX512F();
|
||||
const bool hasNeon = SDL_HasNEON();
|
||||
const bool hasArmSimd = SDL_HasARMSIMD();
|
||||
const bool hasAltivec = SDL_HasAltiVec();
|
||||
const bool hasLsx = SDL_HasLSX();
|
||||
const bool hasLasx = SDL_HasLASX();
|
||||
logger_->TraceVariable("platform.cpu.hasSSE", hasSse);
|
||||
logger_->TraceVariable("platform.cpu.hasSSE2", hasSse2);
|
||||
logger_->TraceVariable("platform.cpu.hasSSE3", hasSse3);
|
||||
logger_->TraceVariable("platform.cpu.hasSSE41", hasSse41);
|
||||
logger_->TraceVariable("platform.cpu.hasSSE42", hasSse42);
|
||||
logger_->TraceVariable("platform.cpu.hasAVX", hasAvx);
|
||||
logger_->TraceVariable("platform.cpu.hasAVX2", hasAvx2);
|
||||
logger_->TraceVariable("platform.cpu.hasAVX512F", hasAvx512f);
|
||||
logger_->TraceVariable("platform.cpu.hasNEON", hasNeon);
|
||||
logger_->TraceVariable("platform.cpu.hasARMSIMD", hasArmSimd);
|
||||
logger_->TraceVariable("platform.cpu.hasAltiVec", hasAltivec);
|
||||
logger_->TraceVariable("platform.cpu.hasLSX", hasLsx);
|
||||
logger_->TraceVariable("platform.cpu.hasLASX", hasLasx);
|
||||
values.cpuHasSse = hasSse;
|
||||
values.cpuHasSse2 = hasSse2;
|
||||
values.cpuHasSse3 = hasSse3;
|
||||
values.cpuHasSse41 = hasSse41;
|
||||
values.cpuHasSse42 = hasSse42;
|
||||
values.cpuHasAvx = hasAvx;
|
||||
values.cpuHasAvx2 = hasAvx2;
|
||||
values.cpuHasAvx512f = hasAvx512f;
|
||||
values.cpuHasNeon = hasNeon;
|
||||
values.cpuHasArmSimd = hasArmSimd;
|
||||
values.cpuHasAltivec = hasAltivec;
|
||||
values.cpuHasLsx = hasLsx;
|
||||
values.cpuHasLasx = hasLasx;
|
||||
|
||||
const std::string envSessionType = EnvValueOrUnset("XDG_SESSION_TYPE");
|
||||
const std::string envWaylandDisplay = EnvValueOrUnset("WAYLAND_DISPLAY");
|
||||
const std::string envX11Display = EnvValueOrUnset("DISPLAY");
|
||||
const std::string envDesktopSession = EnvValueOrUnset("DESKTOP_SESSION");
|
||||
const std::string envCurrentDesktop = EnvValueOrUnset("XDG_CURRENT_DESKTOP");
|
||||
const std::string envRuntimeDir = EnvValueOrUnset("XDG_RUNTIME_DIR");
|
||||
const std::string envSdlVideoDriver = EnvValueOrUnset("SDL_VIDEODRIVER");
|
||||
const std::string envSdlRenderDriver = EnvValueOrUnset("SDL_RENDER_DRIVER");
|
||||
logger_->TraceVariable("env.xdgSessionType", envSessionType);
|
||||
logger_->TraceVariable("env.waylandDisplay", envWaylandDisplay);
|
||||
logger_->TraceVariable("env.x11Display", envX11Display);
|
||||
logger_->TraceVariable("env.desktopSession", envDesktopSession);
|
||||
logger_->TraceVariable("env.xdgCurrentDesktop", envCurrentDesktop);
|
||||
logger_->TraceVariable("env.xdgRuntimeDir", envRuntimeDir);
|
||||
logger_->TraceVariable("env.sdlVideoDriver", envSdlVideoDriver);
|
||||
logger_->TraceVariable("env.sdlRenderDriver", envSdlRenderDriver);
|
||||
values.envXdgSessionType = envSessionType;
|
||||
values.envWaylandDisplay = envWaylandDisplay;
|
||||
values.envX11Display = envX11Display;
|
||||
values.envDesktopSession = envDesktopSession;
|
||||
values.envXdgCurrentDesktop = envCurrentDesktop;
|
||||
values.envXdgRuntimeDir = envRuntimeDir;
|
||||
values.envSdlVideoDriver = envSdlVideoDriver;
|
||||
values.envSdlRenderDriver = envSdlRenderDriver;
|
||||
|
||||
const std::string hintVideoDriver = HintValueOrUnset(SDL_HINT_VIDEO_DRIVER);
|
||||
const std::string hintRenderDriver = HintValueOrUnset(SDL_HINT_RENDER_DRIVER);
|
||||
const std::string hintWaylandLibdecor = HintValueOrUnset(SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR);
|
||||
logger_->TraceVariable("sdl.hint.videoDriver", hintVideoDriver);
|
||||
logger_->TraceVariable("sdl.hint.renderDriver", hintRenderDriver);
|
||||
logger_->TraceVariable("sdl.hint.waylandPreferLibdecor", hintWaylandLibdecor);
|
||||
values.hintVideoDriver = hintVideoDriver;
|
||||
values.hintRenderDriver = hintRenderDriver;
|
||||
values.hintWaylandPreferLibdecor = hintWaylandLibdecor;
|
||||
|
||||
std::vector<std::string> videoDrivers = GetAvailableVideoDrivers();
|
||||
values.sdlVideoDriverCount = static_cast<int>(videoDrivers.size());
|
||||
logger_->TraceVariable("sdl.videoDriverCount", values.sdlVideoDriverCount);
|
||||
if (!videoDrivers.empty()) {
|
||||
const std::string joinedDrivers = JoinStrings(videoDrivers);
|
||||
logger_->TraceVariable("sdl.videoDrivers", joinedDrivers);
|
||||
values.sdlVideoDrivers = joinedDrivers;
|
||||
}
|
||||
values.sdlVideoBackendSupportsWayland = ContainsDriver(videoDrivers, "wayland");
|
||||
values.sdlVideoBackendSupportsX11 = ContainsDriver(videoDrivers, "x11");
|
||||
values.sdlVideoBackendSupportsKmsdrm = ContainsDriver(videoDrivers, "kmsdrm");
|
||||
values.sdlVideoBackendSupportsWindows = ContainsDriver(videoDrivers, "windows");
|
||||
values.sdlVideoBackendSupportsCocoa = ContainsDriver(videoDrivers, "cocoa");
|
||||
logger_->TraceVariable("sdl.videoBackend.supportsWayland", values.sdlVideoBackendSupportsWayland);
|
||||
logger_->TraceVariable("sdl.videoBackend.supportsX11", values.sdlVideoBackendSupportsX11);
|
||||
logger_->TraceVariable("sdl.videoBackend.supportsKmsdrm", values.sdlVideoBackendSupportsKmsdrm);
|
||||
logger_->TraceVariable("sdl.videoBackend.supportsWindows", values.sdlVideoBackendSupportsWindows);
|
||||
logger_->TraceVariable("sdl.videoBackend.supportsCocoa", values.sdlVideoBackendSupportsCocoa);
|
||||
|
||||
const bool videoInitialized = (SDL_WasInit(SDL_INIT_VIDEO) & SDL_INIT_VIDEO) != 0;
|
||||
logger_->TraceVariable("sdl.videoInitialized", videoInitialized);
|
||||
values.sdlVideoInitialized = videoInitialized;
|
||||
|
||||
const std::string currentDriverName = GetCurrentVideoDriverName();
|
||||
logger_->TraceVariable("sdl.currentVideoDriver", currentDriverName);
|
||||
values.sdlCurrentVideoDriver = currentDriverName;
|
||||
values.sdlVideoBackendIsWayland = currentDriverName == "wayland";
|
||||
values.sdlVideoBackendIsX11 = currentDriverName == "x11";
|
||||
values.sdlVideoBackendIsKmsdrm = currentDriverName == "kmsdrm";
|
||||
values.sdlVideoBackendIsWindows = currentDriverName == "windows";
|
||||
values.sdlVideoBackendIsCocoa = currentDriverName == "cocoa";
|
||||
logger_->TraceVariable("sdl.videoBackend.isWayland", values.sdlVideoBackendIsWayland);
|
||||
logger_->TraceVariable("sdl.videoBackend.isX11", values.sdlVideoBackendIsX11);
|
||||
logger_->TraceVariable("sdl.videoBackend.isKmsdrm", values.sdlVideoBackendIsKmsdrm);
|
||||
logger_->TraceVariable("sdl.videoBackend.isWindows", values.sdlVideoBackendIsWindows);
|
||||
logger_->TraceVariable("sdl.videoBackend.isCocoa", values.sdlVideoBackendIsCocoa);
|
||||
const std::string systemTheme = SystemThemeName(SDL_GetSystemTheme());
|
||||
logger_->TraceVariable("sdl.systemTheme", systemTheme);
|
||||
values.sdlSystemTheme = systemTheme;
|
||||
|
||||
std::vector<std::string> renderDrivers = GetAvailableRenderDrivers();
|
||||
values.sdlRenderDriverCount = static_cast<int>(renderDrivers.size());
|
||||
logger_->TraceVariable("sdl.renderDriverCount", values.sdlRenderDriverCount);
|
||||
if (!renderDrivers.empty()) {
|
||||
const std::string joinedDrivers = JoinStrings(renderDrivers);
|
||||
logger_->TraceVariable("sdl.renderDrivers", joinedDrivers);
|
||||
values.sdlRenderDrivers = joinedDrivers;
|
||||
}
|
||||
values.sdlRenderSupportsOpenGL = ContainsDriver(renderDrivers, "opengl");
|
||||
values.sdlRenderSupportsOpenGLES2 = ContainsDriver(renderDrivers, "opengles2");
|
||||
values.sdlRenderSupportsDirect3D11 = ContainsDriver(renderDrivers, "direct3d11");
|
||||
values.sdlRenderSupportsDirect3D12 = ContainsDriver(renderDrivers, "direct3d12");
|
||||
values.sdlRenderSupportsMetal = ContainsDriver(renderDrivers, "metal");
|
||||
values.sdlRenderSupportsSoftware = ContainsDriver(renderDrivers, "software");
|
||||
logger_->TraceVariable("sdl.render.supportsOpenGL", values.sdlRenderSupportsOpenGL);
|
||||
logger_->TraceVariable("sdl.render.supportsOpenGLES2", values.sdlRenderSupportsOpenGLES2);
|
||||
logger_->TraceVariable("sdl.render.supportsDirect3D11", values.sdlRenderSupportsDirect3D11);
|
||||
logger_->TraceVariable("sdl.render.supportsDirect3D12", values.sdlRenderSupportsDirect3D12);
|
||||
logger_->TraceVariable("sdl.render.supportsMetal", values.sdlRenderSupportsMetal);
|
||||
logger_->TraceVariable("sdl.render.supportsSoftware", values.sdlRenderSupportsSoftware);
|
||||
|
||||
if (!videoInitialized) {
|
||||
logger_->Info("PlatformService::FeatureTable\n" + BuildFeatureTable(values));
|
||||
return;
|
||||
}
|
||||
|
||||
int displayCount = 0;
|
||||
SDL_DisplayID* displays = SDL_GetDisplays(&displayCount);
|
||||
logger_->TraceVariable("sdl.displayCount", displayCount);
|
||||
values.sdlDisplayCount = displayCount;
|
||||
if (displays) {
|
||||
SDL_DisplayID primaryDisplay = SDL_GetPrimaryDisplay();
|
||||
logger_->TraceVariable("sdl.primaryDisplayId", static_cast<int>(primaryDisplay));
|
||||
values.sdlPrimaryDisplayId = static_cast<int>(primaryDisplay);
|
||||
std::string displaySummary;
|
||||
for (int i = 0; i < displayCount; ++i) {
|
||||
SDL_DisplayID displayId = displays[i];
|
||||
const char* name = SDL_GetDisplayName(displayId);
|
||||
SDL_Rect bounds{};
|
||||
const bool hasBounds = SDL_GetDisplayBounds(displayId, &bounds);
|
||||
const std::string index = std::to_string(i);
|
||||
logger_->TraceVariable("sdl.display." + index + ".id",
|
||||
static_cast<int>(displayId));
|
||||
logger_->TraceVariable("sdl.display." + index + ".isPrimary",
|
||||
displayId == primaryDisplay);
|
||||
logger_->TraceVariable("sdl.display." + index + ".name",
|
||||
name && *name != '\0' ? std::string(name) : "unknown");
|
||||
logger_->TraceVariable("sdl.display." + index + ".bounds",
|
||||
hasBounds ? FormatBounds(bounds) : "unavailable");
|
||||
if (i > 0) {
|
||||
displaySummary += " | ";
|
||||
}
|
||||
displaySummary += index;
|
||||
displaySummary += ":";
|
||||
displaySummary += name && *name != '\0' ? name : "unknown";
|
||||
displaySummary += "@";
|
||||
displaySummary += hasBounds ? FormatBounds(bounds) : "unavailable";
|
||||
}
|
||||
values.sdlDisplaySummary = displaySummary.empty() ? "none" : displaySummary;
|
||||
SDL_free(displays);
|
||||
} else {
|
||||
const char* error = SDL_GetError();
|
||||
const std::string displayError = error && *error != '\0' ? std::string(error) : "unknown";
|
||||
logger_->TraceVariable("sdl.displayError", displayError);
|
||||
values.sdlDisplayError = displayError;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
struct utsname systemInfo {};
|
||||
if (uname(&systemInfo) == 0) {
|
||||
logger_->TraceVariable("platform.uname.sysname", std::string(systemInfo.sysname));
|
||||
logger_->TraceVariable("platform.uname.release", std::string(systemInfo.release));
|
||||
logger_->TraceVariable("platform.uname.version", std::string(systemInfo.version));
|
||||
logger_->TraceVariable("platform.uname.machine", std::string(systemInfo.machine));
|
||||
values.unameSysname = systemInfo.sysname;
|
||||
values.unameRelease = systemInfo.release;
|
||||
values.unameVersion = systemInfo.version;
|
||||
values.unameMachine = systemInfo.machine;
|
||||
}
|
||||
#endif
|
||||
|
||||
logger_->Info("PlatformService::FeatureTable\n" + BuildFeatureTable(values));
|
||||
}
|
||||
|
||||
} // namespace sdl3cpp::services::impl
|
||||
|
||||
@@ -13,6 +13,11 @@ public:
|
||||
|
||||
std::optional<std::filesystem::path> GetUserConfigDirectory() const override;
|
||||
std::string GetPlatformError() const override;
|
||||
std::string GetPlatformName() const override;
|
||||
std::string GetCurrentVideoDriverName() const override;
|
||||
std::vector<std::string> GetAvailableVideoDrivers() const override;
|
||||
std::vector<std::string> GetAvailableRenderDrivers() const override;
|
||||
void LogSystemInfo() const override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<ILogger> logger_;
|
||||
|
||||
@@ -174,6 +174,10 @@ void SdlWindowService::CreateWindow(const WindowConfig& config) {
|
||||
}
|
||||
}
|
||||
|
||||
if (platformService_) {
|
||||
platformService_->LogSystemInfo();
|
||||
}
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (config.resizable) {
|
||||
flags |= SDL_WINDOW_RESIZABLE;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace sdl3cpp::services {
|
||||
|
||||
@@ -12,6 +13,11 @@ public:
|
||||
|
||||
virtual std::optional<std::filesystem::path> GetUserConfigDirectory() const = 0;
|
||||
virtual std::string GetPlatformError() const = 0;
|
||||
virtual std::string GetPlatformName() const = 0;
|
||||
virtual std::string GetCurrentVideoDriverName() const = 0;
|
||||
virtual std::vector<std::string> GetAvailableVideoDrivers() const = 0;
|
||||
virtual std::vector<std::string> GetAvailableRenderDrivers() const = 0;
|
||||
virtual void LogSystemInfo() const = 0;
|
||||
};
|
||||
|
||||
} // namespace sdl3cpp::services
|
||||
|
||||
Reference in New Issue
Block a user