瀏覽代碼

Merge pull request #103763 from lawnjelly/global_get_fast

[3.x] Add `GLOBAL_GET` cached macros.
lawnjelly 5 月之前
父節點
當前提交
585909ef69
共有 33 個文件被更改,包括 79 次插入51 次删除
  1. 1 1
      core/error_macros.cpp
  2. 2 0
      core/project_settings.cpp
  3. 26 0
      core/project_settings.h
  4. 1 1
      drivers/gles2/rasterizer_gles2.cpp
  5. 2 2
      drivers/gles2/rasterizer_scene_gles2.cpp
  6. 1 1
      drivers/gles2/rasterizer_storage_gles2.cpp
  7. 2 2
      drivers/gles2/shader_compiler_gles2.cpp
  8. 1 1
      drivers/gles2/shader_gles2.cpp
  9. 1 1
      drivers/gles3/rasterizer_gles3.cpp
  10. 8 8
      drivers/gles3/rasterizer_scene_gles3.cpp
  11. 1 1
      drivers/gles3/rasterizer_storage_gles3.cpp
  12. 2 2
      drivers/gles3/shader_compiler_gles3.cpp
  13. 2 2
      editor/import/resource_importer_texture.cpp
  14. 1 1
      editor/plugins/animation_player_editor_plugin.cpp
  15. 1 1
      editor/plugins/canvas_item_editor_plugin.cpp
  16. 1 1
      editor/plugins/editor_preview_plugins.cpp
  17. 1 1
      editor/plugins/script_text_editor.cpp
  18. 1 1
      editor/plugins/theme_editor_preview.cpp
  19. 1 1
      editor/plugins/version_control_editor_plugin.cpp
  20. 1 1
      main/main.cpp
  21. 1 1
      modules/bullet/shape_bullet.cpp
  22. 1 1
      modules/fbx/editor_scene_importer_fbx.cpp
  23. 1 1
      modules/gdscript/gdscript_editor.cpp
  24. 3 3
      modules/gdscript/gdscript_parser.cpp
  25. 1 1
      platform/android/export/gradle_export_util.cpp
  26. 2 2
      scene/3d/mesh_instance.cpp
  27. 1 1
      scene/main/scene_tree.cpp
  28. 4 4
      scene/main/viewport.cpp
  29. 1 1
      scene/resources/material.cpp
  30. 1 1
      servers/audio/audio_stream.cpp
  31. 1 1
      servers/visual/portals/portal_occlusion_culler.cpp
  32. 1 1
      servers/visual/visual_server_viewport.cpp
  33. 4 4
      servers/visual_server.cpp

+ 1 - 1
core/error_macros.cpp

@@ -145,7 +145,7 @@ void _physics_interpolation_warning(const char *p_function, const char *p_file,
 		warn_count = warn_max;
 		warn_count = warn_max;
 		warn_timeout = time_now + warn_timeout_seconds;
 		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.
 			// UINT64_MAX means unused.
 			if (p_id == UINT64_MAX) {
 			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);
 				_err_print_error(p_function, p_file, p_line, "[Physics interpolation] " + String(p_warn_string) + " (possibly benign).", ERR_HANDLER_WARNING);

+ 2 - 0
core/project_settings.cpp

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

+ 26 - 0
core/project_settings.h

@@ -66,6 +66,10 @@ class ProjectSettings : public Object {
 
 
 	int _dirty_this_frame = 2;
 	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:
 public:
 	typedef Map<String, Variant> CustomMap;
 	typedef Map<String, Variant> CustomMap;
 	static const String PROJECT_DATA_DIR_NAME_SUFFIX;
 	static const String PROJECT_DATA_DIR_NAME_SUFFIX;
@@ -201,6 +205,10 @@ public:
 	// There is therefore the potential for a change to be missed. Persisting the counter
 	// 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.
 	// for two frames avoids this, at the cost of a frame delay.
 	bool has_changes() const { return _dirty_this_frame == 1; }
 	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();
 	void update();
 
 
 	ProjectSettings();
 	ProjectSettings();
@@ -218,4 +226,22 @@ 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_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)
 #define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get(m_var)
 
 
+/////////////////////////////////////////////////////////////////////////////////////////
+// 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
 #endif // PROJECT_SETTINGS_H

+ 1 - 1
drivers/gles2/rasterizer_gles2.cpp

@@ -275,7 +275,7 @@ void RasterizerGLES2::begin_frame(double frame_step) {
 		frame_step = 0.001;
 		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);
 	time_total = Math::fmod(time_total, time_roll_over);
 
 
 	storage->frame.time[0] = time_total;
 	storage->frame.time[0] = time_total;

+ 2 - 2
drivers/gles2/rasterizer_scene_gles2.cpp

@@ -4129,9 +4129,9 @@ void RasterizerSceneGLES2::initialize() {
 }
 }
 
 
 void RasterizerSceneGLES2::iteration() {
 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) {
 	if (directional_shadow_size != directional_shadow_size_new) {
 		directional_shadow_size = directional_shadow_size_new;
 		directional_shadow_size = directional_shadow_size_new;
 		directional_shadow_create();
 		directional_shadow_create();

+ 1 - 1
drivers/gles2/rasterizer_storage_gles2.cpp

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

+ 2 - 2
drivers/gles2/shader_compiler_gles2.cpp

@@ -1225,7 +1225,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	//actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
 	//actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
 	//actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
 	//actions[VS::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) {
 	if (!force_lambert) {
 		actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
 		actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
@@ -1235,7 +1235,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
 	actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
 	actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
 	actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
 	actions[VS::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) {
 	if (!force_blinn) {
 		actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
 		actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";

+ 1 - 1
drivers/gles2/shader_gles2.cpp

@@ -177,7 +177,7 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
 	strings.push_back("#define USE_HIGHP_PRECISION\n");
 	strings.push_back("#define USE_HIGHP_PRECISION\n");
 #endif
 #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
 		// 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
 		// 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");
 		strings.push_back("#ifdef GL_FRAGMENT_PRECISION_HIGH\n  #define USE_HIGHP_PRECISION\n#endif\n");

+ 1 - 1
drivers/gles3/rasterizer_gles3.cpp

@@ -199,7 +199,7 @@ void RasterizerGLES3::begin_frame(double frame_step) {
 		frame_step = 0.001;
 		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);
 	time_total = Math::fmod(time_total, time_roll_over);
 
 
 	storage->frame.time[0] = time_total;
 	storage->frame.time[0] = time_total;

+ 8 - 8
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -5376,22 +5376,22 @@ void RasterizerSceneGLES3::initialize() {
 }
 }
 
 
 void RasterizerSceneGLES3::iteration() {
 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) {
 	if (directional_shadow_size != directional_shadow_size_new) {
 		directional_shadow_size = directional_shadow_size_new;
 		directional_shadow_size = directional_shadow_size_new;
 		directional_shadow_create();
 		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::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() {
 void RasterizerSceneGLES3::finalize() {

+ 1 - 1
drivers/gles3/rasterizer_storage_gles3.cpp

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

+ 2 - 2
drivers/gles3/shader_compiler_gles3.cpp

@@ -1267,7 +1267,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
 	actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
 	actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
 	actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
 	actions[VS::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) {
 	if (!force_lambert) {
 		actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
 		actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
@@ -1277,7 +1277,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
 	actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
 	actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
 	actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
 	actions[VS::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) {
 	if (!force_blinn) {
 		actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
 		actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";

+ 2 - 2
editor/import/resource_importer_texture.cpp

@@ -417,12 +417,12 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
 		tex_flags |= Texture::FLAG_REPEAT;
 		tex_flags |= Texture::FLAG_REPEAT;
 
 
 		const bool min_gles3 = GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3" &&
 		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()) {
 		if (!min_gles3 && !image->is_size_po2()) {
 			// The project can be run using GLES2. GLES2 does not guarantee that
 			// The project can be run using GLES2. GLES2 does not guarantee that
 			// repeating textures with a non-power-of-two size will be displayed
 			// repeating textures with a non-power-of-two size will be displayed
 			// without artifacts (due to upscaling to the nearest power of 2).
 			// 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.",
 				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()));
 						p_source_file, image->get_width(), image->get_height()));
 			} else {
 			} else {

+ 1 - 1
editor/plugins/animation_player_editor_plugin.cpp

@@ -1433,7 +1433,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
 	// Render every past/future step with the capture shader.
 	// Render every past/future step with the capture shader.
 
 
 	VS::get_singleton()->canvas_item_set_material(onion.capture.canvas_item, onion.capture.material->get_rid());
 	VS::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("differences_only", onion.differences_only);
 	onion.capture.material->set_shader_param("present", onion.differences_only ? VS::get_singleton()->viewport_get_texture(present_rid) : RID());
 	onion.capture.material->set_shader_param("present", onion.differences_only ? VS::get_singleton()->viewport_get_texture(present_rid) : RID());
 
 

+ 1 - 1
editor/plugins/canvas_item_editor_plugin.cpp

@@ -4071,7 +4071,7 @@ void CanvasItemEditor::set_current_tool(Tool p_tool) {
 
 
 void CanvasItemEditor::_notification(int p_what) {
 void CanvasItemEditor::_notification(int p_what) {
 	if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
 	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;
 		bool has_container_parents = false;
 		int nb_control = 0;
 		int nb_control = 0;

+ 1 - 1
editor/plugins/editor_preview_plugins.cpp

@@ -867,7 +867,7 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, c
 
 
 	Ref<Font> font = sampled_font;
 	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;
 	const float fg = c.get_luminance() < 0.5 ? 1.0 : 0.0;
 	font->draw(canvas_item, pos, sampled_text, Color(fg, fg, fg));
 	font->draw(canvas_item, pos, sampled_text, Color(fg, fg, fg));
 
 

+ 1 - 1
editor/plugins/script_text_editor.cpp

@@ -590,7 +590,7 @@ void ScriptTextEditor::_validate_script() {
 	warnings_panel->clear();
 	warnings_panel->clear();
 
 
 	// Add missing connections.
 	// 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();
 		Node *base = get_tree()->get_edited_scene_root();
 		if (base && missing_connections.size() > 0) {
 		if (base && missing_connections.size() > 0) {
 			warnings_panel->push_table(1);
 			warnings_panel->push_table(1);

+ 1 - 1
editor/plugins/theme_editor_preview.cpp

@@ -61,7 +61,7 @@ void ThemeEditorPreview::_propagate_redraw(Control *p_at) {
 
 
 void ThemeEditorPreview::_refresh_interval() {
 void ThemeEditorPreview::_refresh_interval() {
 	// In case the project settings have changed.
 	// 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_bg);
 	_propagate_redraw(preview_content);
 	_propagate_redraw(preview_content);

+ 1 - 1
editor/plugins/version_control_editor_plugin.cpp

@@ -86,7 +86,7 @@ void VersionControlEditorPlugin::_bind_methods() {
 void VersionControlEditorPlugin::_notification(int p_what) {
 void VersionControlEditorPlugin::_notification(int p_what) {
 	if (p_what == NOTIFICATION_READY) {
 	if (p_what == NOTIFICATION_READY) {
 		String installed_plugin = GLOBAL_GET("editor/version_control_plugin_name");
 		String installed_plugin = GLOBAL_GET("editor/version_control_plugin_name");
-		bool has_autoload_enable = GLOBAL_GET("editor/version_control_autoload_on_startup");
+		bool has_autoload_enable = GLOBAL_GET_CACHED(bool, "editor/version_control_autoload_on_startup");
 
 
 		if (installed_plugin != "" && has_autoload_enable) {
 		if (installed_plugin != "" && has_autoload_enable) {
 			if (_load_plugin(installed_plugin)) {
 			if (_load_plugin(installed_plugin)) {

+ 1 - 1
main/main.cpp

@@ -2480,7 +2480,7 @@ bool Main::iteration() {
 				if (print_fps) {
 				if (print_fps) {
 					print_line(vformat("Editor FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(2)));
 					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)));
 				print_line(vformat("Project FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(2)));
 			}
 			}
 		} else {
 		} else {

+ 1 - 1
modules/bullet/shape_bullet.cpp

@@ -422,7 +422,7 @@ void ConcavePolygonShapeBullet::setup(PoolVector<Vector3> p_faces) {
 
 
 		meshShape = bulletnew(btBvhTriangleMeshShape(shapeInterface, useQuantizedAabbCompression));
 		meshShape = bulletnew(btBvhTriangleMeshShape(shapeInterface, useQuantizedAabbCompression));
 
 
-		if (GLOBAL_GET("physics/3d/smooth_trimesh_collision")) {
+		if (GLOBAL_GET_CACHED(bool, "physics/3d/smooth_trimesh_collision")) {
 			btTriangleInfoMap *triangleInfoMap = new btTriangleInfoMap();
 			btTriangleInfoMap *triangleInfoMap = new btTriangleInfoMap();
 			btGenerateInternalEdgeInfo(meshShape, triangleInfoMap);
 			btGenerateInternalEdgeInfo(meshShape, triangleInfoMap);
 		}
 		}

+ 1 - 1
modules/fbx/editor_scene_importer_fbx.cpp

@@ -58,7 +58,7 @@
 
 
 void EditorSceneImporterFBX::get_extensions(List<String> *r_extensions) const {
 void EditorSceneImporterFBX::get_extensions(List<String> *r_extensions) const {
 	// register FBX as the one and only format for FBX importing
 	// register FBX as the one and only format for FBX importing
-	if (GLOBAL_GET("filesystem/import/fbx/use_fbx")) {
+	if (GLOBAL_GET_CACHED(bool, "filesystem/import/fbx/use_fbx")) {
 		r_extensions->push_back("fbx");
 		r_extensions->push_back("fbx");
 	}
 	}
 }
 }

+ 1 - 1
modules/gdscript/gdscript_editor.cpp

@@ -2077,7 +2077,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
 
 
 				if (!_static) {
 				if (!_static) {
 					List<MethodInfo> methods;
 					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);
 					ClassDB::get_method_list(type, &methods, false, !is_autocompleting_getters);
 					for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
 					for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
 						if (E->get().name.begins_with("_")) {
 						if (E->get().name.begins_with("_")) {

+ 3 - 3
modules/gdscript/gdscript_parser.cpp

@@ -8680,10 +8680,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) {
 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;
 		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;
 		return;
 	}
 	}
 	String warn_name = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)p_code).to_lower();
 	String warn_name = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)p_code).to_lower();
@@ -8797,7 +8797,7 @@ Error GDScriptParser::_parse(const String &p_base_path) {
 
 
 	// Resolve warning ignores
 	// Resolve warning ignores
 	Vector<Pair<int, String>> warning_skips = tokenizer->get_warning_skips();
 	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;) {
 	for (List<GDScriptWarning>::Element *E = warnings.front(); E;) {
 		GDScriptWarning &w = E->get();
 		GDScriptWarning &w = E->get();
 		int skip_index = -1;
 		int skip_index = -1;

+ 1 - 1
platform/android/export/gradle_export_util.cpp

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

+ 2 - 2
scene/3d/mesh_instance.cpp

@@ -184,12 +184,12 @@ void MeshInstance::_resolve_skeleton_path() {
 
 
 bool MeshInstance::_is_global_software_skinning_enabled() {
 bool MeshInstance::_is_global_software_skinning_enabled() {
 	// Check if forced in project settings.
 	// 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;
 		return true;
 	}
 	}
 
 
 	// Check if enabled in project settings.
 	// 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;
 		return false;
 	}
 	}
 
 

+ 1 - 1
scene/main/scene_tree.cpp

@@ -595,7 +595,7 @@ bool SceneTree::iteration(float p_time) {
 	emit_signal("physics_frame");
 	emit_signal("physics_frame");
 
 
 	_notify_group_pause("physics_process_internal", Node::NOTIFICATION_INTERNAL_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);
 		call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_process_picking", true);
 	}
 	}
 	_notify_group_pause("physics_process", Node::NOTIFICATION_PHYSICS_PROCESS);
 	_notify_group_pause("physics_process", Node::NOTIFICATION_PHYSICS_PROCESS);

+ 4 - 4
scene/main/viewport.cpp

@@ -171,14 +171,14 @@ class TooltipPanel : public PanelContainer {
 	GDCLASS(TooltipPanel, PanelContainer);
 	GDCLASS(TooltipPanel, PanelContainer);
 
 
 public:
 public:
-	TooltipPanel(){};
+	TooltipPanel() {}
 };
 };
 
 
 class TooltipLabel : public Label {
 class TooltipLabel : public Label {
 	GDCLASS(TooltipLabel, Label);
 	GDCLASS(TooltipLabel, Label);
 
 
 public:
 public:
-	TooltipLabel(){};
+	TooltipLabel() {}
 };
 };
 
 
 /////////////////////////////////////
 /////////////////////////////////////
@@ -397,7 +397,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);
 				_process_picking(false);
 			}
 			}
 		} break;
 		} break;
@@ -3005,7 +3005,7 @@ void Viewport::set_disable_input(bool p_disable) {
 	if (p_disable == disable_input) {
 	if (p_disable == disable_input) {
 		return;
 		return;
 	}
 	}
-	if (p_disable && GLOBAL_GET("gui/common/drop_mouse_on_gui_input_disabled")) {
+	if (p_disable && GLOBAL_GET_CACHED(bool, "gui/common/drop_mouse_on_gui_input_disabled")) {
 		_drop_mouse_focus();
 		_drop_mouse_focus();
 		_drop_mouse_over();
 		_drop_mouse_over();
 		_gui_cancel_tooltip();
 		_gui_cancel_tooltip();

+ 1 - 1
scene/resources/material.cpp

@@ -2429,7 +2429,7 @@ Material3D::Material3D(bool p_orm) :
 		flags[i] = false;
 		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;
 	diffuse_mode = DIFFUSE_BURLEY;
 	specular_mode = SPECULAR_SCHLICK_GGX;
 	specular_mode = SPECULAR_SCHLICK_GGX;

+ 1 - 1
servers/audio/audio_stream.cpp

@@ -184,7 +184,7 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
 		return;
 		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.");
 		WARN_PRINT("Need to enable Project settings > Audio > Enable Audio Input option to use capturing.");
 		return;
 		return;
 	}
 	}

+ 1 - 1
servers/visual/portals/portal_occlusion_culler.cpp

@@ -248,7 +248,7 @@ void PortalOcclusionCuller::prepare_generic(PortalRenderer &p_portal_renderer, c
 	// Bodge to keep settings up to date, until the project settings PR is merged
 	// Bodge to keep settings up to date, until the project settings PR is merged
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 	if (Engine::get_singleton()->is_editor_hint() && ((Engine::get_singleton()->get_frames_drawn() % 16) == 0)) {
 	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
 #endif
 	_num_spheres = 0;
 	_num_spheres = 0;

+ 1 - 1
servers/visual/visual_server_viewport.cpp

@@ -281,7 +281,7 @@ void VisualServerViewport::draw_viewports() {
 	}
 	}
 
 
 	if (Engine::get_singleton()->is_editor_hint()) {
 	if (Engine::get_singleton()->is_editor_hint()) {
-		clear_color = GLOBAL_GET("rendering/environment/default_clear_color");
+		clear_color = GLOBAL_GET_CACHED(Color, "rendering/environment/default_clear_color");
 	}
 	}
 
 
 	//sort viewports
 	//sort viewports

+ 4 - 4
servers/visual_server.cpp

@@ -873,7 +873,7 @@ uint32_t VisualServer::mesh_surface_get_format_stride(uint32_t p_format, int p_v
 }
 }
 
 
 void VisualServer::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 {
 void VisualServer::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 & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
+	bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
 
 
 	int attributes_base_offset = 0;
 	int attributes_base_offset = 0;
 	int attributes_stride = 0;
 	int attributes_stride = 0;
@@ -1251,7 +1251,7 @@ bool VisualServer::_mesh_find_format(VS::PrimitiveType p_primitive, const Array
 }
 }
 
 
 uint32_t VisualServer::mesh_find_format_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_compress_format) {
 uint32_t VisualServer::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 & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
+	bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_compress_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
 
 
 	uint32_t offsets[VS::ARRAY_MAX];
 	uint32_t offsets[VS::ARRAY_MAX];
 
 
@@ -1271,7 +1271,7 @@ uint32_t VisualServer::mesh_find_format_from_arrays(PrimitiveType p_primitive, c
 }
 }
 
 
 void VisualServer::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) {
 void VisualServer::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 & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
+	bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_compress_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
 
 
 	uint32_t offsets[VS::ARRAY_MAX];
 	uint32_t offsets[VS::ARRAY_MAX];
 
 
@@ -1341,7 +1341,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim
 }
 }
 
 
 Array VisualServer::_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 {
 Array VisualServer::_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 & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
+	bool use_split_stream = GLOBAL_GET_CACHED(bool, "rendering/misc/mesh_storage/split_stream") && !(p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
 
 
 	uint32_t offsets[ARRAY_MAX];
 	uint32_t offsets[ARRAY_MAX];
 	uint32_t strides[VS::ARRAY_MAX];
 	uint32_t strides[VS::ARRAY_MAX];