Add GLOBAL_GET cached macros.

GLOBAL_GET is an expensive operation which should not be used each frame / tick.
This PR adds macros which do a cheaper revision check, and only call the expensive GLOBAL_GET when project settings have changed.

Co-authored-by: Lukas Tenbrink <lukas.tenbrink@gmail.com>
This commit is contained in:
lawnjelly 2025-03-07 12:43:51 +00:00 committed by Relintai
parent 3b688f6162
commit d149a59513
29 changed files with 76 additions and 47 deletions

View File

@ -194,6 +194,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
for (int i = 0; i < custom_feature_array.size(); i++) {
custom_features.insert(custom_feature_array[i]);
}
_version++;
return true;
}
@ -207,6 +208,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
}
}
_version++;
return true;
}
bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const {

View File

@ -67,6 +67,10 @@ class ProjectSettings : public Object {
int _dirty_this_frame = 2;
// Starting version from 1 ensures that all callers can reset their tested version to 0,
// and will always detect the initial project settings as a "change".
uint32_t _version = 1;
public:
typedef RBMap<String, Variant> CustomMap;
static const String PROJECT_DATA_DIR_NAME_SUFFIX;
@ -198,6 +202,10 @@ public:
// There is therefore the potential for a change to be missed. Persisting the counter
// for two frames avoids this, at the cost of a frame delay.
bool has_changes() const { return _dirty_this_frame == 1; }
// Testing a version allows fast cached GET_GLOBAL macros.
uint32_t get_version() const { return _version; }
void update();
ProjectSettings();
@ -215,4 +223,23 @@ Variant _GLOBAL_DEF_ALIAS(const String &p_var, const String &p_old_name, const V
#define GLOBAL_DEF_ALIAS_RST(m_var, m_old_name, m_value) _GLOBAL_DEF(m_var, m_old_name, m_value, true)
#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get(m_var)
#endif
/////////////////////////////////////////////////////////////////////////////////////////
// Cached versions of GLOBAL_GET.
// Cached but uses a typed variable for storage, this can be more efficient.
#define GLOBAL_GET_CACHED(m_type, m_setting_name) ([](const char *p_name) -> m_type {\
static_assert(std::is_trivially_destructible<m_type>::value, "GLOBAL_GET_CACHED must use a trivial type that allows static lifetime.");\
static m_type local_var;\
static uint32_t local_version = 0;\
static Mutex local_mutex;\
uint32_t new_version = ProjectSettings::get_singleton()->get_version();\
if (local_version != new_version) {\
MutexLock lock(local_mutex);\
local_version = new_version;\
local_var = ProjectSettings::get_singleton()->get(p_name);\
return local_var;\
}\
MutexLock lock(local_mutex);\
return local_var; })(m_setting_name)
#endif // PROJECT_SETTINGS_H

View File

@ -147,7 +147,7 @@ void _physics_interpolation_warning(const char *p_function, const char *p_file,
warn_count = warn_max;
warn_timeout = time_now + warn_timeout_seconds;
if (GLOBAL_GET("debug/settings/physics_interpolation/enable_warnings")) {
if (GLOBAL_GET_CACHED(bool, "debug/settings/physics_interpolation/enable_warnings")) {
// UINT64_MAX means unused.
if (p_id == UINT64_MAX) {
_err_print_error(p_function, p_file, p_line, "[Physics interpolation] " + String(p_warn_string) + " (possibly benign).", ERR_HANDLER_WARNING);

View File

@ -276,7 +276,7 @@ void RasterizerGLES2::begin_frame(double frame_step) {
frame_step = 0.001;
}
double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
double time_roll_over = GLOBAL_GET_CACHED(double, "rendering/limits/time/time_rollover_secs");
time_total = Math::fmod(time_total, time_roll_over);
storage->frame.time[0] = time_total;

View File

@ -4059,9 +4059,9 @@ void RasterizerSceneGLES2::initialize() {
}
void RasterizerSceneGLES2::iteration() {
shadow_filter_mode = ShadowFilterMode(int(GLOBAL_GET("rendering/quality/shadows/filter_mode")));
shadow_filter_mode = ShadowFilterMode(int(GLOBAL_GET_CACHED(int32_t, "rendering/quality/shadows/filter_mode")));
const int directional_shadow_size_new = next_power_of_2(int(GLOBAL_GET("rendering/quality/directional_shadow/size")));
const int directional_shadow_size_new = next_power_of_2(GLOBAL_GET_CACHED(int32_t, "rendering/quality/directional_shadow/size"));
if (directional_shadow_size != directional_shadow_size_new) {
directional_shadow_size = directional_shadow_size_new;
directional_shadow_create();

View File

@ -2296,7 +2296,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
}
//bool has_morph = p_blend_shapes.size();
bool use_split_stream = GLOBAL_GET("rendering/misc/mesh_storage/split_stream") && !(p_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
Surface::Attrib attribs[RS::ARRAY_MAX];

View File

@ -1226,7 +1226,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
//actions[RS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
//actions[RS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley");
bool force_lambert = GLOBAL_GET_CACHED(bool, "rendering/quality/shading/force_lambert_over_burley");
if (!force_lambert) {
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
@ -1236,7 +1236,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx");
bool force_blinn = GLOBAL_GET_CACHED(bool, "rendering/quality/shading/force_blinn_over_ggx");
if (!force_blinn) {
actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";

View File

@ -178,7 +178,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
strings.push_back("#define USE_HIGHP_PRECISION\n");
#endif
if (GLOBAL_GET("rendering/gles2/compatibility/enable_high_float.Android")) {
if (GLOBAL_GET_CACHED(bool, "rendering/gles2/compatibility/enable_high_float.Android")) {
// enable USE_HIGHP_PRECISION but safeguarded by an availability check as highp support is optional in GLES2
// see Section 4.5.4 of the GLSL_ES_Specification_1.00
strings.push_back("#ifdef GL_FRAGMENT_PRECISION_HIGH\n #define USE_HIGHP_PRECISION\n#endif\n");

View File

@ -200,7 +200,7 @@ void RasterizerGLES3::begin_frame(double frame_step) {
frame_step = 0.001;
}
double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
double time_roll_over = GLOBAL_GET_CACHED(double, "rendering/limits/time/time_rollover_secs");
time_total = Math::fmod(time_total, time_roll_over);
storage->frame.time[0] = time_total;

View File

@ -5315,22 +5315,22 @@ void RasterizerSceneGLES3::initialize() {
}
void RasterizerSceneGLES3::iteration() {
shadow_filter_mode = ShadowFilterMode(int(GLOBAL_GET("rendering/quality/shadows/filter_mode")));
shadow_filter_mode = ShadowFilterMode(GLOBAL_GET_CACHED(int32_t, "rendering/quality/shadows/filter_mode"));
const int directional_shadow_size_new = next_power_of_2(int(GLOBAL_GET("rendering/quality/directional_shadow/size")));
const int directional_shadow_size_new = next_power_of_2(GLOBAL_GET_CACHED(int32_t, "rendering/quality/directional_shadow/size"));
if (directional_shadow_size != directional_shadow_size_new) {
directional_shadow_size = directional_shadow_size_new;
directional_shadow_create();
}
subsurface_scatter_follow_surface = GLOBAL_GET("rendering/quality/subsurface_scattering/follow_surface");
subsurface_scatter_weight_samples = GLOBAL_GET("rendering/quality/subsurface_scattering/weight_samples");
subsurface_scatter_quality = SubSurfaceScatterQuality(int(GLOBAL_GET("rendering/quality/subsurface_scattering/quality")));
subsurface_scatter_size = GLOBAL_GET("rendering/quality/subsurface_scattering/scale");
subsurface_scatter_follow_surface = GLOBAL_GET_CACHED(bool, "rendering/quality/subsurface_scattering/follow_surface");
subsurface_scatter_weight_samples = GLOBAL_GET_CACHED(bool, "rendering/quality/subsurface_scattering/weight_samples");
subsurface_scatter_quality = SubSurfaceScatterQuality(int(GLOBAL_GET_CACHED(int32_t, "rendering/quality/subsurface_scattering/quality")));
subsurface_scatter_size = GLOBAL_GET_CACHED(float, "rendering/quality/subsurface_scattering/scale");
storage->config.use_lightmap_filter_bicubic = GLOBAL_GET("rendering/quality/lightmapping/use_bicubic_sampling");
storage->config.use_lightmap_filter_bicubic = GLOBAL_GET_CACHED(bool, "rendering/quality/lightmapping/use_bicubic_sampling");
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHTMAP_FILTER_BICUBIC, storage->config.use_lightmap_filter_bicubic);
state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, GLOBAL_GET("rendering/quality/voxel_cone_tracing/high_quality"));
state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, GLOBAL_GET_CACHED(bool, "rendering/quality/voxel_cone_tracing/high_quality"));
}
void RasterizerSceneGLES3::finalize() {

View File

@ -3390,7 +3390,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
}
//bool has_morph = p_blend_shapes.size();
bool use_split_stream = GLOBAL_GET("rendering/misc/mesh_storage/split_stream") && !(p_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
Surface::Attrib attribs[RS::ARRAY_MAX];

View File

@ -1268,7 +1268,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[RS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
actions[RS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley");
bool force_lambert = GLOBAL_GET_CACHED(bool, "rendering/quality/shading/force_lambert_over_burley");
if (!force_lambert) {
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
@ -1278,7 +1278,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx");
bool force_blinn = GLOBAL_GET_CACHED(bool, "rendering/quality/shading/force_blinn_over_ggx");
if (!force_blinn) {
actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";

View File

@ -419,12 +419,12 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
tex_flags |= Texture::FLAG_REPEAT;
const bool min_gles3 = GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3" &&
!GLOBAL_GET("rendering/quality/driver/fallback_to_gles2");
!GLOBAL_GET_CACHED(bool, "rendering/quality/driver/fallback_to_gles2");
if (!min_gles3 && !image->is_size_po2()) {
// The project can be run using GLES2. GLES2 does not guarantee that
// repeating textures with a non-power-of-two size will be displayed
// without artifacts (due to upscaling to the nearest power of 2).
if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) {
if (GLOBAL_GET_CACHED(bool, "rendering/quality/driver/fallback_to_gles2")) {
WARN_PRINT(vformat("%s: Imported a repeating texture with a size of %dx%d, but the project is configured to allow falling back to GLES2.\nNon-power-of-2 repeating textures may not display correctly on some platforms such as HTML5. This is because GLES2 does not mandate support for non-power-of-2 repeating textures.",
p_source_file, image->get_width(), image->get_height()));
} else {

View File

@ -1475,7 +1475,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
// Render every past/future step with the capture shader.
RS::get_singleton()->canvas_item_set_material(onion.capture.canvas_item, onion.capture.material->get_rid());
onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET("rendering/environment/default_clear_color"));
onion.capture.material->set_shader_param("bkg_color", GLOBAL_GET_CACHED(Color, "rendering/environment/default_clear_color"));
onion.capture.material->set_shader_param("differences_only", onion.differences_only);
onion.capture.material->set_shader_param("present", onion.differences_only ? RS::get_singleton()->viewport_get_texture(present_rid) : RID());

View File

@ -3677,7 +3677,7 @@ void CanvasItemEditor::set_current_tool(Tool p_tool) {
void CanvasItemEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels"));
EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET_CACHED(bool, "gui/common/snap_controls_to_pixels"));
bool has_container_parents = false;
int nb_control = 0;

View File

@ -894,7 +894,7 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, c
Ref<Font> font = sampled_font;
const Color c = GLOBAL_GET("rendering/environment/default_clear_color");
const Color c = GLOBAL_GET_CACHED(Color, "rendering/environment/default_clear_color");
const float fg = c.get_luminance() < 0.5 ? 1.0 : 0.0;
font->draw(canvas_item, pos, sampled_text, Color(fg, fg, fg));

View File

@ -96,7 +96,7 @@ void ThemeEditorPreview::_propagate_redraw(Control *p_at) {
void ThemeEditorPreview::_refresh_interval() {
// In case the project settings have changed.
preview_bg->set_frame_color(GLOBAL_GET("rendering/environment/default_clear_color"));
preview_bg->set_frame_color(GLOBAL_GET_CACHED(Color, "rendering/environment/default_clear_color"));
_propagate_redraw(preview_bg);
_propagate_redraw(preview_content);

View File

@ -446,7 +446,7 @@ void EditorScriptTextEditor::_validate_script() {
warnings_panel->clear();
// Add missing connections.
if (GLOBAL_GET("debug/gdscript/warnings/enable").booleanize()) {
if (GLOBAL_GET_CACHED(bool, "debug/gdscript/warnings/enable")) {
Node *base = get_tree()->get_edited_scene_root();
if (base && missing_connections.size() > 0) {
warnings_panel->push_table(1);

View File

@ -2544,7 +2544,7 @@ bool Main::iteration() {
if (print_fps) {
print_line(vformat("Editor FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(2)));
}
} else if (print_fps || GLOBAL_GET("debug/settings/stdout/print_fps")) {
} else if (print_fps || GLOBAL_GET_CACHED(bool, "debug/settings/stdout/print_fps")) {
print_line(vformat("Project FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(2)));
}
} else {

View File

@ -2091,7 +2091,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
if (!_static) {
List<MethodInfo> methods;
bool is_autocompleting_getters = GLOBAL_GET("debug/gdscript/completion/autocomplete_setters_and_getters").booleanize();
bool is_autocompleting_getters = GLOBAL_GET_CACHED(bool, "debug/gdscript/completion/autocomplete_setters_and_getters");
ClassDB::get_method_list(type, &methods, false, !is_autocompleting_getters);
for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
if (E->get().name.begins_with("_")) {

View File

@ -8703,10 +8703,10 @@ void GDScriptParser::_add_warning(int p_code, int p_line, const String &p_symbol
}
void GDScriptParser::_add_warning(int p_code, int p_line, const Vector<String> &p_symbols) {
if (GLOBAL_GET("debug/gdscript/warnings/exclude_addons").booleanize() && base_path.begins_with("res://addons/")) {
if (GLOBAL_GET_CACHED(bool, "debug/gdscript/warnings/exclude_addons") && base_path.begins_with("res://addons/")) {
return;
}
if (tokenizer->is_ignoring_warnings() || !GLOBAL_GET("debug/gdscript/warnings/enable").booleanize()) {
if (tokenizer->is_ignoring_warnings() || !GLOBAL_GET_CACHED(bool, "debug/gdscript/warnings/enable")) {
return;
}
String warn_name = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)p_code).to_lower();
@ -8820,7 +8820,7 @@ Error GDScriptParser::_parse(const String &p_base_path) {
// Resolve warning ignores
Vector<Pair<int, String>> warning_skips = tokenizer->get_warning_skips();
bool warning_is_error = GLOBAL_GET("debug/gdscript/warnings/treat_warnings_as_errors").booleanize();
bool warning_is_error = GLOBAL_GET_CACHED(bool, "debug/gdscript/warnings/treat_warnings_as_errors");
for (List<GDScriptWarning>::Element *E = warnings.front(); E;) {
GDScriptWarning &w = E->get();
int skip_index = -1;

View File

@ -223,7 +223,7 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
"android:resizeableActivity=\"%s\">\n",
bool_to_string(p_preset->get("package/exclude_from_recents")),
orientation,
bool_to_string(bool(GLOBAL_GET("display/window/size/resizable"))));
bool_to_string(GLOBAL_GET_CACHED(bool, "display/window/size/resizable")));
manifest_activity_text += " <meta-data tools:node=\"remove\" android:name=\"com.oculus.vr.focusaware\" />\n";
manifest_activity_text += " </activity>\n";
return manifest_activity_text;

View File

@ -202,12 +202,12 @@ void MeshInstance::_resolve_skeleton_path() {
bool MeshInstance::_is_global_software_skinning_enabled() {
// Check if forced in project settings.
if (GLOBAL_GET("rendering/quality/skinning/force_software_skinning")) {
if (GLOBAL_GET_CACHED(bool, "rendering/quality/skinning/force_software_skinning")) {
return true;
}
// Check if enabled in project settings.
if (!GLOBAL_GET("rendering/quality/skinning/software_skinning_fallback")) {
if (!GLOBAL_GET_CACHED(bool, "rendering/quality/skinning/software_skinning_fallback")) {
return false;
}

View File

@ -652,7 +652,7 @@ bool SceneTree::iteration(float p_time) {
call_group_flags(GROUP_CALL_REALTIME, "_pg_process", "trigger_physics_process");
_notify_group_pause("physics_process_internal", Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
if (GLOBAL_GET("physics/common/enable_pause_aware_picking")) {
if (GLOBAL_GET_CACHED(bool, "physics/common/enable_pause_aware_picking")) {
call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_process_picking", true);
}
_notify_group_pause("physics_process", Node::NOTIFICATION_PHYSICS_PROCESS);

View File

@ -174,14 +174,14 @@ class TooltipPanel : public PanelContainer {
GDCLASS(TooltipPanel, PanelContainer);
public:
TooltipPanel() {};
TooltipPanel() {}
};
class TooltipLabel : public Label {
GDCLASS(TooltipLabel, Label);
public:
TooltipLabel() {};
TooltipLabel() {}
};
/////////////////////////////////////
@ -387,7 +387,7 @@ void Viewport::_notification(int p_what) {
}
}
if (!GLOBAL_GET("physics/common/enable_pause_aware_picking")) {
if (!GLOBAL_GET_CACHED(bool, "physics/common/enable_pause_aware_picking")) {
_process_picking(false);
}
} break;

View File

@ -2194,7 +2194,7 @@ SpatialMaterial::SpatialMaterial(bool p_orm) :
flags[i] = false;
}
force_vertex_shading = GLOBAL_GET("rendering/quality/shading/force_vertex_shading");
force_vertex_shading = GLOBAL_GET_CACHED(bool, "rendering/quality/shading/force_vertex_shading");
diffuse_mode = DIFFUSE_BURLEY;
specular_mode = SPECULAR_SCHLICK_GGX;

View File

@ -185,7 +185,7 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
return;
}
if (!GLOBAL_GET("audio/enable_audio_input")) {
if (!GLOBAL_GET_CACHED(bool, "audio/enable_audio_input")) {
WARN_PRINT("Need to enable Project settings > Audio > Enable Audio Input option to use capturing.");
return;
}

View File

@ -249,7 +249,7 @@ void PortalOcclusionCuller::prepare_generic(PortalRenderer &p_portal_renderer, c
// Bodge to keep settings up to date, until the project settings PR is merged
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && ((Engine::get_singleton()->get_frames_drawn() % 16) == 0)) {
_max_polys = GLOBAL_GET("rendering/misc/occlusion_culling/max_active_polygons");
_max_polys = GLOBAL_GET_CACHED(int32_t, "rendering/misc/occlusion_culling/max_active_polygons");
}
#endif
_num_spheres = 0;

View File

@ -870,7 +870,7 @@ uint32_t RenderingServer::mesh_surface_get_format_stride(uint32_t p_format, int
}
void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t *r_strides) const {
bool use_split_stream = GLOBAL_GET("rendering/misc/mesh_storage/split_stream") && !(p_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
int attributes_base_offset = 0;
int attributes_stride = 0;
@ -1248,7 +1248,7 @@ bool RenderingServer::_mesh_find_format(RS::PrimitiveType p_primitive, const Arr
}
uint32_t RenderingServer::mesh_find_format_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_compress_format) {
bool use_split_stream = GLOBAL_GET("rendering/misc/mesh_storage/split_stream") && !(p_compress_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_compress_format & rS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
uint32_t offsets[RS::ARRAY_MAX];
@ -1268,7 +1268,7 @@ uint32_t RenderingServer::mesh_find_format_from_arrays(PrimitiveType p_primitive
}
void RenderingServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_compress_format) {
bool use_split_stream = GLOBAL_GET("rendering/misc/mesh_storage/split_stream") && !(p_compress_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_compress_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
uint32_t offsets[RS::ARRAY_MAX];
@ -1338,7 +1338,7 @@ void RenderingServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_p
}
Array RenderingServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_t> p_vertex_data, int p_vertex_len, PoolVector<uint8_t> p_index_data, int p_index_len) const {
bool use_split_stream = GLOBAL_GET("rendering/misc/mesh_storage/split_stream") && !(p_format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_format & rS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
uint32_t offsets[ARRAY_MAX];
uint32_t strides[RS::ARRAY_MAX];