summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/static_checks.yml4
-rw-r--r--core/doc_data.cpp2
-rw-r--r--core/doc_data.h25
-rw-r--r--core/input/input.cpp2
-rw-r--r--core/io/ip.cpp2
-rw-r--r--core/io/ip.h1
-rw-r--r--core/io/xml_parser.cpp2
-rw-r--r--core/io/xml_parser.h2
-rw-r--r--core/os/time.cpp3
-rw-r--r--core/os/time.h3
-rw-r--r--doc/class.xsd9
-rw-r--r--doc/classes/ArrayMesh.xml4
-rw-r--r--doc/classes/BaseButton.xml2
-rw-r--r--doc/classes/Callable.xml11
-rw-r--r--doc/classes/CanvasItem.xml12
-rw-r--r--doc/classes/Control.xml4
-rw-r--r--doc/classes/DisplayServer.xml9
-rw-r--r--doc/classes/EditorInspectorPlugin.xml2
-rw-r--r--doc/classes/EditorSpinSlider.xml2
-rw-r--r--doc/classes/Font.xml20
-rw-r--r--doc/classes/FontFile.xml2
-rw-r--r--doc/classes/ImageFormatLoaderExtension.xml2
-rw-r--r--doc/classes/Input.xml2
-rw-r--r--doc/classes/InputEventMouse.xml2
-rw-r--r--doc/classes/InputEventWithModifiers.xml2
-rw-r--r--doc/classes/Label.xml4
-rw-r--r--doc/classes/Label3D.xml2
-rw-r--r--doc/classes/NavigationAgent2D.xml2
-rw-r--r--doc/classes/NavigationAgent3D.xml2
-rw-r--r--doc/classes/NavigationPathQueryParameters2D.xml2
-rw-r--r--doc/classes/NavigationPathQueryParameters3D.xml2
-rw-r--r--doc/classes/NavigationServer2D.xml2
-rw-r--r--doc/classes/NavigationServer3D.xml2
-rw-r--r--doc/classes/Node.xml8
-rw-r--r--doc/classes/RDTextureFormat.xml2
-rw-r--r--doc/classes/Range.xml2
-rw-r--r--doc/classes/RenderingDevice.xml26
-rw-r--r--doc/classes/RenderingServer.xml18
-rw-r--r--doc/classes/ResourceSaver.xml2
-rw-r--r--doc/classes/RichTextLabel.xml2
-rw-r--r--doc/classes/SpinBox.xml2
-rw-r--r--doc/classes/TextLine.xml2
-rw-r--r--doc/classes/TextMesh.xml2
-rw-r--r--doc/classes/TextParagraph.xml4
-rw-r--r--doc/classes/TextServer.xml14
-rw-r--r--doc/classes/TextServerExtension.xml14
-rw-r--r--doc/classes/TextureProgressBar.xml2
-rw-r--r--doc/classes/VScrollBar.xml4
-rw-r--r--doc/classes/VSlider.xml4
-rwxr-xr-xdoc/tools/make_rst.py23
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp59
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp122
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h1
-rw-r--r--drivers/gles3/storage/light_storage.cpp100
-rw-r--r--drivers/gles3/storage/mesh_storage.cpp46
-rw-r--r--drivers/gles3/storage/particles_storage.cpp44
-rw-r--r--drivers/gles3/storage/texture_storage.cpp76
-rw-r--r--drivers/gles3/storage/texture_storage.h4
-rw-r--r--drivers/gles3/storage/utilities.cpp38
-rw-r--r--drivers/gles3/storage/utilities.h64
-rw-r--r--editor/doc_tools.cpp25
-rw-r--r--editor/editor_help.cpp24
-rw-r--r--editor/editor_help.h2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp2
-rw-r--r--editor/project_converter_3_to_4.cpp2
-rw-r--r--main/main.cpp10
-rwxr-xr-xmisc/scripts/codespell.sh2
-rw-r--r--platform/android/display_server_android.cpp4
-rw-r--r--platform/android/display_server_android.h1
-rw-r--r--platform/ios/display_server_ios.h1
-rw-r--r--platform/ios/display_server_ios.mm4
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp9
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h1
-rw-r--r--platform/macos/display_server_macos.h2
-rw-r--r--platform/macos/display_server_macos.mm9
-rw-r--r--platform/macos/godot_window_delegate.mm11
-rw-r--r--platform/web/display_server_web.cpp4
-rw-r--r--platform/web/display_server_web.h1
-rw-r--r--platform/windows/display_server_windows.cpp9
-rw-r--r--platform/windows/display_server_windows.h1
-rw-r--r--scene/2d/line_2d.cpp5
-rw-r--r--scene/2d/line_2d.h5
-rw-r--r--scene/2d/navigation_agent_2d.h2
-rw-r--r--scene/3d/navigation_agent_3d.h2
-rw-r--r--scene/main/node.cpp11
-rw-r--r--scene/main/node.h4
-rw-r--r--scene/main/scene_tree.h4
-rw-r--r--scene/main/window.cpp8
-rw-r--r--servers/display_server.cpp1
-rw-r--r--servers/display_server.h1
-rw-r--r--servers/display_server_headless.h1
-rw-r--r--servers/navigation_server_2d.h2
-rw-r--r--servers/navigation_server_3d.h2
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp4
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp4
-rw-r--r--servers/rendering/renderer_viewport.cpp2
-rw-r--r--servers/rendering/renderer_viewport.h2
-rw-r--r--servers/rendering/rendering_server_default.cpp2
-rw-r--r--tests/scene/test_code_edit.h6
99 files changed, 629 insertions, 397 deletions
diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml
index f35206ab57..c6ec244b7d 100644
--- a/.github/workflows/static_checks.yml
+++ b/.github/workflows/static_checks.yml
@@ -103,8 +103,8 @@ jobs:
- name: Spell checks via codespell
if: github.event_name == 'pull_request' && env.CHANGED_FILES != ''
- uses: codespell-project/actions-codespell@v1
+ uses: codespell-project/actions-codespell@v2
with:
skip: "./bin,./thirdparty,*.desktop,*.gen.*,*.po,*.pot,*.rc,./AUTHORS.md,./COPYRIGHT.txt,./DONORS.md,./core/input/gamecontrollerdb.txt,./core/string/locales.h,./editor/project_converter_3_to_4.cpp,./misc/scripts/codespell.sh,./platform/android/java/lib/src/com,./platform/web/node_modules,./platform/web/package-lock.json"
- ignore_words_list: "curvelinear,doubleclick,expct,findn,gird,hel,inout,lod,nd,numer,ot,te,vai"
+ ignore_words_list: "curvelinear,doubleclick,expct,findn,gird,hel,inout,lod,mis,nd,numer,ot,requestor,te,vai"
path: ${{ env.CHANGED_FILES }}
diff --git a/core/doc_data.cpp b/core/doc_data.cpp
index 2d909f5335..7549ba884e 100644
--- a/core/doc_data.cpp
+++ b/core/doc_data.cpp
@@ -51,6 +51,7 @@ void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const Proper
if (p_method.return_enum.begins_with("_")) { //proxy class
p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length());
}
+ p_method.return_is_bitfield = p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD;
p_method.return_type = "int";
} else if (p_retinfo.class_name != StringName()) {
p_method.return_type = p_retinfo.class_name;
@@ -82,6 +83,7 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const
if (p_argument.enumeration.begins_with("_")) { //proxy class
p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length());
}
+ p_argument.is_bitfield = p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD;
p_argument.type = "int";
} else if (p_arginfo.class_name != StringName()) {
p_argument.type = p_arginfo.class_name;
diff --git a/core/doc_data.h b/core/doc_data.h
index fc184c411c..0fe7414b98 100644
--- a/core/doc_data.h
+++ b/core/doc_data.h
@@ -50,6 +50,7 @@ public:
String name;
String type;
String enumeration;
+ bool is_bitfield = false;
String default_value;
bool operator<(const ArgumentDoc &p_arg) const {
if (name == p_arg.name) {
@@ -70,6 +71,9 @@ public:
if (p_dict.has("enumeration")) {
doc.enumeration = p_dict["enumeration"];
+ if (p_dict.has("is_bitfield")) {
+ doc.is_bitfield = p_dict["is_bitfield"];
+ }
}
if (p_dict.has("default_value")) {
@@ -91,6 +95,7 @@ public:
if (!p_doc.enumeration.is_empty()) {
dict["enumeration"] = p_doc.enumeration;
+ dict["is_bitfield"] = p_doc.is_bitfield;
}
if (!p_doc.default_value.is_empty()) {
@@ -105,6 +110,7 @@ public:
String name;
String return_type;
String return_enum;
+ bool return_is_bitfield = false;
String qualifiers;
String description;
bool is_deprecated = false;
@@ -152,6 +158,9 @@ public:
if (p_dict.has("return_enum")) {
doc.return_enum = p_dict["return_enum"];
+ if (p_dict.has("return_is_bitfield")) {
+ doc.return_is_bitfield = p_dict["return_is_bitfield"];
+ }
}
if (p_dict.has("qualifiers")) {
@@ -201,6 +210,7 @@ public:
if (!p_doc.return_enum.is_empty()) {
dict["return_enum"] = p_doc.return_enum;
+ dict["return_is_bitfield"] = p_doc.return_is_bitfield;
}
if (!p_doc.qualifiers.is_empty()) {
@@ -264,10 +274,9 @@ public:
if (p_dict.has("enumeration")) {
doc.enumeration = p_dict["enumeration"];
- }
-
- if (p_dict.has("is_bitfield")) {
- doc.is_bitfield = p_dict["is_bitfield"];
+ if (p_dict.has("is_bitfield")) {
+ doc.is_bitfield = p_dict["is_bitfield"];
+ }
}
if (p_dict.has("description")) {
@@ -299,10 +308,9 @@ public:
if (!p_doc.enumeration.is_empty()) {
dict["enumeration"] = p_doc.enumeration;
+ dict["is_bitfield"] = p_doc.is_bitfield;
}
- dict["is_bitfield"] = p_doc.is_bitfield;
-
if (!p_doc.description.is_empty()) {
dict["description"] = p_doc.description;
}
@@ -319,6 +327,7 @@ public:
String name;
String type;
String enumeration;
+ bool is_bitfield = false;
String description;
String setter, getter;
String default_value;
@@ -342,6 +351,9 @@ public:
if (p_dict.has("enumeration")) {
doc.enumeration = p_dict["enumeration"];
+ if (p_dict.has("is_bitfield")) {
+ doc.is_bitfield = p_dict["is_bitfield"];
+ }
}
if (p_dict.has("description")) {
@@ -391,6 +403,7 @@ public:
if (!p_doc.enumeration.is_empty()) {
dict["enumeration"] = p_doc.enumeration;
+ dict["is_bitfield"] = p_doc.is_bitfield;
}
if (!p_doc.description.is_empty()) {
diff --git a/core/input/input.cpp b/core/input/input.cpp
index b4945b41a8..cf8d71b9a7 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -1544,7 +1544,7 @@ Input::Input() {
legacy_just_pressed_behavior = GLOBAL_DEF("input_devices/compatibility/legacy_just_pressed_behavior", false);
if (Engine::get_singleton()->is_editor_hint()) {
- // Always use standard behaviour in the editor.
+ // Always use standard behavior in the editor.
legacy_just_pressed_behavior = false;
}
}
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 65728f34f6..772f700916 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -35,8 +35,6 @@
#include "core/templates/hash_map.h"
#include "core/variant/typed_array.h"
-VARIANT_ENUM_CAST(IP::ResolverStatus);
-
/************* RESOLVER ******************/
struct _IP_ResolverPrivate {
diff --git a/core/io/ip.h b/core/io/ip.h
index b768f0b9d4..4816d59ac2 100644
--- a/core/io/ip.h
+++ b/core/io/ip.h
@@ -109,5 +109,6 @@ public:
};
VARIANT_ENUM_CAST(IP::Type);
+VARIANT_ENUM_CAST(IP::ResolverStatus);
#endif // IP_H
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index 5c0a017bfc..958734addf 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -34,8 +34,6 @@
//#define DEBUG_XML
-VARIANT_ENUM_CAST(XMLParser::NodeType);
-
static inline bool _is_white_space(char c) {
return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
}
diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h
index b96478c7a5..77df99a881 100644
--- a/core/io/xml_parser.h
+++ b/core/io/xml_parser.h
@@ -126,4 +126,6 @@ public:
~XMLParser();
};
+VARIANT_ENUM_CAST(XMLParser::NodeType);
+
#endif // XML_PARSER_H
diff --git a/core/os/time.cpp b/core/os/time.cpp
index 038e4adc03..bad5cc2e4f 100644
--- a/core/os/time.cpp
+++ b/core/os/time.cpp
@@ -52,9 +52,6 @@ static const uint8_t MONTH_DAYS_TABLE[2][12] = {
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
-VARIANT_ENUM_CAST(Month);
-VARIANT_ENUM_CAST(Weekday);
-
#define UNIX_TIME_TO_HMS \
uint8_t hour, minute, second; \
{ \
diff --git a/core/os/time.h b/core/os/time.h
index 19bc900aee..ccd2d92b8b 100644
--- a/core/os/time.h
+++ b/core/os/time.h
@@ -81,4 +81,7 @@ public:
virtual ~Time();
};
+VARIANT_ENUM_CAST(Month);
+VARIANT_ENUM_CAST(Weekday);
+
#endif // TIME_H
diff --git a/doc/class.xsd b/doc/class.xsd
index d29d053006..83880ed5f9 100644
--- a/doc/class.xsd
+++ b/doc/class.xsd
@@ -33,6 +33,7 @@
</xs:sequence>
<xs:attribute type="xs:string" name="type" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
</xs:complexType>
</xs:element>
<xs:element name="param" maxOccurs="unbounded" minOccurs="0">
@@ -44,6 +45,7 @@
<xs:attribute type="xs:string" name="name" />
<xs:attribute type="xs:string" name="type" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
<xs:attribute type="xs:string" name="default" use="optional" />
</xs:complexType>
</xs:element>
@@ -69,6 +71,7 @@
</xs:sequence>
<xs:attribute type="xs:string" name="type" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
</xs:complexType>
</xs:element>
<xs:element name="returns_error" maxOccurs="unbounded" minOccurs="0">
@@ -88,6 +91,7 @@
<xs:attribute type="xs:string" name="name" />
<xs:attribute type="xs:string" name="type" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
<xs:attribute type="xs:string" name="default" use="optional" />
</xs:complexType>
</xs:element>
@@ -115,6 +119,7 @@
<xs:attribute type="xs:string" name="getter" />
<xs:attribute type="xs:string" name="overrides" use="optional" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
<xs:attribute type="xs:string" name="default" use="optional" />
<xs:attribute type="xs:boolean" name="is_deprecated" use="optional" />
<xs:attribute type="xs:boolean" name="is_experimental" use="optional" />
@@ -182,6 +187,7 @@
</xs:sequence>
<xs:attribute type="xs:string" name="type" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
</xs:complexType>
</xs:element>
<xs:element name="param" maxOccurs="unbounded" minOccurs="0">
@@ -193,6 +199,7 @@
<xs:attribute type="xs:string" name="name" />
<xs:attribute type="xs:string" name="type" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
<xs:attribute type="xs:string" name="default" use="optional" />
</xs:complexType>
</xs:element>
@@ -236,6 +243,7 @@
</xs:sequence>
<xs:attribute type="xs:string" name="type" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
</xs:complexType>
</xs:element>
<xs:element name="param" maxOccurs="unbounded" minOccurs="0">
@@ -247,6 +255,7 @@
<xs:attribute type="xs:string" name="name" />
<xs:attribute type="xs:string" name="type" />
<xs:attribute type="xs:string" name="enum" use="optional" />
+ <xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
<xs:attribute type="xs:string" name="default" use="optional" />
</xs:complexType>
</xs:element>
diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml
index 91b333ae89..6d2b05e729 100644
--- a/doc/classes/ArrayMesh.xml
+++ b/doc/classes/ArrayMesh.xml
@@ -65,7 +65,7 @@
<param index="1" name="arrays" type="Array" />
<param index="2" name="blend_shapes" type="Array[]" default="[]" />
<param index="3" name="lods" type="Dictionary" default="{}" />
- <param index="4" name="flags" type="int" enum="Mesh.ArrayFormat" default="0" />
+ <param index="4" name="flags" type="int" enum="Mesh.ArrayFormat" is_bitfield="true" default="0" />
<description>
Creates a new surface. [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface.
Surfaces are created to be rendered using a [param primitive], which may be any of the values defined in [enum Mesh.PrimitiveType].
@@ -145,7 +145,7 @@
</description>
</method>
<method name="surface_get_format" qualifiers="const">
- <return type="int" enum="Mesh.ArrayFormat" />
+ <return type="int" enum="Mesh.ArrayFormat" is_bitfield="true" />
<param index="0" name="surf_idx" type="int" />
<description>
Returns the format mask of the requested surface (see [method add_surface_from_arrays]).
diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml
index 1290bfc0f2..cc95c97e68 100644
--- a/doc/classes/BaseButton.xml
+++ b/doc/classes/BaseButton.xml
@@ -51,7 +51,7 @@
The [ButtonGroup] associated with the button. Not to be confused with node groups.
[b]Note:[/b] The button will be configured as a radio button if a [ButtonGroup] is assigned to it.
</member>
- <member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" enum="MouseButtonMask" default="1">
+ <member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" enum="MouseButtonMask" is_bitfield="true" default="1">
Binary mask to choose which mouse buttons this button will respond to.
To allow both left-click and right-click, use [code]MOUSE_BUTTON_MASK_LEFT | MOUSE_BUTTON_MASK_RIGHT[/code].
</member>
diff --git a/doc/classes/Callable.xml b/doc/classes/Callable.xml
index 87f1f0b538..5eea774cf4 100644
--- a/doc/classes/Callable.xml
+++ b/doc/classes/Callable.xml
@@ -46,6 +46,17 @@
# Prints "Attack!", when the button_pressed signal is emitted.
button_pressed.connect(func(): print("Attack!"))
[/codeblock]
+ [b]Note:[/b] Methods of native types such as [Signal], [Array], or [Dictionary] are not of type [Callable] in order to avoid unnecessary overhead. If you need to pass those methods as [Callable], use a lambda function as a wrapper.
+ [codeblock]
+ func _init():
+ var my_dictionary = { "hello": "world" }
+
+ # This will not work, `clear` is not a callable.
+ create_tween().tween_callback(my_dictionary.clear)
+
+ # This will work, as lambdas are custom callables.
+ create_tween().tween_callback(func(): my_dictionary.clear())
+ [/codeblock]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index cb10367183..ba280ab0fa 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -193,8 +193,8 @@
<param index="5" name="font_size" type="int" default="16" />
<param index="6" name="max_lines" type="int" default="-1" />
<param index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <param index="8" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
- <param index="9" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="8" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" is_bitfield="true" default="3" />
+ <param index="9" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="10" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="11" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
@@ -212,8 +212,8 @@
<param index="6" name="max_lines" type="int" default="-1" />
<param index="7" name="size" type="int" default="1" />
<param index="8" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <param index="9" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
- <param index="10" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="9" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" is_bitfield="true" default="3" />
+ <param index="10" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="11" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="12" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
@@ -309,7 +309,7 @@
<param index="4" name="width" type="float" default="-1" />
<param index="5" name="font_size" type="int" default="16" />
<param index="6" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <param index="7" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="7" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="8" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="9" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
@@ -346,7 +346,7 @@
<param index="5" name="font_size" type="int" default="16" />
<param index="6" name="size" type="int" default="1" />
<param index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <param index="8" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="8" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="9" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="10" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index e0dd0eb9a8..e20651b1ee 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -1028,13 +1028,13 @@
<member name="size" type="Vector2" setter="_set_size" getter="get_size" default="Vector2(0, 0)">
The size of the node's bounding rectangle, in the node's coordinate system. [Container] nodes update this property automatically.
</member>
- <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" enum="Control.SizeFlags" default="1">
+ <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" enum="Control.SizeFlags" is_bitfield="true" default="1">
Tells the parent [Container] nodes how they should resize and place the node on the X axis. Use a combination of the [enum SizeFlags] constants to change the flags. See the constants to learn what each does.
</member>
<member name="size_flags_stretch_ratio" type="float" setter="set_stretch_ratio" getter="get_stretch_ratio" default="1.0">
If the node and at least one of its neighbors uses the [constant SIZE_EXPAND] size flag, the parent [Container] will let it take more or less space depending on this property. If this node has a stretch ratio of 2 and its neighbor a ratio of 1, this node will take two thirds of the available space.
</member>
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" enum="Control.SizeFlags" default="1">
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" enum="Control.SizeFlags" is_bitfield="true" default="1">
Tells the parent [Container] nodes how they should resize and place the node on the Y axis. Use a combination of the [enum SizeFlags] constants to change the flags. See the constants to learn what each does.
</member>
<member name="theme" type="Theme" setter="set_theme" getter="get_theme">
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index cd39543c45..789975eafa 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -807,7 +807,7 @@
</description>
</method>
<method name="mouse_get_button_state" qualifiers="const">
- <return type="int" enum="MouseButtonMask" />
+ <return type="int" enum="MouseButtonMask" is_bitfield="true" />
<description>
Returns the current state of mouse buttons (whether each button is pressed) as a bitmask. If multiple mouse buttons are pressed at the same time, the bits are added together. Equivalent to [method Input.get_mouse_button_mask].
</description>
@@ -1258,6 +1258,13 @@
Returns the V-Sync mode of the given window.
</description>
</method>
+ <method name="window_is_focused" qualifiers="const">
+ <return type="bool" />
+ <param index="0" name="window_id" type="int" default="0" />
+ <description>
+ Returns [code]true[/code] if the window specified by [param window_id] is focused.
+ </description>
+ </method>
<method name="window_is_maximize_allowed" qualifiers="const">
<return type="bool" />
<param index="0" name="window_id" type="int" default="0" />
diff --git a/doc/classes/EditorInspectorPlugin.xml b/doc/classes/EditorInspectorPlugin.xml
index f6bd0ee844..340e22c46a 100644
--- a/doc/classes/EditorInspectorPlugin.xml
+++ b/doc/classes/EditorInspectorPlugin.xml
@@ -60,7 +60,7 @@
<param index="2" name="name" type="String" />
<param index="3" name="hint_type" type="int" enum="PropertyHint" />
<param index="4" name="hint_string" type="String" />
- <param index="5" name="usage_flags" type="int" enum="PropertyUsageFlags" />
+ <param index="5" name="usage_flags" type="int" enum="PropertyUsageFlags" is_bitfield="true" />
<param index="6" name="wide" type="bool" />
<description>
Called to allow adding property-specific editors to the property list for [param object]. The added editor control must extend [EditorProperty]. Returning [code]true[/code] removes the built-in editor for this property, otherwise allows to insert a custom editor before the built-in one.
diff --git a/doc/classes/EditorSpinSlider.xml b/doc/classes/EditorSpinSlider.xml
index 9ef778f7b6..045a1796dd 100644
--- a/doc/classes/EditorSpinSlider.xml
+++ b/doc/classes/EditorSpinSlider.xml
@@ -22,7 +22,7 @@
<member name="read_only" type="bool" setter="set_read_only" getter="is_read_only" default="false">
If [code]true[/code], the slider can't be interacted with.
</member>
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" default="1" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" is_bitfield="true" default="1" />
<member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="1.0" />
<member name="suffix" type="String" setter="set_suffix" getter="get_suffix" default="&quot;&quot;">
The suffix to display after the value (in a faded color). This should generally be a plural word. You may have to use an abbreviation if the suffix is too long to be displayed.
diff --git a/doc/classes/Font.xml b/doc/classes/Font.xml
index 57c31bebb5..5d34e38b13 100644
--- a/doc/classes/Font.xml
+++ b/doc/classes/Font.xml
@@ -44,8 +44,8 @@
<param index="5" name="font_size" type="int" default="16" />
<param index="6" name="max_lines" type="int" default="-1" />
<param index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <param index="8" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
- <param index="9" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="8" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" is_bitfield="true" default="3" />
+ <param index="9" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="10" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="11" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
@@ -64,8 +64,8 @@
<param index="6" name="max_lines" type="int" default="-1" />
<param index="7" name="size" type="int" default="1" />
<param index="8" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <param index="9" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
- <param index="10" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="9" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" is_bitfield="true" default="3" />
+ <param index="10" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="11" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="12" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
@@ -82,7 +82,7 @@
<param index="4" name="width" type="float" default="-1" />
<param index="5" name="font_size" type="int" default="16" />
<param index="6" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <param index="7" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="7" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="8" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="9" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
@@ -100,7 +100,7 @@
<param index="5" name="font_size" type="int" default="16" />
<param index="6" name="size" type="int" default="1" />
<param index="7" name="modulate" type="Color" default="Color(1, 1, 1, 1)" />
- <param index="8" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="8" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="9" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="10" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
@@ -168,7 +168,7 @@
</description>
</method>
<method name="get_font_style" qualifiers="const">
- <return type="int" enum="TextServer.FontStyle" />
+ <return type="int" enum="TextServer.FontStyle" is_bitfield="true" />
<description>
Returns font style flags, see [enum TextServer.FontStyle].
</description>
@@ -200,8 +200,8 @@
<param index="2" name="width" type="float" default="-1" />
<param index="3" name="font_size" type="int" default="16" />
<param index="4" name="max_lines" type="int" default="-1" />
- <param index="5" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
- <param index="6" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="5" name="brk_flags" type="int" enum="TextServer.LineBreakFlag" is_bitfield="true" default="3" />
+ <param index="6" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="7" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="8" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
@@ -240,7 +240,7 @@
<param index="1" name="alignment" type="int" enum="HorizontalAlignment" default="0" />
<param index="2" name="width" type="float" default="-1" />
<param index="3" name="font_size" type="int" default="16" />
- <param index="4" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="4" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<param index="5" name="direction" type="int" enum="TextServer.Direction" default="0" />
<param index="6" name="orientation" type="int" enum="TextServer.Orientation" default="0" />
<description>
diff --git a/doc/classes/FontFile.xml b/doc/classes/FontFile.xml
index 1430f79614..7f438435bd 100644
--- a/doc/classes/FontFile.xml
+++ b/doc/classes/FontFile.xml
@@ -580,7 +580,7 @@
<member name="font_stretch" type="int" setter="set_font_stretch" getter="get_font_stretch" default="100">
Font stretch amount, compared to a normal width. A percentage value between [code]50%[/code] and [code]200%[/code].
</member>
- <member name="font_style" type="int" setter="set_font_style" getter="get_font_style" enum="TextServer.FontStyle" default="0">
+ <member name="font_style" type="int" setter="set_font_style" getter="get_font_style" enum="TextServer.FontStyle" is_bitfield="true" default="0">
Font style flags, see [enum TextServer.FontStyle].
</member>
<member name="font_weight" type="int" setter="set_font_weight" getter="get_font_weight" default="400">
diff --git a/doc/classes/ImageFormatLoaderExtension.xml b/doc/classes/ImageFormatLoaderExtension.xml
index 98d682d868..be695de629 100644
--- a/doc/classes/ImageFormatLoaderExtension.xml
+++ b/doc/classes/ImageFormatLoaderExtension.xml
@@ -20,7 +20,7 @@
<return type="int" enum="Error" />
<param index="0" name="image" type="Image" />
<param index="1" name="fileaccess" type="FileAccess" />
- <param index="2" name="flags" type="int" enum="ImageFormatLoader.LoaderFlags" />
+ <param index="2" name="flags" type="int" enum="ImageFormatLoader.LoaderFlags" is_bitfield="true" />
<param index="3" name="scale" type="float" />
<description>
Loads the content of [param fileaccess] into the provided [param image].
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index fab4d2385b..cea8e66e52 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -156,7 +156,7 @@
</description>
</method>
<method name="get_mouse_button_mask" qualifiers="const">
- <return type="int" enum="MouseButtonMask" />
+ <return type="int" enum="MouseButtonMask" is_bitfield="true" />
<description>
Returns mouse buttons as a bitmask. If multiple mouse buttons are pressed at the same time, the bits are added together. Equivalent to [method DisplayServer.mouse_get_button_state].
</description>
diff --git a/doc/classes/InputEventMouse.xml b/doc/classes/InputEventMouse.xml
index 0f3794a1f6..061438dd9a 100644
--- a/doc/classes/InputEventMouse.xml
+++ b/doc/classes/InputEventMouse.xml
@@ -10,7 +10,7 @@
<link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link>
</tutorials>
<members>
- <member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" enum="MouseButtonMask" default="0">
+ <member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" enum="MouseButtonMask" is_bitfield="true" default="0">
The mouse button mask identifier, one of or a bitwise combination of the [enum MouseButton] button masks.
</member>
<member name="global_position" type="Vector2" setter="set_global_position" getter="get_global_position" default="Vector2(0, 0)">
diff --git a/doc/classes/InputEventWithModifiers.xml b/doc/classes/InputEventWithModifiers.xml
index 9ba0d5d641..9de6469dfb 100644
--- a/doc/classes/InputEventWithModifiers.xml
+++ b/doc/classes/InputEventWithModifiers.xml
@@ -11,7 +11,7 @@
</tutorials>
<methods>
<method name="get_modifiers_mask" qualifiers="const">
- <return type="int" enum="KeyModifierMask" />
+ <return type="int" enum="KeyModifierMask" is_bitfield="true" />
<description>
Returns the keycode combination of modifier keys.
</description>
diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml
index 466b353f15..d54f209244 100644
--- a/doc/classes/Label.xml
+++ b/doc/classes/Label.xml
@@ -48,7 +48,7 @@
<member name="horizontal_alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="0">
Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants.
</member>
- <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" default="163">
+ <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" is_bitfield="true" default="163">
Line fill alignment rules. For more info see [enum TextServer.JustificationFlag].
</member>
<member name="label_settings" type="LabelSettings" setter="set_label_settings" getter="get_label_settings">
@@ -64,7 +64,7 @@
Limits the lines of text the node shows on screen.
</member>
<member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="2" />
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" default="4" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" is_bitfield="true" default="4" />
<member name="structured_text_bidi_override" type="int" setter="set_structured_text_bidi_override" getter="get_structured_text_bidi_override" enum="TextServer.StructuredTextParser" default="0">
Set BiDi algorithm override for the structured text.
</member>
diff --git a/doc/classes/Label3D.xml b/doc/classes/Label3D.xml
index 7b2f054703..79e96d0d45 100644
--- a/doc/classes/Label3D.xml
+++ b/doc/classes/Label3D.xml
@@ -71,7 +71,7 @@
<member name="horizontal_alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="1">
Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants.
</member>
- <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" default="163">
+ <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" is_bitfield="true" default="163">
Line fill alignment rules. For more info see [enum TextServer.JustificationFlag].
</member>
<member name="language" type="String" setter="set_language" getter="get_language" default="&quot;&quot;">
diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml
index 00aedb490d..332219be1e 100644
--- a/doc/classes/NavigationAgent2D.xml
+++ b/doc/classes/NavigationAgent2D.xml
@@ -184,7 +184,7 @@
<member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="100.0">
The maximum distance the agent is allowed away from the ideal path to the final position. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path.
</member>
- <member name="path_metadata_flags" type="int" setter="set_path_metadata_flags" getter="get_path_metadata_flags" enum="NavigationPathQueryParameters2D.PathMetadataFlags" default="7">
+ <member name="path_metadata_flags" type="int" setter="set_path_metadata_flags" getter="get_path_metadata_flags" enum="NavigationPathQueryParameters2D.PathMetadataFlags" is_bitfield="true" default="7">
Additional information to return with the navigation path.
</member>
<member name="path_postprocessing" type="int" setter="set_path_postprocessing" getter="get_path_postprocessing" enum="NavigationPathQueryParameters2D.PathPostProcessing" default="0">
diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml
index f341686d57..2450f84929 100644
--- a/doc/classes/NavigationAgent3D.xml
+++ b/doc/classes/NavigationAgent3D.xml
@@ -187,7 +187,7 @@
<member name="path_max_distance" type="float" setter="set_path_max_distance" getter="get_path_max_distance" default="5.0">
The maximum distance the agent is allowed away from the ideal path to the final position. This can happen due to trying to avoid collisions. When the maximum distance is exceeded, it recalculates the ideal path.
</member>
- <member name="path_metadata_flags" type="int" setter="set_path_metadata_flags" getter="get_path_metadata_flags" enum="NavigationPathQueryParameters3D.PathMetadataFlags" default="7">
+ <member name="path_metadata_flags" type="int" setter="set_path_metadata_flags" getter="get_path_metadata_flags" enum="NavigationPathQueryParameters3D.PathMetadataFlags" is_bitfield="true" default="7">
Additional information to return with the navigation path.
</member>
<member name="path_postprocessing" type="int" setter="set_path_postprocessing" getter="get_path_postprocessing" enum="NavigationPathQueryParameters3D.PathPostProcessing" default="0">
diff --git a/doc/classes/NavigationPathQueryParameters2D.xml b/doc/classes/NavigationPathQueryParameters2D.xml
index 0e48508197..a4fd04696d 100644
--- a/doc/classes/NavigationPathQueryParameters2D.xml
+++ b/doc/classes/NavigationPathQueryParameters2D.xml
@@ -13,7 +13,7 @@
<member name="map" type="RID" setter="set_map" getter="get_map">
The navigation [code]map[/code] [RID] used in the path query.
</member>
- <member name="metadata_flags" type="int" setter="set_metadata_flags" getter="get_metadata_flags" enum="NavigationPathQueryParameters2D.PathMetadataFlags" default="7">
+ <member name="metadata_flags" type="int" setter="set_metadata_flags" getter="get_metadata_flags" enum="NavigationPathQueryParameters2D.PathMetadataFlags" is_bitfield="true" default="7">
Additional information to include with the navigation path.
</member>
<member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1">
diff --git a/doc/classes/NavigationPathQueryParameters3D.xml b/doc/classes/NavigationPathQueryParameters3D.xml
index 7564c6a858..e63a3582bd 100644
--- a/doc/classes/NavigationPathQueryParameters3D.xml
+++ b/doc/classes/NavigationPathQueryParameters3D.xml
@@ -13,7 +13,7 @@
<member name="map" type="RID" setter="set_map" getter="get_map">
The navigation [code]map[/code] [RID] used in the path query.
</member>
- <member name="metadata_flags" type="int" setter="set_metadata_flags" getter="get_metadata_flags" enum="NavigationPathQueryParameters3D.PathMetadataFlags" default="7">
+ <member name="metadata_flags" type="int" setter="set_metadata_flags" getter="get_metadata_flags" enum="NavigationPathQueryParameters3D.PathMetadataFlags" is_bitfield="true" default="7">
Additional information to include with the navigation path.
</member>
<member name="navigation_layers" type="int" setter="set_navigation_layers" getter="get_navigation_layers" default="1">
diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml
index f46f2912b3..ee3fdda3d5 100644
--- a/doc/classes/NavigationServer2D.xml
+++ b/doc/classes/NavigationServer2D.xml
@@ -156,7 +156,7 @@
<param index="0" name="agent" type="RID" />
<param index="1" name="velocity" type="Vector2" />
<description>
- Sets [param velocity] as the new wanted velocity for the specified [param agent]. The avoidance simulation will try to fulfil this velocity if possible but will modify it to avoid collision with other agent's and obstacles. When an agent is teleported to a new position far away use [method agent_set_velocity_forced] instead to reset the internal velocity state.
+ Sets [param velocity] as the new wanted velocity for the specified [param agent]. The avoidance simulation will try to fulfill this velocity if possible but will modify it to avoid collision with other agent's and obstacles. When an agent is teleported to a new position far away use [method agent_set_velocity_forced] instead to reset the internal velocity state.
</description>
</method>
<method name="agent_set_velocity_forced">
diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml
index 4c759beac0..1ecf425fd5 100644
--- a/doc/classes/NavigationServer3D.xml
+++ b/doc/classes/NavigationServer3D.xml
@@ -181,7 +181,7 @@
<param index="0" name="agent" type="RID" />
<param index="1" name="velocity" type="Vector3" />
<description>
- Sets [param velocity] as the new wanted velocity for the specified [param agent]. The avoidance simulation will try to fulfil this velocity if possible but will modify it to avoid collision with other agent's and obstacles. When an agent is teleported to a new position use [method agent_set_velocity_forced] as well to reset the internal simulation velocity.
+ Sets [param velocity] as the new wanted velocity for the specified [param agent]. The avoidance simulation will try to fulfill this velocity if possible but will modify it to avoid collision with other agent's and obstacles. When an agent is teleported to a new position use [method agent_set_velocity_forced] as well to reset the internal simulation velocity.
</description>
</method>
<method name="agent_set_velocity_forced">
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 1557b5f3c2..1b6f972b36 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -877,7 +877,7 @@
<member name="process_thread_group_order" type="int" setter="set_process_thread_group_order" getter="get_process_thread_group_order">
Change the process thread group order. Groups with a lesser order will process before groups with a greater order. This is useful when a large amount of nodes process in sub thread and, afterwards, another group wants to collect their result in the main thread, as an example.
</member>
- <member name="process_thread_messages" type="int" setter="set_process_thread_messages" getter="get_process_thread_messages" enum="Node.ProcessThreadMessages">
+ <member name="process_thread_messages" type="int" setter="set_process_thread_messages" getter="get_process_thread_messages" enum="Node.ProcessThreadMessages" is_bitfield="true">
Set whether the current thread group will process messages (calls to [method call_deferred_thread_group] on threads, and whether it wants to receive them during regular process or physics process callbacks.
</member>
<member name="scene_file_path" type="String" setter="set_scene_file_path" getter="get_scene_file_path">
@@ -1115,11 +1115,11 @@
<constant name="PROCESS_THREAD_GROUP_SUB_THREAD" value="2" enum="ProcessThreadGroup">
Process this node (and children nodes set to inherit) on a sub-thread. See [member process_thread_group] for more information.
</constant>
- <constant name="FLAG_PROCESS_THREAD_MESSAGES" value="1" enum="ProcessThreadMessages">
+ <constant name="FLAG_PROCESS_THREAD_MESSAGES" value="1" enum="ProcessThreadMessages" is_bitfield="true">
</constant>
- <constant name="FLAG_PROCESS_THREAD_MESSAGES_PHYSICS" value="2" enum="ProcessThreadMessages">
+ <constant name="FLAG_PROCESS_THREAD_MESSAGES_PHYSICS" value="2" enum="ProcessThreadMessages" is_bitfield="true">
</constant>
- <constant name="FLAG_PROCESS_THREAD_MESSAGES_ALL" value="3" enum="ProcessThreadMessages">
+ <constant name="FLAG_PROCESS_THREAD_MESSAGES_ALL" value="3" enum="ProcessThreadMessages" is_bitfield="true">
</constant>
<constant name="DUPLICATE_SIGNALS" value="1" enum="DuplicateFlags">
Duplicate the node's signals.
diff --git a/doc/classes/RDTextureFormat.xml b/doc/classes/RDTextureFormat.xml
index ff674a8d7e..7308127c3f 100644
--- a/doc/classes/RDTextureFormat.xml
+++ b/doc/classes/RDTextureFormat.xml
@@ -44,7 +44,7 @@
<member name="texture_type" type="int" setter="set_texture_type" getter="get_texture_type" enum="RenderingDevice.TextureType" default="1">
The texture type.
</member>
- <member name="usage_bits" type="int" setter="set_usage_bits" getter="get_usage_bits" enum="RenderingDevice.TextureUsageBits" default="0">
+ <member name="usage_bits" type="int" setter="set_usage_bits" getter="get_usage_bits" enum="RenderingDevice.TextureUsageBits" is_bitfield="true" default="0">
The texture's usage bits, which determine what can be done using the texture.
</member>
<member name="width" type="int" setter="set_width" getter="get_width" default="1">
diff --git a/doc/classes/Range.xml b/doc/classes/Range.xml
index a6b29f9e26..e75b47af24 100644
--- a/doc/classes/Range.xml
+++ b/doc/classes/Range.xml
@@ -62,7 +62,7 @@
<member name="rounded" type="bool" setter="set_use_rounded_values" getter="is_using_rounded_values" default="false">
If [code]true[/code], [member value] will always be rounded to the nearest integer.
</member>
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" default="0" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" is_bitfield="true" default="0" />
<member name="step" type="float" setter="set_step" getter="get_step" default="0.01">
If greater than 0, [member value] will always be rounded to a multiple of this property's value. If [member rounded] is also [code]true[/code], [member value] will first be rounded to a multiple of this property's value, then rounded to the nearest integer.
</member>
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index e19bb440ec..f557dc2fdd 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -16,8 +16,8 @@
<methods>
<method name="barrier">
<return type="void" />
- <param index="0" name="from" type="int" enum="RenderingDevice.BarrierMask" default="7" />
- <param index="1" name="to" type="int" enum="RenderingDevice.BarrierMask" default="7" />
+ <param index="0" name="from" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
+ <param index="1" name="to" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
<description>
Puts a memory barrier in place. This is used for synchronization to avoid data races. See also [method full_barrier], which may be useful for debugging.
</description>
@@ -27,7 +27,7 @@
<param index="0" name="buffer" type="RID" />
<param index="1" name="offset" type="int" />
<param index="2" name="size_bytes" type="int" />
- <param index="3" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" default="7" />
+ <param index="3" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
<description>
</description>
</method>
@@ -46,7 +46,7 @@
<param index="1" name="offset" type="int" />
<param index="2" name="size_bytes" type="int" />
<param index="3" name="data" type="PackedByteArray" />
- <param index="4" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" default="7" />
+ <param index="4" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
<description>
</description>
</method>
@@ -114,7 +114,7 @@
</method>
<method name="compute_list_end">
<return type="void" />
- <param index="0" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" default="7" />
+ <param index="0" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
<description>
Finishes a list of compute commands created with the [code]compute_*[/code] methods.
</description>
@@ -296,7 +296,7 @@
</method>
<method name="draw_list_end">
<return type="void" />
- <param index="0" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" default="7" />
+ <param index="0" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
<description>
Finishes a list of raster drawing commands created with the [code]draw_*[/code] methods.
</description>
@@ -534,7 +534,7 @@
<param index="5" name="multisample_state" type="RDPipelineMultisampleState" />
<param index="6" name="stencil_state" type="RDPipelineDepthStencilState" />
<param index="7" name="color_blend_state" type="RDPipelineColorBlendState" />
- <param index="8" name="dynamic_state_flags" type="int" enum="RenderingDevice.PipelineDynamicStateFlags" default="0" />
+ <param index="8" name="dynamic_state_flags" type="int" enum="RenderingDevice.PipelineDynamicStateFlags" is_bitfield="true" default="0" />
<param index="9" name="for_render_pass" type="int" default="0" />
<param index="10" name="specialization_constants" type="RDPipelineSpecializationConstant[]" default="[]" />
<description>
@@ -643,7 +643,7 @@
<return type="RID" />
<param index="0" name="size_bytes" type="int" />
<param index="1" name="data" type="PackedByteArray" default="PackedByteArray()" />
- <param index="2" name="usage" type="int" enum="RenderingDevice.StorageBufferUsage" default="0" />
+ <param index="2" name="usage" type="int" enum="RenderingDevice.StorageBufferUsage" is_bitfield="true" default="0" />
<description>
Creates a [url=https://vkguide.dev/docs/chapter-4/storage_buffers/]storage buffer[/url] with the specified [param data] and [param usage]. It can be accessed with the RID that is returned.
Once finished with your RID, you will want to free the RID using the RenderingDevice's [method free_rid] method.
@@ -682,7 +682,7 @@
<param index="3" name="mipmap_count" type="int" />
<param index="4" name="base_layer" type="int" />
<param index="5" name="layer_count" type="int" />
- <param index="6" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" default="7" />
+ <param index="6" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
<description>
Clears the specified [param texture] by replacing all of its pixels with the specified [param color]. [param base_mipmap] and [param mipmap_count] determine which mipmaps of the texture are affected by this clear operation, while [param base_layer] and [param layer_count] determine which layers of a 3D texture (or texture array) are affected by this clear operation. For 2D textures (which only have one layer by design), [param base_layer] and [param layer_count] must both be [code]0[/code].
[b]Note:[/b] [param texture] can't be cleared while a draw list that uses it as part of a framebuffer is being created. Ensure the draw list is finalized (and that the color/depth texture using it is not set to [constant FINAL_ACTION_CONTINUE]) to clear this texture.
@@ -699,7 +699,7 @@
<param index="6" name="dst_mipmap" type="int" />
<param index="7" name="src_layer" type="int" />
<param index="8" name="dst_layer" type="int" />
- <param index="9" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" default="7" />
+ <param index="9" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
<description>
Copies the [param from_texture] to [param to_texture] with the specified [param from_pos], [param to_pos] and [param size] coordinates. The Z axis of the [param from_pos], [param to_pos] and [param size] must be [code]0[/code] for 2-dimensional textures. Source and destination mipmaps/layers must also be specified, with these parameters being [code]0[/code] for textures without mipmaps or single-layer textures. Returns [constant @GlobalScope.OK] if the texture copy was successful or [constant @GlobalScope.ERR_INVALID_PARAMETER] otherwise.
[b]Note:[/b] [param from_texture] texture can't be copied while a draw list that uses it as part of a framebuffer is being created. Ensure the draw list is finalized (and that the color/depth texture using it is not set to [constant FINAL_ACTION_CONTINUE]) to copy this texture.
@@ -763,7 +763,7 @@
<method name="texture_is_format_supported_for_usage" qualifiers="const">
<return type="bool" />
<param index="0" name="format" type="int" enum="RenderingDevice.DataFormat" />
- <param index="1" name="usage_flags" type="int" enum="RenderingDevice.TextureUsageBits" />
+ <param index="1" name="usage_flags" type="int" enum="RenderingDevice.TextureUsageBits" is_bitfield="true" />
<description>
Returns [code]true[/code] if the specified [param format] is supported for the given [param usage_flags], [code]false[/code] otherwise.
</description>
@@ -786,7 +786,7 @@
<return type="int" enum="Error" />
<param index="0" name="from_texture" type="RID" />
<param index="1" name="to_texture" type="RID" />
- <param index="2" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" default="7" />
+ <param index="2" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
<description>
Resolves the [param from_texture] texture onto [param to_texture] with multisample antialiasing enabled. This must be used when rendering a framebuffer for MSAA to work. Returns [constant @GlobalScope.OK] if successful, [constant @GlobalScope.ERR_INVALID_PARAMETER] otherwise.
[b]Note:[/b] [param from_texture] and [param to_texture] textures must have the same dimension, format and type (color or depth).
@@ -803,7 +803,7 @@
<param index="0" name="texture" type="RID" />
<param index="1" name="layer" type="int" />
<param index="2" name="data" type="PackedByteArray" />
- <param index="3" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" default="7" />
+ <param index="3" name="post_barrier" type="int" enum="RenderingDevice.BarrierMask" is_bitfield="true" default="7" />
<description>
Updates texture data with new data, replacing the previous data in place. The updated texture data must have the same dimensions and format. For 2D textures (which only have one layer), [param layer] must be [code]0[/code]. Returns [constant @GlobalScope.OK] if the update was successful, [constant @GlobalScope.ERR_INVALID_PARAMETER] otherwise.
[b]Note:[/b] Updating textures is forbidden during creation of a draw or compute list.
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 6b65302a7d..878b685c67 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -2096,7 +2096,7 @@
<param index="2" name="arrays" type="Array" />
<param index="3" name="blend_shapes" type="Array" default="[]" />
<param index="4" name="lods" type="Dictionary" default="{}" />
- <param index="5" name="compress_format" type="int" enum="RenderingServer.ArrayFormat" default="0" />
+ <param index="5" name="compress_format" type="int" enum="RenderingServer.ArrayFormat" is_bitfield="true" default="0" />
<description>
</description>
</method>
@@ -2199,14 +2199,14 @@
</method>
<method name="mesh_surface_get_format_attribute_stride" qualifiers="const">
<return type="int" />
- <param index="0" name="format" type="int" enum="RenderingServer.ArrayFormat" />
+ <param index="0" name="format" type="int" enum="RenderingServer.ArrayFormat" is_bitfield="true" />
<param index="1" name="vertex_count" type="int" />
<description>
</description>
</method>
<method name="mesh_surface_get_format_offset" qualifiers="const">
<return type="int" />
- <param index="0" name="format" type="int" enum="RenderingServer.ArrayFormat" />
+ <param index="0" name="format" type="int" enum="RenderingServer.ArrayFormat" is_bitfield="true" />
<param index="1" name="vertex_count" type="int" />
<param index="2" name="array_index" type="int" />
<description>
@@ -2214,14 +2214,14 @@
</method>
<method name="mesh_surface_get_format_skin_stride" qualifiers="const">
<return type="int" />
- <param index="0" name="format" type="int" enum="RenderingServer.ArrayFormat" />
+ <param index="0" name="format" type="int" enum="RenderingServer.ArrayFormat" is_bitfield="true" />
<param index="1" name="vertex_count" type="int" />
<description>
</description>
</method>
<method name="mesh_surface_get_format_vertex_stride" qualifiers="const">
<return type="int" />
- <param index="0" name="format" type="int" enum="RenderingServer.ArrayFormat" />
+ <param index="0" name="format" type="int" enum="RenderingServer.ArrayFormat" is_bitfield="true" />
<param index="1" name="vertex_count" type="int" />
<description>
</description>
@@ -4575,7 +4575,7 @@
Number of objects drawn in a single frame.
</constant>
<constant name="VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME" value="1" enum="ViewportRenderInfo">
- Number of vertices drawn in a single frame.
+ Number of points, lines, or triangles drawn in a single frame.
</constant>
<constant name="VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME" value="2" enum="ViewportRenderInfo">
Number of draw calls during this frame.
@@ -5201,7 +5201,7 @@
Number of objects rendered in the current 3D scene. This varies depending on camera position and rotation.
</constant>
<constant name="RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME" value="1" enum="RenderingInfo">
- Number of vertices/indices rendered in the current 3D scene. This varies depending on camera position and rotation.
+ Number of points, lines, or triangles rendered in the current 3D scene. This varies depending on camera position and rotation.
</constant>
<constant name="RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME" value="2" enum="RenderingInfo">
Number of draw calls performed to render in the current 3D scene. This varies depending on camera position and rotation.
@@ -5210,10 +5210,10 @@
Texture memory used (in bytes).
</constant>
<constant name="RENDERING_INFO_BUFFER_MEM_USED" value="4" enum="RenderingInfo">
- Buffer memory used (in bytes).
+ Buffer memory used (in bytes). This includes vertex data, uniform buffers, and many miscellaneous buffer types used internally.
</constant>
<constant name="RENDERING_INFO_VIDEO_MEM_USED" value="5" enum="RenderingInfo">
- Video memory used (in bytes). This is always greater than the sum of [constant RENDERING_INFO_TEXTURE_MEM_USED] and [constant RENDERING_INFO_BUFFER_MEM_USED], since there is miscellaneous data not accounted for by those two metrics.
+ Video memory used (in bytes). When using the Forward+ or mobile rendering backends, this is always greater than the sum of [constant RENDERING_INFO_TEXTURE_MEM_USED] and [constant RENDERING_INFO_BUFFER_MEM_USED], since there is miscellaneous data not accounted for by those two metrics. When using the GL Compatibility backend, this is equal to the sum of [constant RENDERING_INFO_TEXTURE_MEM_USED] and [constant RENDERING_INFO_BUFFER_MEM_USED].
</constant>
<constant name="FEATURE_SHADERS" value="0" enum="Features">
Hardware supports shaders. This enum is currently unused in Godot 3.x.
diff --git a/doc/classes/ResourceSaver.xml b/doc/classes/ResourceSaver.xml
index f173f34c5a..9d19d81f05 100644
--- a/doc/classes/ResourceSaver.xml
+++ b/doc/classes/ResourceSaver.xml
@@ -37,7 +37,7 @@
<return type="int" enum="Error" />
<param index="0" name="resource" type="Resource" />
<param index="1" name="path" type="String" default="&quot;&quot;" />
- <param index="2" name="flags" type="int" enum="ResourceSaver.SaverFlags" default="0" />
+ <param index="2" name="flags" type="int" enum="ResourceSaver.SaverFlags" is_bitfield="true" default="0" />
<description>
Saves a resource to disk to the given path, using a [ResourceFormatSaver] that recognizes the resource object. If [param path] is empty, [ResourceSaver] will try to use [member Resource.resource_path].
The [param flags] bitmask can be specified to customize the save behavior using [enum SaverFlags] flags.
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index 44936925ce..6fbdb4faad 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -410,7 +410,7 @@
<param index="1" name="base_direction" type="int" enum="Control.TextDirection" default="0" />
<param index="2" name="language" type="String" default="&quot;&quot;" />
<param index="3" name="st_parser" type="int" enum="TextServer.StructuredTextParser" default="0" />
- <param index="4" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="163" />
+ <param index="4" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="163" />
<param index="5" name="tab_stops" type="PackedFloat32Array" default="PackedFloat32Array()" />
<description>
Adds a [code][p][/code] tag to the tag stack.
diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml
index 8fbd97e78b..e276ca6903 100644
--- a/doc/classes/SpinBox.xml
+++ b/doc/classes/SpinBox.xml
@@ -60,7 +60,7 @@
<member name="select_all_on_focus" type="bool" setter="set_select_all_on_focus" getter="is_select_all_on_focus" default="false">
If [code]true[/code], the [SpinBox] will select the whole text when the [LineEdit] gains focus. Clicking the up and down arrows won't trigger this behavior.
</member>
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" default="1" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" is_bitfield="true" default="1" />
<member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="1.0" />
<member name="suffix" type="String" setter="set_suffix" getter="get_suffix" default="&quot;&quot;">
Adds the specified [code]suffix[/code] string after the numerical value of the [SpinBox].
diff --git a/doc/classes/TextLine.xml b/doc/classes/TextLine.xml
index 93cd8065e2..e9bdd67167 100644
--- a/doc/classes/TextLine.xml
+++ b/doc/classes/TextLine.xml
@@ -151,7 +151,7 @@
<member name="direction" type="int" setter="set_direction" getter="get_direction" enum="TextServer.Direction" default="0">
Text writing direction.
</member>
- <member name="flags" type="int" setter="set_flags" getter="get_flags" enum="TextServer.JustificationFlag" default="3">
+ <member name="flags" type="int" setter="set_flags" getter="get_flags" enum="TextServer.JustificationFlag" is_bitfield="true" default="3">
Line alignment rules. For more info see [TextServer].
</member>
<member name="orientation" type="int" setter="set_orientation" getter="get_orientation" enum="TextServer.Orientation" default="0">
diff --git a/doc/classes/TextMesh.xml b/doc/classes/TextMesh.xml
index 9258dca657..e1999c5f6a 100644
--- a/doc/classes/TextMesh.xml
+++ b/doc/classes/TextMesh.xml
@@ -29,7 +29,7 @@
<member name="horizontal_alignment" type="int" setter="set_horizontal_alignment" getter="get_horizontal_alignment" enum="HorizontalAlignment" default="1">
Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants.
</member>
- <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" default="163">
+ <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" is_bitfield="true" default="163">
Line fill alignment rules. For more info see [enum TextServer.JustificationFlag].
</member>
<member name="language" type="String" setter="set_language" getter="get_language" default="&quot;&quot;">
diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml
index c7e9880fe7..2452c9d262 100644
--- a/doc/classes/TextParagraph.xml
+++ b/doc/classes/TextParagraph.xml
@@ -265,7 +265,7 @@
<member name="alignment" type="int" setter="set_alignment" getter="get_alignment" enum="HorizontalAlignment" default="0">
Paragraph horizontal alignment.
</member>
- <member name="break_flags" type="int" setter="set_break_flags" getter="get_break_flags" enum="TextServer.LineBreakFlag" default="3">
+ <member name="break_flags" type="int" setter="set_break_flags" getter="get_break_flags" enum="TextServer.LineBreakFlag" is_bitfield="true" default="3">
Line breaking rules. For more info see [TextServer].
</member>
<member name="custom_punctuation" type="String" setter="set_custom_punctuation" getter="get_custom_punctuation" default="&quot;&quot;">
@@ -274,7 +274,7 @@
<member name="direction" type="int" setter="set_direction" getter="get_direction" enum="TextServer.Direction" default="0">
Text writing direction.
</member>
- <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" default="163">
+ <member name="justification_flags" type="int" setter="set_justification_flags" getter="get_justification_flags" enum="TextServer.JustificationFlag" is_bitfield="true" default="163">
Line fill alignment rules. For more info see [enum TextServer.JustificationFlag].
</member>
<member name="max_lines_visible" type="int" setter="set_max_lines_visible" getter="get_max_lines_visible" default="-1">
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index 6d4ecb255e..17805f259c 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -386,7 +386,7 @@
</description>
</method>
<method name="font_get_style" qualifiers="const">
- <return type="int" enum="TextServer.FontStyle" />
+ <return type="int" enum="TextServer.FontStyle" is_bitfield="true" />
<param index="0" name="font_rid" type="RID" />
<description>
Returns font style flags, see [enum FontStyle].
@@ -840,7 +840,7 @@
<method name="font_set_style">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
- <param index="1" name="style" type="int" enum="TextServer.FontStyle" />
+ <param index="1" name="style" type="int" enum="TextServer.FontStyle" is_bitfield="true" />
<description>
Sets the font style flags, see [enum FontStyle].
[b]Note:[/b] This value is used for font matching only and will not affect font rendering. Use [method font_set_face_index], [method font_set_variation_coordinates], [method font_set_embolden], or [method font_set_transform] instead.
@@ -1168,7 +1168,7 @@
<return type="float" />
<param index="0" name="shaped" type="RID" />
<param index="1" name="width" type="float" />
- <param index="2" name="justification_flags" type="int" enum="TextServer.JustificationFlag" default="3" />
+ <param index="2" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" default="3" />
<description>
Adjusts text width to fit to specified width, returns new text width.
</description>
@@ -1275,7 +1275,7 @@
<param index="0" name="shaped" type="RID" />
<param index="1" name="width" type="float" />
<param index="2" name="start" type="int" default="0" />
- <param index="3" name="break_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
+ <param index="3" name="break_flags" type="int" enum="TextServer.LineBreakFlag" is_bitfield="true" default="3" />
<description>
Breaks text to the lines and returns character ranges for each line.
</description>
@@ -1286,7 +1286,7 @@
<param index="1" name="width" type="PackedFloat32Array" />
<param index="2" name="start" type="int" default="0" />
<param index="3" name="once" type="bool" default="true" />
- <param index="4" name="break_flags" type="int" enum="TextServer.LineBreakFlag" default="3" />
+ <param index="4" name="break_flags" type="int" enum="TextServer.LineBreakFlag" is_bitfield="true" default="3" />
<description>
Breaks text to the lines and columns. Returns character ranges for each segment.
</description>
@@ -1397,7 +1397,7 @@
<method name="shaped_text_get_word_breaks" qualifiers="const">
<return type="PackedInt32Array" />
<param index="0" name="shaped" type="RID" />
- <param index="1" name="grapheme_flags" type="int" enum="TextServer.GraphemeFlag" default="264" />
+ <param index="1" name="grapheme_flags" type="int" enum="TextServer.GraphemeFlag" is_bitfield="true" default="264" />
<description>
Breaks text into words and returns array of character ranges. Use [param grapheme_flags] to set what characters are used for breaking (see [enum GraphemeFlag]).
</description>
@@ -1444,7 +1444,7 @@
<return type="void" />
<param index="0" name="shaped" type="RID" />
<param index="1" name="width" type="float" default="0" />
- <param index="2" name="overrun_trim_flags" type="int" enum="TextServer.TextOverrunFlag" default="0" />
+ <param index="2" name="overrun_trim_flags" type="int" enum="TextServer.TextOverrunFlag" is_bitfield="true" default="0" />
<description>
Trims text if it exceeds the given width.
</description>
diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml
index 7efd5a2a75..3240b025bf 100644
--- a/doc/classes/TextServerExtension.xml
+++ b/doc/classes/TextServerExtension.xml
@@ -332,7 +332,7 @@
</description>
</method>
<method name="_font_get_style" qualifiers="virtual const">
- <return type="int" enum="TextServer.FontStyle" />
+ <return type="int" enum="TextServer.FontStyle" is_bitfield="true" />
<param index="0" name="font_rid" type="RID" />
<description>
</description>
@@ -734,7 +734,7 @@
<method name="_font_set_style" qualifiers="virtual">
<return type="void" />
<param index="0" name="font_rid" type="RID" />
- <param index="1" name="style" type="int" enum="TextServer.FontStyle" />
+ <param index="1" name="style" type="int" enum="TextServer.FontStyle" is_bitfield="true" />
<description>
</description>
</method>
@@ -1008,7 +1008,7 @@
<return type="float" />
<param index="0" name="shaped" type="RID" />
<param index="1" name="width" type="float" />
- <param index="2" name="justification_flags" type="int" enum="TextServer.JustificationFlag" />
+ <param index="2" name="justification_flags" type="int" enum="TextServer.JustificationFlag" is_bitfield="true" />
<description>
</description>
</method>
@@ -1100,7 +1100,7 @@
<param index="0" name="shaped" type="RID" />
<param index="1" name="width" type="float" />
<param index="2" name="start" type="int" />
- <param index="3" name="break_flags" type="int" enum="TextServer.LineBreakFlag" />
+ <param index="3" name="break_flags" type="int" enum="TextServer.LineBreakFlag" is_bitfield="true" />
<description>
</description>
</method>
@@ -1110,7 +1110,7 @@
<param index="1" name="width" type="PackedFloat32Array" />
<param index="2" name="start" type="int" />
<param index="3" name="once" type="bool" />
- <param index="4" name="break_flags" type="int" enum="TextServer.LineBreakFlag" />
+ <param index="4" name="break_flags" type="int" enum="TextServer.LineBreakFlag" is_bitfield="true" />
<description>
</description>
</method>
@@ -1205,7 +1205,7 @@
<method name="_shaped_text_get_word_breaks" qualifiers="virtual const">
<return type="PackedInt32Array" />
<param index="0" name="shaped" type="RID" />
- <param index="1" name="grapheme_flags" type="int" enum="TextServer.GraphemeFlag" />
+ <param index="1" name="grapheme_flags" type="int" enum="TextServer.GraphemeFlag" is_bitfield="true" />
<description>
</description>
</method>
@@ -1240,7 +1240,7 @@
<return type="void" />
<param index="0" name="shaped" type="RID" />
<param index="1" name="width" type="float" />
- <param index="2" name="trim_flags" type="int" enum="TextServer.TextOverrunFlag" />
+ <param index="2" name="trim_flags" type="int" enum="TextServer.TextOverrunFlag" is_bitfield="true" />
<description>
</description>
</method>
diff --git a/doc/classes/TextureProgressBar.xml b/doc/classes/TextureProgressBar.xml
index c969573d37..5fd90e6b4d 100644
--- a/doc/classes/TextureProgressBar.xml
+++ b/doc/classes/TextureProgressBar.xml
@@ -43,7 +43,7 @@
<member name="radial_initial_angle" type="float" setter="set_radial_initial_angle" getter="get_radial_initial_angle" default="0.0">
Starting angle for the fill of [member texture_progress] if [member fill_mode] is [constant FILL_CLOCKWISE] or [constant FILL_COUNTER_CLOCKWISE]. When the node's [code]value[/code] is equal to its [code]min_value[/code], the texture doesn't show up at all. When the [code]value[/code] increases, the texture fills and tends towards [member radial_fill_degrees].
</member>
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" default="1" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" is_bitfield="true" default="1" />
<member name="step" type="float" setter="set_step" getter="get_step" overrides="Range" default="1.0" />
<member name="stretch_margin_bottom" type="int" setter="set_stretch_margin" getter="get_stretch_margin" default="0">
The height of the 9-patch's bottom row. A margin of 16 means the 9-slice's bottom corners and side will have a height of 16 pixels. You can set all 4 margin values individually to create panels with non-uniform borders.
diff --git a/doc/classes/VScrollBar.xml b/doc/classes/VScrollBar.xml
index 3a6acb529a..9ecbcdef8a 100644
--- a/doc/classes/VScrollBar.xml
+++ b/doc/classes/VScrollBar.xml
@@ -9,8 +9,8 @@
<tutorials>
</tutorials>
<members>
- <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" overrides="Control" enum="Control.SizeFlags" default="0" />
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" default="1" />
+ <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" overrides="Control" enum="Control.SizeFlags" is_bitfield="true" default="0" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" is_bitfield="true" default="1" />
</members>
<theme_items>
<theme_item name="decrement" data_type="icon" type="Texture2D">
diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml
index 5c1d61d0f9..964facc45c 100644
--- a/doc/classes/VSlider.xml
+++ b/doc/classes/VSlider.xml
@@ -9,8 +9,8 @@
<tutorials>
</tutorials>
<members>
- <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" overrides="Control" enum="Control.SizeFlags" default="0" />
- <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" default="1" />
+ <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" overrides="Control" enum="Control.SizeFlags" is_bitfield="true" default="0" />
+ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" overrides="Control" enum="Control.SizeFlags" is_bitfield="true" default="1" />
</members>
<theme_items>
<theme_item name="center_grabber" data_type="constant" type="int" default="0">
diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py
index 2594fa8cbd..7cc05087b7 100755
--- a/doc/tools/make_rst.py
+++ b/doc/tools/make_rst.py
@@ -27,7 +27,7 @@ MARKUP_ALLOWED_SUBSEQUENT = " -.,:;!?\\/'\")]}>"
# Used to translate section headings and other hardcoded strings when required with
# the --lang argument. The BASE_STRINGS list should be synced with what we actually
# write in this script (check `translate()` uses), and also hardcoded in
-# `doc/translations/extract.py` to include them in the source POT file.
+# `scripts/extract_classes.py` (godotengine/godot-editor-l10n repo) to include them in the source POT file.
BASE_STRINGS = [
"All classes",
"Globals",
@@ -65,6 +65,7 @@ BASE_STRINGS = [
"This method is used to construct a type.",
"This method doesn't need an instance to be called, so it can be called directly using the class name.",
"This method describes a valid operator to use with this type as left-hand operand.",
+ "This value is an integer composed as a bitmask of the following flags.",
]
strings_l10n: Dict[str, str] = {}
@@ -362,13 +363,14 @@ class State:
class TypeName:
- def __init__(self, type_name: str, enum: Optional[str] = None) -> None:
+ def __init__(self, type_name: str, enum: Optional[str] = None, is_bitfield: bool = False) -> None:
self.type_name = type_name
self.enum = enum
+ self.is_bitfield = is_bitfield
def to_rst(self, state: State) -> str:
if self.enum is not None:
- return make_enum(self.enum, state)
+ return make_enum(self.enum, self.is_bitfield, state)
elif self.type_name == "void":
return "void"
else:
@@ -376,7 +378,7 @@ class TypeName:
@classmethod
def from_element(cls, element: ET.Element) -> "TypeName":
- return cls(element.attrib["type"], element.get("enum"))
+ return cls(element.attrib["type"], element.get("enum"), element.get("is_bitfield") == "true")
class DefinitionBase:
@@ -1280,7 +1282,7 @@ def make_type(klass: str, state: State) -> str:
return klass
-def make_enum(t: str, state: State) -> str:
+def make_enum(t: str, is_bitfield: bool, state: State) -> str:
p = t.find(".")
if p >= 0:
c = t[0:p]
@@ -1296,7 +1298,12 @@ def make_enum(t: str, state: State) -> str:
c = "@GlobalScope"
if c in state.classes and e in state.classes[c].enums:
- return f":ref:`{e}<enum_{c}_{e}>`"
+ if is_bitfield:
+ if not state.classes[c].enums[e].is_bitfield:
+ print_error(f'{state.current_class}.xml: Enum "{t}" is not bitfield.', state)
+ return f"|bitfield|\<:ref:`{e}<enum_{c}_{e}>`\>"
+ else:
+ return f":ref:`{e}<enum_{c}_{e}>`"
# Don't fail for `Vector3.Axis`, as this enum is a special case which is expected not to be resolved.
if f"{c}.{e}" != "Vector3.Axis":
@@ -1412,6 +1419,7 @@ def make_footer() -> str:
"This method doesn't need an instance to be called, so it can be called directly using the class name."
)
operator_msg = translate("This method describes a valid operator to use with this type as left-hand operand.")
+ bitfield_msg = translate("This value is an integer composed as a bitmask of the following flags.")
return (
f".. |virtual| replace:: :abbr:`virtual ({virtual_msg})`\n"
@@ -1420,6 +1428,7 @@ def make_footer() -> str:
f".. |constructor| replace:: :abbr:`constructor ({constructor_msg})`\n"
f".. |static| replace:: :abbr:`static ({static_msg})`\n"
f".. |operator| replace:: :abbr:`operator ({operator_msg})`\n"
+ f".. |bitfield| replace:: :abbr:`BitField ({bitfield_msg})`\n"
)
@@ -1834,7 +1843,7 @@ def format_text_block(
escape_post = True
elif cmd.startswith("enum"):
- tag_text = make_enum(link_target, state)
+ tag_text = make_enum(link_target, False, state)
escape_pre = True
escape_post = True
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 59a65b4538..86405fa3f0 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -1790,6 +1790,7 @@ void RasterizerCanvasGLES3::_update_shadow_atlas() {
state.shadow_depth_buffer = 0;
WARN_PRINT("Could not create CanvasItem shadow atlas, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
}
+ GLES3::Utilities::get_singleton()->texture_allocated_data(state.shadow_texture, state.shadow_texture_size * data.max_lights_per_render * 2 * 4, "2D shadow atlas texture");
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
}
}
@@ -1894,8 +1895,8 @@ void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vec
if (oc->line_point_count != lines.size() && oc->vertex_array != 0) {
glDeleteVertexArrays(1, &oc->vertex_array);
- glDeleteBuffers(1, &oc->vertex_buffer);
- glDeleteBuffers(1, &oc->index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(oc->vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(oc->index_buffer);
oc->vertex_array = 0;
oc->vertex_buffer = 0;
@@ -1954,13 +1955,15 @@ void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vec
glGenBuffers(1, &oc->vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, oc->vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(float), geometry.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, oc->vertex_buffer, lc * 6 * sizeof(float), geometry.ptr(), GL_STATIC_DRAW, "Occluder polygon vertex buffer");
+
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
glVertexAttribPointer(RS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glGenBuffers(1, &oc->index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oc->index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * lc * sizeof(uint16_t), indices.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, oc->index_buffer, 3 * lc * sizeof(uint16_t), indices.ptr(), GL_STATIC_DRAW, "Occluder polygon index buffer");
+
glBindVertexArray(0);
} else {
glBindBuffer(GL_ARRAY_BUFFER, oc->vertex_buffer);
@@ -1995,8 +1998,8 @@ void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vec
if (oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size() && oc->sdf_vertex_array != 0) {
glDeleteVertexArrays(1, &oc->sdf_vertex_array);
- glDeleteBuffers(1, &oc->sdf_vertex_buffer);
- glDeleteBuffers(1, &oc->sdf_index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(oc->sdf_vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(oc->sdf_index_buffer);
oc->sdf_vertex_array = 0;
oc->sdf_vertex_buffer = 0;
@@ -2015,13 +2018,15 @@ void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vec
glGenBuffers(1, &oc->sdf_vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, oc->sdf_vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, p_points.size() * 2 * sizeof(float), p_points.to_byte_array().ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, oc->sdf_vertex_buffer, oc->sdf_point_count * 2 * sizeof(float), p_points.to_byte_array().ptr(), GL_STATIC_DRAW, "Occluder polygon SDF vertex buffer");
+
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), nullptr);
glGenBuffers(1, &oc->sdf_index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oc->sdf_index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sdf_indices.size() * sizeof(uint32_t), sdf_indices.to_byte_array().ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, oc->sdf_index_buffer, oc->sdf_index_count * sizeof(uint32_t), sdf_indices.to_byte_array().ptr(), GL_STATIC_DRAW, "Occluder polygon SDF index buffer");
+
glBindVertexArray(0);
} else {
glBindBuffer(GL_ARRAY_BUFFER, oc->sdf_vertex_buffer);
@@ -2410,7 +2415,7 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec
}
ERR_FAIL_COND_V(base_offset != stride, 0);
- glBufferData(GL_ARRAY_BUFFER, vertex_count * stride * sizeof(float), polygon_buffer.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, pb.vertex_buffer, vertex_count * stride * sizeof(float), polygon_buffer.ptr(), GL_STATIC_DRAW, "Polygon 2D vertex buffer");
}
if (p_indices.size()) {
@@ -2423,7 +2428,7 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec
}
glGenBuffers(1, &pb.index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_indices.size() * 4, index_buffer.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer, p_indices.size() * 4, index_buffer.ptr(), GL_STATIC_DRAW, "Polygon 2D index buffer");
pb.count = p_indices.size();
}
@@ -2444,11 +2449,11 @@ void RasterizerCanvasGLES3::free_polygon(PolygonID p_polygon) {
PolygonBuffers &pb = *pb_ptr;
if (pb.index_buffer != 0) {
- glDeleteBuffers(1, &pb.index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(pb.index_buffer);
}
glDeleteVertexArrays(1, &pb.vertex_array);
- glDeleteBuffers(1, &pb.vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(pb.vertex_buffer);
polygon_buffers.polygons.erase(p_polygon);
}
@@ -2462,13 +2467,13 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() {
glGenBuffers(3, new_buffers);
// Batch UBO.
glBindBuffer(GL_ARRAY_BUFFER, new_buffers[0]);
- glBufferData(GL_ARRAY_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffers[0], data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW, "2D Batch UBO[" + itos(state.current_data_buffer_index) + "][0]");
// Light uniform buffer.
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[1]);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[1], sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW, "2D Lights UBO[" + itos(state.current_data_buffer_index) + "]");
// State buffer.
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[2]);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[2], sizeof(StateBuffer), nullptr, GL_STREAM_DRAW, "2D State UBO[" + itos(state.current_data_buffer_index) + "]");
state.current_data_buffer_index = (state.current_data_buffer_index + 1);
DataBuffer db;
@@ -2493,7 +2498,7 @@ void RasterizerCanvasGLES3::_allocate_instance_buffer() {
glGenBuffers(1, &new_buffer);
glBindBuffer(GL_ARRAY_BUFFER, new_buffer);
- glBufferData(GL_ARRAY_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffer, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW, "Batch UBO[" + itos(state.current_data_buffer_index) + "][" + itos(state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.size()) + "]");
state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.push_back(new_buffer);
@@ -2656,13 +2661,13 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
glGenBuffers(3, new_buffers);
// Batch UBO.
glBindBuffer(GL_ARRAY_BUFFER, new_buffers[0]);
- glBufferData(GL_ARRAY_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffers[0], data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW, "Batch UBO[0][0]");
// Light uniform buffer.
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[1]);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[1], sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW, "2D lights UBO[0]");
// State buffer.
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[2]);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[2], sizeof(StateBuffer), nullptr, GL_STREAM_DRAW, "2D state UBO[0]");
DataBuffer db;
db.instance_buffers.push_back(new_buffers[0]);
db.light_ubo = new_buffers[1];
@@ -2779,12 +2784,26 @@ RasterizerCanvasGLES3::~RasterizerCanvasGLES3() {
if (state.shadow_fb != 0) {
glDeleteFramebuffers(1, &state.shadow_fb);
- glDeleteTextures(1, &state.shadow_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(state.shadow_texture);
glDeleteRenderbuffers(1, &state.shadow_depth_buffer);
state.shadow_fb = 0;
state.shadow_texture = 0;
state.shadow_depth_buffer = 0;
}
+
+ for (uint32_t i = 0; i < state.canvas_instance_data_buffers.size(); i++) {
+ for (int j = 0; j < state.canvas_instance_data_buffers[i].instance_buffers.size(); j++) {
+ if (state.canvas_instance_data_buffers[i].instance_buffers[j]) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(state.canvas_instance_data_buffers[i].instance_buffers[j]);
+ }
+ }
+ if (state.canvas_instance_data_buffers[i].light_ubo) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(state.canvas_instance_data_buffers[i].light_ubo);
+ }
+ if (state.canvas_instance_data_buffers[i].state_ubo) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(state.canvas_instance_data_buffers[i].state_ubo);
+ }
+ }
}
#endif // GLES3_ENABLED
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 3d8f7924a7..6ed5b3b2f8 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -443,8 +443,10 @@ void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_g
void RasterizerSceneGLES3::_free_sky_data(Sky *p_sky) {
if (p_sky->radiance != 0) {
- glDeleteTextures(1, &p_sky->radiance);
+ GLES3::Utilities::get_singleton()->texture_free_data(p_sky->radiance);
p_sky->radiance = 0;
+ GLES3::Utilities::get_singleton()->texture_free_data(p_sky->raw_radiance);
+ p_sky->raw_radiance = 0;
glDeleteFramebuffers(1, &p_sky->radiance_framebuffer);
p_sky->radiance_framebuffer = 0;
}
@@ -546,6 +548,8 @@ void RasterizerSceneGLES3::_update_dirty_skys() {
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count - 1);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(sky->radiance, Image::get_image_data_size(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8, true), "Sky radiance map");
+
glGenTextures(1, &sky->raw_radiance);
glBindTexture(GL_TEXTURE_CUBE_MAP, sky->raw_radiance);
@@ -568,6 +572,7 @@ void RasterizerSceneGLES3::_update_dirty_skys() {
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, sky->mipmap_count - 1);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(sky->raw_radiance, Image::get_image_data_size(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBA8, true), "Sky raw radiance map");
}
sky->reflection_dirty = true;
@@ -1154,6 +1159,11 @@ void RasterizerSceneGLES3::voxel_gi_update(RID p_probe, bool p_update_light_inst
void RasterizerSceneGLES3::voxel_gi_set_quality(RS::VoxelGIQuality) {
}
+_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {
+ static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };
+ static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 };
+ return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];
+}
void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append) {
GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();
@@ -1258,7 +1268,8 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
uint32_t indices = 0;
surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, indices);
- /*
+ surf->index_count = indices;
+
if (p_render_data->render_info) {
indices = _indices_to_primitives(surf->primitive, indices);
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
@@ -1267,21 +1278,20 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;
}
}
- */
+
} else {
surf->lod_index = 0;
- /*
+
if (p_render_data->render_info) {
uint32_t to_draw = mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
to_draw = _indices_to_primitives(surf->primitive, to_draw);
- to_draw *= inst->instance_count;
+ to_draw *= inst->instance_count > 0 ? inst->instance_count : 1;
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
}
}
- */
}
// ADD Element
@@ -1451,17 +1461,26 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
if (scene_state.ubo_buffer == 0) {
glGenBuffers(1, &scene_state.ubo_buffer);
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.ubo_buffer, sizeof(SceneState::UBO), &scene_state.ubo, GL_STREAM_DRAW, "Scene state UBO");
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ } else {
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::UBO), &scene_state.ubo, GL_STREAM_DRAW);
}
- glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::UBO), &scene_state.ubo, GL_STREAM_DRAW);
+
glBindBuffer(GL_UNIFORM_BUFFER, 0);
if (p_render_data->view_count > 1) {
if (scene_state.multiview_buffer == 0) {
glGenBuffers(1, &scene_state.multiview_buffer);
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.multiview_buffer, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_ubo, GL_STREAM_DRAW, "Multiview UBO");
+ } else {
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_ubo, GL_STREAM_DRAW);
}
- glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_ubo, GL_STREAM_DRAW);
+
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
}
@@ -1792,9 +1811,14 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
if (scene_state.tonemap_buffer == 0) {
// Only create if using 3D
glGenBuffers(1, &scene_state.tonemap_buffer);
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.tonemap_buffer, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW, "Tonemap UBO");
+ } else {
+ glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW);
}
- glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_TONEMAP_UNIFORM_LOCATION, scene_state.tonemap_buffer);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::TonemapUBO), &tonemap_ubo, GL_STREAM_DRAW);
+
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
scene_state.ubo.emissive_exposure_normalization = -1.0; // Use default exposure normalization.
@@ -2086,6 +2110,12 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
}
bool should_request_redraw = false;
+ if constexpr (p_pass_mode != PASS_MODE_DEPTH) {
+ // Don't count elements during depth pre-pass to match the RD renderers.
+ if (p_render_data->render_info) {
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += p_to_element - p_from_element;
+ }
+ }
for (uint32_t i = p_from_element; i < p_to_element; i++) {
const GeometryInstanceSurface *surf = p_params->elements[i];
@@ -2326,6 +2356,21 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
}
material_storage->shaders.scene_shader.version_set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, world_transform, shader->version, instance_variant, spec_constants);
+
+ // Can be index count or vertex count
+ uint32_t count = 0;
+ if (surf->lod_index > 0) {
+ count = surf->index_count;
+ } else {
+ count = mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface);
+ }
+ if constexpr (p_pass_mode != PASS_MODE_DEPTH) {
+ // Don't count draw calls during depth pre-pass to match the RD renderers.
+ if (p_render_data->render_info) {
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
+ }
+ }
+
if (inst->instance_count > 0) {
// Using MultiMesh or Particles.
// Bind instance buffers.
@@ -2366,16 +2411,16 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
glVertexAttribDivisor(15, 1);
}
if (use_index_buffer) {
- glDrawElementsInstanced(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), mesh_storage->mesh_surface_get_index_type(mesh_surface), 0, inst->instance_count);
+ glDrawElementsInstanced(primitive_gl, count, mesh_storage->mesh_surface_get_index_type(mesh_surface), 0, inst->instance_count);
} else {
- glDrawArraysInstanced(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), inst->instance_count);
+ glDrawArraysInstanced(primitive_gl, 0, count, inst->instance_count);
}
} else {
// Using regular Mesh.
if (use_index_buffer) {
- glDrawElements(primitive_gl, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface), mesh_storage->mesh_surface_get_index_type(mesh_surface), 0);
+ glDrawElements(primitive_gl, count, mesh_storage->mesh_surface_get_index_type(mesh_surface), 0);
} else {
- glDrawArrays(primitive_gl, 0, mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface));
+ glDrawArrays(primitive_gl, 0, count);
}
}
if (inst->instance_count > 0) {
@@ -2579,19 +2624,20 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
scene_state.omni_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);
glGenBuffers(1, &scene_state.omni_light_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer);
- glBufferData(GL_UNIFORM_BUFFER, light_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer, light_buffer_size, nullptr, GL_STREAM_DRAW, "OmniLight UBO");
scene_state.spot_lights = memnew_arr(LightData, config->max_renderable_lights);
scene_state.spot_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);
glGenBuffers(1, &scene_state.spot_light_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer);
- glBufferData(GL_UNIFORM_BUFFER, light_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer, light_buffer_size, nullptr, GL_STREAM_DRAW, "SpotLight UBO");
uint32_t directional_light_buffer_size = MAX_DIRECTIONAL_LIGHTS * sizeof(DirectionalLightData);
scene_state.directional_lights = memnew_arr(DirectionalLightData, MAX_DIRECTIONAL_LIGHTS);
glGenBuffers(1, &scene_state.directional_light_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, scene_state.directional_light_buffer);
- glBufferData(GL_UNIFORM_BUFFER, directional_light_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.directional_light_buffer, directional_light_buffer_size, nullptr, GL_STREAM_DRAW, "DirectionalLight UBO");
+
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
@@ -2603,7 +2649,8 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
sky_globals.last_frame_directional_light_count = sky_globals.max_directional_lights + 1;
glGenBuffers(1, &sky_globals.directional_light_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, sky_globals.directional_light_buffer);
- glBufferData(GL_UNIFORM_BUFFER, directional_light_buffer_size, nullptr, GL_STREAM_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, sky_globals.directional_light_buffer, directional_light_buffer_size, nullptr, GL_STREAM_DRAW, "Sky DirectionalLight UBO");
+
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
@@ -2702,6 +2749,8 @@ void sky() {
}
{
+ glGenVertexArrays(1, &sky_globals.screen_triangle_array);
+ glBindVertexArray(sky_globals.screen_triangle_array);
glGenBuffers(1, &sky_globals.screen_triangle);
glBindBuffer(GL_ARRAY_BUFFER, sky_globals.screen_triangle);
@@ -2714,12 +2763,8 @@ void sky() {
3.0f,
};
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6, qv, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, sky_globals.screen_triangle, sizeof(float) * 6, qv, GL_STATIC_DRAW, "Screen triangle vertex buffer");
- glGenVertexArrays(1, &sky_globals.screen_triangle_array);
- glBindVertexArray(sky_globals.screen_triangle_array);
- glBindBuffer(GL_ARRAY_BUFFER, sky_globals.screen_triangle);
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
glBindVertexArray(0);
@@ -2735,9 +2780,9 @@ void sky() {
}
RasterizerSceneGLES3::~RasterizerSceneGLES3() {
- glDeleteBuffers(1, &scene_state.directional_light_buffer);
- glDeleteBuffers(1, &scene_state.omni_light_buffer);
- glDeleteBuffers(1, &scene_state.spot_light_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.directional_light_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.omni_light_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.spot_light_buffer);
memdelete_arr(scene_state.directional_lights);
memdelete_arr(scene_state.omni_lights);
memdelete_arr(scene_state.spot_lights);
@@ -2756,13 +2801,26 @@ RasterizerSceneGLES3::~RasterizerSceneGLES3() {
RSG::material_storage->shader_free(sky_globals.default_shader);
RSG::material_storage->material_free(sky_globals.fog_material);
RSG::material_storage->shader_free(sky_globals.fog_shader);
- glDeleteBuffers(1, &sky_globals.screen_triangle);
+ GLES3::Utilities::get_singleton()->buffer_free_data(sky_globals.screen_triangle);
glDeleteVertexArrays(1, &sky_globals.screen_triangle_array);
glDeleteTextures(1, &sky_globals.radical_inverse_vdc_cache_tex);
- glDeleteBuffers(1, &sky_globals.directional_light_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(sky_globals.directional_light_buffer);
memdelete_arr(sky_globals.directional_lights);
memdelete_arr(sky_globals.last_frame_directional_lights);
+ // UBOs
+ if (scene_state.ubo_buffer != 0) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.ubo_buffer);
+ }
+
+ if (scene_state.multiview_buffer != 0) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.multiview_buffer);
+ }
+
+ if (scene_state.tonemap_buffer != 0) {
+ GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.tonemap_buffer);
+ }
+
singleton = nullptr;
}
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index b4e787ad85..9709d6be2a 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -220,6 +220,7 @@ private:
uint32_t flags = 0;
uint32_t surface_index = 0;
uint32_t lod_index = 0;
+ uint32_t index_count = 0;
void *surface = nullptr;
GLES3::SceneShaderData *shader = nullptr;
diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp
index 8da5e657cd..5aab91e8ae 100644
--- a/drivers/gles3/storage/light_storage.cpp
+++ b/drivers/gles3/storage/light_storage.cpp
@@ -595,106 +595,6 @@ void LightStorage::lightmap_instance_free(RID p_lightmap) {
void LightStorage::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) {
}
-/* LIGHT SHADOW MAPPING */
-/*
-
-RID LightStorage::canvas_light_occluder_create() {
- CanvasOccluder *co = memnew(CanvasOccluder);
- co->index_id = 0;
- co->vertex_id = 0;
- co->len = 0;
-
- return canvas_occluder_owner.make_rid(co);
-}
-
-void LightStorage::canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines) {
- CanvasOccluder *co = canvas_occluder_owner.get(p_occluder);
- ERR_FAIL_COND(!co);
-
- co->lines = p_lines;
-
- if (p_lines.size() != co->len) {
- if (co->index_id) {
- glDeleteBuffers(1, &co->index_id);
- } if (co->vertex_id) {
- glDeleteBuffers(1, &co->vertex_id);
- }
-
- co->index_id = 0;
- co->vertex_id = 0;
- co->len = 0;
- }
-
- if (p_lines.size()) {
- PoolVector<float> geometry;
- PoolVector<uint16_t> indices;
- int lc = p_lines.size();
-
- geometry.resize(lc * 6);
- indices.resize(lc * 3);
-
- PoolVector<float>::Write vw = geometry.write();
- PoolVector<uint16_t>::Write iw = indices.write();
-
- PoolVector<Vector2>::Read lr = p_lines.read();
-
- const int POLY_HEIGHT = 16384;
-
- for (int i = 0; i < lc / 2; i++) {
- vw[i * 12 + 0] = lr[i * 2 + 0].x;
- vw[i * 12 + 1] = lr[i * 2 + 0].y;
- vw[i * 12 + 2] = POLY_HEIGHT;
-
- vw[i * 12 + 3] = lr[i * 2 + 1].x;
- vw[i * 12 + 4] = lr[i * 2 + 1].y;
- vw[i * 12 + 5] = POLY_HEIGHT;
-
- vw[i * 12 + 6] = lr[i * 2 + 1].x;
- vw[i * 12 + 7] = lr[i * 2 + 1].y;
- vw[i * 12 + 8] = -POLY_HEIGHT;
-
- vw[i * 12 + 9] = lr[i * 2 + 0].x;
- vw[i * 12 + 10] = lr[i * 2 + 0].y;
- vw[i * 12 + 11] = -POLY_HEIGHT;
-
- iw[i * 6 + 0] = i * 4 + 0;
- iw[i * 6 + 1] = i * 4 + 1;
- iw[i * 6 + 2] = i * 4 + 2;
-
- iw[i * 6 + 3] = i * 4 + 2;
- iw[i * 6 + 4] = i * 4 + 3;
- iw[i * 6 + 5] = i * 4 + 0;
- }
-
- //if same buffer len is being set, just use BufferSubData to avoid a pipeline flush
-
- if (!co->vertex_id) {
- glGenBuffers(1, &co->vertex_id);
- glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
- glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
- } else {
- glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
- glBufferSubData(GL_ARRAY_BUFFER, 0, lc * 6 * sizeof(real_t), vw.ptr());
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
-
- if (!co->index_id) {
- glGenBuffers(1, &co->index_id);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_DYNAMIC_DRAW);
- } else {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, lc * 3 * sizeof(uint16_t), iw.ptr());
- }
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
-
- co->len = lc;
- }
-}
-*/
-
/* SHADOW ATLAS API */
RID LightStorage::shadow_atlas_create() {
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp
index 585ed5ff96..8a027aad1c 100644
--- a/drivers/gles3/storage/mesh_storage.cpp
+++ b/drivers/gles3/storage/mesh_storage.cpp
@@ -193,26 +193,26 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
if (p_surface.vertex_data.size()) {
glGenBuffers(1, &s->vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s->vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, p_surface.vertex_data.size(), p_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->vertex_buffer, p_surface.vertex_data.size(), p_surface.vertex_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh vertex buffer");
s->vertex_buffer_size = p_surface.vertex_data.size();
}
if (p_surface.attribute_data.size()) {
glGenBuffers(1, &s->attribute_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s->attribute_buffer);
- glBufferData(GL_ARRAY_BUFFER, p_surface.attribute_data.size(), p_surface.attribute_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->attribute_buffer, p_surface.attribute_data.size(), p_surface.attribute_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh attribute buffer");
s->attribute_buffer_size = p_surface.attribute_data.size();
}
+
if (p_surface.skin_data.size()) {
glGenBuffers(1, &s->skin_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s->skin_buffer);
- glBufferData(GL_ARRAY_BUFFER, p_surface.skin_data.size(), p_surface.skin_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->skin_buffer, p_surface.skin_data.size(), p_surface.skin_data.ptr(), (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh skin buffer");
s->skin_buffer_size = p_surface.skin_data.size();
}
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
s->vertex_count = p_surface.vertex_count;
if (p_surface.format & RS::ARRAY_FORMAT_BONES) {
@@ -223,7 +223,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
bool is_index_16 = p_surface.vertex_count <= 65536 && p_surface.vertex_count > 0;
glGenBuffers(1, &s->index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_surface.index_data.size(), p_surface.index_data.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, s->index_buffer, p_surface.index_data.size(), p_surface.index_data.ptr(), GL_STATIC_DRAW, "Mesh index buffer");
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
s->index_count = p_surface.index_count;
s->index_buffer_size = p_surface.index_data.size();
@@ -235,7 +235,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
for (int i = 0; i < p_surface.lods.size(); i++) {
glGenBuffers(1, &s->lods[i].index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->lods[i].index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_surface.lods[i].index_data.size(), p_surface.lods[i].index_data.ptr(), GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, s->lods[i].index_buffer, p_surface.lods[i].index_data.size(), p_surface.lods[i].index_data.ptr(), GL_STATIC_DRAW, "Mesh index buffer LOD[" + itos(i) + "]");
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
s->lods[i].edge_length = p_surface.lods[i].edge_length;
s->lods[i].index_count = p_surface.lods[i].index_data.size() / (is_index_16 ? 2 : 4);
@@ -282,7 +282,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
glBindVertexArray(s->blend_shapes[i].vertex_array);
glGenBuffers(1, &s->blend_shapes[i].vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s->blend_shapes[i].vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, size, p_surface.blend_shape_data.ptr() + i * size, (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s->blend_shapes[i].vertex_buffer, size, p_surface.blend_shape_data.ptr() + i * size, (s->format & RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW, "Mesh blend shape buffer");
if ((p_surface.format & (1 << RS::ARRAY_VERTEX))) {
glEnableVertexAttribArray(RS::ARRAY_VERTEX + 3);
@@ -637,7 +637,7 @@ void MeshStorage::mesh_clear(RID p_mesh) {
Mesh::Surface &s = *mesh->surfaces[i];
if (s.vertex_buffer != 0) {
- glDeleteBuffers(1, &s.vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.vertex_buffer);
s.vertex_buffer = 0;
}
@@ -649,17 +649,17 @@ void MeshStorage::mesh_clear(RID p_mesh) {
}
if (s.attribute_buffer != 0) {
- glDeleteBuffers(1, &s.attribute_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.attribute_buffer);
s.attribute_buffer = 0;
}
if (s.skin_buffer != 0) {
- glDeleteBuffers(1, &s.skin_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.skin_buffer);
s.skin_buffer = 0;
}
if (s.index_buffer != 0) {
- glDeleteBuffers(1, &s.index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.index_buffer);
s.index_buffer = 0;
}
@@ -670,7 +670,7 @@ void MeshStorage::mesh_clear(RID p_mesh) {
if (s.lod_count) {
for (uint32_t j = 0; j < s.lod_count; j++) {
if (s.lods[j].index_buffer != 0) {
- glDeleteBuffers(1, &s.lods[j].index_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.lods[j].index_buffer);
s.lods[j].index_buffer = 0;
}
}
@@ -680,7 +680,7 @@ void MeshStorage::mesh_clear(RID p_mesh) {
if (mesh->blend_shape_count) {
for (uint32_t j = 0; j < mesh->blend_shape_count; j++) {
if (s.blend_shapes[j].vertex_buffer != 0) {
- glDeleteBuffers(1, &s.blend_shapes[j].vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(s.blend_shapes[j].vertex_buffer);
s.blend_shapes[j].vertex_buffer = 0;
}
if (s.blend_shapes[j].vertex_array != 0) {
@@ -916,13 +916,14 @@ void MeshStorage::_mesh_instance_clear(MeshInstance *mi) {
}
if (mi->surfaces[i].vertex_buffers[0] != 0) {
- glDeleteBuffers(2, mi->surfaces[i].vertex_buffers);
+ GLES3::Utilities::get_singleton()->buffer_free_data(mi->surfaces[i].vertex_buffers[0]);
+ GLES3::Utilities::get_singleton()->buffer_free_data(mi->surfaces[i].vertex_buffers[1]);
mi->surfaces[i].vertex_buffers[0] = 0;
mi->surfaces[i].vertex_buffers[1] = 0;
}
if (mi->surfaces[i].vertex_buffer != 0) {
- glDeleteBuffers(1, &mi->surfaces[i].vertex_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(mi->surfaces[i].vertex_buffer);
mi->surfaces[i].vertex_buffer = 0;
}
}
@@ -963,13 +964,13 @@ void MeshStorage::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint3
// Buffer to be used for rendering. Final output of skeleton and blend shapes.
glGenBuffers(1, &s.vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count, nullptr, GL_DYNAMIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s.vertex_buffer, s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count, nullptr, GL_DYNAMIC_DRAW, "MeshInstance vertex buffer");
if (mesh->blend_shape_count > 0) {
// Ping-Pong buffers for processing blendshapes.
glGenBuffers(2, s.vertex_buffers);
for (uint32_t i = 0; i < 2; i++) {
glBindBuffer(GL_ARRAY_BUFFER, s.vertex_buffers[i]);
- glBufferData(GL_ARRAY_BUFFER, s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count, nullptr, GL_DYNAMIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, s.vertex_buffers[i], s.vertex_stride_cache * mesh->surfaces[p_surface]->vertex_count, nullptr, GL_DYNAMIC_DRAW, "MeshInstance process buffer[" + itos(i) + "]");
}
}
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
@@ -1271,7 +1272,7 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
}
if (multimesh->buffer) {
- glDeleteBuffers(1, &multimesh->buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(multimesh->buffer);
multimesh->buffer = 0;
}
@@ -1298,7 +1299,7 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
if (multimesh->instances) {
glGenBuffers(1, &multimesh->buffer);
glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
- glBufferData(GL_ARRAY_BUFFER, multimesh->instances * multimesh->stride_cache * sizeof(float), nullptr, GL_STATIC_DRAW);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, multimesh->buffer, multimesh->instances * multimesh->stride_cache * sizeof(float), nullptr, GL_STATIC_DRAW, "MultiMesh buffer");
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
@@ -1958,7 +1959,7 @@ void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_
}
if (skeleton->transforms_texture != 0) {
- glDeleteTextures(1, &skeleton->transforms_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(skeleton->transforms_texture);
skeleton->transforms_texture = 0;
skeleton->data.clear();
}
@@ -1973,6 +1974,7 @@ void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(skeleton->transforms_texture, skeleton->data.size() * sizeof(float), "Skeleton transforms texture");
memset(skeleton->data.ptrw(), 0, skeleton->data.size() * sizeof(float));
diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp
index 4b64e2aec1..dbd86451d2 100644
--- a/drivers/gles3/storage/particles_storage.cpp
+++ b/drivers/gles3/storage/particles_storage.cpp
@@ -141,23 +141,23 @@ void ParticlesStorage::_particles_free_data(Particles *particles) {
if (particles->front_process_buffer != 0) {
glDeleteVertexArrays(1, &particles->front_vertex_array);
- glDeleteBuffers(1, &particles->front_process_buffer);
- glDeleteBuffers(1, &particles->front_instance_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->front_process_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->front_instance_buffer);
particles->front_vertex_array = 0;
particles->front_process_buffer = 0;
particles->front_instance_buffer = 0;
glDeleteVertexArrays(1, &particles->back_vertex_array);
- glDeleteBuffers(1, &particles->back_process_buffer);
- glDeleteBuffers(1, &particles->back_instance_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->back_process_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->back_instance_buffer);
particles->back_vertex_array = 0;
particles->back_process_buffer = 0;
particles->back_instance_buffer = 0;
}
if (particles->sort_buffer != 0) {
- glDeleteBuffers(1, &particles->last_frame_buffer);
- glDeleteBuffers(1, &particles->sort_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->last_frame_buffer);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->sort_buffer);
particles->last_frame_buffer = 0;
particles->sort_buffer = 0;
particles->sort_buffer_filled = false;
@@ -165,7 +165,7 @@ void ParticlesStorage::_particles_free_data(Particles *particles) {
}
if (particles->frame_params_ubo != 0) {
- glDeleteBuffers(1, &particles->frame_params_ubo);
+ GLES3::Utilities::get_singleton()->buffer_free_data(particles->frame_params_ubo);
particles->frame_params_ubo = 0;
}
}
@@ -680,10 +680,13 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
if (p_particles->frame_params_ubo == 0) {
glGenBuffers(1, &p_particles->frame_params_ubo);
+ glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, p_particles->frame_params_ubo, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW, "Particle Frame UBO");
+ } else {
+ // Update per-frame UBO.
+ glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW);
}
- // Update per-frame UBO.
- glBindBufferBase(GL_UNIFORM_BUFFER, PARTICLES_FRAME_UNIFORM_LOCATION, p_particles->frame_params_ubo);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(ParticlesFrameParams), &frame_params, GL_STREAM_DRAW);
// Get shader and set shader uniforms;
ParticleProcessMaterialData *m = static_cast<ParticleProcessMaterialData *>(material_storage->material_get_data(p_particles->process_material, RS::SHADER_PARTICLES));
@@ -831,7 +834,7 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
glGenBuffers(1, &particles->front_instance_buffer);
glBindBuffer(GL_ARRAY_BUFFER, particles->front_process_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->process_buffer_stride_cache * total_amount, data, GL_DYNAMIC_COPY);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->front_process_buffer, particles->process_buffer_stride_cache * total_amount, data, GL_DYNAMIC_COPY, "Particles front process buffer");
for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
glEnableVertexAttribArray(j);
@@ -840,7 +843,7 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, particles->front_instance_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_COPY);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->front_instance_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_COPY, "Particles front instance buffer");
}
{
@@ -850,7 +853,7 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
glGenBuffers(1, &particles->back_instance_buffer);
glBindBuffer(GL_ARRAY_BUFFER, particles->back_process_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->process_buffer_stride_cache * total_amount, data, GL_DYNAMIC_COPY);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->back_process_buffer, particles->process_buffer_stride_cache * total_amount, data, GL_DYNAMIC_COPY, "Particles back process buffer");
for (uint32_t j = 0; j < particles->num_attrib_arrays_cache; j++) {
glEnableVertexAttribArray(j);
@@ -859,7 +862,7 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, particles->back_instance_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_COPY);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->back_instance_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_COPY, "Particles back instance buffer");
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -871,11 +874,12 @@ void ParticlesStorage::_particles_allocate_history_buffers(Particles *particles)
if (particles->sort_buffer == 0) {
glGenBuffers(1, &particles->last_frame_buffer);
glBindBuffer(GL_ARRAY_BUFFER, particles->last_frame_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->last_frame_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ, "Particles last frame buffer");
glGenBuffers(1, &particles->sort_buffer);
glBindBuffer(GL_ARRAY_BUFFER, particles->sort_buffer);
- glBufferData(GL_ARRAY_BUFFER, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ);
+ GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, particles->sort_buffer, particles->instance_buffer_size_cache, nullptr, GL_DYNAMIC_READ, "Particles sort buffer");
+
particles->sort_buffer_filled = false;
particles->last_frame_buffer_filled = false;
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -1179,7 +1183,7 @@ void ParticlesStorage::particles_collision_free(RID p_rid) {
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_rid);
if (particles_collision->heightfield_texture != 0) {
- glDeleteTextures(1, &particles_collision->heightfield_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
particles_collision->heightfield_texture = 0;
glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
particles_collision->heightfield_fb = 0;
@@ -1226,6 +1230,8 @@ GLuint ParticlesStorage::particles_collision_get_heightfield_framebuffer(RID p_p
WARN_PRINT("Could create heightmap texture status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
}
#endif
+ GLES3::Utilities::get_singleton()->texture_allocated_data(particles_collision->heightfield_texture, size.x * size.y * 4, "Particles collision heightfield texture");
+
particles_collision->heightfield_fb_size = size;
glBindTexture(GL_TEXTURE_2D, 0);
@@ -1244,7 +1250,7 @@ void ParticlesStorage::particles_collision_set_collision_type(RID p_particles_co
}
if (particles_collision->heightfield_texture != 0) {
- glDeleteTextures(1, &particles_collision->heightfield_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
particles_collision->heightfield_texture = 0;
glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
particles_collision->heightfield_fb = 0;
@@ -1319,7 +1325,7 @@ void ParticlesStorage::particles_collision_set_height_field_resolution(RID p_par
particles_collision->heightfield_resolution = p_resolution;
if (particles_collision->heightfield_texture != 0) {
- glDeleteTextures(1, &particles_collision->heightfield_texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(particles_collision->heightfield_texture);
particles_collision->heightfield_texture = 0;
glDeleteFramebuffers(1, &particles_collision->heightfield_fb);
particles_collision->heightfield_fb = 0;
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index c4fef89cfd..05b4443963 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -33,6 +33,7 @@
#include "texture_storage.h"
#include "config.h"
#include "drivers/gles3/effects/copy_effects.h"
+#include "utilities.h"
#ifdef ANDROID_ENABLED
#define glFramebufferTextureMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultiviewOVR
@@ -164,6 +165,7 @@ TextureStorage::TextureStorage() {
glBindTexture(GL_TEXTURE_2D, texture.tex_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 4, 4, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixel_data);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 4, "Default uint texture");
texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
}
{
@@ -185,6 +187,7 @@ TextureStorage::TextureStorage() {
glBindTexture(GL_TEXTURE_2D, texture.tex_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 4, 4, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixel_data);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 2, "Default depth texture");
texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
}
}
@@ -203,6 +206,7 @@ TextureStorage::TextureStorage() {
glGenTextures(1, &texture_atlas.texture);
glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, 4 * 4 * 4, "Texture atlas (Default)");
}
glBindTexture(GL_TEXTURE_2D, 0);
@@ -222,8 +226,9 @@ TextureStorage::~TextureStorage() {
for (int i = 0; i < DEFAULT_GL_TEXTURE_MAX; i++) {
texture_free(default_gl_textures[i]);
}
-
- glDeleteTextures(1, &texture_atlas.texture);
+ if (texture_atlas.texture != 0) {
+ GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
+ }
texture_atlas.texture = 0;
glDeleteFramebuffers(1, &texture_atlas.framebuffer);
texture_atlas.framebuffer = 0;
@@ -706,7 +711,7 @@ void TextureStorage::texture_free(RID p_texture) {
if (t->tex_id != 0) {
if (!t->is_external) {
- glDeleteTextures(1, &t->tex_id);
+ GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);
}
t->tex_id = 0;
}
@@ -743,9 +748,10 @@ void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_im
texture.type = Texture::TYPE_2D;
texture.target = GL_TEXTURE_2D;
_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);
- //texture.total_data_size = p_image->get_image_data_size(); // verify that this returns size in bytes
+ texture.total_data_size = p_image->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps);
texture.active = true;
glGenTextures(1, &texture.tex_id);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 2D");
texture_owner.initialize_rid(p_texture, texture);
texture_set_data(p_texture, p_image);
}
@@ -792,8 +798,10 @@ void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<R
texture.target = p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D_ARRAY;
texture.layers = p_layers.size();
_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);
+ texture.total_data_size = p_layers[0]->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps) * texture.layers;
texture.active = true;
glGenTextures(1, &texture.tex_id);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture Layered");
texture_owner.initialize_rid(p_texture, texture);
for (int i = 0; i < p_layers.size(); i++) {
_texture_set_data(p_texture, p_layers[i], i, i == 0);
@@ -850,10 +858,12 @@ RID TextureStorage::texture_create_external(Texture::Type p_type, Image::Format
void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
texture_set_data(p_texture, p_image, p_layer);
-#ifdef TOOLS_ENABLED
+
Texture *tex = texture_owner.get_or_null(p_texture);
ERR_FAIL_COND(!tex);
+ GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);
+#ifdef TOOLS_ENABLED
tex->image_cache_2d.unref();
#endif
}
@@ -1063,7 +1073,7 @@ void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
}
if (tex_to->tex_id) {
- glDeleteTextures(1, &tex_to->tex_id);
+ GLES3::Utilities::get_singleton()->texture_free_data(tex_to->tex_id);
tex_to->tex_id = 0;
}
@@ -1213,15 +1223,11 @@ void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image,
ERR_FAIL_COND(!p_image->get_width());
ERR_FAIL_COND(!p_image->get_height());
- // ERR_FAIL_COND(texture->type == RS::TEXTURE_TYPE_EXTERNAL);
-
GLenum type;
GLenum format;
GLenum internal_format;
bool compressed = false;
- // print_line("texture_set_data width " + itos (p_image->get_width()) + " height " + itos(p_image->get_height()));
-
Image::Format real_format;
Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), real_format, format, internal_format, type, compressed, texture->resize_to_po2);
ERR_FAIL_COND(img.is_null());
@@ -1322,21 +1328,13 @@ void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image,
h = MAX(1, h >> 1);
}
- // info.texture_mem -= texture->total_data_size; // TODO make this work again!!
texture->total_data_size = tsize;
- // info.texture_mem += texture->total_data_size; // TODO make this work again!!
-
- // printf("texture: %i x %i - size: %i - total: %i\n", texture->width, texture->height, tsize, info.texture_mem);
texture->stored_cube_sides |= (1 << p_layer);
texture->mipmaps = mipmaps;
}
-void TextureStorage::texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer) {
- ERR_PRINT("Not implemented yet, sorry :(");
-}
-
Image::Format TextureStorage::texture_get_format(RID p_texture) const {
Texture *texture = texture_owner.get_or_null(p_texture);
@@ -1386,10 +1384,6 @@ void TextureStorage::texture_bind(RID p_texture, uint32_t p_texture_no) {
glBindTexture(texture->target, texture->tex_id);
}
-RID TextureStorage::texture_create_radiance_cubemap(RID p_source, int p_resolution) const {
- return RID();
-}
-
/* TEXTURE ATLAS API */
void TextureStorage::texture_add_to_texture_atlas(RID p_texture) {
@@ -1442,7 +1436,7 @@ void TextureStorage::update_texture_atlas() {
texture_atlas.dirty = false;
if (texture_atlas.texture != 0) {
- glDeleteTextures(1, &texture_atlas.texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
texture_atlas.texture = 0;
glDeleteFramebuffers(1, &texture_atlas.framebuffer);
texture_atlas.framebuffer = 0;
@@ -1559,6 +1553,7 @@ void TextureStorage::update_texture_atlas() {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture_atlas.size.width, texture_atlas.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, texture_atlas.size.width * texture_atlas.size.height * 4, "Texture atlas");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -1576,7 +1571,7 @@ void TextureStorage::update_texture_atlas() {
if (status != GL_FRAMEBUFFER_COMPLETE) {
glDeleteFramebuffers(1, &texture_atlas.framebuffer);
texture_atlas.framebuffer = 0;
- glDeleteTextures(1, &texture_atlas.texture);
+ GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
texture_atlas.texture = 0;
WARN_PRINT("Could not create texture atlas, status: " + get_framebuffer_error(status));
return;
@@ -1702,6 +1697,8 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->color, rt->size.x * rt->size.y * rt->view_count * 4, "Render target color texture");
}
#ifndef IOS_ENABLED
if (use_multiview) {
@@ -1733,6 +1730,8 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->depth, rt->size.x * rt->size.y * rt->view_count * 3, "Render target depth texture");
}
#ifndef IOS_ENABLED
if (use_multiview) {
@@ -1747,7 +1746,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
glDeleteFramebuffers(1, &rt->fbo);
- glDeleteTextures(1, &rt->color);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->color);
rt->fbo = 0;
rt->size.x = 0;
rt->size.y = 0;
@@ -1805,8 +1804,10 @@ void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {
glGenTextures(1, &rt->backbuffer);
glBindTexture(GL_TEXTURE_2D, rt->backbuffer);
+ uint32_t texture_size_bytes = 0;
for (int l = 0; l < count; l++) {
+ texture_size_bytes += width * height * 4;
glTexImage2D(GL_TEXTURE_2D, l, rt->color_internal_format, width, height, 0, rt->color_format, rt->color_type, nullptr);
width = MAX(1, (width / 2));
height = MAX(1, (height / 2));
@@ -1826,6 +1827,7 @@ void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {
glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
return;
}
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, texture_size_bytes, "Render target backbuffer color texture");
// Initialize all levels to opaque Magenta.
for (int j = 0; j < count; j++) {
@@ -1862,7 +1864,7 @@ void GLES3::TextureStorage::copy_scene_to_backbuffer(RenderTarget *rt, const boo
} else {
glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);
}
-
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, rt->size.x * rt->size.y * rt->view_count * 4, "Render target backbuffer color texture (3D)");
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -1885,6 +1887,8 @@ void GLES3::TextureStorage::copy_scene_to_backbuffer(RenderTarget *rt, const boo
} else {
glTexImage2D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
}
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer_depth, rt->size.x * rt->size.y * rt->view_count * 3, "Render target backbuffer depth texture");
+
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -1941,7 +1945,7 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
if (rt->overridden.color.is_valid()) {
rt->overridden.color = RID();
} else if (rt->color) {
- glDeleteTextures(1, &rt->color);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->color);
if (rt->texture.is_valid()) {
Texture *tex = get_texture(rt->texture);
tex->tex_id = 0;
@@ -1952,7 +1956,7 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
if (rt->overridden.depth.is_valid()) {
rt->overridden.depth = RID();
} else if (rt->depth) {
- glDeleteTextures(1, &rt->depth);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);
}
rt->depth = 0;
@@ -1961,12 +1965,12 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
if (rt->backbuffer_fbo != 0) {
glDeleteFramebuffers(1, &rt->backbuffer_fbo);
- glDeleteTextures(1, &rt->backbuffer);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer);
rt->backbuffer = 0;
rt->backbuffer_fbo = 0;
}
if (rt->backbuffer_depth != 0) {
- glDeleteTextures(1, &rt->backbuffer_depth);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer_depth);
rt->backbuffer_depth = 0;
}
_render_target_clear_sdf(rt);
@@ -2331,6 +2335,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size.width, size.height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_write, size.width * size.height, "SDF texture");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
@@ -2371,6 +2376,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[0], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[0]");
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);
@@ -2380,6 +2386,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[1], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[1]");
glGenTextures(1, &rt->sdf_texture_read);
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_read);
@@ -2390,13 +2397,16 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_read, rt->process_size.width * rt->process_size.height * 4, "SDF texture (read)");
}
void TextureStorage::_render_target_clear_sdf(RenderTarget *rt) {
if (rt->sdf_texture_write_fb != 0) {
- glDeleteTextures(1, &rt->sdf_texture_read);
- glDeleteTextures(1, &rt->sdf_texture_write);
- glDeleteTextures(2, rt->sdf_texture_process);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_read);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_write);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[0]);
+ GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[1]);
+
glDeleteFramebuffers(1, &rt->sdf_texture_write_fb);
rt->sdf_texture_read = 0;
rt->sdf_texture_write = 0;
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index 2b939aa7fa..7aa69d48be 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -542,16 +542,12 @@ public:
virtual uint64_t texture_get_native_handle(RID p_texture, bool p_srgb = false) const override;
void texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer = 0);
- void texture_set_data_partial(RID p_texture, const Ref<Image> &p_image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int p_dst_mip, int p_layer = 0);
- //Ref<Image> texture_get_data(RID p_texture, int p_layer = 0) const;
- void texture_set_sampler(RID p_texture, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat);
Image::Format texture_get_format(RID p_texture) const;
uint32_t texture_get_texid(RID p_texture) const;
uint32_t texture_get_width(RID p_texture) const;
uint32_t texture_get_height(RID p_texture) const;
uint32_t texture_get_depth(RID p_texture) const;
void texture_bind(RID p_texture, uint32_t p_texture_no);
- RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const;
/* TEXTURE ATLAS API */
diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp
index 5f21d8f70a..3e6e72edad 100644
--- a/drivers/gles3/storage/utilities.cpp
+++ b/drivers/gles3/storage/utilities.cpp
@@ -67,6 +67,37 @@ Utilities::~Utilities() {
for (int i = 0; i < FRAME_COUNT; i++) {
glDeleteQueries(max_timestamp_query_elements, frames[i].queries);
}
+
+ if (texture_mem_cache) {
+ uint32_t leaked_data_size = 0;
+ for (const KeyValue<GLuint, ResourceAllocation> &E : texture_allocs_cache) {
+#ifdef DEV_ENABLED
+ ERR_PRINT(E.value.name + ": leaked " + itos(E.value.size) + " bytes.");
+#else
+ ERR_PRINT("Texture with GL ID of " + itos(E.key) + ": leaked " + itos(E.value.size) + " bytes.");
+#endif
+ leaked_data_size += E.value.size;
+ }
+ if (leaked_data_size < texture_mem_cache) {
+ ERR_PRINT("Texture cache is not empty. There may be an additional texture leak of " + itos(texture_mem_cache - leaked_data_size) + " bytes.");
+ }
+ }
+
+ if (buffer_mem_cache) {
+ uint32_t leaked_data_size = 0;
+
+ for (const KeyValue<GLuint, ResourceAllocation> &E : buffer_allocs_cache) {
+#ifdef DEV_ENABLED
+ ERR_PRINT(E.value.name + ": leaked " + itos(E.value.size) + " bytes.");
+#else
+ ERR_PRINT("Buffer with GL ID of " + itos(E.key) + ": leaked " + itos(E.value.size) + " bytes.");
+#endif
+ leaked_data_size += E.value.size;
+ }
+ if (leaked_data_size < buffer_mem_cache) {
+ ERR_PRINT("Buffer cache is not empty. There may be an additional buffer leak of " + itos(buffer_mem_cache - leaked_data_size) + " bytes.");
+ }
+ }
}
Vector<uint8_t> Utilities::buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size) {
@@ -324,6 +355,13 @@ void Utilities::update_memory_info() {
}
uint64_t Utilities::get_rendering_info(RS::RenderingInfo p_info) {
+ if (p_info == RS::RENDERING_INFO_TEXTURE_MEM_USED) {
+ return texture_mem_cache;
+ } else if (p_info == RS::RENDERING_INFO_BUFFER_MEM_USED) {
+ return buffer_mem_cache;
+ } else if (p_info == RS::RENDERING_INFO_VIDEO_MEM_USED) {
+ return texture_mem_cache + buffer_mem_cache;
+ }
return 0;
}
diff --git a/drivers/gles3/storage/utilities.h b/drivers/gles3/storage/utilities.h
index 92131aff8c..243342014b 100644
--- a/drivers/gles3/storage/utilities.h
+++ b/drivers/gles3/storage/utilities.h
@@ -48,6 +48,18 @@ class Utilities : public RendererUtilities {
private:
static Utilities *singleton;
+ struct ResourceAllocation {
+#ifdef DEV_ENABLED
+ String name;
+#endif
+ uint32_t size = 0;
+ };
+ HashMap<GLuint, ResourceAllocation> buffer_allocs_cache;
+ HashMap<GLuint, ResourceAllocation> texture_allocs_cache;
+
+ uint64_t buffer_mem_cache = 0;
+ uint64_t texture_mem_cache = 0;
+
public:
static Utilities *get_singleton() { return singleton; }
@@ -57,6 +69,58 @@ public:
// Buffer size is specified in bytes
static Vector<uint8_t> buffer_get_data(GLenum p_target, GLuint p_buffer, uint32_t p_buffer_size);
+ // Allocate memory with glBufferData. Does not handle resizing.
+ _FORCE_INLINE_ void buffer_allocate_data(GLenum p_target, GLuint p_id, uint32_t p_size, const void *p_data, GLenum p_usage, String p_name = "") {
+ glBufferData(p_target, p_size, p_data, p_usage);
+ buffer_mem_cache += p_size;
+
+#ifdef DEV_ENABLED
+ ERR_FAIL_COND_MSG(buffer_allocs_cache.has(p_id), "trying to allocate buffer with name " + p_name + " but ID already used by " + buffer_allocs_cache[p_id].name);
+#endif
+
+ ResourceAllocation resource_allocation;
+ resource_allocation.size = p_size;
+#ifdef DEV_ENABLED
+ resource_allocation.name = p_name + ": " + itos((uint64_t)p_id);
+#endif
+ buffer_allocs_cache[p_id] = resource_allocation;
+ }
+
+ _FORCE_INLINE_ void buffer_free_data(GLuint p_id) {
+ ERR_FAIL_COND(!buffer_allocs_cache.has(p_id));
+ glDeleteBuffers(1, &p_id);
+ buffer_mem_cache -= buffer_allocs_cache[p_id].size;
+ buffer_allocs_cache.erase(p_id);
+ }
+
+ // Records that data was allocated for state tracking purposes.
+ _FORCE_INLINE_ void texture_allocated_data(GLuint p_id, uint32_t p_size, String p_name = "") {
+ texture_mem_cache += p_size;
+#ifdef DEV_ENABLED
+ ERR_FAIL_COND_MSG(texture_allocs_cache.has(p_id), "trying to allocate texture with name " + p_name + " but ID already used by " + texture_allocs_cache[p_id].name);
+#endif
+ ResourceAllocation resource_allocation;
+ resource_allocation.size = p_size;
+#ifdef DEV_ENABLED
+ resource_allocation.name = p_name + ": " + itos((uint64_t)p_id);
+#endif
+ texture_allocs_cache[p_id] = resource_allocation;
+ }
+
+ _FORCE_INLINE_ void texture_free_data(GLuint p_id) {
+ ERR_FAIL_COND(!texture_allocs_cache.has(p_id));
+ glDeleteTextures(1, &p_id);
+ texture_mem_cache -= texture_allocs_cache[p_id].size;
+ texture_allocs_cache.erase(p_id);
+ }
+
+ _FORCE_INLINE_ void texture_resize_data(GLuint p_id, uint32_t p_size) {
+ ERR_FAIL_COND(!texture_allocs_cache.has(p_id));
+ texture_mem_cache -= texture_allocs_cache[p_id].size;
+ texture_mem_cache += p_size;
+ texture_allocs_cache[p_id].size = p_size;
+ }
+
/* INSTANCES */
virtual RS::InstanceType get_base_type(RID p_rid) const override;
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 67a8814aa1..91358c3475 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -502,6 +502,7 @@ void DocTools::generate(bool p_basic_types) {
found_type = true;
if (retinfo.type == Variant::INT && retinfo.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
prop.enumeration = retinfo.class_name;
+ prop.is_bitfield = retinfo.usage & PROPERTY_USAGE_CLASS_IS_BITFIELD;
prop.type = "int";
} else if (retinfo.class_name != StringName()) {
prop.type = retinfo.class_name;
@@ -1065,6 +1066,9 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
method.return_type = parser->get_named_attribute_value("type");
if (parser->has_attribute("enum")) {
method.return_enum = parser->get_named_attribute_value("enum");
+ if (parser->has_attribute("is_bitfield")) {
+ method.return_is_bitfield = parser->get_named_attribute_value("is_bitfield").to_lower() == "true";
+ }
}
} else if (name == "returns_error") {
ERR_FAIL_COND_V(!parser->has_attribute("number"), ERR_FILE_CORRUPT);
@@ -1077,6 +1081,9 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
argument.type = parser->get_named_attribute_value("type");
if (parser->has_attribute("enum")) {
argument.enumeration = parser->get_named_attribute_value("enum");
+ if (parser->has_attribute("is_bitfield")) {
+ argument.is_bitfield = parser->get_named_attribute_value("is_bitfield").to_lower() == "true";
+ }
}
method.arguments.push_back(argument);
@@ -1267,6 +1274,9 @@ Error DocTools::_load(Ref<XMLParser> parser) {
}
if (parser->has_attribute("enum")) {
prop2.enumeration = parser->get_named_attribute_value("enum");
+ if (parser->has_attribute("is_bitfield")) {
+ prop2.is_bitfield = parser->get_named_attribute_value("is_bitfield").to_lower() == "true";
+ }
}
if (parser->has_attribute("is_deprecated")) {
prop2.is_deprecated = parser->get_named_attribute_value("is_deprecated").to_lower() == "true";
@@ -1334,9 +1344,9 @@ Error DocTools::_load(Ref<XMLParser> parser) {
constant2.is_value_valid = true;
if (parser->has_attribute("enum")) {
constant2.enumeration = parser->get_named_attribute_value("enum");
- }
- if (parser->has_attribute("is_bitfield")) {
- constant2.is_bitfield = parser->get_named_attribute_value("is_bitfield").to_lower() == "true";
+ if (parser->has_attribute("is_bitfield")) {
+ constant2.is_bitfield = parser->get_named_attribute_value("is_bitfield").to_lower() == "true";
+ }
}
if (parser->has_attribute("is_deprecated")) {
constant2.is_deprecated = parser->get_named_attribute_value("is_deprecated").to_lower() == "true";
@@ -1407,6 +1417,9 @@ static void _write_method_doc(Ref<FileAccess> f, const String &p_name, Vector<Do
String enum_text;
if (!m.return_enum.is_empty()) {
enum_text = " enum=\"" + m.return_enum + "\"";
+ if (m.return_is_bitfield) {
+ enum_text += " is_bitfield=\"true\"";
+ }
}
_write_string(f, 3, "<return type=\"" + m.return_type.xml_escape(true) + "\"" + enum_text + " />");
}
@@ -1422,6 +1435,9 @@ static void _write_method_doc(Ref<FileAccess> f, const String &p_name, Vector<Do
String enum_text;
if (!a.enumeration.is_empty()) {
enum_text = " enum=\"" + a.enumeration + "\"";
+ if (a.is_bitfield) {
+ enum_text += " is_bitfield=\"true\"";
+ }
}
if (!a.default_value.is_empty()) {
@@ -1512,6 +1528,9 @@ Error DocTools::save_classes(const String &p_default_path, const HashMap<String,
String additional_attributes;
if (!c.properties[i].enumeration.is_empty()) {
additional_attributes += " enum=\"" + c.properties[i].enumeration + "\"";
+ if (c.properties[i].is_bitfield) {
+ additional_attributes += " is_bitfield=\"true\"";
+ }
}
if (!c.properties[i].default_value.is_empty()) {
additional_attributes += " default=\"" + c.properties[i].default_value.xml_escape(true) + "\"";
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index e709371ec6..991807ccbb 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -293,7 +293,7 @@ void EditorHelp::_class_desc_resized(bool p_force_update_theme) {
}
}
-void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
+void EditorHelp::_add_type(const String &p_type, const String &p_enum, bool p_is_bitfield) {
if (p_type.is_empty() || p_type == "void") {
class_desc->push_color(Color(theme_cache.type_color, 0.5));
class_desc->push_hint(TTR("No return value."));
@@ -304,6 +304,7 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
}
bool is_enum_type = !p_enum.is_empty();
+ bool is_bitfield = p_is_bitfield && is_enum_type;
bool can_ref = !p_type.contains("*") || is_enum_type;
String link_t = p_type; // For links in metadata
@@ -327,6 +328,13 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
class_desc->add_text("Array");
class_desc->pop();
class_desc->add_text("[");
+ } else if (is_bitfield) {
+ class_desc->push_color(Color(theme_cache.type_color, 0.5));
+ class_desc->push_hint(TTR("This value is an integer composed as a bitmask of the following flags."));
+ class_desc->add_text("BitField");
+ class_desc->pop();
+ class_desc->add_text("[");
+ class_desc->pop();
}
if (is_enum_type) {
@@ -340,6 +348,10 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
class_desc->pop(); // Pushed meta above.
if (add_array) {
class_desc->add_text("]");
+ } else if (is_bitfield) {
+ class_desc->push_color(Color(theme_cache.type_color, 0.5));
+ class_desc->add_text("]");
+ class_desc->pop();
}
}
class_desc->pop();
@@ -403,7 +415,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
_add_bulletpoint();
}
- _add_type(p_method.return_type, p_method.return_enum);
+ _add_type(p_method.return_type, p_method.return_enum, p_method.return_is_bitfield);
if (p_overview) {
class_desc->pop(); // align
@@ -437,7 +449,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
_add_text(p_method.arguments[j].name);
class_desc->add_text(": ");
- _add_type(p_method.arguments[j].type, p_method.arguments[j].enumeration);
+ _add_type(p_method.arguments[j].type, p_method.arguments[j].enumeration, p_method.arguments[j].is_bitfield);
if (!p_method.arguments[j].default_value.is_empty()) {
class_desc->push_color(theme_cache.symbol_color);
class_desc->add_text(" = ");
@@ -953,7 +965,7 @@ void EditorHelp::_update_doc() {
class_desc->push_cell();
class_desc->push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT, Control::TEXT_DIRECTION_AUTO, "");
_push_code_font();
- _add_type(cd.properties[i].type, cd.properties[i].enumeration);
+ _add_type(cd.properties[i].type, cd.properties[i].enumeration, cd.properties[i].is_bitfield);
_pop_code_font();
class_desc->pop();
class_desc->pop(); // cell
@@ -1252,7 +1264,7 @@ void EditorHelp::_update_doc() {
_add_text(cd.signals[i].arguments[j].name);
class_desc->add_text(": ");
- _add_type(cd.signals[i].arguments[j].type, cd.signals[i].arguments[j].enumeration);
+ _add_type(cd.signals[i].arguments[j].type, cd.signals[i].arguments[j].enumeration, cd.signals[i].arguments[j].is_bitfield);
if (!cd.signals[i].arguments[j].default_value.is_empty()) {
class_desc->push_color(theme_cache.symbol_color);
class_desc->add_text(" = ");
@@ -1630,7 +1642,7 @@ void EditorHelp::_update_doc() {
_push_code_font();
_add_bulletpoint();
- _add_type(cd.properties[i].type, cd.properties[i].enumeration);
+ _add_type(cd.properties[i].type, cd.properties[i].enumeration, cd.properties[i].is_bitfield);
class_desc->add_text(" ");
_pop_code_font();
class_desc->pop(); // cell
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 4175ece816..0aa8302b27 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -158,7 +158,7 @@ class EditorHelp : public VBoxContainer {
bool scroll_locked = false;
//void _button_pressed(int p_idx);
- void _add_type(const String &p_type, const String &p_enum = String());
+ void _add_type(const String &p_type, const String &p_enum = String(), bool p_is_bitfield = false);
void _add_type_icon(const String &p_type, int p_size = 0, const String &p_fallback = "");
void _add_method(const DocData::MethodDoc &p_method, bool p_overview = true);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index c3e011b812..7fad4061b1 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -2817,7 +2817,7 @@ void Node3DEditorViewport::_notification(int p_what) {
text += "\n";
text += vformat(TTR("Objects: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_OBJECTS_IN_FRAME));
- text += vformat(TTR("Primitive Indices: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_PRIMITIVES_IN_FRAME));
+ text += vformat(TTR("Primitives: %d\n"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_PRIMITIVES_IN_FRAME));
text += vformat(TTR("Draw Calls: %d"), viewport->get_render_info(Viewport::RENDER_INFO_TYPE_VISIBLE, Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME));
info_label->set_text(text);
diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp
index 74bf32d133..e9af697226 100644
--- a/editor/project_converter_3_to_4.cpp
+++ b/editor/project_converter_3_to_4.cpp
@@ -459,6 +459,8 @@ bool ProjectConverter3To4::convert() {
String &line = source_line.line;
if (line.contains("nodes/root_type=\"Spatial\"")) {
line = "nodes/root_type=\"Node3D\"";
+ } else if (line == "importer=\"ogg_vorbis\"") {
+ line = "importer=\"oggvorbisstr\"";
}
}
} else {
diff --git a/main/main.cpp b/main/main.cpp
index a9e2d357fa..ed6a320e4c 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1011,19 +1011,19 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--delta-smoothing") {
if (I->next()) {
String string = I->next()->get();
- bool recognised = false;
+ bool recognized = false;
if (string == "enable") {
OS::get_singleton()->set_delta_smoothing(true);
delta_smoothing_override = true;
- recognised = true;
+ recognized = true;
}
if (string == "disable") {
OS::get_singleton()->set_delta_smoothing(false);
delta_smoothing_override = false;
- recognised = true;
+ recognized = true;
}
- if (!recognised) {
- OS::get_singleton()->print("Delta-smoothing argument not recognised, aborting.\n");
+ if (!recognized) {
+ OS::get_singleton()->print("Delta-smoothing argument not recognized, aborting.\n");
goto error;
}
N = I->next()->next();
diff --git a/misc/scripts/codespell.sh b/misc/scripts/codespell.sh
index d15b6593f7..a55a39bf99 100755
--- a/misc/scripts/codespell.sh
+++ b/misc/scripts/codespell.sh
@@ -3,6 +3,6 @@ SKIP_LIST="./.*,./**/.*,./bin,./thirdparty,*.desktop,*.gen.*,*.po,*.pot,*.rc,./A
SKIP_LIST+="./core/input/gamecontrollerdb.txt,./core/string/locales.h,./editor/renames_map_3_to_4.cpp,./misc/scripts/codespell.sh,"
SKIP_LIST+="./platform/android/java/lib/src/com,./platform/web/node_modules,./platform/web/package-lock.json,"
-IGNORE_LIST="curvelinear,doubleclick,expct,findn,gird,hel,inout,lod,nd,numer,ot,te,vai"
+IGNORE_LIST="curvelinear,doubleclick,expct,findn,gird,hel,inout,lod,mis,nd,numer,ot,requestor,te,vai"
codespell -w -q 3 -S "${SKIP_LIST}" -L "${IGNORE_LIST}" --builtin "clear,rare,en-GB_to_en-US"
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 4d9a49c35c..f02b292868 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -453,6 +453,10 @@ void DisplayServerAndroid::window_move_to_foreground(DisplayServer::WindowID p_w
// Not supported on Android.
}
+bool DisplayServerAndroid::window_is_focused(WindowID p_window) const {
+ return true;
+}
+
bool DisplayServerAndroid::window_can_draw(DisplayServer::WindowID p_window) const {
return true;
}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index ad1cbddb08..e0ad2cb916 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -178,6 +178,7 @@ public:
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h
index b29bdeec62..da16449c61 100644
--- a/platform/ios/display_server_ios.h
+++ b/platform/ios/display_server_ios.h
@@ -193,6 +193,7 @@ public:
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual float screen_get_max_scale() const override;
diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm
index bfb09b6861..7d91274a0c 100644
--- a/platform/ios/display_server_ios.mm
+++ b/platform/ios/display_server_ios.mm
@@ -562,6 +562,10 @@ void DisplayServerIOS::window_move_to_foreground(WindowID p_window) {
// Probably not supported for iOS
}
+bool DisplayServerIOS::window_is_focused(WindowID p_window) const {
+ return true;
+}
+
float DisplayServerIOS::screen_get_max_scale() const {
return screen_get_scale(SCREEN_OF_MAIN_WINDOW);
}
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 83b6fb7628..a607e26ac5 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -2626,6 +2626,15 @@ void DisplayServerX11::window_move_to_foreground(WindowID p_window) {
XFlush(x11_display);
}
+bool DisplayServerX11::window_is_focused(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND_V(!windows.has(p_window), false);
+ const WindowData &wd = windows[p_window];
+
+ return wd.focused;
+}
+
bool DisplayServerX11::window_can_draw(WindowID p_window) const {
//this seems to be all that is provided by X11
return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED;
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index 176a1ffb9a..180362923b 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -477,6 +477,7 @@ public:
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index 5944cc8abd..93fa93b259 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -117,6 +117,7 @@ public:
bool no_focus = false;
bool is_popup = false;
bool mpass = false;
+ bool focused = false;
Rect2i parent_safe_rect;
};
@@ -390,6 +391,7 @@ public:
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index b77715d648..a0a851b7dc 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -3075,6 +3075,15 @@ void DisplayServerMacOS::window_move_to_foreground(WindowID p_window) {
}
}
+bool DisplayServerMacOS::window_is_focused(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND_V(!windows.has(p_window), false);
+ const WindowData &wd = windows[p_window];
+
+ return wd.focused;
+}
+
bool DisplayServerMacOS::window_can_draw(WindowID p_window) const {
return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED;
}
diff --git a/platform/macos/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm
index df971c5139..1c6dbb1981 100644
--- a/platform/macos/godot_window_delegate.mm
+++ b/platform/macos/godot_window_delegate.mm
@@ -314,6 +314,7 @@
[self windowDidResize:notification]; // Emit resize event, to ensure content is resized if the window was resized while it was hidden.
+ wd.focused = true;
ds->set_last_focused_window(window_id);
ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN);
}
@@ -330,6 +331,7 @@
[(GodotButtonView *)wd.window_button_view displayButtons];
}
+ wd.focused = false;
ds->release_pressed_events();
ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT);
}
@@ -342,6 +344,7 @@
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
+ wd.focused = false;
ds->release_pressed_events();
ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_OUT);
}
@@ -353,9 +356,11 @@
}
DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
-
- ds->set_last_focused_window(window_id);
- ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN);
+ if ([wd.window_object isKeyWindow]) {
+ wd.focused = true;
+ ds->set_last_focused_window(window_id);
+ ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_FOCUS_IN);
+ }
}
@end
diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp
index 6cb56b404f..951ce110e0 100644
--- a/platform/web/display_server_web.cpp
+++ b/platform/web/display_server_web.cpp
@@ -1073,6 +1073,10 @@ void DisplayServerWeb::window_move_to_foreground(WindowID p_window) {
// Not supported.
}
+bool DisplayServerWeb::window_is_focused(WindowID p_window) const {
+ return true;
+}
+
bool DisplayServerWeb::window_can_draw(WindowID p_window) const {
return true;
}
diff --git a/platform/web/display_server_web.h b/platform/web/display_server_web.h
index 3b03b102cd..a4fd75f33b 100644
--- a/platform/web/display_server_web.h
+++ b/platform/web/display_server_web.h
@@ -211,6 +211,7 @@ public:
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index fc208eb4bb..ea93c47ec5 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -1615,6 +1615,15 @@ void DisplayServerWindows::window_move_to_foreground(WindowID p_window) {
}
}
+bool DisplayServerWindows::window_is_focused(WindowID p_window) const {
+ _THREAD_SAFE_METHOD_
+
+ ERR_FAIL_COND_V(!windows.has(p_window), false);
+ const WindowData &wd = windows[p_window];
+
+ return wd.window_focused;
+}
+
bool DisplayServerWindows::window_can_draw(WindowID p_window) const {
_THREAD_SAFE_METHOD_
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index ae2cd4e8b5..7228de7d31 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -594,6 +594,7 @@ public:
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
+ virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index 8b19b653fc..58dad40403 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -34,11 +34,6 @@
#include "core/math/geometry_2d.h"
#include "line_builder.h"
-// Needed so we can bind functions
-VARIANT_ENUM_CAST(Line2D::LineJointMode)
-VARIANT_ENUM_CAST(Line2D::LineCapMode)
-VARIANT_ENUM_CAST(Line2D::LineTextureMode)
-
Line2D::Line2D() {
}
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index b98c27138f..aa873ca642 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -138,4 +138,9 @@ private:
bool _antialiased = false;
};
+// Needed so we can bind functions
+VARIANT_ENUM_CAST(Line2D::LineJointMode)
+VARIANT_ENUM_CAST(Line2D::LineCapMode)
+VARIANT_ENUM_CAST(Line2D::LineTextureMode)
+
#endif // LINE_2D_H
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index ca43abf833..358dac46d9 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -75,7 +75,7 @@ class NavigationAgent2D : public Node {
Vector2 safe_velocity;
/// The submitted target velocity, sets the "wanted" rvo agent velocity on the next update
- // this velocity is not guaranteed, the simulation will try to fulfil it if possible
+ // this velocity is not guaranteed, the simulation will try to fulfill it if possible
// if other agents or obstacles interfere it will be changed accordingly
Vector2 velocity;
bool velocity_submitted = false;
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index b74e816d43..ea6657c425 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -78,7 +78,7 @@ class NavigationAgent3D : public Node {
Vector3 safe_velocity;
/// The submitted target velocity, sets the "wanted" rvo agent velocity on the next update
- // this velocity is not guaranteed, the simulation will try to fulfil it if possible
+ // this velocity is not guaranteed, the simulation will try to fulfill it if possible
// if other agents or obstacles interfere it will be changed accordingly
Vector3 velocity;
bool velocity_submitted = false;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 54e1b02518..ea89a719e8 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -46,11 +46,6 @@
#include <stdint.h>
-VARIANT_ENUM_CAST(Node::ProcessMode);
-VARIANT_ENUM_CAST(Node::ProcessThreadGroup);
-VARIANT_BITFIELD_CAST(Node::ProcessThreadMessages);
-VARIANT_ENUM_CAST(Node::InternalMode);
-
int Node::orphan_node_count = 0;
thread_local Node *Node::current_process_thread_group = nullptr;
@@ -3446,9 +3441,9 @@ void Node::_bind_methods() {
BIND_ENUM_CONSTANT(PROCESS_THREAD_GROUP_MAIN_THREAD);
BIND_ENUM_CONSTANT(PROCESS_THREAD_GROUP_SUB_THREAD);
- BIND_ENUM_CONSTANT(FLAG_PROCESS_THREAD_MESSAGES);
- BIND_ENUM_CONSTANT(FLAG_PROCESS_THREAD_MESSAGES_PHYSICS);
- BIND_ENUM_CONSTANT(FLAG_PROCESS_THREAD_MESSAGES_ALL);
+ BIND_BITFIELD_FLAG(FLAG_PROCESS_THREAD_MESSAGES);
+ BIND_BITFIELD_FLAG(FLAG_PROCESS_THREAD_MESSAGES_PHYSICS);
+ BIND_BITFIELD_FLAG(FLAG_PROCESS_THREAD_MESSAGES_ALL);
BIND_ENUM_CONSTANT(DUPLICATE_SIGNALS);
BIND_ENUM_CONSTANT(DUPLICATE_GROUPS);
diff --git a/scene/main/node.h b/scene/main/node.h
index bb29e473e0..ed8f699d7b 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -711,6 +711,10 @@ public:
};
VARIANT_ENUM_CAST(Node::DuplicateFlags);
+VARIANT_ENUM_CAST(Node::ProcessMode);
+VARIANT_ENUM_CAST(Node::ProcessThreadGroup);
+VARIANT_BITFIELD_CAST(Node::ProcessThreadMessages);
+VARIANT_ENUM_CAST(Node::InternalMode);
typedef HashSet<Node *, Node::Comparator> NodeSet;
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 4e7a10c7e9..6a21a74a09 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -185,12 +185,8 @@ private:
Color debug_collision_contact_color;
Color debug_paths_color;
float debug_paths_width = 1.0f;
- Color debug_navigation_color;
- Color debug_navigation_disabled_color;
Ref<ArrayMesh> debug_contact_mesh;
Ref<Material> debug_paths_material;
- Ref<Material> navigation_material;
- Ref<Material> navigation_disabled_material;
Ref<Material> collision_material;
int collision_debug_contacts;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index b82b215e54..e8395f59c9 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -616,6 +616,8 @@ void Window::_update_from_window() {
void Window::_clear_window() {
ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
+ bool had_focus = has_focus();
+
DisplayServer::get_singleton()->window_set_rect_changed_callback(Callable(), window_id);
DisplayServer::get_singleton()->window_set_window_event_callback(Callable(), window_id);
DisplayServer::get_singleton()->window_set_input_event_callback(Callable(), window_id);
@@ -638,7 +640,7 @@ void Window::_clear_window() {
window_id = DisplayServer::INVALID_WINDOW_ID;
// If closing window was focused and has a parent, return focus.
- if (focused && transient_parent) {
+ if (had_focus && transient_parent) {
transient_parent->grab_focus();
}
@@ -1185,6 +1187,7 @@ void Window::_notification(int p_what) {
{
position = DisplayServer::get_singleton()->window_get_position(window_id);
size = DisplayServer::get_singleton()->window_get_size(window_id);
+ focused = DisplayServer::get_singleton()->window_is_focused(window_id);
}
_update_window_size(); // Inform DisplayServer of minimum and maximum size.
_update_viewport_size(); // Then feed back to the viewport.
@@ -1762,6 +1765,9 @@ void Window::grab_focus() {
bool Window::has_focus() const {
ERR_READ_THREAD_GUARD_V(false);
+ if (window_id != DisplayServer::INVALID_WINDOW_ID) {
+ return DisplayServer::get_singleton()->window_is_focused(window_id);
+ }
return focused;
}
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 516f2f1be6..41fa0d2d47 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -716,6 +716,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("window_request_attention", "window_id"), &DisplayServer::window_request_attention, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_move_to_foreground", "window_id"), &DisplayServer::window_move_to_foreground, DEFVAL(MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("window_is_focused", "window_id"), &DisplayServer::window_is_focused, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_can_draw", "window_id"), &DisplayServer::window_can_draw, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_set_transient", "window_id", "parent_window_id"), &DisplayServer::window_set_transient);
diff --git a/servers/display_server.h b/servers/display_server.h
index d8e67b4f92..fc8207f2d3 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -424,6 +424,7 @@ public:
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) = 0;
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) = 0;
+ virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const = 0;
virtual void window_set_window_buttons_offset(const Vector2i &p_offset, WindowID p_window = MAIN_WINDOW_ID) {}
virtual Vector3i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const { return Vector3i(); }
diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h
index 0c43b84f2e..af13f8db21 100644
--- a/servers/display_server_headless.h
+++ b/servers/display_server_headless.h
@@ -119,6 +119,7 @@ public:
void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override {}
void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override {}
+ bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override { return true; };
bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override { return false; }
diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h
index 36c964e2ea..fa50772872 100644
--- a/servers/navigation_server_2d.h
+++ b/servers/navigation_server_2d.h
@@ -222,7 +222,7 @@ public:
virtual void agent_set_velocity_forced(RID p_agent, Vector2 p_velocity);
/// The wanted velocity for the agent as a "suggestion" to the avoidance simulation.
- /// The simulation will try to fulfil this velocity wish if possible but may change the velocity depending on other agent's and obstacles'.
+ /// The simulation will try to fulfill this velocity wish if possible but may change the velocity depending on other agent's and obstacles'.
virtual void agent_set_velocity(RID p_agent, Vector2 p_velocity);
/// Position of the agent in world space.
diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h
index a524f0f595..d74e72ed66 100644
--- a/servers/navigation_server_3d.h
+++ b/servers/navigation_server_3d.h
@@ -244,7 +244,7 @@ public:
virtual void agent_set_velocity_forced(RID p_agent, Vector3 p_velocity) = 0;
/// The wanted velocity for the agent as a "suggestion" to the avoidance simulation.
- /// The simulation will try to fulfil this velocity wish if possible but may change the velocity depending on other agent's and obstacles'.
+ /// The simulation will try to fulfill this velocity wish if possible but may change the velocity depending on other agent's and obstacles'.
virtual void agent_set_velocity(RID p_agent, Vector3 p_velocity) = 0;
/// Position of the agent in world space.
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index eea891792a..4f47a80c13 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -984,9 +984,9 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
to_draw = _indices_to_primitives(surf->primitive, to_draw);
to_draw *= inst->instance_count;
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
}
}
}
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 0b4157c5d6..77dd39b8d9 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -1884,9 +1884,9 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
to_draw = _indices_to_primitives(surf->primitive, to_draw);
to_draw *= inst->instance_count;
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
} else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
- p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += mesh_storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += to_draw;
}
}
}
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 8813c2e651..71f6a28671 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -1403,7 +1403,7 @@ void RendererViewport::call_set_vsync_mode(DisplayServer::VSyncMode p_mode, Disp
int RendererViewport::get_total_objects_drawn() const {
return total_objects_drawn;
}
-int RendererViewport::get_total_vertices_drawn() const {
+int RendererViewport::get_total_primitives_drawn() const {
return total_vertices_drawn;
}
int RendererViewport::get_total_draw_calls_used() const {
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index 2f9537a47c..c004d05b23 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -297,7 +297,7 @@ public:
bool free(RID p_rid);
int get_total_objects_drawn() const;
- int get_total_vertices_drawn() const;
+ int get_total_primitives_drawn() const;
int get_total_draw_calls_used() const;
// Workaround for setting this on thread.
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index 5f14245307..65bdb94c9f 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -251,7 +251,7 @@ uint64_t RenderingServerDefault::get_rendering_info(RenderingInfo p_info) {
if (p_info == RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME) {
return RSG::viewport->get_total_objects_drawn();
} else if (p_info == RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME) {
- return RSG::viewport->get_total_vertices_drawn();
+ return RSG::viewport->get_total_primitives_drawn();
} else if (p_info == RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME) {
return RSG::viewport->get_total_draw_calls_used();
}
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index c8ce49f318..d6858fbcb4 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -3496,7 +3496,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->confirm_code_completion();
CHECK(code_edit->get_line(0) == "test");
- /* Favorize good capitalisation. */
+ /* Favorize good capitalization. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
@@ -3506,7 +3506,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->confirm_code_completion();
CHECK(code_edit->get_line(0) == "test");
- /* Favorize location to good capitalisation. */
+ /* Favorize location to good capitalization. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);
@@ -3526,7 +3526,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
code_edit->confirm_code_completion();
CHECK(code_edit->get_line(0) == "stest");
- /* Favorize good capitalisation to closest to start. */
+ /* Favorize good capitalization to closest to start. */
code_edit->clear();
code_edit->insert_text_at_caret("te");
code_edit->set_caret_column(2);