mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
[Refactor] (MG_Config): centralize env-var and driver-feature reads
MG_Config::FeaturesTable snapshots every MOBILEGL_* toggle once in ConfigLoader::Init with a single truthy rule (non-empty, not '0', not 'false' case-insensitively), replacing 13 scattered std::getenv sites that used four different parsing conventions. Renderer-derived bits (IsAngleRenderer/IsAngleLlvmpipeRenderer/AvoidSamplerMipmapMinFilter) move into GLESCapabilities, set once in FillInGLESCapabilities, so hot paths (glMemoryBarrier ANGLE flush, sampler min-filter sync) stop doing per-call string scans. MOBILEGL_PRESENT_DUMP_CALL/_CURRENT_CALL stay live getenv (the retrace harness mutates them at runtime) and MOBILEGL_LOG_FILE_PATH stays in Log.cpp (log init precedes config init); both are documented in Config.h. Known semantic unification: MOBILEGL_DISABLE_SUBGROUP previously required exactly 'true' and MOBILEGL_PRESENT_STATS exactly '1'; both now follow the shared rule (CI's 0/1 values parse identically). Also bumps CoreVersion to 26.07. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+44
-1
@@ -14,9 +14,52 @@ namespace MobileGL::MG_Config {
|
||||
inline const String ProjectName = "MobileGL";
|
||||
inline const String CoreName = "MobileGL Core";
|
||||
inline const String CoreVendor = "MobileGL-Dev (BZLZHH, Swung0x48, Tungsten)";
|
||||
inline const Version CoreVersion = {26, 6, 0, "-dev", VersionType::Development};
|
||||
inline const Version CoreVersion = {26, 7, 0, "-dev", VersionType::Development};
|
||||
inline const VersionStringFormatAttrib DefaultVersionStringFormatAttrib = {2, 2, 0, true, true};
|
||||
inline const Uint64 CacheVersion = 0;
|
||||
|
||||
extern BackendType ActiveBackendType;
|
||||
|
||||
// Feature toggles parsed once from environment variables in MG_ConfigLoader::Init()
|
||||
// (ConfigLoader.cpp), before the accepted-env map is destroyed. All Bool fields share
|
||||
// one truthy rule: the variable is set, non-empty, not "0", and not "false"
|
||||
// (case-insensitive).
|
||||
//
|
||||
// Env variables intentionally NOT mirrored here (kept as live std::getenv at their
|
||||
// call sites):
|
||||
// - MOBILEGL_PRESENT_DUMP_CALL / MOBILEGL_PRESENT_CURRENT_CALL: the retrace harness
|
||||
// mutates them at runtime via setenv, so a one-shot snapshot would go stale.
|
||||
// - DISPLAY: X11 session variable, not MobileGL configuration.
|
||||
// - MOBILEGL_LOG_FILE_PATH: log-file init runs before MG_ConfigLoader::Init
|
||||
// (see MG_Util/Debug/Log.cpp).
|
||||
struct FeaturesTable {
|
||||
// MOBILEGL_DISABLE_TIMERQUERY: do not advertise or use GPU timer queries.
|
||||
Bool DisableTimerQuery = false;
|
||||
// MOBILEGL_RETRACE_USE_ANGLE: load ANGLE EGL/GLES libraries for retrace runs.
|
||||
Bool RetraceUseAngle = false;
|
||||
// MOBILEGL_RETRACE_ANGLE_DIR: directory searched first for the ANGLE libraries.
|
||||
String RetraceAngleDir;
|
||||
// MOBILEGL_DISABLE_SUBGROUP: force-disable Vulkan shader subgroup support.
|
||||
Bool DisableSubgroup = false;
|
||||
// MOBILEGL_VULKAN_R11G11B10F_FALLBACK: use fallback format for R11G11B10F on Vulkan.
|
||||
Bool VulkanR11G11B10FFallback = false;
|
||||
// MOBILEGL_GLES_PRESENT_STATS: log present pixel statistics (DirectGLES backend).
|
||||
Bool GlesPresentStats = false;
|
||||
// MOBILEGL_ANGLE_LLVMPIPE_AVOID_SAMPLER_MIPMAP_MIN_FILTER: avoid mipmap min
|
||||
// filters in samplers on ANGLE/llvmpipe renderers.
|
||||
Bool AvoidAngleLlvmpipeSamplerMipmapMinFilter = false;
|
||||
// MOBILEGL_DESCRIPTOR_STATS: log descriptor binding statistics (DirectVulkan).
|
||||
Bool DescriptorStats = false;
|
||||
// MOBILEGL_TEXTURE_UPLOAD_STATS: log texture upload statistics (DirectVulkan).
|
||||
Bool TextureUploadStats = false;
|
||||
// MOBILEGL_VERTEX_INPUT_STATS: log vertex input statistics (DirectVulkan).
|
||||
Bool VertexInputStats = false;
|
||||
// MOBILEGL_PRESENT_DUMP_PATH: directory for present frame dumps (DirectVulkan).
|
||||
String PresentDumpPath;
|
||||
// MOBILEGL_PRESENT_STATS: log present pixel statistics (DirectVulkan backend).
|
||||
Bool PresentStats = false;
|
||||
// MOBILEGL_TRACE_SKIP_AUTODESTROY: skip teardown in the ELF destructor (Init.cpp).
|
||||
Bool TraceSkipAutodestroy = false;
|
||||
};
|
||||
extern FeaturesTable Features;
|
||||
} // namespace MobileGL::MG_Config
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
extern char** environ;
|
||||
#endif
|
||||
|
||||
namespace MobileGL::MG_Config {
|
||||
// Zero/default-initialized at static-init time (all fields have constexpr-friendly
|
||||
// defaults), so it is safe to read even if MG_ConfigLoader::Init has not run yet.
|
||||
FeaturesTable Features;
|
||||
} // namespace MobileGL::MG_Config
|
||||
|
||||
namespace MobileGL::MG_ConfigLoader {
|
||||
static UniquePtr<UnorderedMap<String, String>> acceptedEnvVariablesMap;
|
||||
|
||||
@@ -60,6 +66,41 @@ namespace MobileGL::MG_ConfigLoader {
|
||||
}
|
||||
}
|
||||
|
||||
// Unified truthy rule for boolean feature env variables: set, non-empty, not "0",
|
||||
// and not "false" (case-insensitive).
|
||||
static Bool IsTruthyValue(const String& value) {
|
||||
if (value.empty() || value == "0") {
|
||||
return false;
|
||||
}
|
||||
String lowered = value;
|
||||
std::transform(lowered.begin(), lowered.end(), lowered.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
return lowered != "false";
|
||||
}
|
||||
|
||||
inline Bool QueryEnvFlag(const String& key) {
|
||||
auto it = acceptedEnvVariablesMap->find(key);
|
||||
return it != acceptedEnvVariablesMap->end() && IsTruthyValue(it->second);
|
||||
}
|
||||
|
||||
inline void InitFeatures() {
|
||||
auto& features = MG_Config::Features;
|
||||
features.DisableTimerQuery = QueryEnvFlag("MOBILEGL_DISABLE_TIMERQUERY");
|
||||
features.RetraceUseAngle = QueryEnvFlag("MOBILEGL_RETRACE_USE_ANGLE");
|
||||
QueryEnvVariable("MOBILEGL_RETRACE_ANGLE_DIR", features.RetraceAngleDir, "");
|
||||
features.DisableSubgroup = QueryEnvFlag("MOBILEGL_DISABLE_SUBGROUP");
|
||||
features.VulkanR11G11B10FFallback = QueryEnvFlag("MOBILEGL_VULKAN_R11G11B10F_FALLBACK");
|
||||
features.GlesPresentStats = QueryEnvFlag("MOBILEGL_GLES_PRESENT_STATS");
|
||||
features.AvoidAngleLlvmpipeSamplerMipmapMinFilter =
|
||||
QueryEnvFlag("MOBILEGL_ANGLE_LLVMPIPE_AVOID_SAMPLER_MIPMAP_MIN_FILTER");
|
||||
features.DescriptorStats = QueryEnvFlag("MOBILEGL_DESCRIPTOR_STATS");
|
||||
features.TextureUploadStats = QueryEnvFlag("MOBILEGL_TEXTURE_UPLOAD_STATS");
|
||||
features.VertexInputStats = QueryEnvFlag("MOBILEGL_VERTEX_INPUT_STATS");
|
||||
QueryEnvVariable("MOBILEGL_PRESENT_DUMP_PATH", features.PresentDumpPath, "");
|
||||
features.PresentStats = QueryEnvFlag("MOBILEGL_PRESENT_STATS");
|
||||
features.TraceSkipAutodestroy = QueryEnvFlag("MOBILEGL_TRACE_SKIP_AUTODESTROY");
|
||||
}
|
||||
|
||||
inline void InitBackendType() {
|
||||
String backendTypeStr;
|
||||
QueryEnvVariable("MOBILEGL_BACKEND_TYPE", backendTypeStr, "DirectGLES");
|
||||
@@ -81,6 +122,7 @@ namespace MobileGL::MG_ConfigLoader {
|
||||
InitializeAcceptedEnvVariables();
|
||||
|
||||
InitBackendType();
|
||||
InitFeatures();
|
||||
|
||||
// Destroy the map since we won't need it anymore
|
||||
acceptedEnvVariablesMap.reset();
|
||||
|
||||
+1
-2
@@ -13,7 +13,6 @@
|
||||
#include <MG_State/EGLState/Core.h>
|
||||
#include <MG_Impl/GLImpl/Texture/ProxyTexture.h>
|
||||
#include <MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace MobileGL {
|
||||
namespace {
|
||||
@@ -75,7 +74,7 @@ namespace MobileGL {
|
||||
}
|
||||
|
||||
__attribute__((destructor)) static void AutoDestroy() {
|
||||
if (std::getenv("MOBILEGL_TRACE_SKIP_AUTODESTROY") != nullptr) {
|
||||
if (MG_Config::Features.TraceSkipAutodestroy) {
|
||||
return;
|
||||
}
|
||||
#if defined(__APPLE__)
|
||||
|
||||
@@ -41,13 +41,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
constexpr const char* ZERO_BASED_INSTANCE_ID_NAME = "mg_ZeroBasedInstanceID";
|
||||
|
||||
static Bool IsAngleLlvmpipeRenderer() {
|
||||
return g_GLESCapabilities.GLESRendererString.find("ANGLE") != String::npos &&
|
||||
g_GLESCapabilities.GLESRendererString.find("llvmpipe") != String::npos;
|
||||
return g_GLESCapabilities.IsAngleLlvmpipeRenderer;
|
||||
}
|
||||
|
||||
static Bool ShouldAvoidSamplerMipmapMinFilterOnAngleLlvmpipe() {
|
||||
const char* value = std::getenv("MOBILEGL_ANGLE_LLVMPIPE_AVOID_SAMPLER_MIPMAP_MIN_FILTER");
|
||||
return value != nullptr && std::strcmp(value, "1") == 0 && IsAngleLlvmpipeRenderer();
|
||||
// IsAngleLlvmpipeRenderer combined with the
|
||||
// MOBILEGL_ANGLE_LLVMPIPE_AVOID_SAMPLER_MIPMAP_MIN_FILTER feature toggle,
|
||||
// both resolved in FillInGLESCapabilities.
|
||||
return g_GLESCapabilities.AvoidSamplerMipmapMinFilter;
|
||||
}
|
||||
|
||||
static GLenum ResolveBackendMinFilter(const SamplerParameters& samplerParams,
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
namespace {
|
||||
Flags<PixelFormatNormalizeOptionBit> GetForcedPixelFormatNormalizeOptions() {
|
||||
Flags<PixelFormatNormalizeOptionBit> options;
|
||||
if (g_GLESCapabilities.GLESRendererString.find("ANGLE") != String::npos) {
|
||||
if (g_GLESCapabilities.IsAngleRenderer) {
|
||||
options |= PixelFormatNormalizeOptionBit::NoRgb16;
|
||||
options |= PixelFormatNormalizeOptionBit::NoSnorm16;
|
||||
options |= PixelFormatNormalizeOptionBit::NoSnorm8;
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
|
||||
#include "Loader.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <Config.h>
|
||||
|
||||
namespace MobileGL::MG_Util::BackendLoader {
|
||||
namespace {
|
||||
@@ -61,11 +60,7 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
}
|
||||
|
||||
Bool IsShaderSubgroupForcedDisabled() {
|
||||
const char* value = std::getenv("MOBILEGL_DISABLE_SUBGROUP");
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
return std::strcmp(value, "true") == 0 || std::strcmp(value, "TRUE") == 0;
|
||||
return MG_Config::Features.DisableSubgroup;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ namespace MobileGL {
|
||||
void InitFile() {
|
||||
#if MOBILEGL_LOG_ENABLE_FILE
|
||||
if (!s_logFile) {
|
||||
// MOBILEGL_LOG_FILE_PATH must stay a raw getenv (not MG_Config::Features):
|
||||
// InitFile() runs before MG_ConfigLoader::Init() in MobileGL::Initialize().
|
||||
const char* logPath = std::getenv("MOBILEGL_LOG_FILE_PATH");
|
||||
if (!logPath || !*logPath) {
|
||||
logPath = MOBILEGL_LOG_FILE_PATH;
|
||||
|
||||
Reference in New Issue
Block a user