From 0e29f7974b59e4440cf02e1388fb9d8ab2b5c5fd Mon Sep 17 00:00:00 2001 From: Hein-Pieter van Braam Date: Wed, 25 Jul 2018 03:11:03 +0200 Subject: Reduce unnecessary COW on Vector by make writing explicit This commit makes operator[] on Vector const and adds a write proxy to it. From now on writes to Vectors need to happen through the .write proxy. So for instance: Vector vec; vec.push_back(10); std::cout << vec[0] << std::endl; vec.write[0] = 20; Failing to use the .write proxy will cause a compilation error. In addition COWable datatypes can now embed a CowData pointer to their data. This means that String, CharString, and VMap no longer use or derive from Vector. _ALWAYS_INLINE_ and _FORCE_INLINE_ are now equivalent for debug and non-debug builds. This is a lot faster for Vector in the editor and while running tests. The reason why this difference used to exist is because force-inlined methods used to give a bad debugging experience. After extensive testing with modern compilers this is no longer the case. --- servers/physics_2d/body_2d_sw.h | 6 +++--- servers/physics_2d/collision_object_2d_sw.cpp | 22 +++++++++++----------- servers/physics_2d/collision_object_2d_sw.h | 2 +- servers/physics_2d/shape_2d_sw.cpp | 16 ++++++++-------- servers/physics_2d/space_2d_sw.h | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) (limited to 'servers/physics_2d') diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h index 7fe805b1f9..fef233a72b 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/body_2d_sw.h @@ -141,7 +141,7 @@ public: _FORCE_INLINE_ void add_area(Area2DSW *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { - areas[index].refCount += 1; + areas.write[index].refCount += 1; } else { areas.ordered_insert(AreaCMP(p_area)); } @@ -150,7 +150,7 @@ public: _FORCE_INLINE_ void remove_area(Area2DSW *p_area) { int index = areas.find(AreaCMP(p_area)); if (index > -1) { - areas[index].refCount -= 1; + areas.write[index].refCount -= 1; if (areas[index].refCount < 1) areas.remove(index); } @@ -311,7 +311,7 @@ void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_no if (c_max == 0) return; - Contact *c = &contacts[0]; + Contact *c = contacts.ptrw(); int idx = -1; diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp index 23084a4241..4dd5b2040f 100644 --- a/servers/physics_2d/collision_object_2d_sw.cpp +++ b/servers/physics_2d/collision_object_2d_sw.cpp @@ -50,7 +50,7 @@ void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) { ERR_FAIL_INDEX(p_index, shapes.size()); shapes[p_index].shape->remove_owner(this); - shapes[p_index].shape = p_shape; + shapes.write[p_index].shape = p_shape; p_shape->add_owner(this); _update_shapes(); @@ -60,15 +60,15 @@ void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) { void CollisionObject2DSW::set_shape_metadata(int p_index, const Variant &p_metadata) { ERR_FAIL_INDEX(p_index, shapes.size()); - shapes[p_index].metadata = p_metadata; + shapes.write[p_index].metadata = p_metadata; } void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_transform) { ERR_FAIL_INDEX(p_index, shapes.size()); - shapes[p_index].xform = p_transform; - shapes[p_index].xform_inv = p_transform.affine_inverse(); + shapes.write[p_index].xform = p_transform; + shapes.write[p_index].xform_inv = p_transform.affine_inverse(); _update_shapes(); _shapes_changed(); } @@ -76,7 +76,7 @@ void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_ void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) { ERR_FAIL_INDEX(p_idx, shapes.size()); - CollisionObject2DSW::Shape &shape = shapes[p_idx]; + CollisionObject2DSW::Shape &shape = shapes.write[p_idx]; if (shape.disabled == p_disabled) return; @@ -116,7 +116,7 @@ void CollisionObject2DSW::remove_shape(int p_index) { continue; //should never get here with a null owner space->get_broadphase()->remove(shapes[i].bpid); - shapes[i].bpid = 0; + shapes.write[i].bpid = 0; } shapes[p_index].shape->remove_owner(this); shapes.remove(p_index); @@ -133,7 +133,7 @@ void CollisionObject2DSW::_set_static(bool p_static) { if (!space) return; for (int i = 0; i < get_shape_count(); i++) { - Shape &s = shapes[i]; + const Shape &s = shapes[i]; if (s.bpid > 0) { space->get_broadphase()->set_static(s.bpid, _static); } @@ -144,7 +144,7 @@ void CollisionObject2DSW::_unregister_shapes() { for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes[i]; + Shape &s = shapes.write[i]; if (s.bpid > 0) { space->get_broadphase()->remove(s.bpid); s.bpid = 0; @@ -159,7 +159,7 @@ void CollisionObject2DSW::_update_shapes() { for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes[i]; + Shape &s = shapes.write[i]; if (s.disabled) continue; @@ -187,7 +187,7 @@ void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) { for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes[i]; + Shape &s = shapes.write[i]; if (s.disabled) continue; @@ -215,7 +215,7 @@ void CollisionObject2DSW::_set_space(Space2DSW *p_space) { for (int i = 0; i < shapes.size(); i++) { - Shape &s = shapes[i]; + Shape &s = shapes.write[i]; if (s.bpid) { space->get_broadphase()->remove(s.bpid); s.bpid = 0; diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index ab3e219ac0..393c4a6ed7 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -144,7 +144,7 @@ public: _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision) { ERR_FAIL_INDEX(p_idx, shapes.size()); - shapes[p_idx].one_way_collision = p_one_way_collision; + shapes.write[p_idx].one_way_collision = p_one_way_collision; } _FORCE_INLINE_ bool is_shape_set_as_one_way_collision(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, shapes.size(), false); diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index 2b0eab5999..dc8ec23e69 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -891,8 +891,8 @@ int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) { int l = _generate_bvh(p_bvh, median, p_depth + 1); int r = _generate_bvh(&p_bvh[median], p_len - median, p_depth + 1); - bvh[node_idx].left = l; - bvh[node_idx].right = r; + bvh.write[node_idx].left = l; + bvh.write[node_idx].right = r; return node_idx; } @@ -953,20 +953,20 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) { for (Map::Element *E = pointmap.front(); E; E = E->next()) { aabb.expand_to(E->key()); - points[E->get()] = E->key(); + points.write[E->get()] = E->key(); } Vector main_vbh; main_vbh.resize(segments.size()); for (int i = 0; i < main_vbh.size(); i++) { - main_vbh[i].aabb.position = points[segments[i].points[0]]; - main_vbh[i].aabb.expand_to(points[segments[i].points[1]]); - main_vbh[i].left = -1; - main_vbh[i].right = i; + main_vbh.write[i].aabb.position = points[segments[i].points[0]]; + main_vbh.write[i].aabb.expand_to(points[segments[i].points[1]]); + main_vbh.write[i].left = -1; + main_vbh.write[i].right = i; } - _generate_bvh(&main_vbh[0], main_vbh.size(), 1); + _generate_bvh(main_vbh.ptrw(), main_vbh.size(), 1); } else { //dictionary with arrays diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index 959e15e12d..1247317b03 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -188,7 +188,7 @@ public: void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); } _FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); } _FORCE_INLINE_ void add_debug_contact(const Vector2 &p_contact) { - if (contact_debug_count < contact_debug.size()) contact_debug[contact_debug_count++] = p_contact; + if (contact_debug_count < contact_debug.size()) contact_debug.write[contact_debug_count++] = p_contact; } _FORCE_INLINE_ Vector get_debug_contacts() { return contact_debug; } _FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; } -- cgit v1.2.3