1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-09 12:50:35 +00:00

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<int> 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.
This commit is contained in:
Hein-Pieter van Braam
2018-07-25 03:11:03 +02:00
parent 9423f23ffb
commit 0e29f7974b
228 changed files with 2200 additions and 2082 deletions

View File

@@ -589,7 +589,7 @@ void VisualServerScene::instance_set_blend_shape_weight(RID p_instance, int p_sh
}
ERR_FAIL_INDEX(p_shape, instance->blend_values.size());
instance->blend_values[p_shape] = p_weight;
instance->blend_values.write[p_shape] = p_weight;
}
void VisualServerScene::instance_set_surface_material(RID p_instance, int p_surface, RID p_material) {
@@ -606,7 +606,7 @@ void VisualServerScene::instance_set_surface_material(RID p_instance, int p_surf
if (instance->materials[p_surface].is_valid()) {
VSG::storage->material_remove_instance_owner(instance->materials[p_surface], instance);
}
instance->materials[p_surface] = p_material;
instance->materials.write[p_surface] = p_material;
instance->base_material_changed();
if (instance->materials[p_surface].is_valid()) {
@@ -1253,7 +1253,7 @@ void VisualServerScene::_update_instance_lightmap_captures(Instance *p_instance)
Vector3 dir = to_cell_xform.basis.xform(cone_traces[i]).normalized();
Color capture = _light_capture_voxel_cone_trace(octree_r.ptr(), pos, dir, cone_aperture, cell_subdiv);
p_instance->lightmap_capture_data[i] += capture;
p_instance->lightmap_capture_data.write[i] += capture;
}
}
}
@@ -1464,14 +1464,14 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
light_frustum_planes.resize(6);
//right/left
light_frustum_planes[0] = Plane(x_vec, x_max);
light_frustum_planes[1] = Plane(-x_vec, -x_min);
light_frustum_planes.write[0] = Plane(x_vec, x_max);
light_frustum_planes.write[1] = Plane(-x_vec, -x_min);
//top/bottom
light_frustum_planes[2] = Plane(y_vec, y_max);
light_frustum_planes[3] = Plane(-y_vec, -y_min);
light_frustum_planes.write[2] = Plane(y_vec, y_max);
light_frustum_planes.write[3] = Plane(-y_vec, -y_min);
//near/far
light_frustum_planes[4] = Plane(z_vec, z_max + 1e6);
light_frustum_planes[5] = Plane(-z_vec, -z_min); // z_min is ok, since casters further than far-light plane are not needed
light_frustum_planes.write[4] = Plane(z_vec, z_max + 1e6);
light_frustum_planes.write[5] = Plane(-z_vec, -z_min); // z_min is ok, since casters further than far-light plane are not needed
int cull_count = p_scenario->octree.cull_convex(light_frustum_planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
@@ -1532,11 +1532,11 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
float z = i == 0 ? -1 : 1;
Vector<Plane> planes;
planes.resize(5);
planes[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
planes[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
planes[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
planes[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
planes[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
@@ -1898,7 +1898,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
ins->light_instances[l++] = light->instance;
ins->light_instances.write[l++] = light->instance;
}
geom->lighting_dirty = false;
@@ -1913,7 +1913,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
ins->reflection_probe_instances[l++] = reflection_probe->instance;
ins->reflection_probe_instances.write[l++] = reflection_probe->instance;
}
geom->reflection_dirty = false;
@@ -1928,7 +1928,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data);
ins->gi_probe_instances[l++] = gi_probe->probe_instance;
ins->gi_probe_instances.write[l++] = gi_probe->probe_instance;
}
geom->gi_probes_dirty = false;
@@ -2372,7 +2372,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) {
uint32_t key = blockz * blockw * blockh + blocky * blockw + blockx;
Map<uint32_t, InstanceGIProbeData::CompBlockS3TC> &cmap = comp_blocks[mipmap];
Map<uint32_t, InstanceGIProbeData::CompBlockS3TC> &cmap = comp_blocks.write[mipmap];
if (!cmap.has(key)) {
@@ -2392,8 +2392,8 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) {
for (int i = 0; i < mipmap_count; i++) {
print_line("S3TC level: " + itos(i) + " blocks: " + itos(comp_blocks[i].size()));
probe->dynamic.mipmaps_s3tc[i].resize(comp_blocks[i].size());
PoolVector<InstanceGIProbeData::CompBlockS3TC>::Write w = probe->dynamic.mipmaps_s3tc[i].write();
probe->dynamic.mipmaps_s3tc.write[i].resize(comp_blocks[i].size());
PoolVector<InstanceGIProbeData::CompBlockS3TC>::Write w = probe->dynamic.mipmaps_s3tc.write[i].write();
int block_idx = 0;
for (Map<uint32_t, InstanceGIProbeData::CompBlockS3TC>::Element *E = comp_blocks[i].front(); E; E = E->next()) {
@@ -2861,7 +2861,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
int level_cell_count = probe_data->dynamic.level_cell_lists[i].size();
const uint32_t *level_cells = probe_data->dynamic.level_cell_lists[i].ptr();
PoolVector<uint8_t>::Write lw = probe_data->dynamic.mipmaps_3d[stage].write();
PoolVector<uint8_t>::Write lw = probe_data->dynamic.mipmaps_3d.write[stage].write();
uint8_t *mipmapw = lw.ptr();
uint32_t sizes[3] = { header->width >> stage, header->height >> stage, header->depth >> stage };
@@ -2890,7 +2890,7 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
for (int mmi = 0; mmi < mipmap_count; mmi++) {
PoolVector<uint8_t>::Write mmw = probe_data->dynamic.mipmaps_3d[mmi].write();
PoolVector<uint8_t>::Write mmw = probe_data->dynamic.mipmaps_3d.write[mmi].write();
int block_count = probe_data->dynamic.mipmaps_s3tc[mmi].size();
PoolVector<InstanceGIProbeData::CompBlockS3TC>::Read mmr = probe_data->dynamic.mipmaps_s3tc[mmi].read();
@@ -3223,7 +3223,7 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
if (new_blend_shape_count != p_instance->blend_values.size()) {
p_instance->blend_values.resize(new_blend_shape_count);
for (int i = 0; i < new_blend_shape_count; i++) {
p_instance->blend_values[i] = 0;
p_instance->blend_values.write[i] = 0;
}
}
}