Przeglądaj źródła

Merge pull request #54907 from lawnjelly/rid_handles

Rémi Verschelde 3 lat temu
rodzic
commit
efadd46640
82 zmienionych plików z 876 dodań i 247 usunięć
  1. 17 0
      SConstruct
  2. 4 4
      core/math/bvh_structs.inc
  3. 72 32
      core/pooled_list.h
  4. 2 0
      core/rid.cpp
  5. 5 0
      core/rid.h
  6. 303 0
      core/rid_handle.cpp
  7. 253 0
      core/rid_handle.h
  8. 3 2
      drivers/gles2/rasterizer_gles2.cpp
  9. 10 10
      drivers/gles2/rasterizer_scene_gles2.cpp
  10. 2 2
      drivers/gles3/rasterizer_canvas_gles3.cpp
  11. 3 3
      drivers/gles3/rasterizer_gles3.cpp
  12. 22 22
      drivers/gles3/rasterizer_scene_gles3.cpp
  13. 4 4
      editor/editor_plugin.cpp
  14. 3 3
      editor/plugins/animation_player_editor_plugin.cpp
  15. 13 13
      editor/plugins/editor_preview_plugins.cpp
  16. 8 8
      editor/plugins/spatial_editor_plugin.cpp
  17. 8 0
      main/main.cpp
  18. 14 14
      main/tests/test_physics.cpp
  19. 14 14
      main/tests/test_physics_2d.cpp
  20. 4 4
      main/tests/test_render.cpp
  21. 2 2
      modules/csg/csg_shape.cpp
  22. 7 7
      modules/gridmap/grid_map.cpp
  23. 4 4
      modules/gridmap/grid_map_editor_plugin.cpp
  24. 1 1
      modules/opensimplex/noise_texture.cpp
  25. 1 1
      scene/2d/area_2d.cpp
  26. 1 1
      scene/2d/canvas_item.cpp
  27. 2 2
      scene/2d/cpu_particles_2d.cpp
  28. 1 1
      scene/2d/light_2d.cpp
  29. 2 2
      scene/2d/light_occluder_2d.cpp
  30. 1 1
      scene/2d/particles_2d.cpp
  31. 1 1
      scene/2d/physics_body_2d.cpp
  32. 1 1
      scene/2d/skeleton_2d.cpp
  33. 5 5
      scene/2d/tile_map.cpp
  34. 1 1
      scene/3d/area.cpp
  35. 2 2
      scene/3d/baked_lightmap.cpp
  36. 2 2
      scene/3d/camera.cpp
  37. 1 1
      scene/3d/collision_object.cpp
  38. 1 1
      scene/3d/collision_shape.cpp
  39. 1 1
      scene/3d/cpu_particles.cpp
  40. 2 2
      scene/3d/gi_probe.cpp
  41. 1 1
      scene/3d/immediate_geometry.cpp
  42. 3 3
      scene/3d/light.cpp
  43. 1 1
      scene/3d/particles.cpp
  44. 6 6
      scene/3d/physics_body.cpp
  45. 1 1
      scene/3d/physics_joint.cpp
  46. 1 1
      scene/3d/portal.cpp
  47. 1 1
      scene/3d/reflection_probe.cpp
  48. 1 1
      scene/3d/room.cpp
  49. 1 1
      scene/3d/room_group.cpp
  50. 1 1
      scene/3d/skeleton.cpp
  51. 1 1
      scene/3d/soft_body.cpp
  52. 2 2
      scene/3d/sprite_3d.cpp
  53. 1 1
      scene/3d/visibility_notifier.cpp
  54. 1 1
      scene/3d/visual_instance.cpp
  55. 1 1
      scene/animation/root_motion_view.cpp
  56. 1 1
      scene/main/canvas_layer.cpp
  57. 6 6
      scene/main/viewport.cpp
  58. 1 1
      scene/resources/box_shape.cpp
  59. 1 1
      scene/resources/capsule_shape.cpp
  60. 1 1
      scene/resources/concave_polygon_shape.cpp
  61. 1 1
      scene/resources/convex_polygon_shape.cpp
  62. 1 1
      scene/resources/cylinder_shape.cpp
  63. 1 1
      scene/resources/environment.cpp
  64. 1 1
      scene/resources/height_map_shape.cpp
  65. 1 1
      scene/resources/material.cpp
  66. 1 1
      scene/resources/mesh.cpp
  67. 1 1
      scene/resources/multimesh.cpp
  68. 1 1
      scene/resources/occluder_shape.cpp
  69. 1 1
      scene/resources/plane_shape.cpp
  70. 1 1
      scene/resources/primitive_meshes.cpp
  71. 1 1
      scene/resources/ray_shape.cpp
  72. 1 1
      scene/resources/sky.cpp
  73. 1 1
      scene/resources/sphere_shape.cpp
  74. 9 9
      scene/resources/texture.cpp
  75. 2 2
      scene/resources/world.cpp
  76. 2 2
      scene/resources/world_2d.cpp
  77. 4 4
      servers/camera/camera_feed.cpp
  78. 2 2
      servers/physics/physics_server_sw.cpp
  79. 1 1
      servers/physics_2d/physics_2d_server_sw.cpp
  80. 4 4
      servers/visual/portals/portal_renderer.cpp
  81. 1 1
      servers/visual/portals/portal_renderer.h
  82. 2 2
      servers/visual_server.cpp

+ 17 - 0
SConstruct

@@ -150,6 +150,14 @@ opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and be
 opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True))
 opts.Add("system_certs_path", "Use this path as SSL certificates default for editor (for package maintainers)", "")
 opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
+opts.Add(
+    EnumVariable(
+        "rids",
+        "Server object management technique (debug option)",
+        "pointers",
+        ("pointers", "handles", "tracked_handles"),
+    )
+)
 
 # Thirdparty libraries
 opts.Add(BoolVariable("builtin_bullet", "Use the built-in Bullet library", True))
@@ -327,6 +335,15 @@ if env_base["no_editor_splash"]:
 if not env_base["deprecated"]:
     env_base.Append(CPPDEFINES=["DISABLE_DEPRECATED"])
 
+if env_base["rids"] == "handles":
+    env_base.Append(CPPDEFINES=["RID_HANDLES_ENABLED"])
+    print("WARNING: Building with RIDs as handles.")
+
+if env_base["rids"] == "tracked_handles":
+    env_base.Append(CPPDEFINES=["RID_HANDLES_ENABLED"])
+    env_base.Append(CPPDEFINES=["RID_HANDLE_ALLOCATION_TRACKING_ENABLED"])
+    print("WARNING: Building with RIDs as tracked handles.")
+
 if selected_platform in platform_list:
     tmppath = "./platform/" + selected_platform
     sys.path.insert(0, tmppath)

+ 4 - 4
core/math/bvh_structs.inc

@@ -127,13 +127,13 @@ struct TNode {
 
 // instead of using linked list we maintain
 // item references (for quick lookup)
-PooledList<ItemRef, true> _refs;
-PooledList<ItemExtra, true> _extra;
+PooledList<ItemRef, uint32_t, true> _refs;
+PooledList<ItemExtra, uint32_t, true> _extra;
 PooledList<ItemPairs> _pairs;
 
 // these 2 are not in sync .. nodes != leaves!
-PooledList<TNode, true> _nodes;
-PooledList<TLeaf, true> _leaves;
+PooledList<TNode, uint32_t, true> _nodes;
+PooledList<TLeaf, uint32_t, true> _leaves;
 
 // we can maintain an un-ordered list of which references are active,
 // in order to do a slow incremental optimize of the tree over each frame.

+ 72 - 32
core/pooled_list.h

@@ -43,35 +43,59 @@
 // that does call constructors / destructors on request / free, this should probably be
 // a separate template.
 
+// The zero_on_first_request feature is optional and is useful for e.g. pools of handles,
+// which may use a ref count which we want to be initialized to zero the first time a handle is created,
+// but left alone on subsequent allocations (as will typically be incremented).
+
+// Note that there is no function to compact the pool - this would
+// invalidate any existing pool IDs held externally.
+// Compaction can be done but would rely on a more complex method
+// of preferentially giving out lower IDs in the freelist first.
+
 #include "core/local_vector.h"
 
-template <class T, bool force_trivial = false>
+template <class T, class U = uint32_t, bool force_trivial = false, bool zero_on_first_request = false>
 class PooledList {
-	LocalVector<T, uint32_t, force_trivial> list;
-	LocalVector<uint32_t, uint32_t, true> freelist;
+	LocalVector<T, U, force_trivial> list;
+	LocalVector<U, U, true> freelist;
 
 	// not all list members are necessarily used
-	int _used_size;
+	U _used_size;
 
 public:
 	PooledList() {
 		_used_size = 0;
 	}
 
-	int estimate_memory_use() const {
-		return (list.size() * sizeof(T)) + (freelist.size() * sizeof(uint32_t));
+	// Use with care, in most cases you should make sure to
+	// free all elements first (i.e. _used_size would be zero),
+	// although it could also be used without this as an optimization
+	// in some cases.
+	void clear() {
+		list.clear();
+		freelist.clear();
+		_used_size = 0;
+	}
+
+	uint64_t estimate_memory_use() const {
+		return ((uint64_t)list.size() * sizeof(T)) + ((uint64_t)freelist.size() * sizeof(U));
 	}
 
-	const T &operator[](uint32_t p_index) const {
+	const T &operator[](U p_index) const {
 		return list[p_index];
 	}
-	T &operator[](uint32_t p_index) {
+	T &operator[](U p_index) {
 		return list[p_index];
 	}
 
-	int size() const { return _used_size; }
+	// To be explicit in a pool there is a distinction
+	// between the number of elements that are currently
+	// in use, and the number of elements that have been reserved.
+	// Using size() would be vague.
+	U used_size() const { return _used_size; }
+	U reserved_size() const { return list.size(); }
 
-	T *request(uint32_t &r_id) {
+	T *request(U &r_id) {
 		_used_size++;
 
 		if (freelist.size()) {
@@ -79,57 +103,73 @@ public:
 			int new_size = freelist.size() - 1;
 			r_id = freelist[new_size];
 			freelist.resize(new_size);
+
 			return &list[r_id];
 		}
 
 		r_id = list.size();
 		list.resize(r_id + 1);
+
+		static_assert((!zero_on_first_request) || (__is_pod(T)), "zero_on_first_request requires trivial type");
+		if (zero_on_first_request && __is_pod(T)) {
+			list[r_id] = {};
+		}
+
 		return &list[r_id];
 	}
-	void free(const uint32_t &p_id) {
+	void free(const U &p_id) {
 		// should not be on free list already
-		CRASH_COND(p_id >= list.size());
+		ERR_FAIL_UNSIGNED_INDEX(p_id, list.size());
 		freelist.push_back(p_id);
+		ERR_FAIL_COND_MSG(!_used_size, "_used_size has become out of sync, have you double freed an item?");
 		_used_size--;
 	}
 };
 
 // a pooled list which automatically keeps a list of the active members
-template <class T, bool force_trivial = false>
+template <class T, class U = uint32_t, bool force_trivial = false, bool zero_on_first_request = false>
 class TrackedPooledList {
 public:
-	int pool_size() const { return _pool.size(); }
-	int active_size() const { return _active_list.size(); }
+	U pool_used_size() const { return _pool.used_size(); }
+	U pool_reserved_size() const { return _pool.reserved_size(); }
+	U active_size() const { return _active_list.size(); }
+
+	// use with care, see the earlier notes in the PooledList clear()
+	void clear() {
+		_pool.clear();
+		_active_list.clear();
+		_active_map.clear();
+	}
 
-	uint32_t get_active_id(uint32_t p_index) const {
+	U get_active_id(U p_index) const {
 		return _active_list[p_index];
 	}
 
-	const T &get_active(uint32_t p_index) const {
+	const T &get_active(U p_index) const {
 		return _pool[get_active_id(p_index)];
 	}
 
-	T &get_active(uint32_t p_index) {
+	T &get_active(U p_index) {
 		return _pool[get_active_id(p_index)];
 	}
 
-	const T &operator[](uint32_t p_index) const {
+	const T &operator[](U p_index) const {
 		return _pool[p_index];
 	}
-	T &operator[](uint32_t p_index) {
+	T &operator[](U p_index) {
 		return _pool[p_index];
 	}
 
-	T *request(uint32_t &r_id) {
+	T *request(U &r_id) {
 		T *item = _pool.request(r_id);
 
 		// add to the active list
-		uint32_t active_list_id = _active_list.size();
+		U active_list_id = _active_list.size();
 		_active_list.push_back(r_id);
 
 		// expand the active map (this should be in sync with the pool list
-		if (_pool.size() > (int)_active_map.size()) {
-			_active_map.resize(_pool.size());
+		if (_pool.used_size() > _active_map.size()) {
+			_active_map.resize(_pool.used_size());
 		}
 
 		// store in the active map
@@ -138,11 +178,11 @@ public:
 		return item;
 	}
 
-	void free(const uint32_t &p_id) {
+	void free(const U &p_id) {
 		_pool.free(p_id);
 
 		// remove from the active list.
-		uint32_t list_id = _active_map[p_id];
+		U list_id = _active_map[p_id];
 
 		// zero the _active map to detect bugs (only in debug?)
 		_active_map[p_id] = -1;
@@ -150,19 +190,19 @@ public:
 		_active_list.remove_unordered(list_id);
 
 		// keep the replacement in sync with the correct list Id
-		if (list_id < (uint32_t)_active_list.size()) {
+		if (list_id < _active_list.size()) {
 			// which pool id has been replaced in the active list
-			uint32_t replacement_id = _active_list[list_id];
+			U replacement_id = _active_list[list_id];
 
 			// keep that replacements map up to date with the new position
 			_active_map[replacement_id] = list_id;
 		}
 	}
 
-	const LocalVector<uint32_t, uint32_t> &get_active_list() const { return _active_list; }
+	const LocalVector<U, U> &get_active_list() const { return _active_list; }
 
 private:
-	PooledList<T, force_trivial> _pool;
-	LocalVector<uint32_t, uint32_t> _active_map;
-	LocalVector<uint32_t, uint32_t> _active_list;
+	PooledList<T, U, force_trivial, zero_on_first_request> _pool;
+	LocalVector<U, U> _active_map;
+	LocalVector<U, U> _active_list;
 };

+ 2 - 0
core/rid.cpp

@@ -30,6 +30,7 @@
 
 #include "rid.h"
 
+#ifndef RID_HANDLES_ENABLED
 RID_Data::~RID_Data() {
 }
 
@@ -38,3 +39,4 @@ SafeRefCount RID_OwnerBase::refcount;
 void RID_OwnerBase::init_rid() {
 	refcount.init();
 }
+#endif // not RID_HANDLES_ENABLED

+ 5 - 0
core/rid.h

@@ -33,10 +33,13 @@
 
 #include "core/list.h"
 #include "core/os/memory.h"
+#include "core/rid_handle.h"
 #include "core/safe_refcount.h"
 #include "core/set.h"
 #include "core/typedefs.h"
 
+#ifndef RID_HANDLES_ENABLED
+
 class RID_OwnerBase;
 
 class RID_Data {
@@ -187,4 +190,6 @@ public:
 	}
 };
 
+#endif // not handles
+
 #endif

+ 303 - 0
core/rid_handle.cpp

@@ -0,0 +1,303 @@
+/*************************************************************************/
+/*  rid_handle.cpp                                                       */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "rid_handle.h"
+
+#ifdef RID_HANDLES_ENABLED
+#include "core/os/memory.h"
+#include "core/print_string.h"
+#include "core/ustring.h"
+
+// This define will flag up an error when get() or getptr() is called with a NULL object.
+// These calls should more correctly be made as get_or_null().
+// #define RID_HANDLE_FLAG_NULL_GETS
+
+RID_Database g_rid_database;
+
+RID_Data::~RID_Data() {
+}
+
+void RID_OwnerBase::init_rid() {
+	// NOOP
+}
+
+RID_OwnerBase::~RID_OwnerBase() {
+	_shutdown = true;
+}
+
+void RID_OwnerBase::_rid_print(const char *pszType, String sz, const RID &p_rid) {
+	String tn = pszType;
+	print_line(tn + " : " + sz + " " + itos(p_rid._id) + " [ " + itos(p_rid._revision) + " ]");
+}
+
+RID_Database::RID_Database() {
+	// request first element so the handles start from 1
+	uint32_t dummy;
+	_pool.request(dummy);
+}
+
+RID_Database::~RID_Database() {
+}
+
+String RID_Database::_rid_to_string(const RID &p_rid, const PoolElement &p_pe) {
+	String s = "RID id=" + itos(p_rid._id);
+	s += " [ rev " + itos(p_rid._revision) + " ], ";
+
+	s += "PE [ rev " + itos(p_pe.revision) + " ] ";
+#ifdef RID_HANDLE_ALLOCATION_TRACKING_ENABLED
+	if (p_pe.filename) {
+		s += String(p_pe.filename) + " ";
+	}
+	s += "line " + itos(p_pe.line_number);
+#endif
+	return s;
+}
+
+void RID_Database::preshutdown() {
+#ifdef RID_HANDLE_ALLOCATION_TRACKING_ENABLED
+	for (uint32_t n = 0; n < _pool.active_size(); n++) {
+		uint32_t id = _pool.get_active_id(n);
+
+		// ignore zero as it is a dummy
+		if (!id) {
+			continue;
+		}
+
+		PoolElement &pe = _pool[id];
+
+		if (pe.data) {
+			if (pe.data->_owner) {
+				const char *tn = pe.data->_owner->get_typename();
+
+				// does it already exist?
+				bool found = false;
+				for (unsigned int i = 0; i < _owner_names.size(); i++) {
+					if (_owner_names[i] == tn) {
+						found = true;
+						pe.owner_name_id = i;
+					}
+				}
+
+				if (!found) {
+					pe.owner_name_id = _owner_names.size();
+					_owner_names.push_back(tn);
+				}
+			}
+		}
+	}
+#endif
+}
+
+void RID_Database::register_leak(uint32_t p_line_number, uint32_t p_owner_name_id, const char *p_filename) {
+	// does the leak exist already?
+	for (unsigned int n = 0; n < _leaks.size(); n++) {
+		Leak &leak = _leaks[n];
+		if ((leak.line_number == p_line_number) && (leak.filename == p_filename) && (leak.owner_name_id == p_owner_name_id)) {
+			leak.num_objects_leaked += 1;
+			return;
+		}
+	}
+
+	Leak leak;
+	leak.filename = p_filename;
+	leak.line_number = p_line_number;
+	leak.owner_name_id = p_owner_name_id;
+	leak.num_objects_leaked = 1;
+	_leaks.push_back(leak);
+}
+
+void RID_Database::shutdown() {
+	// free the first dummy element, so we don't report a false leak
+	_pool.free(0);
+
+	// print leaks
+	if (_pool.active_size()) {
+		ERR_PRINT("RID_Database leaked " + itos(_pool.active_size()) + " objects at exit.");
+
+#ifdef RID_HANDLE_ALLOCATION_TRACKING_ENABLED
+		for (uint32_t n = 0; n < _pool.active_size(); n++) {
+			const PoolElement &pe = _pool.get_active(n);
+
+			register_leak(pe.line_number, pe.owner_name_id, pe.filename);
+		}
+#endif
+	}
+
+#ifdef RID_HANDLE_ALLOCATION_TRACKING_ENABLED
+	for (uint32_t n = 0; n < _leaks.size(); n++) {
+		const Leak &leak = _leaks[n];
+
+		const char *tn = "RID_Owner unknown";
+		if (_owner_names.size()) {
+			tn = _owner_names[leak.owner_name_id];
+		}
+
+		const char *fn = "Filename unknown";
+		if (leak.filename) {
+			fn = leak.filename;
+		}
+
+		_err_print_error(tn, fn, leak.line_number, itos(leak.num_objects_leaked) + " RID objects leaked");
+	}
+#endif
+
+	_shutdown = true;
+}
+
+void RID_Database::handle_make_rid(RID &r_rid, RID_Data *p_data, RID_OwnerBase *p_owner) {
+	ERR_FAIL_COND_MSG(_shutdown, "RID_Database make_rid use after shutdown.");
+	ERR_FAIL_COND_MSG(!p_data, "RID_Database make_rid, data is empty.");
+	bool data_was_empty = true;
+
+	_mutex.lock();
+	PoolElement *pe = _pool.request(r_rid._id);
+	data_was_empty = !pe->data;
+
+	pe->data = p_data;
+	p_data->_owner = p_owner;
+	pe->revision = pe->revision + 1;
+	r_rid._revision = pe->revision;
+
+#ifdef RID_HANDLE_ALLOCATION_TRACKING_ENABLED
+	pe->line_number = 0;
+	pe->filename = nullptr;
+#endif
+
+	_mutex.unlock();
+
+	ERR_FAIL_COND_MSG(!data_was_empty, "RID_Database make_rid, previous data was not empty.");
+}
+
+RID_Data *RID_Database::handle_get(const RID &p_rid) {
+	RID_Data *data = handle_get_or_null(p_rid);
+#ifdef RID_HANDLE_FLAG_NULL_GETS
+	ERR_FAIL_COND_V_MSG(!data, nullptr, "RID_Database get is NULL");
+#endif
+	return data;
+}
+
+RID_Data *RID_Database::handle_getptr(const RID &p_rid) {
+	RID_Data *data = handle_get_or_null(p_rid);
+#ifdef RID_HANDLE_FLAG_NULL_GETS
+	ERR_FAIL_COND_V_MSG(!data, nullptr, "RID_Database getptr is NULL");
+#endif
+	return data;
+}
+
+// Note, no locks used in the getters.
+// Godot 4.x does use locks in the getters, but it is arguably overkill because even though
+// the pointer returned will be correct (i.e. it has not been replaced during this call),
+// it can be invalidated during the client code use. (There may also be an internal reason why
+// locks are needed in 4.x, as the database is different.)
+// An example of a "safer" way to do this kind of thing is object level locking,
+// (but that has complications of its own), or atomic object changes.
+
+RID_Data *RID_Database::handle_get_or_null(const RID &p_rid) {
+	if (p_rid.is_valid()) {
+		ERR_FAIL_COND_V_MSG(_shutdown, nullptr, "RID_Database get_or_null after shutdown.");
+
+		// The if statement is to allow breakpointing without a recompile.
+		if (p_rid._id >= _pool.pool_reserved_size()) {
+			ERR_FAIL_COND_V_MSG(p_rid._id >= _pool.pool_reserved_size(), nullptr, "RID_Database get_or_null, RID id was outside pool size.");
+		}
+
+		const PoolElement &pe = _pool[p_rid._id];
+		if (pe.revision != p_rid._revision) {
+			print_verbose("RID revision incorrect : " + _rid_to_string(p_rid, pe));
+			ERR_FAIL_COND_V_MSG(pe.revision != p_rid._revision, nullptr, "RID_Database get_or_null, revision is incorrect, object possibly freed before use.");
+		}
+
+		return pe.data;
+	}
+	return nullptr;
+}
+
+bool RID_Database::handle_owns(const RID &p_rid) const {
+	ERR_FAIL_COND_V_MSG(_shutdown, false, "RID_Database owns after shutdown.");
+
+	if (!p_rid.is_valid()) {
+		return false;
+	}
+
+	if (p_rid._id >= _pool.pool_reserved_size()) {
+		return false;
+	}
+
+	const PoolElement &pe = _pool[p_rid._id];
+	if (pe.revision != p_rid._revision) {
+		return false;
+	}
+
+	if (!pe.data) {
+		return false;
+	}
+
+	return true;
+}
+
+void RID_Database::handle_free(const RID &p_rid) {
+	ERR_FAIL_COND_MSG(_shutdown, "RID_Database free after shutdown.");
+	bool revision_correct = true;
+
+	ERR_FAIL_COND_MSG(p_rid._id >= _pool.pool_reserved_size(), "RID_Database free, RID id was outside pool size.");
+	_mutex.lock();
+	PoolElement &pe = _pool[p_rid._id];
+	revision_correct = pe.revision == p_rid._revision;
+
+	// mark the data as zero, which indicates unused element
+	if (revision_correct) {
+		pe.data->_owner = nullptr;
+		pe.data = nullptr;
+		_pool.free(p_rid._id);
+	}
+
+	_mutex.unlock();
+
+	ERR_FAIL_COND_MSG(!revision_correct, "RID_Database free, revision is incorrect, object possibly freed more than once.");
+}
+
+RID RID_Database::prime(const RID &p_rid, int p_line_number, const char *p_filename) {
+#ifdef RID_HANDLE_ALLOCATION_TRACKING_ENABLED
+	if (p_rid.is_valid()) {
+		ERR_FAIL_COND_V_MSG(_shutdown, p_rid, "RID_Database prime after shutdown.");
+		ERR_FAIL_COND_V_MSG(p_rid._id >= _pool.pool_reserved_size(), p_rid, "RID_Database prime, RID id was outside pool size.");
+
+		PoolElement &pe = _pool[p_rid._id];
+		ERR_FAIL_COND_V_MSG(pe.revision != p_rid._revision, p_rid, "RID_Database prime, revision is incorrect, object possibly freed before use.");
+
+		// no threading checks as it the tracking info doesn't matter if there is a race condition
+		pe.line_number = p_line_number;
+		pe.filename = p_filename;
+	}
+#endif
+	return p_rid;
+}
+
+#endif // RID_HANDLES_ENABLED

+ 253 - 0
core/rid_handle.h

@@ -0,0 +1,253 @@
+/*************************************************************************/
+/*  rid_handle.h                                                         */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef RID_HANDLE_H
+#define RID_HANDLE_H
+
+#include "core/list.h"
+#include "core/os/mutex.h"
+#include "core/pooled_list.h"
+#include "core/safe_refcount.h"
+#include "core/typedefs.h"
+
+#include <typeinfo>
+
+// SCONS parameters:
+// rids=pointers (default)
+// rids=handles
+// rids=tracked_handles (handles plus allocation tracking)
+
+// Defines RID_HANDLES_ENABLED and RID_HANDLE_ALLOCATION_TRACKING_ENABLED
+// should be defined from Scons as required following the above convention.
+
+// RID_PRIME is the macro which stores line numbers and file in the RID_Database.
+// It will be a NOOP if tracking is off.
+#ifdef RID_HANDLE_ALLOCATION_TRACKING_ENABLED
+#define RID_PRIME(a) g_rid_database.prime(a, __LINE__, __FILE__)
+#else
+#define RID_PRIME(a) a
+#endif
+
+// All the handle code can be compiled out if they are not in use.
+#ifdef RID_HANDLES_ENABLED
+
+// This define will print out each make_rid and free_rid. Useful for debugging.
+// #define RID_HANDLE_PRINT_LIFETIMES
+
+class RID_OwnerBase;
+class RID_Database;
+
+class RID_Data {
+	friend class RID_OwnerBase;
+	friend class RID_Database;
+
+	RID_OwnerBase *_owner;
+	uint32_t _id;
+
+public:
+	uint32_t get_id() const { return _id; }
+
+	virtual ~RID_Data();
+};
+
+class RID_Handle {
+public:
+	union {
+		struct {
+			uint32_t _id;
+			uint32_t _revision;
+		};
+		uint64_t _handle_data;
+	};
+
+	RID_Handle() {
+		_handle_data = 0;
+	}
+
+	bool operator==(const RID_Handle &p_rid) const {
+		return _handle_data == p_rid._handle_data;
+	}
+	bool operator<(const RID_Handle &p_rid) const {
+		return _handle_data < p_rid._handle_data;
+	}
+	bool operator<=(const RID_Handle &p_rid) const {
+		return _handle_data <= p_rid._handle_data;
+	}
+	bool operator>(const RID_Handle &p_rid) const {
+		return _handle_data > p_rid._handle_data;
+	}
+	bool operator!=(const RID_Handle &p_rid) const {
+		return _handle_data != p_rid._handle_data;
+	}
+	bool is_valid() const { return _id != 0; }
+
+	uint32_t get_id() const { return _id ? _handle_data : 0; }
+};
+
+class RID : public RID_Handle {
+};
+
+class RID_Database {
+	struct PoolElement {
+		RID_Data *data;
+		uint32_t revision;
+#ifdef RID_HANDLE_ALLOCATION_TRACKING_ENABLED
+		uint16_t line_number;
+		uint16_t owner_name_id;
+		const char *filename;
+#endif
+	};
+
+	struct Leak {
+		uint16_t line_number;
+		uint16_t owner_name_id;
+		const char *filename;
+		uint32_t num_objects_leaked;
+	};
+
+	// The pooled list zeros on first request .. this is important
+	// so that we initialize the revision to zero. Other than that, it
+	// is treated as a POD type.
+	TrackedPooledList<PoolElement, uint32_t, true, true> _pool;
+	bool _shutdown = false;
+	Mutex _mutex;
+
+	// This is purely for printing the leaks at the end, as RID_Owners may be
+	// destroyed before the RID_Database is shutdown, so the RID_Data may be invalid
+	// by this point, and we still want to have a record of the owner names.
+	// The owner names should part of the binary, thus the pointers should still be valid.
+	// They were retrieved using typeid(T).name()
+	LocalVector<const char *> _owner_names;
+	LocalVector<Leak> _leaks;
+
+	void register_leak(uint32_t p_line_number, uint32_t p_owner_name_id, const char *p_filename);
+	String _rid_to_string(const RID &p_rid, const PoolElement &p_pe);
+
+public:
+	RID_Database();
+	~RID_Database();
+
+	// Called to record the owner names before RID_Owners are destroyed
+	void preshutdown();
+
+	// Called after destroying RID_Owners to detect leaks
+	void shutdown();
+
+	// Prepare a RID for memory tracking
+	RID prime(const RID &p_rid, int p_line_number, const char *p_filename);
+
+	void handle_make_rid(RID &r_rid, RID_Data *p_data, RID_OwnerBase *p_owner);
+	RID_Data *handle_get(const RID &p_rid);
+	RID_Data *handle_getptr(const RID &p_rid);
+	RID_Data *handle_get_or_null(const RID &p_rid);
+	bool handle_owns(const RID &p_rid) const;
+	void handle_free(const RID &p_rid);
+};
+
+extern RID_Database g_rid_database;
+
+class RID_OwnerBase {
+protected:
+	bool _is_owner(const RID &p_rid) const {
+		const RID_Data *p = g_rid_database.handle_get_or_null(p_rid);
+		return (p && (p->_owner == this));
+	}
+
+	void _remove_owner(RID &p_rid) {
+		RID_Data *p = g_rid_database.handle_get_or_null(p_rid);
+		if (p) {
+			p->_owner = nullptr;
+		}
+	}
+
+	void _rid_print(const char *pszType, String sz, const RID &p_rid);
+
+	const char *_typename = nullptr;
+	bool _shutdown = false;
+
+public:
+	virtual void get_owned_list(List<RID> *p_owned) = 0;
+	const char *get_typename() const { return _typename; }
+
+	static void init_rid();
+	virtual ~RID_OwnerBase();
+};
+
+template <class T>
+class RID_Owner : public RID_OwnerBase {
+public:
+	RID make_rid(T *p_data) {
+		RID rid;
+		g_rid_database.handle_make_rid(rid, p_data, this);
+
+#ifdef RID_HANDLE_PRINT_LIFETIMES
+		_rid_print(_typename, "make_rid", rid);
+#endif
+		return rid;
+	}
+
+	T *get(const RID &p_rid) {
+		return static_cast<T *>(g_rid_database.handle_get(p_rid));
+	}
+
+	T *getornull(const RID &p_rid) {
+		return static_cast<T *>(g_rid_database.handle_get_or_null(p_rid));
+	}
+
+	T *getptr(const RID &p_rid) {
+		return static_cast<T *>(g_rid_database.handle_getptr(p_rid));
+	}
+
+	bool owns(const RID &p_rid) const {
+		return _is_owner(p_rid);
+	}
+
+	void free(RID p_rid) {
+#ifdef RID_HANDLE_PRINT_LIFETIMES
+		_rid_print(_typename, "free_rid", p_rid);
+#endif
+		_remove_owner(p_rid);
+		g_rid_database.handle_free(p_rid);
+	}
+
+	void get_owned_list(List<RID> *p_owned){
+#ifdef DEBUG_ENABLED
+
+#endif
+	}
+
+	RID_Owner() {
+		_typename = typeid(T).name();
+	}
+};
+
+#endif // RID_HANDLES_ENABLED
+
+#endif // RID_HANDLE_H

+ 3 - 2
drivers/gles2/rasterizer_gles2.cpp

@@ -354,7 +354,7 @@ void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_c
 
 	canvas->canvas_begin();
 
-	RID texture = storage->texture_create();
+	RID texture = RID_PRIME(storage->texture_create());
 	storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_use_filter ? (uint32_t)VS::TEXTURE_FLAG_FILTER : 0);
 	storage->texture_set_data(texture, p_image);
 
@@ -535,6 +535,7 @@ RasterizerGLES2::RasterizerGLES2() {
 }
 
 RasterizerGLES2::~RasterizerGLES2() {
-	memdelete(storage);
+	memdelete(scene);
 	memdelete(canvas);
+	memdelete(storage);
 }

+ 10 - 10
drivers/gles2/rasterizer_scene_gles2.cpp

@@ -3919,25 +3919,25 @@ void RasterizerSceneGLES2::initialize() {
 	{
 		//default material and shader
 
-		default_shader = storage->shader_create();
+		default_shader = RID_PRIME(storage->shader_create());
 		storage->shader_set_code(default_shader, "shader_type spatial;\n");
-		default_material = storage->material_create();
+		default_material = RID_PRIME(storage->material_create());
 		storage->material_set_shader(default_material, default_shader);
 
-		default_shader_twosided = storage->shader_create();
-		default_material_twosided = storage->material_create();
+		default_shader_twosided = RID_PRIME(storage->shader_create());
+		default_material_twosided = RID_PRIME(storage->material_create());
 		storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n");
 		storage->material_set_shader(default_material_twosided, default_shader_twosided);
 	}
 
 	{
-		default_worldcoord_shader = storage->shader_create();
+		default_worldcoord_shader = RID_PRIME(storage->shader_create());
 		storage->shader_set_code(default_worldcoord_shader, "shader_type spatial; render_mode world_vertex_coords;\n");
-		default_worldcoord_material = storage->material_create();
+		default_worldcoord_material = RID_PRIME(storage->material_create());
 		storage->material_set_shader(default_worldcoord_material, default_worldcoord_shader);
 
-		default_worldcoord_shader_twosided = storage->shader_create();
-		default_worldcoord_material_twosided = storage->material_create();
+		default_worldcoord_shader_twosided = RID_PRIME(storage->shader_create());
+		default_worldcoord_material_twosided = RID_PRIME(storage->material_create());
 		storage->shader_set_code(default_worldcoord_shader_twosided, "shader_type spatial; render_mode cull_disabled,world_vertex_coords;\n");
 		storage->material_set_shader(default_worldcoord_material_twosided, default_worldcoord_shader_twosided);
 	}
@@ -3945,10 +3945,10 @@ void RasterizerSceneGLES2::initialize() {
 	{
 		//default material and shader
 
-		default_overdraw_shader = storage->shader_create();
+		default_overdraw_shader = RID_PRIME(storage->shader_create());
 		// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
 		storage->shader_set_code(default_overdraw_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.1; }");
-		default_overdraw_material = storage->material_create();
+		default_overdraw_material = RID_PRIME(storage->material_create());
 		storage->material_set_shader(default_overdraw_material, default_overdraw_shader);
 	}
 

+ 2 - 2
drivers/gles3/rasterizer_canvas_gles3.cpp

@@ -396,7 +396,7 @@ void RasterizerCanvasGLES3::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
 					}
 				}
 
-				glBindBufferBase(GL_UNIFORM_BUFFER, 1, static_cast<LightInternal *>(light->light_internal.get_data())->ubo);
+				glBindBufferBase(GL_UNIFORM_BUFFER, 1, static_cast<LightInternal *>(light_internal_owner.get(light->light_internal))->ubo);
 
 				if (has_shadow) {
 					RasterizerStorageGLES3::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(light->shadow_buffer);
@@ -1500,7 +1500,7 @@ void RasterizerCanvasGLES3::render_joined_item(const BItemJoined &p_bij, RenderI
 					}
 				}
 
-				glBindBufferBase(GL_UNIFORM_BUFFER, 1, static_cast<LightInternal *>(light->light_internal.get_data())->ubo);
+				glBindBufferBase(GL_UNIFORM_BUFFER, 1, static_cast<LightInternal *>(light_internal_owner.get(light->light_internal))->ubo);
 
 				if (has_shadow) {
 					RasterizerStorageGLES3::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(light->shadow_buffer);

+ 3 - 3
drivers/gles3/rasterizer_gles3.cpp

@@ -291,7 +291,7 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
 	glClear(GL_COLOR_BUFFER_BIT);
 	canvas->canvas_begin();
 
-	RID texture = storage->texture_create();
+	RID texture = RID_PRIME(storage->texture_create());
 	storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), 0, p_image->get_format(), VS::TEXTURE_TYPE_2D, p_use_filter ? (uint32_t)VS::TEXTURE_FLAG_FILTER : 0);
 	storage->texture_set_data(texture, p_image);
 
@@ -497,7 +497,7 @@ RasterizerGLES3::RasterizerGLES3() {
 }
 
 RasterizerGLES3::~RasterizerGLES3() {
-	memdelete(storage);
-	memdelete(canvas);
 	memdelete(scene);
+	memdelete(canvas);
+	memdelete(storage);
 }

+ 22 - 22
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -4942,25 +4942,25 @@ void RasterizerSceneGLES3::initialize() {
 	{
 		//default material and shader
 
-		default_shader = storage->shader_create();
+		default_shader = RID_PRIME(storage->shader_create());
 		storage->shader_set_code(default_shader, "shader_type spatial;\n");
-		default_material = storage->material_create();
+		default_material = RID_PRIME(storage->material_create());
 		storage->material_set_shader(default_material, default_shader);
 
-		default_shader_twosided = storage->shader_create();
-		default_material_twosided = storage->material_create();
+		default_shader_twosided = RID_PRIME(storage->shader_create());
+		default_material_twosided = RID_PRIME(storage->material_create());
 		storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n");
 		storage->material_set_shader(default_material_twosided, default_shader_twosided);
 
 		//default for shaders using world coordinates (typical for triplanar)
 
-		default_worldcoord_shader = storage->shader_create();
+		default_worldcoord_shader = RID_PRIME(storage->shader_create());
 		storage->shader_set_code(default_worldcoord_shader, "shader_type spatial; render_mode world_vertex_coords;\n");
-		default_worldcoord_material = storage->material_create();
+		default_worldcoord_material = RID_PRIME(storage->material_create());
 		storage->material_set_shader(default_worldcoord_material, default_worldcoord_shader);
 
-		default_worldcoord_shader_twosided = storage->shader_create();
-		default_worldcoord_material_twosided = storage->material_create();
+		default_worldcoord_shader_twosided = RID_PRIME(storage->shader_create());
+		default_worldcoord_material_twosided = RID_PRIME(storage->material_create());
 		storage->shader_set_code(default_worldcoord_shader_twosided, "shader_type spatial; render_mode cull_disabled,world_vertex_coords;\n");
 		storage->material_set_shader(default_worldcoord_material_twosided, default_worldcoord_shader_twosided);
 	}
@@ -4968,10 +4968,10 @@ void RasterizerSceneGLES3::initialize() {
 	{
 		//default material and shader
 
-		default_overdraw_shader = storage->shader_create();
+		default_overdraw_shader = RID_PRIME(storage->shader_create());
 		// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
 		storage->shader_set_code(default_overdraw_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.1; }");
-		default_overdraw_material = storage->material_create();
+		default_overdraw_material = RID_PRIME(storage->material_create());
 		storage->material_set_shader(default_overdraw_material, default_overdraw_shader);
 	}
 
@@ -5282,18 +5282,18 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
 }
 
 RasterizerSceneGLES3::~RasterizerSceneGLES3() {
-	memdelete(default_material.get_data());
-	memdelete(default_material_twosided.get_data());
-	memdelete(default_shader.get_data());
-	memdelete(default_shader_twosided.get_data());
-
-	memdelete(default_worldcoord_material.get_data());
-	memdelete(default_worldcoord_material_twosided.get_data());
-	memdelete(default_worldcoord_shader.get_data());
-	memdelete(default_worldcoord_shader_twosided.get_data());
-
-	memdelete(default_overdraw_material.get_data());
-	memdelete(default_overdraw_shader.get_data());
+	memdelete(storage->material_owner.getptr(default_material));
+	memdelete(storage->material_owner.getptr(default_material_twosided));
+	memdelete(storage->shader_owner.getptr(default_shader));
+	memdelete(storage->shader_owner.getptr(default_shader_twosided));
+
+	memdelete(storage->material_owner.getptr(default_worldcoord_material));
+	memdelete(storage->material_owner.getptr(default_worldcoord_material_twosided));
+	memdelete(storage->shader_owner.getptr(default_worldcoord_shader));
+	memdelete(storage->shader_owner.getptr(default_worldcoord_shader_twosided));
+
+	memdelete(storage->material_owner.getptr(default_overdraw_material));
+	memdelete(storage->shader_owner.getptr(default_overdraw_shader));
 
 	memfree(state.spot_array_tmp);
 	memfree(state.omni_array_tmp);

+ 4 - 4
editor/editor_plugin.cpp

@@ -62,9 +62,9 @@ Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_
 Vector<Ref<Texture>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform> *p_transforms, int p_preview_size) {
 	int size = p_preview_size;
 
-	RID scenario = VS::get_singleton()->scenario_create();
+	RID scenario = RID_PRIME(VS::get_singleton()->scenario_create());
 
-	RID viewport = VS::get_singleton()->viewport_create();
+	RID viewport = RID_PRIME(VS::get_singleton()->viewport_create());
 	VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_ALWAYS);
 	VS::get_singleton()->viewport_set_vflip(viewport, true);
 	VS::get_singleton()->viewport_set_scenario(viewport, scenario);
@@ -73,10 +73,10 @@ Vector<Ref<Texture>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh>>
 	VS::get_singleton()->viewport_set_active(viewport, true);
 	RID viewport_texture = VS::get_singleton()->viewport_get_texture(viewport);
 
-	RID camera = VS::get_singleton()->camera_create();
+	RID camera = RID_PRIME(VS::get_singleton()->camera_create());
 	VS::get_singleton()->viewport_attach_camera(viewport, camera);
 
-	RID light = VS::get_singleton()->directional_light_create();
+	RID light = RID_PRIME(VS::get_singleton()->directional_light_create());
 	RID light_instance = VS::get_singleton()->instance_create2(light, scenario);
 
 	RID light2 = VS::get_singleton()->directional_light_create();

+ 3 - 3
editor/plugins/animation_player_editor_plugin.cpp

@@ -1273,7 +1273,7 @@ void AnimationPlayerEditor::_allocate_onion_layers() {
 		bool is_present = onion.differences_only && i == captures - 1;
 
 		// Each capture is a viewport with a canvas item attached that renders a full-size rect with the contents of the main viewport.
-		onion.captures.write[i] = VS::get_singleton()->viewport_create();
+		onion.captures.write[i] = RID_PRIME(VS::get_singleton()->viewport_create());
 		VS::get_singleton()->viewport_set_usage(onion.captures[i], VS::VIEWPORT_USAGE_2D);
 		VS::get_singleton()->viewport_set_size(onion.captures[i], capture_size.width, capture_size.height);
 		VS::get_singleton()->viewport_set_update_mode(onion.captures[i], VS::VIEWPORT_UPDATE_ALWAYS);
@@ -1737,8 +1737,8 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
 	onion.last_frame = 0;
 	onion.can_overlay = false;
 	onion.capture_size = Size2();
-	onion.capture.canvas = VS::get_singleton()->canvas_create();
-	onion.capture.canvas_item = VS::get_singleton()->canvas_item_create();
+	onion.capture.canvas = RID_PRIME(VS::get_singleton()->canvas_create());
+	onion.capture.canvas_item = RID_PRIME(VS::get_singleton()->canvas_item_create());
 	VS::get_singleton()->canvas_item_set_parent(onion.capture.canvas_item, onion.capture.canvas);
 
 	onion.capture.material = Ref<ShaderMaterial>(memnew(ShaderMaterial));

+ 13 - 13
editor/plugins/editor_preview_plugins.cpp

@@ -352,9 +352,9 @@ Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size
 }
 
 EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
-	scenario = VS::get_singleton()->scenario_create();
+	scenario = RID_PRIME(VS::get_singleton()->scenario_create());
 
-	viewport = VS::get_singleton()->viewport_create();
+	viewport = RID_PRIME(VS::get_singleton()->viewport_create());
 	VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_DISABLED);
 	VS::get_singleton()->viewport_set_scenario(viewport, scenario);
 	VS::get_singleton()->viewport_set_size(viewport, 128, 128);
@@ -363,16 +363,16 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
 	VS::get_singleton()->viewport_set_vflip(viewport, true);
 	viewport_texture = VS::get_singleton()->viewport_get_texture(viewport);
 
-	camera = VS::get_singleton()->camera_create();
+	camera = RID_PRIME(VS::get_singleton()->camera_create());
 	VS::get_singleton()->viewport_attach_camera(viewport, camera);
 	VS::get_singleton()->camera_set_transform(camera, Transform(Basis(), Vector3(0, 0, 3)));
 	VS::get_singleton()->camera_set_perspective(camera, 45, 0.1, 10);
 
-	light = VS::get_singleton()->directional_light_create();
+	light = RID_PRIME(VS::get_singleton()->directional_light_create());
 	light_instance = VS::get_singleton()->instance_create2(light, scenario);
 	VS::get_singleton()->instance_set_transform(light_instance, Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0)));
 
-	light2 = VS::get_singleton()->directional_light_create();
+	light2 = RID_PRIME(VS::get_singleton()->directional_light_create());
 	VS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7));
 	//VS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7));
 
@@ -380,7 +380,7 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
 
 	VS::get_singleton()->instance_set_transform(light_instance2, Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1)));
 
-	sphere = VS::get_singleton()->mesh_create();
+	sphere = RID_PRIME(VS::get_singleton()->mesh_create());
 	sphere_instance = VS::get_singleton()->instance_create2(sphere, scenario);
 
 	int lats = 32;
@@ -779,9 +779,9 @@ Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 &p
 }
 
 EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() {
-	scenario = VS::get_singleton()->scenario_create();
+	scenario = RID_PRIME(VS::get_singleton()->scenario_create());
 
-	viewport = VS::get_singleton()->viewport_create();
+	viewport = RID_PRIME(VS::get_singleton()->viewport_create());
 	VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_DISABLED);
 	VS::get_singleton()->viewport_set_vflip(viewport, true);
 	VS::get_singleton()->viewport_set_scenario(viewport, scenario);
@@ -807,8 +807,8 @@ EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() {
 
 	VS::get_singleton()->instance_set_transform(light_instance2, Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1)));
 
-	//sphere = VS::get_singleton()->mesh_create();
-	mesh_instance = VS::get_singleton()->instance_create();
+	//sphere = RID_PRIME(VS::get_singleton()->mesh_create());
+	mesh_instance = RID_PRIME(VS::get_singleton()->instance_create());
 	VS::get_singleton()->instance_set_scenario(mesh_instance, scenario);
 }
 
@@ -910,15 +910,15 @@ Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2 &p
 }
 
 EditorFontPreviewPlugin::EditorFontPreviewPlugin() {
-	viewport = VS::get_singleton()->viewport_create();
+	viewport = RID_PRIME(VS::get_singleton()->viewport_create());
 	VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_DISABLED);
 	VS::get_singleton()->viewport_set_vflip(viewport, true);
 	VS::get_singleton()->viewport_set_size(viewport, 128, 128);
 	VS::get_singleton()->viewport_set_active(viewport, true);
 	viewport_texture = VS::get_singleton()->viewport_get_texture(viewport);
 
-	canvas = VS::get_singleton()->canvas_create();
-	canvas_item = VS::get_singleton()->canvas_item_create();
+	canvas = RID_PRIME(VS::get_singleton()->canvas_create());
+	canvas_item = RID_PRIME(VS::get_singleton()->canvas_item_create());
 
 	VS::get_singleton()->viewport_attach_canvas(viewport, canvas);
 	VS::get_singleton()->canvas_item_set_parent(canvas_item, canvas);

+ 8 - 8
editor/plugins/spatial_editor_plugin.cpp

@@ -3139,7 +3139,7 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
 	uint32_t layer = 1 << (GIZMO_BASE_LAYER + p_idx);
 
 	for (int i = 0; i < 3; i++) {
-		move_gizmo_instance[i] = VS::get_singleton()->instance_create();
+		move_gizmo_instance[i] = RID_PRIME(VS::get_singleton()->instance_create());
 		VS::get_singleton()->instance_set_base(move_gizmo_instance[i], spatial_editor->get_move_gizmo(i)->get_rid());
 		VS::get_singleton()->instance_set_scenario(move_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
 		VS::get_singleton()->instance_set_visible(move_gizmo_instance[i], false);
@@ -3147,7 +3147,7 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
 		VS::get_singleton()->instance_set_layer_mask(move_gizmo_instance[i], layer);
 		VS::get_singleton()->instance_set_portal_mode(move_gizmo_instance[i], VisualServer::INSTANCE_PORTAL_MODE_GLOBAL);
 
-		move_plane_gizmo_instance[i] = VS::get_singleton()->instance_create();
+		move_plane_gizmo_instance[i] = RID_PRIME(VS::get_singleton()->instance_create());
 		VS::get_singleton()->instance_set_base(move_plane_gizmo_instance[i], spatial_editor->get_move_plane_gizmo(i)->get_rid());
 		VS::get_singleton()->instance_set_scenario(move_plane_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
 		VS::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], false);
@@ -3155,7 +3155,7 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
 		VS::get_singleton()->instance_set_layer_mask(move_plane_gizmo_instance[i], layer);
 		VS::get_singleton()->instance_set_portal_mode(move_plane_gizmo_instance[i], VisualServer::INSTANCE_PORTAL_MODE_GLOBAL);
 
-		rotate_gizmo_instance[i] = VS::get_singleton()->instance_create();
+		rotate_gizmo_instance[i] = RID_PRIME(VS::get_singleton()->instance_create());
 		VS::get_singleton()->instance_set_base(rotate_gizmo_instance[i], spatial_editor->get_rotate_gizmo(i)->get_rid());
 		VS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
 		VS::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], false);
@@ -3163,7 +3163,7 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
 		VS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[i], layer);
 		VS::get_singleton()->instance_set_portal_mode(rotate_gizmo_instance[i], VisualServer::INSTANCE_PORTAL_MODE_GLOBAL);
 
-		scale_gizmo_instance[i] = VS::get_singleton()->instance_create();
+		scale_gizmo_instance[i] = RID_PRIME(VS::get_singleton()->instance_create());
 		VS::get_singleton()->instance_set_base(scale_gizmo_instance[i], spatial_editor->get_scale_gizmo(i)->get_rid());
 		VS::get_singleton()->instance_set_scenario(scale_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
 		VS::get_singleton()->instance_set_visible(scale_gizmo_instance[i], false);
@@ -3171,7 +3171,7 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
 		VS::get_singleton()->instance_set_layer_mask(scale_gizmo_instance[i], layer);
 		VS::get_singleton()->instance_set_portal_mode(scale_gizmo_instance[i], VisualServer::INSTANCE_PORTAL_MODE_GLOBAL);
 
-		scale_plane_gizmo_instance[i] = VS::get_singleton()->instance_create();
+		scale_plane_gizmo_instance[i] = RID_PRIME(VS::get_singleton()->instance_create());
 		VS::get_singleton()->instance_set_base(scale_plane_gizmo_instance[i], spatial_editor->get_scale_plane_gizmo(i)->get_rid());
 		VS::get_singleton()->instance_set_scenario(scale_plane_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
 		VS::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], false);
@@ -3181,7 +3181,7 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
 	}
 
 	// Rotation white outline
-	rotate_gizmo_instance[3] = VS::get_singleton()->instance_create();
+	rotate_gizmo_instance[3] = RID_PRIME(VS::get_singleton()->instance_create());
 	VS::get_singleton()->instance_set_base(rotate_gizmo_instance[3], spatial_editor->get_rotate_gizmo(3)->get_rid());
 	VS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[3], get_tree()->get_root()->get_world()->get_scenario());
 	VS::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], false);
@@ -5274,7 +5274,7 @@ void SpatialEditor::_init_indicators() {
 
 		_init_grid();
 
-		origin = VisualServer::get_singleton()->mesh_create();
+		origin = RID_PRIME(VisualServer::get_singleton()->mesh_create());
 		Array d;
 		d.resize(VS::ARRAY_MAX);
 		d[VisualServer::ARRAY_VERTEX] = origin_points;
@@ -5837,7 +5837,7 @@ void SpatialEditor::_init_grid() {
 		}
 
 		// Create a mesh from the pushed vector points and colors.
-		grid[c] = VisualServer::get_singleton()->mesh_create();
+		grid[c] = RID_PRIME(VisualServer::get_singleton()->mesh_create());
 		Array d;
 		d.resize(VS::ARRAY_MAX);
 		d[VisualServer::ARRAY_VERTEX] = grid_points[c];

+ 8 - 0
main/main.cpp

@@ -2343,6 +2343,10 @@ void Main::cleanup(bool p_force) {
 		ERR_FAIL_COND(!_start_success);
 	}
 
+#ifdef RID_HANDLES_ENABLED
+	g_rid_database.preshutdown();
+#endif
+
 	if (script_debugger) {
 		// Flush any remaining messages
 		script_debugger->idle_poll();
@@ -2451,4 +2455,8 @@ void Main::cleanup(bool p_force) {
 	unregister_core_types();
 
 	OS::get_singleton()->finalize_core();
+
+#ifdef RID_HANDLES_ENABLED
+	g_rid_database.shutdown();
+#endif
 }

+ 14 - 14
main/tests/test_physics.cpp

@@ -85,7 +85,7 @@ protected:
 		PhysicsServer *ps = PhysicsServer::get_singleton();
 
 		RID mesh_instance = vs->instance_create2(type_mesh_map[p_shape], scenario);
-		RID body = ps->body_create(p_body, !p_active_default);
+		RID body = RID_PRIME(ps->body_create(p_body, !p_active_default));
 		ps->body_set_space(body, space);
 		ps->body_set_param(body, PhysicsServer::BODY_PARAM_BOUNCE, 0.0);
 		//todo set space
@@ -107,7 +107,7 @@ protected:
 		RID plane_shape = ps->shape_create(PhysicsServer::SHAPE_PLANE);
 		ps->shape_set_data(plane_shape, p_plane);
 
-		RID b = ps->body_create(PhysicsServer::BODY_MODE_STATIC);
+		RID b = RID_PRIME(ps->body_create(PhysicsServer::BODY_MODE_STATIC));
 		ps->body_set_space(b, space);
 		//todo set space
 		ps->body_add_shape(b, plane_shape);
@@ -136,7 +136,7 @@ protected:
 		/* BOX SHAPE */
 
 		PoolVector<Plane> box_planes = Geometry::build_box_planes(Vector3(0.5, 0.5, 0.5));
-		RID box_mesh = vs->mesh_create();
+		RID box_mesh = RID_PRIME(vs->mesh_create());
 		Geometry::MeshData box_data = Geometry::build_convex_mesh(box_planes);
 		vs->mesh_add_surface_from_mesh_data(box_mesh, box_data);
 		type_mesh_map[PhysicsServer::SHAPE_BOX] = box_mesh;
@@ -149,7 +149,7 @@ protected:
 
 		PoolVector<Plane> capsule_planes = Geometry::build_capsule_planes(0.5, 0.7, 12, Vector3::AXIS_Z);
 
-		RID capsule_mesh = vs->mesh_create();
+		RID capsule_mesh = RID_PRIME(vs->mesh_create());
 		Geometry::MeshData capsule_data = Geometry::build_convex_mesh(capsule_planes);
 		vs->mesh_add_surface_from_mesh_data(capsule_mesh, capsule_data);
 
@@ -166,7 +166,7 @@ protected:
 
 		PoolVector<Plane> convex_planes = Geometry::build_cylinder_planes(0.5, 0.7, 5, Vector3::AXIS_Z);
 
-		RID convex_mesh = vs->mesh_create();
+		RID convex_mesh = RID_PRIME(vs->mesh_create());
 		Geometry::MeshData convex_data = Geometry::build_convex_mesh(convex_planes);
 		ConvexHullComputer::convex_hull(convex_data.vertices, convex_data);
 		vs->mesh_add_surface_from_mesh_data(convex_mesh, convex_data);
@@ -192,7 +192,7 @@ protected:
 			normals.push_back(p.normal);
 		}
 
-		RID trimesh_mesh = vs->mesh_create();
+		RID trimesh_mesh = RID_PRIME(vs->mesh_create());
 		Array d;
 		d.resize(VS::ARRAY_MAX);
 		d[VS::ARRAY_VERTEX] = p_faces;
@@ -201,7 +201,7 @@ protected:
 
 		RID triins = vs->instance_create2(trimesh_mesh, scenario);
 
-		RID tribody = ps->body_create(PhysicsServer::BODY_MODE_STATIC);
+		RID tribody = RID_PRIME(ps->body_create(PhysicsServer::BODY_MODE_STATIC));
 		ps->body_set_space(tribody, space);
 		//todo set space
 		ps->body_add_shape(tribody, trimesh_shape);
@@ -273,14 +273,14 @@ public:
 		init_shapes();
 
 		PhysicsServer *ps = PhysicsServer::get_singleton();
-		space = ps->space_create();
+		space = RID_PRIME(ps->space_create());
 		ps->space_set_active(space, true);
 
 		VisualServer *vs = VisualServer::get_singleton();
 
 		/* LIGHT */
-		RID lightaux = vs->directional_light_create();
-		scenario = vs->scenario_create();
+		RID lightaux = RID_PRIME(vs->directional_light_create());
+		scenario = RID_PRIME(vs->scenario_create());
 		vs->light_set_shadow(lightaux, true);
 		light = vs->instance_create2(lightaux, scenario);
 		Transform t;
@@ -289,9 +289,9 @@ public:
 
 		/* CAMERA */
 
-		camera = vs->camera_create();
+		camera = RID_PRIME(vs->camera_create());
 
-		RID viewport = vs->viewport_create();
+		RID viewport = RID_PRIME(vs->viewport_create());
 		Size2i screen_size = OS::get_singleton()->get_window_size();
 		vs->viewport_set_size(viewport, screen_size.x, screen_size.y);
 		vs->viewport_attach_to_screen(viewport, Rect2(Vector2(), screen_size));
@@ -342,7 +342,7 @@ public:
 
 		PoolVector<Plane> capsule_planes = Geometry::build_capsule_planes(0.5, 1, 12, 5, Vector3::AXIS_Y);
 
-		RID capsule_mesh = vs->mesh_create();
+		RID capsule_mesh = RID_PRIME(vs->mesh_create());
 		Geometry::MeshData capsule_data = Geometry::build_convex_mesh(capsule_planes);
 		vs->mesh_add_surface_from_mesh_data(capsule_mesh, capsule_data);
 		type_mesh_map[PhysicsServer::SHAPE_CAPSULE] = capsule_mesh;
@@ -357,7 +357,7 @@ public:
 		ps->shape_set_data(capsule_shape, capsule_params);
 
 		RID mesh_instance = vs->instance_create2(capsule_mesh, scenario);
-		character = ps->body_create(PhysicsServer::BODY_MODE_CHARACTER);
+		character = RID_PRIME(ps->body_create(PhysicsServer::BODY_MODE_CHARACTER));
 		ps->body_set_space(character, space);
 		//todo add space
 		ps->body_add_shape(character, capsule_shape);

+ 14 - 14
main/tests/test_physics_2d.cpp

@@ -80,7 +80,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 
 			Ref<Image> image = memnew(Image(32, 2, 0, Image::FORMAT_LA8, pixels));
 
-			body_shape_data[Physics2DServer::SHAPE_SEGMENT].image = vs->texture_create_from_image(image);
+			body_shape_data[Physics2DServer::SHAPE_SEGMENT].image = RID_PRIME(vs->texture_create_from_image(image));
 
 			RID segment_shape = ps->segment_shape_create();
 			Rect2 sg(Point2(-16, 0), Point2(16, 0));
@@ -104,7 +104,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 
 			Ref<Image> image = memnew(Image(32, 32, 0, Image::FORMAT_LA8, pixels));
 
-			body_shape_data[Physics2DServer::SHAPE_CIRCLE].image = vs->texture_create_from_image(image);
+			body_shape_data[Physics2DServer::SHAPE_CIRCLE].image = RID_PRIME(vs->texture_create_from_image(image));
 
 			RID circle_shape = ps->circle_shape_create();
 			ps->shape_set_data(circle_shape, 16);
@@ -128,7 +128,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 
 			Ref<Image> image = memnew(Image(32, 32, 0, Image::FORMAT_LA8, pixels));
 
-			body_shape_data[Physics2DServer::SHAPE_RECTANGLE].image = vs->texture_create_from_image(image);
+			body_shape_data[Physics2DServer::SHAPE_RECTANGLE].image = RID_PRIME(vs->texture_create_from_image(image));
 
 			RID rectangle_shape = ps->rectangle_shape_create();
 			ps->shape_set_data(rectangle_shape, Vector2(16, 16));
@@ -153,7 +153,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 
 			Ref<Image> image = memnew(Image(32, 64, 0, Image::FORMAT_LA8, pixels));
 
-			body_shape_data[Physics2DServer::SHAPE_CAPSULE].image = vs->texture_create_from_image(image);
+			body_shape_data[Physics2DServer::SHAPE_CAPSULE].image = RID_PRIME(vs->texture_create_from_image(image));
 
 			RID capsule_shape = ps->capsule_shape_create();
 			ps->shape_set_data(capsule_shape, Vector2(16, 32));
@@ -166,7 +166,7 @@ class TestPhysics2DMainLoop : public MainLoop {
 		{
 			Ref<Image> image = memnew(Image(convex_png));
 
-			body_shape_data[Physics2DServer::SHAPE_CONVEX_POLYGON].image = vs->texture_create_from_image(image);
+			body_shape_data[Physics2DServer::SHAPE_CONVEX_POLYGON].image = RID_PRIME(vs->texture_create_from_image(image));
 
 			RID convex_polygon_shape = ps->convex_polygon_shape_create();
 
@@ -229,14 +229,14 @@ protected:
 		VisualServer *vs = VisualServer::get_singleton();
 		Physics2DServer *ps = Physics2DServer::get_singleton();
 
-		RID body = ps->body_create();
+		RID body = RID_PRIME(ps->body_create());
 		ps->body_add_shape(body, body_shape_data[p_shape].shape);
 		ps->body_set_space(body, space);
 		ps->body_set_continuous_collision_detection_mode(body, Physics2DServer::CCD_MODE_CAST_SHAPE);
 		ps->body_set_state(body, Physics2DServer::BODY_STATE_TRANSFORM, p_xform);
 
 		//print_line("add body with xform: "+p_xform);
-		RID sprite = vs->canvas_item_create();
+		RID sprite = RID_PRIME(vs->canvas_item_create());
 		vs->canvas_item_set_parent(sprite, canvas);
 		vs->canvas_item_set_transform(sprite, p_xform);
 		Size2 imgsize(vs->texture_get_width(body_shape_data[p_shape].image), vs->texture_get_height(body_shape_data[p_shape].image));
@@ -259,7 +259,7 @@ protected:
 		RID plane = ps->line_shape_create();
 		ps->shape_set_data(plane, arr);
 
-		RID plane_body = ps->body_create();
+		RID plane_body = RID_PRIME(ps->body_create());
 		ps->body_set_mode(plane_body, Physics2DServer::BODY_MODE_STATIC);
 		ps->body_set_space(plane_body, space);
 		ps->body_add_shape(plane_body, plane);
@@ -271,13 +271,13 @@ protected:
 
 		RID concave = ps->concave_polygon_shape_create();
 		ps->shape_set_data(concave, p_points);
-		RID body = ps->body_create();
+		RID body = RID_PRIME(ps->body_create());
 		ps->body_set_mode(body, Physics2DServer::BODY_MODE_STATIC);
 		ps->body_set_space(body, space);
 		ps->body_add_shape(body, concave);
 		ps->body_set_state(body, Physics2DServer::BODY_STATE_TRANSFORM, p_xform);
 
-		RID sprite = vs->canvas_item_create();
+		RID sprite = RID_PRIME(vs->canvas_item_create());
 		vs->canvas_item_set_parent(sprite, canvas);
 		vs->canvas_item_set_transform(sprite, p_xform);
 		for (int i = 0; i < p_points.size(); i += 2) {
@@ -318,15 +318,15 @@ public:
 		VisualServer *vs = VisualServer::get_singleton();
 		Physics2DServer *ps = Physics2DServer::get_singleton();
 
-		space = ps->space_create();
+		space = RID_PRIME(ps->space_create());
 		ps->space_set_active(space, true);
 		ps->set_active(true);
 		ps->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY_VECTOR, Vector2(0, 1));
 		ps->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY, 98);
 
 		{
-			RID vp = vs->viewport_create();
-			canvas = vs->canvas_create();
+			RID vp = RID_PRIME(vs->viewport_create());
+			canvas = RID_PRIME(vs->canvas_create());
 
 			Size2i screen_size = OS::get_singleton()->get_window_size();
 			vs->viewport_attach_canvas(vp, canvas);
@@ -342,7 +342,7 @@ public:
 			vs->viewport_set_canvas_transform(vp, canvas, view_xform);
 		}
 
-		ray = vs->canvas_item_create();
+		ray = RID_PRIME(vs->canvas_item_create());
 		vs->canvas_item_set_parent(ray, canvas);
 		//ray_query = ps->query_create(this,"_ray_query_callback",Variant());
 		//ps->query_intersection(ray_query,space);

+ 4 - 4
main/tests/test_render.cpp

@@ -73,7 +73,7 @@ public:
 		print_line("INITIALIZING TEST RENDER");
 		VisualServer *vs = VisualServer::get_singleton();
 		test_cube = vs->get_test_cube();
-		scenario = vs->scenario_create();
+		scenario = RID_PRIME(vs->scenario_create());
 
 		Vector<Vector3> vts;
 
@@ -120,7 +120,7 @@ public:
 		Geometry::MeshData md;
 		Error err = ConvexHullComputer::convex_hull(vts, md);
 		print_line("ERR: " + itos(err));
-		test_cube = vs->mesh_create();
+		test_cube = RID_PRIME(vs->mesh_create());
 		vs->mesh_add_surface_from_mesh_data(test_cube, md);
 		//vs->scenario_set_debug(scenario,VS::SCENARIO_DEBUG_WIREFRAME);
 
@@ -154,11 +154,11 @@ public:
 			instances.push_back(ii);
 		}
 
-		camera = vs->camera_create();
+		camera = RID_PRIME(vs->camera_create());
 
 		// 		vs->camera_set_perspective( camera, 60.0,0.1, 100.0 );
 
-		viewport = vs->viewport_create();
+		viewport = RID_PRIME(vs->viewport_create());
 		Size2i screen_size = OS::get_singleton()->get_window_size();
 		vs->viewport_set_size(viewport, screen_size.x, screen_size.y);
 		vs->viewport_attach_to_screen(viewport, Rect2(Vector2(), screen_size));

+ 2 - 2
modules/csg/csg_shape.cpp

@@ -43,7 +43,7 @@ void CSGShape::set_use_collision(bool p_enable) {
 
 	if (use_collision) {
 		root_collision_shape.instance();
-		root_collision_instance = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
+		root_collision_instance = RID_PRIME(PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC));
 		PhysicsServer::get_singleton()->body_set_state(root_collision_instance, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
 		PhysicsServer::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
 		PhysicsServer::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());
@@ -501,7 +501,7 @@ void CSGShape::_notification(int p_what) {
 
 		if (use_collision && is_root_shape()) {
 			root_collision_shape.instance();
-			root_collision_instance = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
+			root_collision_instance = RID_PRIME(PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC));
 			PhysicsServer::get_singleton()->body_set_state(root_collision_instance, PhysicsServer::BODY_STATE_TRANSFORM, get_global_transform());
 			PhysicsServer::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
 			PhysicsServer::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());

+ 7 - 7
modules/gridmap/grid_map.cpp

@@ -70,7 +70,7 @@ bool GridMap::_set(const StringName &p_name, const Variant &p_value) {
 			BakedMesh bm;
 			bm.mesh = meshes[i];
 			ERR_CONTINUE(!bm.mesh.is_valid());
-			bm.instance = VS::get_singleton()->instance_create();
+			bm.instance = RID_PRIME(VS::get_singleton()->instance_create());
 			VS::get_singleton()->get_singleton()->instance_set_base(bm.instance, bm.mesh->get_rid());
 			VS::get_singleton()->instance_attach_object_instance_id(bm.instance, get_instance_id());
 			if (is_inside_tree()) {
@@ -295,15 +295,15 @@ void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) {
 		//create octant because it does not exist
 		Octant *g = memnew(Octant);
 		g->dirty = true;
-		g->static_body = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
+		g->static_body = RID_PRIME(PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC));
 		PhysicsServer::get_singleton()->body_attach_object_instance_id(g->static_body, get_instance_id());
 		PhysicsServer::get_singleton()->body_set_collision_layer(g->static_body, collision_layer);
 		PhysicsServer::get_singleton()->body_set_collision_mask(g->static_body, collision_mask);
 		SceneTree *st = SceneTree::get_singleton();
 
 		if (st && st->is_debugging_collisions_hint()) {
-			g->collision_debug = VisualServer::get_singleton()->mesh_create();
-			g->collision_debug_instance = VisualServer::get_singleton()->instance_create();
+			g->collision_debug = RID_PRIME(VisualServer::get_singleton()->mesh_create());
+			g->collision_debug_instance = RID_PRIME(VisualServer::get_singleton()->instance_create());
 			VisualServer::get_singleton()->instance_set_base(g->collision_debug_instance, g->collision_debug);
 		}
 
@@ -499,7 +499,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
 		for (Map<int, List<Pair<Transform, IndexKey>>>::Element *E = multimesh_items.front(); E; E = E->next()) {
 			Octant::MultimeshInstance mmi;
 
-			RID mm = VS::get_singleton()->multimesh_create();
+			RID mm = RID_PRIME(VS::get_singleton()->multimesh_create());
 			VS::get_singleton()->multimesh_allocate(mm, E->get().size(), VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_NONE);
 			VS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid());
 
@@ -518,7 +518,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
 				idx++;
 			}
 
-			RID instance = VS::get_singleton()->instance_create();
+			RID instance = RID_PRIME(VS::get_singleton()->instance_create());
 			VS::get_singleton()->instance_set_base(instance, mm);
 
 			if (is_inside_tree()) {
@@ -1024,7 +1024,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe
 
 		BakedMesh bm;
 		bm.mesh = mesh;
-		bm.instance = VS::get_singleton()->instance_create();
+		bm.instance = RID_PRIME(VS::get_singleton()->instance_create());
 		VS::get_singleton()->get_singleton()->instance_set_base(bm.instance, bm.mesh->get_rid());
 		VS::get_singleton()->instance_attach_object_instance_id(bm.instance, get_instance_id());
 		if (is_inside_tree()) {

+ 4 - 4
modules/gridmap/grid_map_editor_plugin.cpp

@@ -1033,7 +1033,7 @@ void GridMapEditor::_notification(int p_what) {
 			get_tree()->connect("node_removed", this, "_node_removed");
 			mesh_library_palette->connect("item_selected", this, "_item_selected_cbk");
 			for (int i = 0; i < 3; i++) {
-				grid[i] = VS::get_singleton()->mesh_create();
+				grid[i] = RID_PRIME(VS::get_singleton()->mesh_create());
 				grid_instance[i] = VS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world()->get_scenario());
 				VS::get_singleton()->instance_set_layer_mask(grid_instance[i], 1 << SpatialEditorViewport::MISC_TOOL_LAYER);
 				selection_level_instance[i] = VisualServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world()->get_scenario());
@@ -1327,8 +1327,8 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
 	lock_view = false;
 	cursor_rot = 0;
 
-	selection_mesh = VisualServer::get_singleton()->mesh_create();
-	paste_mesh = VisualServer::get_singleton()->mesh_create();
+	selection_mesh = RID_PRIME(VisualServer::get_singleton()->mesh_create());
+	paste_mesh = RID_PRIME(VisualServer::get_singleton()->mesh_create());
 
 	{
 		// Selection mesh create.
@@ -1438,7 +1438,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
 
 		for (int i = 0; i < 3; i++) {
 			d[VS::ARRAY_VERTEX] = square[i];
-			selection_level_mesh[i] = VS::get_singleton()->mesh_create();
+			selection_level_mesh[i] = RID_PRIME(VS::get_singleton()->mesh_create());
 			VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_level_mesh[i], VS::PRIMITIVE_LINES, d);
 			VisualServer::get_singleton()->mesh_surface_set_material(selection_level_mesh[i], 0, selection_floor_mat->get_rid());
 		}

+ 1 - 1
modules/opensimplex/noise_texture.cpp

@@ -45,7 +45,7 @@ NoiseTexture::NoiseTexture() {
 
 	noise = Ref<OpenSimplexNoise>();
 
-	texture = VS::get_singleton()->texture_create();
+	texture = RID_PRIME(VS::get_singleton()->texture_create());
 
 	_queue_update();
 }

+ 1 - 1
scene/2d/area_2d.cpp

@@ -570,7 +570,7 @@ void Area2D::_bind_methods() {
 }
 
 Area2D::Area2D() :
-		CollisionObject2D(Physics2DServer::get_singleton()->area_create(), true) {
+		CollisionObject2D(RID_PRIME(Physics2DServer::get_singleton()->area_create()), true) {
 	space_override = SPACE_OVERRIDE_DISABLED;
 	set_gravity(98);
 	set_gravity_vector(Vector2(0, 1));

+ 1 - 1
scene/2d/canvas_item.cpp

@@ -1265,7 +1265,7 @@ int CanvasItem::get_canvas_layer() const {
 
 CanvasItem::CanvasItem() :
 		xform_change(this) {
-	canvas_item = VisualServer::get_singleton()->canvas_item_create();
+	canvas_item = RID_PRIME(VisualServer::get_singleton()->canvas_item_create());
 	visible = true;
 	pending_update = false;
 	modulate = Color(1, 1, 1, 1);

+ 2 - 2
scene/2d/cpu_particles_2d.cpp

@@ -1376,8 +1376,8 @@ CPUParticles2D::CPUParticles2D() {
 	redraw = false;
 	emitting = false;
 
-	mesh = VisualServer::get_singleton()->mesh_create();
-	multimesh = VisualServer::get_singleton()->multimesh_create();
+	mesh = RID_PRIME(VisualServer::get_singleton()->mesh_create());
+	multimesh = RID_PRIME(VisualServer::get_singleton()->multimesh_create());
 	VisualServer::get_singleton()->multimesh_set_mesh(multimesh, mesh);
 
 	set_emitting(true);

+ 1 - 1
scene/2d/light_2d.cpp

@@ -435,7 +435,7 @@ void Light2D::_bind_methods() {
 }
 
 Light2D::Light2D() {
-	canvas_light = VisualServer::get_singleton()->canvas_light_create();
+	canvas_light = RID_PRIME(VisualServer::get_singleton()->canvas_light_create());
 	enabled = true;
 	editor_only = false;
 	shadow = false;

+ 2 - 2
scene/2d/light_occluder_2d.cpp

@@ -143,7 +143,7 @@ void OccluderPolygon2D::_bind_methods() {
 }
 
 OccluderPolygon2D::OccluderPolygon2D() {
-	occ_polygon = VS::get_singleton()->canvas_occluder_polygon_create();
+	occ_polygon = RID_PRIME(VS::get_singleton()->canvas_occluder_polygon_create());
 	closed = true;
 	cull = CULL_DISABLED;
 	rect_cache_dirty = true;
@@ -277,7 +277,7 @@ void LightOccluder2D::_bind_methods() {
 }
 
 LightOccluder2D::LightOccluder2D() {
-	occluder = VS::get_singleton()->canvas_light_occluder_create();
+	occluder = RID_PRIME(VS::get_singleton()->canvas_light_occluder_create());
 	mask = 1;
 	set_notify_transform(true);
 }

+ 1 - 1
scene/2d/particles_2d.cpp

@@ -381,7 +381,7 @@ void Particles2D::_bind_methods() {
 }
 
 Particles2D::Particles2D() {
-	particles = VS::get_singleton()->particles_create();
+	particles = RID_PRIME(VS::get_singleton()->particles_create());
 
 	one_shot = false; // Needed so that set_emitting doesn't access uninitialized values
 	set_emitting(true);

+ 1 - 1
scene/2d/physics_body_2d.cpp

@@ -61,7 +61,7 @@ void PhysicsBody2D::_bind_methods() {
 }
 
 PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) :
-		CollisionObject2D(Physics2DServer::get_singleton()->body_create(), false) {
+		CollisionObject2D(RID_PRIME(Physics2DServer::get_singleton()->body_create()), false) {
 	Physics2DServer::get_singleton()->body_set_mode(get_rid(), p_mode);
 	set_pickable(false);
 }

+ 1 - 1
scene/2d/skeleton_2d.cpp

@@ -293,7 +293,7 @@ Skeleton2D::Skeleton2D() {
 	bone_setup_dirty = true;
 	transform_dirty = true;
 
-	skeleton = VS::get_singleton()->skeleton_create();
+	skeleton = RID_PRIME(VS::get_singleton()->skeleton_create());
 	set_notify_transform(true);
 }
 

+ 5 - 5
scene/2d/tile_map.cpp

@@ -415,7 +415,7 @@ void TileMap::update_dirty_quadrants() {
 			RID debug_canvas_item;
 
 			if (prev_canvas_item == RID() || prev_material != mat || prev_z_index != z_index) {
-				canvas_item = vs->canvas_item_create();
+				canvas_item = RID_PRIME(vs->canvas_item_create());
 				if (mat.is_valid()) {
 					vs->canvas_item_set_material(canvas_item, mat->get_rid());
 				}
@@ -430,7 +430,7 @@ void TileMap::update_dirty_quadrants() {
 				q.canvas_items.push_back(canvas_item);
 
 				if (debug_shapes) {
-					debug_canvas_item = vs->canvas_item_create();
+					debug_canvas_item = RID_PRIME(vs->canvas_item_create());
 					vs->canvas_item_set_parent(debug_canvas_item, canvas_item);
 					vs->canvas_item_set_z_as_relative_to_parent(debug_canvas_item, false);
 					vs->canvas_item_set_z_index(debug_canvas_item, VS::CANVAS_ITEM_Z_MAX - 1);
@@ -619,7 +619,7 @@ void TileMap::update_dirty_quadrants() {
 					q.navpoly_ids[E->key()] = np;
 
 					if (debug_navigation) {
-						RID debug_navigation_item = vs->canvas_item_create();
+						RID debug_navigation_item = RID_PRIME(vs->canvas_item_create());
 						vs->canvas_item_set_parent(debug_navigation_item, canvas_item);
 						vs->canvas_item_set_z_as_relative_to_parent(debug_navigation_item, false);
 						vs->canvas_item_set_z_index(debug_navigation_item, VS::CANVAS_ITEM_Z_MAX - 2); // Display one below collision debug
@@ -679,7 +679,7 @@ void TileMap::update_dirty_quadrants() {
 				xform.set_origin(offset.floor() + q.pos);
 				_fix_cell_transform(xform, c, occluder_ofs, s);
 
-				RID orid = VS::get_singleton()->canvas_light_occluder_create();
+				RID orid = RID_PRIME(VS::get_singleton()->canvas_light_occluder_create());
 				VS::get_singleton()->canvas_light_occluder_set_transform(orid, get_global_transform() * xform);
 				VS::get_singleton()->canvas_light_occluder_set_polygon(orid, occluder->get_rid());
 				VS::get_singleton()->canvas_light_occluder_attach_to_canvas(orid, get_canvas());
@@ -757,7 +757,7 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons
 	xform.set_origin(q.pos);
 	//q.canvas_item = VisualServer::get_singleton()->canvas_item_create();
 	if (!use_parent) {
-		q.body = Physics2DServer::get_singleton()->body_create();
+		q.body = RID_PRIME(Physics2DServer::get_singleton()->body_create());
 		Physics2DServer::get_singleton()->body_set_mode(q.body, use_kinematic ? Physics2DServer::BODY_MODE_KINEMATIC : Physics2DServer::BODY_MODE_STATIC);
 
 		Physics2DServer::get_singleton()->body_attach_object_instance_id(q.body, get_instance_id());

+ 1 - 1
scene/3d/area.cpp

@@ -615,7 +615,7 @@ void Area::_bind_methods() {
 }
 
 Area::Area() :
-		CollisionObject(PhysicsServer::get_singleton()->area_create(), true) {
+		CollisionObject(RID_PRIME(PhysicsServer::get_singleton()->area_create()), true) {
 	space_override = SPACE_OVERRIDE_DISABLED;
 	set_gravity(9.8);
 	locked = false;

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

@@ -147,7 +147,7 @@ void BakedLightmapData::clear_data() {
 	if (baked_light.is_valid()) {
 		VS::get_singleton()->free(baked_light);
 	}
-	baked_light = VS::get_singleton()->lightmap_capture_create();
+	baked_light = RID_PRIME(VS::get_singleton()->lightmap_capture_create());
 }
 
 void BakedLightmapData::_set_user_data(const Array &p_data) {
@@ -243,7 +243,7 @@ void BakedLightmapData::_bind_methods() {
 }
 
 BakedLightmapData::BakedLightmapData() {
-	baked_light = VS::get_singleton()->lightmap_capture_create();
+	baked_light = RID_PRIME(VS::get_singleton()->lightmap_capture_create());
 	energy = 1;
 	cell_subdiv = 1;
 	interior = false;

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

@@ -645,7 +645,7 @@ Vector3 Camera::get_doppler_tracked_velocity() const {
 	}
 }
 Camera::Camera() {
-	camera = VisualServer::get_singleton()->camera_create();
+	camera = RID_PRIME(VisualServer::get_singleton()->camera_create());
 	size = 1;
 	fov = 0;
 	frustum_offset = Vector2();
@@ -880,7 +880,7 @@ ClippedCamera::ClippedCamera() {
 	collision_mask = 1;
 	set_notify_local_transform(Engine::get_singleton()->is_editor_hint());
 	points.resize(5);
-	pyramid_shape = PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON);
+	pyramid_shape = RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON));
 	clip_to_areas = false;
 	clip_to_bodies = true;
 }

+ 1 - 1
scene/3d/collision_object.cpp

@@ -244,7 +244,7 @@ void CollisionObject::_update_debug_shapes() {
 					}
 				}
 				if (!s.debug_shape.is_valid()) {
-					s.debug_shape = VS::get_singleton()->instance_create();
+					s.debug_shape = RID_PRIME(VS::get_singleton()->instance_create());
 					VS::get_singleton()->instance_set_scenario(s.debug_shape, get_world()->get_scenario());
 
 					if (!s.shape->is_connected("changed", this, "_shape_changed")) {

+ 1 - 1
scene/3d/collision_shape.cpp

@@ -198,7 +198,7 @@ bool CollisionShape::is_disabled() const {
 }
 
 CollisionShape::CollisionShape() {
-	//indicator = VisualServer::get_singleton()->mesh_create();
+	//indicator = RID_PRIME(VisualServer::get_singleton()->mesh_create());
 	disabled = false;
 	parent = nullptr;
 	owner_id = 0;

+ 1 - 1
scene/3d/cpu_particles.cpp

@@ -1519,7 +1519,7 @@ CPUParticles::CPUParticles() {
 
 	set_notify_transform(true);
 
-	multimesh = VisualServer::get_singleton()->multimesh_create();
+	multimesh = RID_PRIME(VisualServer::get_singleton()->multimesh_create());
 	VisualServer::get_singleton()->multimesh_set_visible_instances(multimesh, 0);
 	set_base(multimesh);
 

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

@@ -175,7 +175,7 @@ void GIProbeData::_bind_methods() {
 }
 
 GIProbeData::GIProbeData() {
-	probe = VS::get_singleton()->gi_probe_create();
+	probe = RID_PRIME(VS::get_singleton()->gi_probe_create());
 }
 
 GIProbeData::~GIProbeData() {
@@ -522,7 +522,7 @@ GIProbe::GIProbe() {
 	interior = false;
 	compress = false;
 
-	gi_probe = VS::get_singleton()->gi_probe_create();
+	gi_probe = RID_PRIME(VS::get_singleton()->gi_probe_create());
 	set_disable_scale(true);
 }
 

+ 1 - 1
scene/3d/immediate_geometry.cpp

@@ -144,7 +144,7 @@ void ImmediateGeometry::_bind_methods() {
 }
 
 ImmediateGeometry::ImmediateGeometry() {
-	im = VisualServer::get_singleton()->immediate_create();
+	im = RID_PRIME(VisualServer::get_singleton()->immediate_create());
 	set_base(im);
 	empty = true;
 }

+ 3 - 3
scene/3d/light.cpp

@@ -273,13 +273,13 @@ Light::Light(VisualServer::LightType p_type) {
 	type = p_type;
 	switch (p_type) {
 		case VS::LIGHT_DIRECTIONAL:
-			light = VisualServer::get_singleton()->directional_light_create();
+			light = RID_PRIME(VisualServer::get_singleton()->directional_light_create());
 			break;
 		case VS::LIGHT_OMNI:
-			light = VisualServer::get_singleton()->omni_light_create();
+			light = RID_PRIME(VisualServer::get_singleton()->omni_light_create());
 			break;
 		case VS::LIGHT_SPOT:
-			light = VisualServer::get_singleton()->spot_light_create();
+			light = RID_PRIME(VisualServer::get_singleton()->spot_light_create());
 			break;
 		default: {
 		};

+ 1 - 1
scene/3d/particles.cpp

@@ -384,7 +384,7 @@ void Particles::_bind_methods() {
 }
 
 Particles::Particles() {
-	particles = VS::get_singleton()->particles_create();
+	particles = RID_PRIME(VS::get_singleton()->particles_create());
 	set_base(particles);
 	one_shot = false; // Needed so that set_emitting doesn't access uninitialized values
 	set_emitting(true);

+ 6 - 6
scene/3d/physics_body.cpp

@@ -99,7 +99,7 @@ void PhysicsBody::_bind_methods() {
 }
 
 PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) :
-		CollisionObject(PhysicsServer::get_singleton()->body_create(p_mode), false) {
+		CollisionObject(RID_PRIME(PhysicsServer::get_singleton()->body_create(p_mode)), false) {
 }
 
 #ifndef DISABLE_DEPRECATED
@@ -2411,7 +2411,7 @@ void PhysicalBone::_reload_joint() {
 
 	switch (get_joint_type()) {
 		case JOINT_TYPE_PIN: {
-			joint = PhysicsServer::get_singleton()->joint_create_pin(body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin);
+			joint = RID_PRIME(PhysicsServer::get_singleton()->joint_create_pin(body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin));
 			const PinJointData *pjd(static_cast<const PinJointData *>(joint_data));
 			PhysicsServer::get_singleton()->pin_joint_set_param(joint, PhysicsServer::PIN_JOINT_BIAS, pjd->bias);
 			PhysicsServer::get_singleton()->pin_joint_set_param(joint, PhysicsServer::PIN_JOINT_DAMPING, pjd->damping);
@@ -2419,7 +2419,7 @@ void PhysicalBone::_reload_joint() {
 
 		} break;
 		case JOINT_TYPE_CONE: {
-			joint = PhysicsServer::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, get_rid(), joint_offset);
+			joint = RID_PRIME(PhysicsServer::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, get_rid(), joint_offset));
 			const ConeJointData *cjd(static_cast<const ConeJointData *>(joint_data));
 			PhysicsServer::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer::CONE_TWIST_JOINT_SWING_SPAN, cjd->swing_span);
 			PhysicsServer::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer::CONE_TWIST_JOINT_TWIST_SPAN, cjd->twist_span);
@@ -2429,7 +2429,7 @@ void PhysicalBone::_reload_joint() {
 
 		} break;
 		case JOINT_TYPE_HINGE: {
-			joint = PhysicsServer::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, get_rid(), joint_offset);
+			joint = RID_PRIME(PhysicsServer::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, get_rid(), joint_offset));
 			const HingeJointData *hjd(static_cast<const HingeJointData *>(joint_data));
 			PhysicsServer::get_singleton()->hinge_joint_set_flag(joint, PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT, hjd->angular_limit_enabled);
 			PhysicsServer::get_singleton()->hinge_joint_set_param(joint, PhysicsServer::HINGE_JOINT_LIMIT_UPPER, hjd->angular_limit_upper);
@@ -2440,7 +2440,7 @@ void PhysicalBone::_reload_joint() {
 
 		} break;
 		case JOINT_TYPE_SLIDER: {
-			joint = PhysicsServer::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, get_rid(), joint_offset);
+			joint = RID_PRIME(PhysicsServer::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, get_rid(), joint_offset));
 			const SliderJointData *sjd(static_cast<const SliderJointData *>(joint_data));
 			PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_UPPER, sjd->linear_limit_upper);
 			PhysicsServer::get_singleton()->slider_joint_set_param(joint, PhysicsServer::SLIDER_JOINT_LINEAR_LIMIT_LOWER, sjd->linear_limit_lower);
@@ -2455,7 +2455,7 @@ void PhysicalBone::_reload_joint() {
 
 		} break;
 		case JOINT_TYPE_6DOF: {
-			joint = PhysicsServer::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, get_rid(), joint_offset);
+			joint = RID_PRIME(PhysicsServer::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, get_rid(), joint_offset));
 			const SixDOFJointData *g6dofjd(static_cast<const SixDOFJointData *>(joint_data));
 			for (int axis = 0; axis < 3; ++axis) {
 				PhysicsServer::get_singleton()->generic_6dof_joint_set_flag(joint, static_cast<Vector3::Axis>(axis), PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, g6dofjd->axis_data[axis].linear_limit_enabled);

+ 1 - 1
scene/3d/physics_joint.cpp

@@ -398,7 +398,7 @@ RID HingeJoint::_configure_joint(PhysicsBody *body_a, PhysicsBody *body_b) {
 
 	local_b.orthonormalize();
 
-	RID j = PhysicsServer::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
+	RID j = RID_PRIME(PhysicsServer::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b));
 	for (int i = 0; i < PARAM_MAX; i++) {
 		PhysicsServer::get_singleton()->hinge_joint_set_param(j, PhysicsServer::HingeJointParam(i), params[i]);
 	}

+ 1 - 1
scene/3d/portal.cpp

@@ -58,7 +58,7 @@ Portal::Portal() {
 	_use_default_margin = true;
 
 	// the visual server portal lifetime is linked to the lifetime of this object
-	_portal_rid = VisualServer::get_singleton()->portal_create();
+	_portal_rid = RID_PRIME(VisualServer::get_singleton()->portal_create());
 
 #ifdef TOOLS_ENABLED
 	_room_manager_godot_ID = 0;

+ 1 - 1
scene/3d/reflection_probe.cpp

@@ -246,7 +246,7 @@ ReflectionProbe::ReflectionProbe() {
 	cull_mask = (1 << 20) - 1;
 	update_mode = UPDATE_ONCE;
 
-	probe = VisualServer::get_singleton()->reflection_probe_create();
+	probe = RID_PRIME(VisualServer::get_singleton()->reflection_probe_create());
 	VS::get_singleton()->instance_set_base(get_instance(), probe);
 	set_disable_scale(true);
 }

+ 1 - 1
scene/3d/room.cpp

@@ -99,7 +99,7 @@ void Room::clear() {
 }
 
 Room::Room() {
-	_room_rid = VisualServer::get_singleton()->room_create();
+	_room_rid = RID_PRIME(VisualServer::get_singleton()->room_create());
 }
 
 Room::~Room() {

+ 1 - 1
scene/3d/room_group.cpp

@@ -41,7 +41,7 @@ void RoomGroup::_bind_methods() {
 }
 
 RoomGroup::RoomGroup() {
-	_room_group_rid = VisualServer::get_singleton()->roomgroup_create();
+	_room_group_rid = RID_PRIME(VisualServer::get_singleton()->roomgroup_create());
 }
 
 RoomGroup::~RoomGroup() {

+ 1 - 1
scene/3d/skeleton.cpp

@@ -813,7 +813,7 @@ Ref<SkinReference> Skeleton::register_skin(const Ref<Skin> &p_skin) {
 
 	skin_ref->skeleton_node = this;
 	skin_ref->bind_count = 0;
-	skin_ref->skeleton = VisualServer::get_singleton()->skeleton_create();
+	skin_ref->skeleton = RID_PRIME(VisualServer::get_singleton()->skeleton_create());
 	skin_ref->skeleton_node = this;
 	skin_ref->skin = skin;
 

+ 1 - 1
scene/3d/soft_body.cpp

@@ -731,7 +731,7 @@ bool SoftBody::is_ray_pickable() const {
 }
 
 SoftBody::SoftBody() :
-		physics_rid(PhysicsServer::get_singleton()->soft_body_create()),
+		physics_rid(RID_PRIME(PhysicsServer::get_singleton()->soft_body_create())),
 		collision_mask(1),
 		collision_layer(1),
 		simulation_started(false),

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

@@ -358,7 +358,7 @@ SpriteBase3D::SpriteBase3D() {
 	pending_update = false;
 	opacity = 1.0;
 
-	material = VisualServer::get_singleton()->material_create();
+	material = RID_PRIME(VisualServer::get_singleton()->material_create());
 	// Set defaults for material, names need to match up those in SpatialMaterial
 	VS::get_singleton()->material_set_param(material, "albedo", Color(1, 1, 1, 1));
 	VS::get_singleton()->material_set_param(material, "specular", 0.5);
@@ -370,7 +370,7 @@ SpriteBase3D::SpriteBase3D() {
 	VS::get_singleton()->material_set_param(material, "uv2_scale", Vector3(1, 1, 1));
 	VS::get_singleton()->material_set_param(material, "alpha_scissor_threshold", 0.98);
 
-	mesh = VisualServer::get_singleton()->mesh_create();
+	mesh = RID_PRIME(VisualServer::get_singleton()->mesh_create());
 
 	PoolVector3Array mesh_vertices;
 	PoolVector3Array mesh_normals;

+ 1 - 1
scene/3d/visibility_notifier.cpp

@@ -98,7 +98,7 @@ void VisibilityNotifier::_refresh_portal_mode() {
 	if (get_portal_mode() == PORTAL_MODE_ROAMING) {
 		if (is_inside_world()) {
 			if (_cull_instance_rid == RID()) {
-				_cull_instance_rid = VisualServer::get_singleton()->ghost_create();
+				_cull_instance_rid = RID_PRIME(VisualServer::get_singleton()->ghost_create());
 			}
 
 			if (is_inside_world() && get_world().is_valid() && get_world()->get_scenario().is_valid() && is_inside_tree()) {

+ 1 - 1
scene/3d/visual_instance.cpp

@@ -156,7 +156,7 @@ RID VisualInstance::get_base() const {
 }
 
 VisualInstance::VisualInstance() {
-	instance = VisualServer::get_singleton()->instance_create();
+	instance = RID_PRIME(VisualServer::get_singleton()->instance_create());
 	VisualServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id());
 	layers = 1;
 	set_notify_transform(true);

+ 1 - 1
scene/animation/root_motion_view.cpp

@@ -191,7 +191,7 @@ RootMotionView::RootMotionView() {
 	radius = 10;
 	cell_size = 1;
 	set_process_internal(true);
-	immediate = VisualServer::get_singleton()->immediate_create();
+	immediate = RID_PRIME(VisualServer::get_singleton()->immediate_create());
 	set_base(immediate);
 	color = Color(0.5, 0.5, 1.0);
 }

+ 1 - 1
scene/main/canvas_layer.cpp

@@ -322,7 +322,7 @@ CanvasLayer::CanvasLayer() {
 	rot = 0;
 	locrotscale_dirty = false;
 	layer = 1;
-	canvas = VS::get_singleton()->canvas_create();
+	canvas = RID_PRIME(VS::get_singleton()->canvas_create());
 	custom_viewport = nullptr;
 	custom_viewport_id = 0;
 	sort_index = 0;

+ 6 - 6
scene/main/viewport.cpp

@@ -146,7 +146,7 @@ ViewportTexture::ViewportTexture() {
 	vp = nullptr;
 	flags = 0;
 	set_local_to_scene(true);
-	proxy = VS::get_singleton()->texture_create();
+	proxy = RID_PRIME(VS::get_singleton()->texture_create());
 }
 
 ViewportTexture::~ViewportTexture() {
@@ -286,15 +286,15 @@ void Viewport::_notification(int p_what) {
 			if (get_tree()->is_debugging_collisions_hint()) {
 				//2D
 				Physics2DServer::get_singleton()->space_set_debug_contacts(find_world_2d()->get_space(), get_tree()->get_collision_debug_contact_count());
-				contact_2d_debug = VisualServer::get_singleton()->canvas_item_create();
+				contact_2d_debug = RID_PRIME(VisualServer::get_singleton()->canvas_item_create());
 				VisualServer::get_singleton()->canvas_item_set_parent(contact_2d_debug, find_world_2d()->get_canvas());
 				//3D
 				PhysicsServer::get_singleton()->space_set_debug_contacts(find_world()->get_space(), get_tree()->get_collision_debug_contact_count());
-				contact_3d_debug_multimesh = VisualServer::get_singleton()->multimesh_create();
+				contact_3d_debug_multimesh = RID_PRIME(VisualServer::get_singleton()->multimesh_create());
 				VisualServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_8BIT);
 				VisualServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0);
 				VisualServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid());
-				contact_3d_debug_instance = VisualServer::get_singleton()->instance_create();
+				contact_3d_debug_instance = RID_PRIME(VisualServer::get_singleton()->instance_create());
 				VisualServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh);
 				VisualServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world()->get_scenario());
 				//VisualServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true);
@@ -1171,7 +1171,7 @@ void Viewport::enable_camera_override(bool p_enable) {
 	}
 
 	if (p_enable) {
-		camera_override.rid = VisualServer::get_singleton()->camera_create();
+		camera_override.rid = RID_PRIME(VisualServer::get_singleton()->camera_create());
 	} else {
 		VisualServer::get_singleton()->free(camera_override.rid);
 		camera_override.rid = RID();
@@ -3337,7 +3337,7 @@ void Viewport::_subwindow_visibility_changed() {
 Viewport::Viewport() {
 	world_2d = Ref<World2D>(memnew(World2D));
 
-	viewport = VisualServer::get_singleton()->viewport_create();
+	viewport = RID_PRIME(VisualServer::get_singleton()->viewport_create());
 	texture_rid = VisualServer::get_singleton()->viewport_get_texture(viewport);
 	texture_flags = 0;
 

+ 1 - 1
scene/resources/box_shape.cpp

@@ -71,6 +71,6 @@ void BoxShape::_bind_methods() {
 }
 
 BoxShape::BoxShape() :
-		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_BOX)) {
+		Shape(RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_BOX))) {
 	set_extents(Vector3(1, 1, 1));
 }

+ 1 - 1
scene/resources/capsule_shape.cpp

@@ -107,7 +107,7 @@ void CapsuleShape::_bind_methods() {
 }
 
 CapsuleShape::CapsuleShape() :
-		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CAPSULE)) {
+		Shape(RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CAPSULE))) {
 	radius = 1.0;
 	height = 1.0;
 	_update_shape();

+ 1 - 1
scene/resources/concave_polygon_shape.cpp

@@ -81,6 +81,6 @@ void ConcavePolygonShape::_bind_methods() {
 }
 
 ConcavePolygonShape::ConcavePolygonShape() :
-		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON)) {
+		Shape(RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON))) {
 	//set_planes(Vector3(1,1,1));
 }

+ 1 - 1
scene/resources/convex_polygon_shape.cpp

@@ -76,5 +76,5 @@ void ConvexPolygonShape::_bind_methods() {
 }
 
 ConvexPolygonShape::ConvexPolygonShape() :
-		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON)) {
+		Shape(RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON))) {
 }

+ 1 - 1
scene/resources/cylinder_shape.cpp

@@ -100,7 +100,7 @@ void CylinderShape::_bind_methods() {
 }
 
 CylinderShape::CylinderShape() :
-		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CYLINDER)) {
+		Shape(RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CYLINDER))) {
 	radius = 1.0;
 	height = 2.0;
 	_update_shape();

+ 1 - 1
scene/resources/environment.cpp

@@ -1175,7 +1175,7 @@ Environment::Environment() :
 		glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE),
 		dof_blur_far_quality(DOF_BLUR_QUALITY_LOW),
 		dof_blur_near_quality(DOF_BLUR_QUALITY_LOW) {
-	environment = VS::get_singleton()->environment_create();
+	environment = RID_PRIME(VS::get_singleton()->environment_create());
 
 	bg_mode = BG_CLEAR_COLOR;
 	bg_sky_custom_fov = 0;

+ 1 - 1
scene/resources/height_map_shape.cpp

@@ -193,7 +193,7 @@ void HeightMapShape::_bind_methods() {
 }
 
 HeightMapShape::HeightMapShape() :
-		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_HEIGHTMAP)) {
+		Shape(RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_HEIGHTMAP))) {
 	map_width = 2;
 	map_depth = 2;
 	map_data.resize(map_width * map_depth);

+ 1 - 1
scene/resources/material.cpp

@@ -96,7 +96,7 @@ void Material::_bind_methods() {
 }
 
 Material::Material() {
-	material = VisualServer::get_singleton()->material_create();
+	material = RID_PRIME(VisualServer::get_singleton()->material_create());
 	render_priority = 0;
 }
 

+ 1 - 1
scene/resources/mesh.cpp

@@ -1446,7 +1446,7 @@ void ArrayMesh::reload_from_file() {
 }
 
 ArrayMesh::ArrayMesh() {
-	mesh = VisualServer::get_singleton()->mesh_create();
+	mesh = RID_PRIME(VisualServer::get_singleton()->mesh_create());
 	blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE;
 }
 

+ 1 - 1
scene/resources/multimesh.cpp

@@ -347,7 +347,7 @@ void MultiMesh::_bind_methods() {
 }
 
 MultiMesh::MultiMesh() {
-	multimesh = VisualServer::get_singleton()->multimesh_create();
+	multimesh = RID_PRIME(VisualServer::get_singleton()->multimesh_create());
 	color_format = COLOR_NONE;
 	custom_data_format = CUSTOM_DATA_NONE;
 	transform_format = TRANSFORM_2D;

+ 1 - 1
scene/resources/occluder_shape.cpp

@@ -212,5 +212,5 @@ void OccluderShapeSphere::set_sphere_radius(int p_idx, real_t p_radius) {
 }
 
 OccluderShapeSphere::OccluderShapeSphere() :
-		OccluderShape(VisualServer::get_singleton()->occluder_create()) {
+		OccluderShape(RID_PRIME(VisualServer::get_singleton()->occluder_create())) {
 }

+ 1 - 1
scene/resources/plane_shape.cpp

@@ -84,6 +84,6 @@ void PlaneShape::_bind_methods() {
 }
 
 PlaneShape::PlaneShape() :
-		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) {
+		Shape(RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE))) {
 	set_plane(Plane(0, 1, 0, 0));
 }

+ 1 - 1
scene/resources/primitive_meshes.cpp

@@ -252,7 +252,7 @@ bool PrimitiveMesh::get_flip_faces() const {
 PrimitiveMesh::PrimitiveMesh() {
 	flip_faces = false;
 	// defaults
-	mesh = VisualServer::get_singleton()->mesh_create();
+	mesh = RID_PRIME(VisualServer::get_singleton()->mesh_create());
 
 	// assume primitive triangles as the type, correct for all but one and it will change this :)
 	primitive_type = Mesh::PRIMITIVE_TRIANGLES;

+ 1 - 1
scene/resources/ray_shape.cpp

@@ -82,7 +82,7 @@ void RayShape::_bind_methods() {
 }
 
 RayShape::RayShape() :
-		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) {
+		Shape(RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY))) {
 	length = 1.0;
 	slips_on_slope = false;
 

+ 1 - 1
scene/resources/sky.cpp

@@ -495,7 +495,7 @@ void ProceduralSky::_bind_methods() {
 
 ProceduralSky::ProceduralSky(bool p_desaturate) {
 	sky = VS::get_singleton()->sky_create();
-	texture = VS::get_singleton()->texture_create();
+	texture = RID_PRIME(VS::get_singleton()->texture_create());
 
 	update_queued = false;
 	sky_top_color = Color::hex(0xa5d6f1ff);

+ 1 - 1
scene/resources/sphere_shape.cpp

@@ -77,6 +77,6 @@ void SphereShape::_bind_methods() {
 }
 
 SphereShape::SphereShape() :
-		Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE)) {
+		Shape(RID_PRIME(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE))) {
 	set_radius(1.0);
 }

+ 9 - 9
scene/resources/texture.cpp

@@ -404,7 +404,7 @@ void ImageTexture::_bind_methods() {
 ImageTexture::ImageTexture() {
 	w = h = 0;
 	flags = FLAGS_DEFAULT;
-	texture = VisualServer::get_singleton()->texture_create();
+	texture = RID_PRIME(VisualServer::get_singleton()->texture_create());
 	storage = STORAGE_RAW;
 	lossy_storage_quality = 0.7;
 	image_stored = false;
@@ -824,7 +824,7 @@ StreamTexture::StreamTexture() {
 	w = 0;
 	h = 0;
 
-	texture = VS::get_singleton()->texture_create();
+	texture = RID_PRIME(VS::get_singleton()->texture_create());
 }
 
 StreamTexture::~StreamTexture() {
@@ -1585,7 +1585,7 @@ CubeMap::CubeMap() {
 	for (int i = 0; i < 6; i++) {
 		valid[i] = false;
 	}
-	cubemap = VisualServer::get_singleton()->texture_create();
+	cubemap = RID_PRIME(VisualServer::get_singleton()->texture_create());
 	storage = STORAGE_RAW;
 	lossy_storage_quality = 0.7;
 	format = Image::FORMAT_BPTC_RGBA;
@@ -1694,7 +1694,7 @@ RID CurveTexture::get_rid() const {
 
 CurveTexture::CurveTexture() {
 	_width = 2048;
-	_texture = VS::get_singleton()->texture_create();
+	_texture = RID_PRIME(VS::get_singleton()->texture_create());
 }
 CurveTexture::~CurveTexture() {
 	VS::get_singleton()->free(_texture);
@@ -1711,7 +1711,7 @@ GradientTexture::GradientTexture() {
 	update_pending = false;
 	width = 2048;
 
-	texture = VS::get_singleton()->texture_create();
+	texture = RID_PRIME(VS::get_singleton()->texture_create());
 	_queue_update();
 }
 
@@ -1860,7 +1860,7 @@ uint32_t ProxyTexture::get_flags() const {
 }
 
 ProxyTexture::ProxyTexture() {
-	proxy = VS::get_singleton()->texture_create();
+	proxy = RID_PRIME(VS::get_singleton()->texture_create());
 }
 
 ProxyTexture::~ProxyTexture() {
@@ -2107,7 +2107,7 @@ void AnimatedTexture::_bind_methods() {
 }
 
 AnimatedTexture::AnimatedTexture() {
-	proxy = VS::get_singleton()->texture_create();
+	proxy = RID_PRIME(VS::get_singleton()->texture_create());
 	VisualServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
 	time = 0;
 	frame_count = 1;
@@ -2416,7 +2416,7 @@ TextureLayered::TextureLayered(bool p_3d) {
 	height = 0;
 	depth = 0;
 
-	texture = VS::get_singleton()->texture_create();
+	texture = RID_PRIME(VS::get_singleton()->texture_create());
 }
 
 TextureLayered::~TextureLayered() {
@@ -2632,7 +2632,7 @@ uint32_t ExternalTexture::get_flags() const {
 
 ExternalTexture::ExternalTexture() {
 	size = Size2(1.0, 1.0);
-	texture = VisualServer::get_singleton()->texture_create();
+	texture = RID_PRIME(VisualServer::get_singleton()->texture_create());
 
 	VisualServer::get_singleton()->texture_allocate(texture, size.width, size.height, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_EXTERNAL, Texture::FLAG_VIDEO_SURFACE);
 	_change_notify();

+ 2 - 2
scene/resources/world.cpp

@@ -309,8 +309,8 @@ void World::_bind_methods() {
 }
 
 World::World() {
-	space = PhysicsServer::get_singleton()->space_create();
-	scenario = VisualServer::get_singleton()->scenario_create();
+	space = RID_PRIME(PhysicsServer::get_singleton()->space_create());
+	scenario = RID_PRIME(VisualServer::get_singleton()->scenario_create());
 
 	PhysicsServer::get_singleton()->space_set_active(space, true);
 	PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/3d/default_gravity", 9.8));

+ 2 - 2
scene/resources/world_2d.cpp

@@ -348,8 +348,8 @@ Physics2DDirectSpaceState *World2D::get_direct_space_state() {
 }
 
 World2D::World2D() {
-	canvas = VisualServer::get_singleton()->canvas_create();
-	space = Physics2DServer::get_singleton()->space_create();
+	canvas = RID_PRIME(VisualServer::get_singleton()->canvas_create());
+	space = RID_PRIME(Physics2DServer::get_singleton()->space_create());
 
 	//set space2D to be more friendly with pixels than meters, by adjusting some constants
 	Physics2DServer::get_singleton()->space_set_active(space, true);

+ 4 - 4
servers/camera/camera_feed.cpp

@@ -144,8 +144,8 @@ CameraFeed::CameraFeed() {
 
 	// create a texture object
 	VisualServer *vs = VisualServer::get_singleton();
-	texture[CameraServer::FEED_Y_IMAGE] = vs->texture_create(); // also used for RGBA
-	texture[CameraServer::FEED_CBCR_IMAGE] = vs->texture_create();
+	texture[CameraServer::FEED_Y_IMAGE] = RID_PRIME(vs->texture_create()); // also used for RGBA
+	texture[CameraServer::FEED_CBCR_IMAGE] = RID_PRIME(vs->texture_create());
 }
 
 CameraFeed::CameraFeed(String p_name, FeedPosition p_position) {
@@ -161,8 +161,8 @@ CameraFeed::CameraFeed(String p_name, FeedPosition p_position) {
 
 	// create a texture object
 	VisualServer *vs = VisualServer::get_singleton();
-	texture[CameraServer::FEED_Y_IMAGE] = vs->texture_create(); // also used for RGBA
-	texture[CameraServer::FEED_CBCR_IMAGE] = vs->texture_create();
+	texture[CameraServer::FEED_Y_IMAGE] = RID_PRIME(vs->texture_create()); // also used for RGBA
+	texture[CameraServer::FEED_CBCR_IMAGE] = RID_PRIME(vs->texture_create());
 }
 
 CameraFeed::~CameraFeed() {

+ 2 - 2
servers/physics/physics_server_sw.cpp

@@ -129,13 +129,13 @@ RID PhysicsServerSW::space_create() {
 	SpaceSW *space = memnew(SpaceSW);
 	RID id = space_owner.make_rid(space);
 	space->set_self(id);
-	RID area_id = area_create();
+	RID area_id = RID_PRIME(area_create());
 	AreaSW *area = area_owner.get(area_id);
 	ERR_FAIL_COND_V(!area, RID());
 	space->set_default_area(area);
 	area->set_space(space);
 	area->set_priority(-1);
-	RID sgb = body_create();
+	RID sgb = RID_PRIME(body_create());
 	body_set_space(sgb, id);
 	body_set_mode(sgb, BODY_MODE_STATIC);
 	space->set_static_global_body(sgb);

+ 1 - 1
servers/physics_2d/physics_2d_server_sw.cpp

@@ -212,7 +212,7 @@ RID Physics2DServerSW::space_create() {
 	Space2DSW *space = memnew(Space2DSW);
 	RID id = space_owner.make_rid(space);
 	space->set_self(id);
-	RID area_id = area_create();
+	RID area_id = RID_PRIME(area_create());
 	Area2DSW *area = area_owner.get(area_id);
 	ERR_FAIL_COND_V(!area, RID());
 	space->set_default_area(area);

+ 4 - 4
servers/visual/portals/portal_renderer.cpp

@@ -940,14 +940,14 @@ void PortalRenderer::_load_finalize_roaming() {
 		instance_moving_update(handle, aabb, true);
 	}
 
-	for (int n = 0; n < _rghost_pool.active_size(); n++) {
+	for (unsigned int n = 0; n < _rghost_pool.active_size(); n++) {
 		RGhost &moving = _rghost_pool.get_active(n);
 		const AABB &aabb = moving.exact_aabb;
 
 		rghost_update(_rghost_pool.get_active_id(n) + 1, aabb, true);
 	}
 
-	for (int n = 0; n < _occluder_pool.active_size(); n++) {
+	for (unsigned int n = 0; n < _occluder_pool.active_size(); n++) {
 		VSOccluder &occ = _occluder_pool.get_active(n);
 		int occluder_id = _occluder_pool.get_active_id(n);
 
@@ -1048,7 +1048,7 @@ void PortalRenderer::rooms_and_portals_clear() {
 		moving.rooms_and_portals_clear();
 	}
 
-	for (int n = 0; n < _rghost_pool.active_size(); n++) {
+	for (unsigned int n = 0; n < _rghost_pool.active_size(); n++) {
 		RGhost &moving = _rghost_pool.get_active(n);
 		moving.rooms_and_portals_clear();
 	}
@@ -1162,7 +1162,7 @@ int PortalRenderer::cull_convex_implementation(const Vector3 &p_point, const Vec
 }
 
 String PortalRenderer::_rid_to_string(RID p_rid) {
-	return _addr_to_string(p_rid.get_data());
+	return itos(p_rid.get_id());
 }
 
 String PortalRenderer::_addr_to_string(const void *p_addr) {

+ 1 - 1
servers/visual/portals/portal_renderer.h

@@ -291,7 +291,7 @@ private:
 
 	// occluders
 	TrackedPooledList<VSOccluder> _occluder_pool;
-	TrackedPooledList<VSOccluder_Sphere> _occluder_sphere_pool;
+	TrackedPooledList<VSOccluder_Sphere, uint32_t, true> _occluder_sphere_pool;
 
 	PVS _pvs;
 

+ 2 - 2
servers/visual_server.cpp

@@ -159,7 +159,7 @@ RID VisualServer::get_test_texture() {
 
 	Ref<Image> data = memnew(Image(TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, false, Image::FORMAT_RGB8, test_data));
 
-	test_texture = texture_create_from_image(data);
+	test_texture = RID_PRIME(texture_create_from_image(data));
 
 	return test_texture;
 }
@@ -325,7 +325,7 @@ RID VisualServer::get_white_texture() {
 		}
 	}
 	Ref<Image> white = memnew(Image(4, 4, 0, Image::FORMAT_RGB8, wt));
-	white_texture = texture_create();
+	white_texture = RID_PRIME(texture_create());
 	texture_allocate(white_texture, 4, 4, 0, Image::FORMAT_RGB8, TEXTURE_TYPE_2D);
 	texture_set_data(white_texture, white);
 	return white_texture;