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. --- modules/bullet/area_bullet.cpp | 6 +++--- modules/bullet/collision_object_bullet.cpp | 16 ++++++++-------- modules/bullet/rigid_body_bullet.cpp | 26 +++++++++++++------------- modules/bullet/shape_bullet.cpp | 2 +- modules/bullet/soft_body_bullet.cpp | 16 ++++++++-------- modules/bullet/space_bullet.cpp | 2 +- modules/bullet/space_bullet.h | 2 +- 7 files changed, 35 insertions(+), 35 deletions(-) (limited to 'modules/bullet') diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index bfb452d109..b004641838 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -80,7 +80,7 @@ void AreaBullet::dispatch_callbacks() { // Reverse order because I've to remove EXIT objects for (int i = overlappingObjects.size() - 1; 0 <= i; --i) { - OverlappingObjectData &otherObj = overlappingObjects[i]; + OverlappingObjectData &otherObj = overlappingObjects.write[i]; switch (otherObj.state) { case OVERLAP_STATE_ENTER: @@ -199,13 +199,13 @@ void AreaBullet::add_overlap(CollisionObjectBullet *p_otherObject) { void AreaBullet::put_overlap_as_exit(int p_index) { scratch(); - overlappingObjects[p_index].state = OVERLAP_STATE_EXIT; + overlappingObjects.write[p_index].state = OVERLAP_STATE_EXIT; } void AreaBullet::put_overlap_as_inside(int p_index) { // This check is required to be sure this body was inside if (OVERLAP_STATE_DIRTY == overlappingObjects[p_index].state) { - overlappingObjects[p_index].state = OVERLAP_STATE_INSIDE; + overlappingObjects.write[p_index].state = OVERLAP_STATE_INSIDE; } } diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index 1d63318fd7..271cdb0223 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -223,7 +223,7 @@ void RigidCollisionObjectBullet::add_shape(ShapeBullet *p_shape, const Transform } void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) { - ShapeWrapper &shp = shapes[p_index]; + ShapeWrapper &shp = shapes.write[p_index]; shp.shape->remove_owner(this); p_shape->add_owner(this); shp.shape = p_shape; @@ -233,8 +233,8 @@ void RigidCollisionObjectBullet::set_shape(int p_index, ShapeBullet *p_shape) { void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) { ERR_FAIL_INDEX(p_index, get_shape_count()); - shapes[p_index].set_transform(p_transform); - on_shape_changed(shapes[p_index].shape); + shapes.write[p_index].set_transform(p_transform); + on_shape_changed(shapes.write[p_index].shape); } void RigidCollisionObjectBullet::remove_shape(ShapeBullet *p_shape) { @@ -287,7 +287,7 @@ void RigidCollisionObjectBullet::on_shape_changed(const ShapeBullet *const p_sha const int size = shapes.size(); for (int i = 0; i < size; ++i) { if (shapes[i].shape == p_shape) { - bulletdelete(shapes[i].bt_shape); + bulletdelete(shapes.write[i].bt_shape); } } on_shapes_changed(); @@ -307,7 +307,7 @@ void RigidCollisionObjectBullet::on_shapes_changed() { // Reset shape if required if (force_shape_reset) { for (i = 0; i < shapes_size; ++i) { - shpWrapper = &shapes[i]; + shpWrapper = &shapes.write[i]; bulletdelete(shpWrapper->bt_shape); } force_shape_reset = false; @@ -316,7 +316,7 @@ void RigidCollisionObjectBullet::on_shapes_changed() { // Insert all shapes btVector3 body_scale(get_bt_body_scale()); for (i = 0; i < shapes_size; ++i) { - shpWrapper = &shapes[i]; + shpWrapper = &shapes.write[i]; if (shpWrapper->active) { if (!shpWrapper->bt_shape) { shpWrapper->bt_shape = shpWrapper->shape->create_bt_shape(shpWrapper->scale * body_scale); @@ -334,7 +334,7 @@ void RigidCollisionObjectBullet::on_shapes_changed() { } void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) { - shapes[p_index].active = !p_disabled; + shapes.write[p_index].active = !p_disabled; on_shapes_changed(); } @@ -348,7 +348,7 @@ void RigidCollisionObjectBullet::on_body_scale_changed() { } void RigidCollisionObjectBullet::internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody) { - ShapeWrapper &shp = shapes[p_index]; + ShapeWrapper &shp = shapes.write[p_index]; shp.shape->remove_owner(this, p_permanentlyFromThisBody); bulletdelete(shp.bt_shape); } diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 18f8f5f677..52453eae17 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -179,7 +179,7 @@ int BulletPhysicsDirectBodyState::get_contact_collider_shape(int p_contact_idx) } Vector3 BulletPhysicsDirectBodyState::get_contact_collider_velocity_at_position(int p_contact_idx) const { - RigidBodyBullet::CollisionData &colDat = body->collisions[p_contact_idx]; + RigidBodyBullet::CollisionData &colDat = body->collisions.write[p_contact_idx]; btVector3 hitLocation; G_TO_B(colDat.hitLocalLocation, hitLocation); @@ -224,8 +224,8 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { continue; } - shapes[i].transform = shape_wrapper->transform; - shapes[i].transform.getOrigin() *= owner_scale; + shapes.write[i].transform = shape_wrapper->transform; + shapes.write[i].transform.getOrigin() *= owner_scale; switch (shape_wrapper->shape->get_type()) { case PhysicsServer::SHAPE_SPHERE: case PhysicsServer::SHAPE_BOX: @@ -233,11 +233,11 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { case PhysicsServer::SHAPE_CYLINDER: case PhysicsServer::SHAPE_CONVEX_POLYGON: case PhysicsServer::SHAPE_RAY: { - shapes[i].shape = static_cast(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin)); + shapes.write[i].shape = static_cast(shape_wrapper->shape->create_bt_shape(owner_scale * shape_wrapper->scale, safe_margin)); } break; default: WARN_PRINT("This shape is not supported to be kinematic!"); - shapes[i].shape = NULL; + shapes.write[i].shape = NULL; } } } @@ -245,7 +245,7 @@ void RigidBodyBullet::KinematicUtilities::copyAllOwnerShapes() { void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) { for (int i = shapes.size() - 1; 0 <= i; --i) { if (shapes[i].shape) { - bulletdelete(shapes[i].shape); + bulletdelete(shapes.write[i].shape); } } shapes.resize(new_size); @@ -287,7 +287,7 @@ RigidBodyBullet::RigidBodyBullet() : areasWhereIam.resize(maxAreasWhereIam); for (int i = areasWhereIam.size() - 1; 0 <= i; --i) { - areasWhereIam[i] = NULL; + areasWhereIam.write[i] = NULL; } btBody->setSleepingThresholds(0.2, 0.2); } @@ -413,7 +413,7 @@ bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const return false; } - CollisionData &cd = collisions[collisionsCount]; + CollisionData &cd = collisions.write[collisionsCount]; cd.hitLocalLocation = p_hitLocalLocation; cd.otherObject = p_otherObject; cd.hitWorldLocation = p_hitWorldLocation; @@ -817,15 +817,15 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) { if (NULL == areasWhereIam[i]) { // This area has the highest priority - areasWhereIam[i] = p_area; + areasWhereIam.write[i] = p_area; break; } else { if (areasWhereIam[i]->get_spOv_priority() > p_area->get_spOv_priority()) { // The position was found, just shift all elements for (int j = i; j < areaWhereIamCount; ++j) { - areasWhereIam[j + 1] = areasWhereIam[j]; + areasWhereIam.write[j + 1] = areasWhereIam[j]; } - areasWhereIam[i] = p_area; + areasWhereIam.write[i] = p_area; break; } } @@ -849,7 +849,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) { if (p_area == areasWhereIam[i]) { // The area was fount, just shift down all elements for (int j = i; j < areaWhereIamCount; ++j) { - areasWhereIam[j] = areasWhereIam[j + 1]; + areasWhereIam.write[j] = areasWhereIam[j + 1]; } wasTheAreaFound = true; break; @@ -862,7 +862,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) { } --areaWhereIamCount; - areasWhereIam[areaWhereIamCount] = NULL; // Even if this is not required, I clear the last element to be safe + areasWhereIam.write[areaWhereIamCount] = NULL; // Even if this is not required, I clear the last element to be safe if (PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED != p_area->get_spOv_mode()) { scratch_space_override_modificator(); } diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index 92e7c2df98..e4c1a5f9b5 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -304,7 +304,7 @@ void ConvexPolygonShapeBullet::get_vertices(Vector &out_vertices) { const int n_of_vertices = vertices.size(); out_vertices.resize(n_of_vertices); for (int i = n_of_vertices - 1; 0 <= i; --i) { - B_TO_G(vertices[i], out_vertices[i]); + B_TO_G(vertices[i], out_vertices.write[i]); } } diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index b3680d58db..1686a6e87e 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -90,7 +90,7 @@ void SoftBodyBullet::update_visual_server(SoftBodyVisualServerHandler *p_visual_ const btSoftBody::tNodeArray &nodes(bt_soft_body->m_nodes); const int nodes_count = nodes.size(); - Vector *vs_indices; + const Vector *vs_indices; const void *vertex_position; const void *vertex_normal; @@ -359,7 +359,7 @@ void SoftBodyBullet::set_trimesh_body_shape(PoolVector p_indices, PoolVecto indices_table.push_back(Vector()); } - indices_table[vertex_id].push_back(vs_vertex_index); + indices_table.write[vertex_id].push_back(vs_vertex_index); vs_indices_to_physics_table.push_back(vertex_id); } } @@ -374,9 +374,9 @@ void SoftBodyBullet::set_trimesh_body_shape(PoolVector p_indices, PoolVecto PoolVector::Read p_vertices_read = p_vertices.read(); for (int i = 0; i < indices_map_size; ++i) { - bt_vertices[3 * i + 0] = p_vertices_read[indices_table[i][0]].x; - bt_vertices[3 * i + 1] = p_vertices_read[indices_table[i][0]].y; - bt_vertices[3 * i + 2] = p_vertices_read[indices_table[i][0]].z; + bt_vertices.write[3 * i + 0] = p_vertices_read[indices_table[i][0]].x; + bt_vertices.write[3 * i + 1] = p_vertices_read[indices_table[i][0]].y; + bt_vertices.write[3 * i + 2] = p_vertices_read[indices_table[i][0]].z; } } @@ -390,9 +390,9 @@ void SoftBodyBullet::set_trimesh_body_shape(PoolVector p_indices, PoolVecto PoolVector::Read p_indices_read = p_indices.read(); for (int i = 0; i < triangles_size; ++i) { - bt_triangles[3 * i + 0] = vs_indices_to_physics_table[p_indices_read[3 * i + 2]]; - bt_triangles[3 * i + 1] = vs_indices_to_physics_table[p_indices_read[3 * i + 1]]; - bt_triangles[3 * i + 2] = vs_indices_to_physics_table[p_indices_read[3 * i + 0]]; + bt_triangles.write[3 * i + 0] = vs_indices_to_physics_table[p_indices_read[3 * i + 2]]; + bt_triangles.write[3 * i + 1] = vs_indices_to_physics_table[p_indices_read[3 * i + 1]]; + bt_triangles.write[3 * i + 2] = vs_indices_to_physics_table[p_indices_read[3 * i + 0]]; } } diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 132c3739d6..1ef631c916 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -686,7 +686,7 @@ void SpaceBullet::check_ghost_overlaps() { /// 1. Reset all states for (i = area->overlappingObjects.size() - 1; 0 <= i; --i) { - AreaBullet::OverlappingObjectData &otherObj = area->overlappingObjects[i]; + AreaBullet::OverlappingObjectData &otherObj = area->overlappingObjects.write[i]; // This check prevent the overwrite of ENTER state // if this function is called more times before dispatchCallbacks if (otherObj.state != AreaBullet::OVERLAP_STATE_ENTER) { diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index 006c6462cf..6b86fc2f03 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -164,7 +164,7 @@ public: contactDebugCount = 0; } _FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) { - if (contactDebugCount < contactDebug.size()) contactDebug[contactDebugCount++] = p_contact; + if (contactDebugCount < contactDebug.size()) contactDebug.write[contactDebugCount++] = p_contact; } _FORCE_INLINE_ Vector get_debug_contacts() { return contactDebug; } _FORCE_INLINE_ int get_debug_contact_count() { return contactDebugCount; } -- cgit v1.2.3