summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlawnjelly <lawnjelly@gmail.com>2023-05-17 16:22:26 +0100
committerlawnjelly <lawnjelly@gmail.com>2023-06-06 15:36:51 +0100
commitb69c8b47916e4b3511c1aeff254ebfa6deef37ba (patch)
tree121f1601353f788375749abd834bfb5515afa843
parent543750a1b3f5696f9ba8e91cb49dc7db05d2ae62 (diff)
downloadredot-engine-b69c8b47916e4b3511c1aeff254ebfa6deef37ba.tar.gz
Single Compilation Unit build.
Adds support for simple SCU build (DEV_ENABLED only). This speeds up compilation by compiling multiple cpp files within a single translation unit.
-rw-r--r--SConstruct12
-rw-r--r--editor/SCsub5
-rw-r--r--editor/editor_about.cpp2
-rw-r--r--editor/editor_about.h2
-rw-r--r--editor/editor_inspector.cpp8
-rw-r--r--editor/editor_inspector.h1
-rw-r--r--editor/editor_node.cpp16
-rw-r--r--editor/editor_quick_open.cpp4
-rw-r--r--editor/editor_quick_open.h3
-rw-r--r--editor/editor_scale.cpp12
-rw-r--r--editor/editor_scale.h11
-rw-r--r--editor/plugins/text_editor.cpp2
-rw-r--r--editor/plugins/text_editor.h2
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp4
-rw-r--r--editor/project_manager.cpp16
-rw-r--r--methods.py84
-rw-r--r--scene/animation/animation_tree.cpp2
-rw-r--r--scene/animation/animation_tree.h2
-rw-r--r--scene/gui/graph_node.cpp6
-rw-r--r--scene/gui/graph_node.h6
-rw-r--r--scene/resources/surface_tool.cpp4
-rw-r--r--scene/resources/surface_tool.h3
-rw-r--r--scu_builders.py339
-rw-r--r--servers/physics_3d/godot_joint_3d.h33
-rw-r--r--servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp33
-rw-r--r--servers/physics_3d/joints/godot_hinge_joint_3d.cpp33
-rw-r--r--servers/physics_3d/joints/godot_slider_joint_3d.cpp19
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp2
-rw-r--r--servers/rendering/renderer_canvas_cull.h2
29 files changed, 531 insertions, 137 deletions
diff --git a/SConstruct b/SConstruct
index 4e67fb7117..c383029eff 100644
--- a/SConstruct
+++ b/SConstruct
@@ -55,6 +55,7 @@ _helper_module("modules.modules_builders", "modules/modules_builders.py")
import methods
import glsl_builders
import gles3_builders
+import scu_builders
from platform_methods import architectures, architecture_aliases
if ARGUMENTS.get("target", "editor") == "editor":
@@ -223,6 +224,7 @@ opts.Add(
"",
)
opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
+opts.Add(EnumVariable("scu_build", "Use single compilation unit build", "none", ("none", "dev", "all")))
# Thirdparty libraries
opts.Add(BoolVariable("builtin_certs", "Use the built-in SSL certificates bundles", True))
@@ -428,14 +430,20 @@ if env_base.debug_features:
# to give *users* extra debugging information for their game development.
env_base.Append(CPPDEFINES=["DEBUG_ENABLED"])
+
if env_base.dev_build:
# DEV_ENABLED enables *engine developer* code which should only be compiled for those
# working on the engine itself.
env_base.Append(CPPDEFINES=["DEV_ENABLED"])
+ env_base["use_scu"] = env_base["scu_build"] in ("dev", "all")
else:
# Disable assert() for production targets (only used in thirdparty code).
env_base.Append(CPPDEFINES=["NDEBUG"])
+ # SCU builds currently use a lot of compiler memory
+ # in release builds, so disallow outside of DEV builds unless "all" is set.
+ env_base["use_scu"] = env_base["scu_build"] == "all"
+
# SCons speed optimization controlled by the `fast_unsafe` option, which provide
# more than 10 s speed up for incremental rebuilds.
# Unsafe as they reduce the certainty of rebuilding all changed files, so it's
@@ -550,6 +558,10 @@ if selected_platform in platform_list:
# LTO "auto" means we handle the preferred option in each platform detect.py.
env["lto"] = ARGUMENTS.get("lto", "auto")
+ # Run SCU file generation script if in a SCU build.
+ if env["use_scu"]:
+ methods.set_scu_folders(scu_builders.generate_scu_files(env["verbose"], env_base.dev_build == False))
+
# Must happen after the flags' definition, as configure is when most flags
# are actually handled to change compile options, etc.
detect.configure(env)
diff --git a/editor/SCsub b/editor/SCsub
index 20bfa78c72..b1a47dae45 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -29,9 +29,8 @@ if env.editor_build:
reg_exporters_inc = '#include "register_exporters.h"\n\n'
reg_exporters = "void register_exporters() {\n"
for e in env.platform_exporters:
- # Glob all .cpp files in export folder
- files = Glob("#platform/" + e + "/export/" + "*.cpp")
- env.add_source_files(env.editor_sources, files)
+ # Add all .cpp files in export folder
+ env.add_source_files(env.editor_sources, "../platform/" + e + "/export/" + "*.cpp")
reg_exporters += "\tregister_" + e + "_exporter();\n"
reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n'
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index 25bca2a099..a4147acade 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -36,7 +36,7 @@
#include "core/version.h"
// The metadata key used to store and retrieve the version text to copy to the clipboard.
-static const String META_TEXT_TO_COPY = "text_to_copy";
+const String EditorAbout::META_TEXT_TO_COPY = "text_to_copy";
void EditorAbout::_theme_changed() {
const Ref<Font> font = get_theme_font(SNAME("source"), SNAME("EditorFonts"));
diff --git a/editor/editor_about.h b/editor/editor_about.h
index a49887c260..0bc863e3c1 100644
--- a/editor/editor_about.h
+++ b/editor/editor_about.h
@@ -51,6 +51,8 @@
class EditorAbout : public AcceptDialog {
GDCLASS(EditorAbout, AcceptDialog);
+ static const String META_TEXT_TO_COPY;
+
private:
void _license_tree_selected();
void _version_button_pressed();
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index c138637fc9..3f6db778c5 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -46,14 +46,14 @@
#include "scene/property_utils.h"
#include "scene/resources/packed_scene.h"
-static bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) {
+bool EditorInspector::_property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) {
if (p_property_path.findn(p_filter) != -1) {
return true;
}
- const Vector<String> sections = p_property_path.split("/");
- for (int i = 0; i < sections.size(); i++) {
- if (p_filter.is_subsequence_ofn(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) {
+ const Vector<String> prop_sections = p_property_path.split("/");
+ for (int i = 0; i < prop_sections.size(); i++) {
+ if (p_filter.is_subsequence_ofn(EditorPropertyNameProcessor::get_singleton()->process_name(prop_sections[i], p_style))) {
return true;
}
}
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index 1ce31e59ac..a5737b7dc6 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -512,6 +512,7 @@ class EditorInspector : public ScrollContainer {
void _property_deleted(const String &p_path);
void _property_checked(const String &p_path, bool p_checked);
void _property_pinned(const String &p_path, bool p_pinned);
+ bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style);
void _resource_selected(const String &p_path, Ref<Resource> p_resource);
void _property_selected(const String &p_path, int p_focusable);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 4cf48a41b0..e0863a5e56 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -6760,28 +6760,28 @@ EditorNode::EditorNode() {
switch (display_scale) {
case 0:
// Try applying a suitable display scale automatically.
- editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
+ EditorScale::set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
break;
case 1:
- editor_set_scale(0.75);
+ EditorScale::set_scale(0.75);
break;
case 2:
- editor_set_scale(1.0);
+ EditorScale::set_scale(1.0);
break;
case 3:
- editor_set_scale(1.25);
+ EditorScale::set_scale(1.25);
break;
case 4:
- editor_set_scale(1.5);
+ EditorScale::set_scale(1.5);
break;
case 5:
- editor_set_scale(1.75);
+ EditorScale::set_scale(1.75);
break;
case 6:
- editor_set_scale(2.0);
+ EditorScale::set_scale(2.0);
break;
default:
- editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
+ EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
break;
}
}
diff --git a/editor/editor_quick_open.cpp b/editor/editor_quick_open.cpp
index c7c41a6ed0..f75ab875e4 100644
--- a/editor/editor_quick_open.cpp
+++ b/editor/editor_quick_open.cpp
@@ -34,8 +34,8 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
-static Rect2i prev_rect = Rect2i();
-static bool was_showed = false;
+Rect2i EditorQuickOpen::prev_rect = Rect2i();
+bool EditorQuickOpen::was_showed = false;
void EditorQuickOpen::popup_dialog(const String &p_base, bool p_enable_multi, bool p_dont_clear) {
base_type = p_base;
diff --git a/editor/editor_quick_open.h b/editor/editor_quick_open.h
index 4b63a226c2..2b64efb151 100644
--- a/editor/editor_quick_open.h
+++ b/editor/editor_quick_open.h
@@ -39,6 +39,9 @@
class EditorQuickOpen : public ConfirmationDialog {
GDCLASS(EditorQuickOpen, ConfirmationDialog);
+ static Rect2i prev_rect;
+ static bool was_showed;
+
LineEdit *search_box = nullptr;
Tree *search_options = nullptr;
String base_type;
diff --git a/editor/editor_scale.cpp b/editor/editor_scale.cpp
index 45ea9a4d5b..0670e98e2c 100644
--- a/editor/editor_scale.cpp
+++ b/editor/editor_scale.cpp
@@ -30,14 +30,12 @@
#include "editor_scale.h"
-#include "core/os/os.h"
+float EditorScale::_scale = 1.0f;
-static float scale = 1.0;
-
-void editor_set_scale(float p_scale) {
- scale = p_scale;
+void EditorScale::set_scale(float p_scale) {
+ _scale = p_scale;
}
-float editor_get_scale() {
- return scale;
+float EditorScale::get_scale() {
+ return _scale;
}
diff --git a/editor/editor_scale.h b/editor/editor_scale.h
index 0183625610..b3583fdcee 100644
--- a/editor/editor_scale.h
+++ b/editor/editor_scale.h
@@ -31,9 +31,14 @@
#ifndef EDITOR_SCALE_H
#define EDITOR_SCALE_H
-void editor_set_scale(float p_scale);
-float editor_get_scale();
+class EditorScale {
+ static float _scale;
-#define EDSCALE (editor_get_scale())
+public:
+ static void set_scale(float p_scale);
+ static float get_scale();
+};
+
+#define EDSCALE (EditorScale::get_scale())
#endif // EDITOR_SCALE_H
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 7a76e4f989..92ee468bc2 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -481,7 +481,7 @@ void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
code_editor->convert_case(p_case);
}
-static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) {
+ScriptEditorBase *TextEditor::create_editor(const Ref<Resource> &p_resource) {
if (Object::cast_to<TextFile>(*p_resource) || Object::cast_to<JSON>(*p_resource)) {
return memnew(TextEditor);
}
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index 0c218e9e0c..d1aa2a9047 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -38,6 +38,8 @@
class TextEditor : public ScriptEditorBase {
GDCLASS(TextEditor, ScriptEditorBase);
+ static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource);
+
private:
CodeTextEditor *code_editor = nullptr;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index d631958ce9..8fbbd81e1d 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -4982,7 +4982,7 @@ void VisualShaderEditor::_preview_size_changed() {
preview_vbox->set_custom_minimum_size(preview_window->get_size());
}
-static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) {
+static ShaderLanguage::DataType _visual_shader_editor_get_global_shader_uniform_type(const StringName &p_variable) {
RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(p_variable);
return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt);
}
@@ -5001,7 +5001,7 @@ void VisualShaderEditor::_update_preview() {
info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode()));
info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode()));
info.shader_types = ShaderTypes::get_singleton()->get_types();
- info.global_shader_uniform_type_func = _get_global_shader_uniform_type;
+ info.global_shader_uniform_type_func = _visual_shader_editor_get_global_shader_uniform_type;
ShaderLanguage sl;
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 994fc8c8e9..5380d106d3 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -2763,28 +2763,28 @@ ProjectManager::ProjectManager() {
switch (display_scale) {
case 0:
// Try applying a suitable display scale automatically.
- editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
+ EditorScale::set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
break;
case 1:
- editor_set_scale(0.75);
+ EditorScale::set_scale(0.75);
break;
case 2:
- editor_set_scale(1.0);
+ EditorScale::set_scale(1.0);
break;
case 3:
- editor_set_scale(1.25);
+ EditorScale::set_scale(1.25);
break;
case 4:
- editor_set_scale(1.5);
+ EditorScale::set_scale(1.5);
break;
case 5:
- editor_set_scale(1.75);
+ EditorScale::set_scale(1.75);
break;
case 6:
- editor_set_scale(2.0);
+ EditorScale::set_scale(2.0);
break;
default:
- editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
+ EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
break;
}
EditorFileDialog::get_icon_func = &ProjectManager::_file_dialog_get_icon;
diff --git a/methods.py b/methods.py
index 33ab894f92..2c15c4a43c 100644
--- a/methods.py
+++ b/methods.py
@@ -6,9 +6,23 @@ import subprocess
from collections import OrderedDict
from collections.abc import Mapping
from typing import Iterator
+from pathlib import Path
+from os.path import normpath, basename
+# Get the "Godot" folder name ahead of time
+base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
+base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
+# Listing all the folders we have converted
+# for SCU in scu_builders.py
+_scu_folders = set()
-def add_source_files(self, sources, files):
+
+def set_scu_folders(scu_folders):
+ global _scu_folders
+ _scu_folders = scu_folders
+
+
+def add_source_files_orig(self, sources, files, allow_gen=False):
# Convert string to list of absolute paths (including expanding wildcard)
if isinstance(files, (str, bytes)):
# Keep SCons project-absolute path as they are (no wildcard support)
@@ -23,7 +37,7 @@ def add_source_files(self, sources, files):
skip_gen_cpp = "*" in files
dir_path = self.Dir(".").abspath
files = sorted(glob.glob(dir_path + "/" + files))
- if skip_gen_cpp:
+ if skip_gen_cpp and not allow_gen:
files = [f for f in files if not f.endswith(".gen.cpp")]
# Add each path as compiled Object following environment (self) configuration
@@ -35,6 +49,72 @@ def add_source_files(self, sources, files):
sources.append(obj)
+# The section name is used for checking
+# the hash table to see whether the folder
+# is included in the SCU build.
+# It will be something like "core/math".
+def _find_scu_section_name(subdir):
+ section_path = os.path.abspath(subdir) + "/"
+
+ folders = []
+ folder = ""
+
+ for i in range(8):
+ folder = os.path.dirname(section_path)
+ folder = os.path.basename(folder)
+ if folder == base_folder_only:
+ break
+ folders += [folder]
+ section_path += "../"
+ section_path = os.path.abspath(section_path) + "/"
+
+ section_name = ""
+ for n in range(len(folders)):
+ # section_name += folders[len(folders) - n - 1] + " "
+ section_name += folders[len(folders) - n - 1]
+ if n != (len(folders) - 1):
+ section_name += "/"
+
+ return section_name
+
+
+def add_source_files_scu(self, sources, files, allow_gen=False):
+ if self["use_scu"] and isinstance(files, str):
+ if "*." not in files:
+ return False
+
+ # If the files are in a subdirectory, we want to create the scu gen
+ # files inside this subdirectory.
+ subdir = os.path.dirname(files)
+ if subdir != "":
+ subdir += "/"
+
+ section_name = _find_scu_section_name(subdir)
+ # if the section name is in the hash table?
+ # i.e. is it part of the SCU build?
+ global _scu_folders
+ if section_name not in (_scu_folders):
+ return False
+
+ if self["verbose"]:
+ print("SCU building " + section_name)
+
+ # Add all the gen.cpp files in the SCU directory
+ add_source_files_orig(self, sources, subdir + "scu/scu_*.gen.cpp", True)
+ return True
+ return False
+
+
+# Either builds the folder using the SCU system,
+# or reverts to regular build.
+def add_source_files(self, sources, files, allow_gen=False):
+ if not add_source_files_scu(self, sources, files, allow_gen):
+ # Wraps the original function when scu build is not active.
+ add_source_files_orig(self, sources, files, allow_gen)
+ return False
+ return True
+
+
def disable_warnings(self):
# 'self' is the environment
if self.msvc:
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 3e62dbc1a5..abd66905d1 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -941,7 +941,7 @@ void AnimationTree::_clear_playing_caches() {
playing_caches.clear();
}
-static void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
+void AnimationTree::_call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
// Separate function to use alloca() more efficiently
const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * p_params.size());
const Variant *args = p_params.ptr();
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 0346fc42a7..422bd0abb1 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -194,6 +194,8 @@ class AnimationNodeEndState : public AnimationRootNode {
class AnimationTree : public Node {
GDCLASS(AnimationTree, Node);
+ void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred);
+
public:
enum AnimationProcessCallback {
ANIMATION_PROCESS_PHYSICS,
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 6031730b81..b0517caab0 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -34,12 +34,6 @@
#include "graph_edit.h"
-struct _MinSizeCache {
- int min_size;
- bool will_stretch;
- int final_size;
-};
-
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
String str = p_name;
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index e6ecc3d89b..7ba2e6db94 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -37,6 +37,12 @@
class GraphNode : public Container {
GDCLASS(GraphNode, Container);
+ struct _MinSizeCache {
+ int min_size;
+ bool will_stretch;
+ int final_size;
+ };
+
public:
enum Overlay {
OVERLAY_DISABLED,
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index c296523475..bd41b234f5 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -795,8 +795,8 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, Local
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
}
-static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
-static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
+const uint32_t SurfaceTool::custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
+const uint32_t SurfaceTool::custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
void SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays, LocalVector<SurfaceTool::Vertex> &ret, uint32_t *r_format) {
ret.clear();
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 452aa835f0..eabdff19ca 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -38,6 +38,9 @@
class SurfaceTool : public RefCounted {
GDCLASS(SurfaceTool, RefCounted);
+ static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT];
+ static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT];
+
public:
struct Vertex {
Vector3 vertex;
diff --git a/scu_builders.py b/scu_builders.py
new file mode 100644
index 0000000000..98363929ae
--- /dev/null
+++ b/scu_builders.py
@@ -0,0 +1,339 @@
+"""Functions used to generate scu build source files during build time
+"""
+import glob, os
+import math
+from pathlib import Path
+from os.path import normpath, basename
+
+base_folder_path = str(Path(__file__).parent) + "/"
+base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
+_verbose = False
+_is_release_build = False
+_scu_folders = set()
+
+
+def clear_out_existing_files(output_folder, extension):
+ output_folder = os.path.abspath(output_folder)
+ # print("clear_out_existing_files from folder: " + output_folder)
+
+ if not os.path.isdir(output_folder):
+ # folder does not exist or has not been created yet,
+ # no files to clearout. (this is not an error)
+ return
+
+ for file in glob.glob(output_folder + "/*." + extension):
+ # print("removed pre-existing file: " + file)
+ os.remove(file)
+
+
+def folder_not_found(folder):
+ abs_folder = base_folder_path + folder + "/"
+ return not os.path.isdir(abs_folder)
+
+
+def find_files_in_folder(folder, sub_folder, include_list, extension, sought_exceptions, found_exceptions):
+ abs_folder = base_folder_path + folder + "/" + sub_folder
+
+ if not os.path.isdir(abs_folder):
+ print("ERROR " + abs_folder + " not found.")
+ return include_list, found_exceptions
+
+ os.chdir(abs_folder)
+
+ sub_folder_slashed = ""
+ if sub_folder != "":
+ sub_folder_slashed = sub_folder + "/"
+
+ for file in glob.glob("*." + extension):
+
+ simple_name = Path(file).stem
+
+ if file.endswith(".gen.cpp"):
+ continue
+
+ li = '#include "../' + sub_folder_slashed + file + '"'
+
+ if not simple_name in sought_exceptions:
+ include_list.append(li)
+ else:
+ found_exceptions.append(li)
+
+ return include_list, found_exceptions
+
+
+def write_output_file(file_count, include_list, start_line, end_line, output_folder, output_filename_prefix, extension):
+
+ output_folder = os.path.abspath(output_folder)
+
+ if not os.path.isdir(output_folder):
+ # create
+ os.mkdir(output_folder)
+ if not os.path.isdir(output_folder):
+ print("ERROR " + output_folder + " could not be created.")
+ return
+ print("CREATING folder " + output_folder)
+
+ file_text = ""
+
+ for l in range(start_line, end_line):
+ if l < len(include_list):
+ line = include_list[l]
+ li = line + "\n"
+ file_text += li
+
+ # print(file_text)
+
+ num_string = ""
+ if file_count > 0:
+ num_string = "_" + str(file_count)
+
+ short_filename = output_filename_prefix + num_string + ".gen." + extension
+ output_filename = output_folder + "/" + short_filename
+ if _verbose:
+ print("generating: " + short_filename)
+
+ output_path = Path(output_filename)
+ output_path.write_text(file_text, encoding="utf8")
+
+
+def write_exception_output_file(file_count, exception_string, output_folder, output_filename_prefix, extension):
+ output_folder = os.path.abspath(output_folder)
+ if not os.path.isdir(output_folder):
+ print("ERROR " + output_folder + " does not exist.")
+ return
+
+ file_text = exception_string + "\n"
+
+ num_string = ""
+ if file_count > 0:
+ num_string = "_" + str(file_count)
+
+ short_filename = output_filename_prefix + "_exception" + num_string + ".gen." + extension
+ output_filename = output_folder + "/" + short_filename
+
+ if _verbose:
+ print("generating: " + short_filename)
+
+ # print("text: " + file_text)
+ # return
+ output_path = Path(output_filename)
+ output_path.write_text(file_text, encoding="utf8")
+
+
+def find_section_name(sub_folder):
+ # Construct a useful name for the section from the path for debug logging
+ section_path = os.path.abspath(base_folder_path + sub_folder) + "/"
+
+ folders = []
+ folder = ""
+
+ for i in range(8):
+ folder = os.path.dirname(section_path)
+ folder = os.path.basename(folder)
+ if folder == base_folder_only:
+ break
+ folders.append(folder)
+ section_path += "../"
+ section_path = os.path.abspath(section_path) + "/"
+
+ section_name = ""
+ for n in range(len(folders)):
+ section_name += folders[len(folders) - n - 1]
+ if n != (len(folders) - 1):
+ section_name += "_"
+
+ return section_name
+
+
+# "folders" is a list of folders to add all the files from to add to the SCU
+# "section (like a module)". The name of the scu file will be derived from the first folder
+# (thus e.g. scene/3d becomes scu_scene_3d.gen.cpp)
+
+# "includes_per_scu" limits the number of includes in a single scu file.
+# This allows the module to be built in several translation units instead of just 1.
+# This will usually be slower to compile but will use less memory per compiler instance, which
+# is most relevant in release builds.
+
+# "sought_exceptions" are a list of files (without extension) that contain
+# e.g. naming conflicts, and are therefore not suitable for the scu build.
+# These will automatically be placed in their own separate scu file,
+# which is slow like a normal build, but prevents the naming conflicts.
+# Ideally in these situations, the source code should be changed to prevent naming conflicts.
+
+# "extension" will usually be cpp, but can also be set to c (for e.g. third party libraries that use c)
+def process_folder(folders, sought_exceptions=[], includes_per_scu=0, extension="cpp"):
+ if len(folders) == 0:
+ return
+
+ # Construct the filename prefix from the FIRST folder name
+ # e.g. "scene_3d"
+ out_filename = find_section_name(folders[0])
+
+ found_includes = []
+ found_exceptions = []
+
+ main_folder = folders[0]
+ abs_main_folder = base_folder_path + main_folder
+
+ # Keep a record of all folders that have been processed for SCU,
+ # this enables deciding what to do when we call "add_source_files()"
+ global _scu_folders
+ _scu_folders.add(main_folder)
+
+ # main folder (first)
+ found_includes, found_exceptions = find_files_in_folder(
+ main_folder, "", found_includes, extension, sought_exceptions, found_exceptions
+ )
+
+ # sub folders
+ for d in range(1, len(folders)):
+ found_includes, found_exceptions = find_files_in_folder(
+ main_folder, folders[d], found_includes, extension, sought_exceptions, found_exceptions
+ )
+
+ found_includes = sorted(found_includes)
+
+ # calculate how many lines to write in each file
+ total_lines = len(found_includes)
+
+ # adjust number of output files according to whether DEV or release
+ num_output_files = 1
+ if _is_release_build:
+ # always have a maximum in release
+ includes_per_scu = 8
+ num_output_files = max(math.ceil(total_lines / float(includes_per_scu)), 1)
+ else:
+ if includes_per_scu > 0:
+ num_output_files = max(math.ceil(total_lines / float(includes_per_scu)), 1)
+
+ lines_per_file = math.ceil(total_lines / float(num_output_files))
+ lines_per_file = max(lines_per_file, 1)
+
+ start_line = 0
+ file_number = 0
+
+ # These do not vary throughout the loop
+ output_folder = abs_main_folder + "/scu/"
+ output_filename_prefix = "scu_" + out_filename
+
+ # Clear out any existing files (usually we will be overwriting,
+ # but we want to remove any that are pre-existing that will not be
+ # overwritten, so as to not compile anything stale)
+ clear_out_existing_files(output_folder, extension)
+
+ for file_count in range(0, num_output_files):
+ end_line = start_line + lines_per_file
+
+ # special case to cover rounding error in final file
+ if file_count == (num_output_files - 1):
+ end_line = len(found_includes)
+
+ write_output_file(
+ file_count, found_includes, start_line, end_line, output_folder, output_filename_prefix, extension
+ )
+
+ start_line = end_line
+
+ # Write the exceptions each in their own scu gen file,
+ # so they can effectively compile in "old style / normal build".
+ for exception_count in range(len(found_exceptions)):
+ write_exception_output_file(
+ exception_count, found_exceptions[exception_count], output_folder, output_filename_prefix, extension
+ )
+
+
+def generate_scu_files(verbose, is_release_build):
+
+ print("=============================")
+ print("Single Compilation Unit Build")
+ print("=============================")
+ print("Generating SCU build files")
+ global _verbose
+ _verbose = verbose
+ global _is_release_build
+ _is_release_build = is_release_build
+
+ curr_folder = os.path.abspath("./")
+
+ # check we are running from the correct folder
+ if folder_not_found("core") or folder_not_found("platform") or folder_not_found("scene"):
+ raise RuntimeError("scu_builders.py must be run from the godot folder.")
+ return
+
+ process_folder(["core"])
+ process_folder(["core/crypto"])
+ process_folder(["core/debugger"])
+ process_folder(["core/extension"])
+ process_folder(["core/input"])
+ process_folder(["core/io"])
+ process_folder(["core/math"])
+ process_folder(["core/object"])
+ process_folder(["core/os"])
+ process_folder(["core/string"])
+ process_folder(["core/variant"], ["variant_utility"])
+
+ process_folder(["drivers/unix"])
+ process_folder(["drivers/png"])
+
+ process_folder(["editor"], ["file_system_dock", "editor_resource_preview"], 32)
+ process_folder(["editor/debugger"])
+ process_folder(["editor/debugger/debug_adapter"])
+ process_folder(["editor/export"])
+ process_folder(["editor/gui"])
+ process_folder(["editor/import"])
+ process_folder(["editor/plugins"])
+ process_folder(["editor/plugins/gizmos"])
+ process_folder(["editor/plugins/tiles"])
+
+ process_folder(["platform/android/export"])
+ process_folder(["platform/ios/export"])
+ process_folder(["platform/linuxbsd/export"])
+ process_folder(["platform/macos/export"])
+ process_folder(["platform/uwp/export"])
+ process_folder(["platform/web/export"])
+ process_folder(["platform/windows/export"])
+
+ process_folder(["modules/gltf"])
+ process_folder(["modules/gltf/structures"])
+ process_folder(["modules/gltf/editor"])
+ process_folder(["modules/gltf/extensions"])
+ process_folder(["modules/gltf/extensions/physics"])
+ process_folder(["modules/navigation"])
+ process_folder(["modules/webrtc"])
+ process_folder(["modules/websocket"])
+ process_folder(["modules/gridmap"])
+ process_folder(["modules/multiplayer"])
+ process_folder(["modules/multiplayer/editor"])
+ process_folder(["modules/openxr"], ["register_types"])
+ process_folder(["modules/openxr/action_map"])
+ process_folder(["modules/openxr/editor"])
+
+ process_folder(["modules/csg"])
+ process_folder(["modules/gdscript"])
+ process_folder(["modules/gdscript/editor"])
+ process_folder(["modules/gdscript/language_server"])
+
+ process_folder(["scene/2d"])
+ process_folder(["scene/3d"])
+ process_folder(["scene/animation"])
+ process_folder(["scene/gui"])
+ process_folder(["scene/main"])
+ process_folder(["scene/resources"])
+
+ process_folder(["servers"])
+ process_folder(["servers/rendering"])
+ process_folder(["servers/rendering/storage"])
+ process_folder(["servers/rendering/renderer_rd"])
+ process_folder(["servers/rendering/renderer_rd/effects"])
+ process_folder(["servers/rendering/renderer_rd/environment"])
+ process_folder(["servers/rendering/renderer_rd/storage_rd"])
+ process_folder(["servers/physics_2d"])
+ process_folder(["servers/physics_3d"])
+ process_folder(["servers/physics_3d/joints"])
+ process_folder(["servers/audio"])
+ process_folder(["servers/audio/effects"])
+
+ # Finally change back the path to the calling folder
+ os.chdir(curr_folder)
+
+ return _scu_folders
diff --git a/servers/physics_3d/godot_joint_3d.h b/servers/physics_3d/godot_joint_3d.h
index 438970e2c9..3207723cb4 100644
--- a/servers/physics_3d/godot_joint_3d.h
+++ b/servers/physics_3d/godot_joint_3d.h
@@ -39,6 +39,39 @@ protected:
bool dynamic_A = false;
bool dynamic_B = false;
+ void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
+ if (Math::abs(n.z) > Math_SQRT12) {
+ // choose p in y-z plane
+ real_t a = n[1] * n[1] + n[2] * n[2];
+ real_t k = 1.0 / Math::sqrt(a);
+ p = Vector3(0, -n[2] * k, n[1] * k);
+ // set q = n x p
+ q = Vector3(a * k, -n[0] * p[2], n[0] * p[1]);
+ } else {
+ // choose p in x-y plane
+ real_t a = n.x * n.x + n.y * n.y;
+ real_t k = 1.0 / Math::sqrt(a);
+ p = Vector3(-n.y * k, n.x * k, 0);
+ // set q = n x p
+ q = Vector3(-n.z * p.y, n.z * p.x, a * k);
+ }
+ }
+
+ _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
+ real_t coeff_1 = Math_PI / 4.0f;
+ real_t coeff_2 = 3.0f * coeff_1;
+ real_t abs_y = Math::abs(y);
+ real_t angle;
+ if (x >= 0.0f) {
+ real_t r = (x - abs_y) / (x + abs_y);
+ angle = coeff_1 - coeff_1 * r;
+ } else {
+ real_t r = (x + abs_y) / (abs_y - x);
+ angle = coeff_2 - coeff_1 * r;
+ }
+ return (y < 0.0f) ? -angle : angle;
+ }
+
public:
virtual bool setup(real_t p_step) override { return false; }
virtual bool pre_solve(real_t p_step) override { return true; }
diff --git a/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp b/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp
index 72d6e33c68..c654756d3c 100644
--- a/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp
+++ b/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp
@@ -51,39 +51,6 @@ Written by: Marcus Hennix
#include "godot_cone_twist_joint_3d.h"
-static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
- if (Math::abs(n.z) > Math_SQRT12) {
- // choose p in y-z plane
- real_t a = n[1] * n[1] + n[2] * n[2];
- real_t k = 1.0 / Math::sqrt(a);
- p = Vector3(0, -n[2] * k, n[1] * k);
- // set q = n x p
- q = Vector3(a * k, -n[0] * p[2], n[0] * p[1]);
- } else {
- // choose p in x-y plane
- real_t a = n.x * n.x + n.y * n.y;
- real_t k = 1.0 / Math::sqrt(a);
- p = Vector3(-n.y * k, n.x * k, 0);
- // set q = n x p
- q = Vector3(-n.z * p.y, n.z * p.x, a * k);
- }
-}
-
-static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
- real_t coeff_1 = Math_PI / 4.0f;
- real_t coeff_2 = 3.0f * coeff_1;
- real_t abs_y = Math::abs(y);
- real_t angle;
- if (x >= 0.0f) {
- real_t r = (x - abs_y) / (x + abs_y);
- angle = coeff_1 - coeff_1 * r;
- } else {
- real_t r = (x + abs_y) / (abs_y - x);
- angle = coeff_2 - coeff_1 * r;
- }
- return (y < 0.0f) ? -angle : angle;
-}
-
GodotConeTwistJoint3D::GodotConeTwistJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) :
GodotJoint3D(_arr, 2) {
A = rbA;
diff --git a/servers/physics_3d/joints/godot_hinge_joint_3d.cpp b/servers/physics_3d/joints/godot_hinge_joint_3d.cpp
index 826401bafb..3d423f70e2 100644
--- a/servers/physics_3d/joints/godot_hinge_joint_3d.cpp
+++ b/servers/physics_3d/joints/godot_hinge_joint_3d.cpp
@@ -49,24 +49,6 @@ subject to the following restrictions:
#include "godot_hinge_joint_3d.h"
-static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
- if (Math::abs(n.z) > Math_SQRT12) {
- // choose p in y-z plane
- real_t a = n[1] * n[1] + n[2] * n[2];
- real_t k = 1.0 / Math::sqrt(a);
- p = Vector3(0, -n[2] * k, n[1] * k);
- // set q = n x p
- q = Vector3(a * k, -n[0] * p[2], n[0] * p[1]);
- } else {
- // choose p in x-y plane
- real_t a = n.x * n.x + n.y * n.y;
- real_t k = 1.0 / Math::sqrt(a);
- p = Vector3(-n.y * k, n.x * k, 0);
- // set q = n x p
- q = Vector3(-n.z * p.y, n.z * p.x, a * k);
- }
-}
-
GodotHingeJoint3D::GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameA, const Transform3D &frameB) :
GodotJoint3D(_arr, 2) {
A = rbA;
@@ -368,21 +350,6 @@ void HingeJointSW::updateRHS(real_t timeStep)
*/
-static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
- real_t coeff_1 = Math_PI / 4.0f;
- real_t coeff_2 = 3.0f * coeff_1;
- real_t abs_y = Math::abs(y);
- real_t angle;
- if (x >= 0.0f) {
- real_t r = (x - abs_y) / (x + abs_y);
- angle = coeff_1 - coeff_1 * r;
- } else {
- real_t r = (x + abs_y) / (abs_y - x);
- angle = coeff_2 - coeff_1 * r;
- }
- return (y < 0.0f) ? -angle : angle;
-}
-
real_t GodotHingeJoint3D::get_hinge_angle() {
const Vector3 refAxis0 = A->get_transform().basis.xform(m_rbAFrame.basis.get_column(0));
const Vector3 refAxis1 = A->get_transform().basis.xform(m_rbAFrame.basis.get_column(1));
diff --git a/servers/physics_3d/joints/godot_slider_joint_3d.cpp b/servers/physics_3d/joints/godot_slider_joint_3d.cpp
index 21004b3395..b9dca94b37 100644
--- a/servers/physics_3d/joints/godot_slider_joint_3d.cpp
+++ b/servers/physics_3d/joints/godot_slider_joint_3d.cpp
@@ -57,25 +57,6 @@ April 04, 2008
//-----------------------------------------------------------------------------
-static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
- real_t coeff_1 = Math_PI / 4.0f;
- real_t coeff_2 = 3.0f * coeff_1;
- real_t abs_y = Math::abs(y);
- real_t angle;
- if (x >= 0.0f) {
- real_t r = (x - abs_y) / (x + abs_y);
- angle = coeff_1 - coeff_1 * r;
- } else {
- real_t r = (x + abs_y) / (abs_y - x);
- angle = coeff_2 - coeff_1 * r;
- }
- return (y < 0.0f) ? -angle : angle;
-}
-
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-
GodotSliderJoint3D::GodotSliderJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameInA, const Transform3D &frameInB) :
GodotJoint3D(_arr, 2),
m_frameInA(frameInA),
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index 097580f3bd..011f0327c9 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -36,8 +36,6 @@
#include "rendering_server_globals.h"
#include "servers/rendering/storage/texture_storage.h"
-static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
-
void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask) {
RENDER_TIMESTAMP("Cull CanvasItem Tree");
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index 1106fc4f1e..4f11d2c7b1 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -183,6 +183,8 @@ private:
void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask);
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort, uint32_t canvas_cull_mask);
+ static constexpr int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
+
RendererCanvasRender::Item **z_list;
RendererCanvasRender::Item **z_last_list;