diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp index 160733c2d93..bcf5eafdebf 100644 --- a/scene/2d/tile_map_layer.cpp +++ b/scene/2d/tile_map_layer.cpp @@ -64,6 +64,9 @@ void TileMapLayer::_debug_update(bool p_force_cleanup) { // Check if we should cleanup everything. bool forced_cleanup = p_force_cleanup || !enabled || tile_set.is_null() || !is_visible_in_tree(); + if (forced_cleanup && _debug_was_cleaned_up) { + return; + } if (forced_cleanup) { for (KeyValue> &kv : debug_quadrant_map) { @@ -203,6 +206,9 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) { // Check if we should cleanup everything. bool forced_cleanup = p_force_cleanup || !enabled || tile_set.is_null() || !is_visible_in_tree(); + if (forced_cleanup && _rendering_was_cleaned_up) { + return; + } // ----------- Layer level processing ----------- if (!forced_cleanup) { @@ -231,7 +237,7 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) { (!is_y_sort_enabled() && dirty.flags[DIRTY_FLAGS_LAYER_RENDERING_QUADRANT_SIZE]); // Free all quadrants. - if (forced_cleanup || quadrant_shape_changed) { + if (!_rendering_was_cleaned_up && (forced_cleanup || quadrant_shape_changed)) { for (const KeyValue> &kv : rendering_quadrant_map) { for (const RID &ci : kv.value->canvas_items) { if (ci.is_valid()) { @@ -395,15 +401,23 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) { int index = -(int64_t)0x80000000; // Always must be drawn below children. // Sort the quadrants coords per local coordinates. - RBMap, RenderingQuadrant::CoordsWorldComparator> local_to_map; + LocalVector>> sortable_quadrant_keys; + sortable_quadrant_keys.reserve(rendering_quadrant_map.size()); for (KeyValue> &kv : rendering_quadrant_map) { - Ref &rendering_quadrant = kv.value; - local_to_map[tile_set->map_to_local(rendering_quadrant->quadrant_coords)] = rendering_quadrant; + Vector2 local_coords = tile_set->map_to_local(kv.value->quadrant_coords); + sortable_quadrant_keys.push_back(Pair>(local_coords, kv.value)); } + struct PairedQuadrantSorter { + RenderingQuadrant::CoordsWorldComparator comparator; + _ALWAYS_INLINE_ bool operator()(const Pair> &p_a, const Pair> &p_b) const { + return comparator(p_a.first, p_b.first); + } + }; + sortable_quadrant_keys.sort_custom(); - // Sort the quadrants. - for (const KeyValue> &E : local_to_map) { - for (const RID &ci : E.value->canvas_items) { + // Set the draw indices. + for (const Pair> &E : sortable_quadrant_keys) { + for (const RID &ci : E.second->canvas_items) { RS::get_singleton()->canvas_item_set_draw_index(ci, index++); } } @@ -426,14 +440,23 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) { } } + // ----------- + // Mark the rendering state as up to date. + _rendering_was_cleaned_up = forced_cleanup; + // ----------- Occluders processing ----------- - if (forced_cleanup || !occlusion_enabled) { + bool cleanup_occlusion = forced_cleanup || !occlusion_enabled; + if (cleanup_occlusion && _occlusion_was_cleaned_up) { + return; + } + + if (cleanup_occlusion) { // Clean everything. for (KeyValue &kv : tile_map_layer_data) { _rendering_occluders_clear_cell(kv.value); } } else { - if (_rendering_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_SET]) { + if (_occlusion_was_cleaned_up || dirty.flags[DIRTY_FLAGS_TILE_SET]) { // Update all cells. for (KeyValue &kv : tile_map_layer_data) { _rendering_occluders_update_cell(kv.value); @@ -448,8 +471,8 @@ void TileMapLayer::_rendering_update(bool p_force_cleanup) { } // ----------- - // Mark the rendering state as up to date. - _rendering_was_cleaned_up = forced_cleanup || !occlusion_enabled; + // Mark the occlusion state as up to date. + _occlusion_was_cleaned_up = cleanup_occlusion; } void TileMapLayer::_rendering_notification(int p_what) { @@ -718,6 +741,9 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) { // Check if we should cleanup everything. bool forced_cleanup = p_force_cleanup || !enabled || !collision_enabled || !is_inside_tree() || tile_set.is_null(); + if (forced_cleanup && _physics_was_cleaned_up) { + return; + } // ----------- Quadrants processing ----------- @@ -729,7 +755,7 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) { bool quadrant_shape_changed = dirty.flags[DIRTY_FLAGS_TILE_SET] || dirty.flags[DIRTY_FLAGS_LAYER_PHYSICS_QUADRANT_SIZE]; // Free all quadrants. - if (forced_cleanup || quadrant_shape_changed) { + if (!_physics_was_cleaned_up && (forced_cleanup || quadrant_shape_changed)) { for (const KeyValue> &kv : physics_quadrant_map) { // Clear bodies. for (KeyValue &kvbody : kv.value->bodies) { @@ -936,7 +962,7 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) { // ----------- // Mark the physics state as up to date. - _physics_was_cleaned_up = forced_cleanup || !occlusion_enabled; + _physics_was_cleaned_up = forced_cleanup; } void TileMapLayer::_physics_quadrants_update_cell(CellData &r_cell_data, SelfList::List &r_dirty_physics_quadrant_list) { @@ -1256,6 +1282,9 @@ void TileMapLayer::_navigation_update(bool p_force_cleanup) { // Check if we should cleanup everything. bool forced_cleanup = p_force_cleanup || !enabled || !navigation_enabled || !is_inside_tree() || tile_set.is_null(); + if (forced_cleanup && _navigation_was_cleaned_up) { + return; + } // ----------- Layer level processing ----------- // All this processing is kept for compatibility with the TileMap node. @@ -1527,6 +1556,9 @@ void TileMapLayer::_navigation_draw_cell_debug(const RID &p_canvas_item, const V void TileMapLayer::_scenes_update(bool p_force_cleanup) { // Check if we should cleanup everything. bool forced_cleanup = p_force_cleanup || !enabled || !is_inside_tree() || tile_set.is_null(); + if (forced_cleanup && _scenes_was_cleaned_up) { + return; + } if (forced_cleanup) { // Clean everything. @@ -1682,7 +1714,7 @@ void TileMapLayer::_build_runtime_update_tile_data(bool p_force_cleanup) { } // ----------- - // Mark the navigation state as up to date. + // Mark the tile data state as up to date. _runtime_update_tile_data_was_cleaned_up = forced_cleanup; } diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h index 10194b79b27..1c778cce825 100644 --- a/scene/2d/tile_map_layer.h +++ b/scene/2d/tile_map_layer.h @@ -430,14 +430,15 @@ private: // Per-system methods. #ifdef DEBUG_ENABLED HashMap> debug_quadrant_map; - bool _debug_was_cleaned_up = false; + bool _debug_was_cleaned_up = true; void _debug_update(bool p_force_cleanup); void _debug_quadrants_update_cell(CellData &r_cell_data); void _get_debug_quadrant_for_cell(const Vector2i &p_coords); #endif // DEBUG_ENABLED HashMap> rendering_quadrant_map; - bool _rendering_was_cleaned_up = false; + bool _rendering_was_cleaned_up = true; + bool _occlusion_was_cleaned_up = true; void _rendering_update(bool p_force_cleanup); void _rendering_notification(int p_what); void _rendering_quadrants_update_cell(CellData &r_cell_data, SelfList::List &r_dirty_rendering_quadrant_list); @@ -450,7 +451,7 @@ private: #ifndef PHYSICS_2D_DISABLED HashMap> physics_quadrant_map; HashMap bodies_coords; // Mapping for RID to coords. - bool _physics_was_cleaned_up = false; + bool _physics_was_cleaned_up = true; void _physics_update(bool p_force_cleanup); void _physics_notification(int p_what); void _physics_quadrants_update_cell(CellData &r_cell_data, SelfList::List &r_dirty_physics_quadrant_list); @@ -462,7 +463,7 @@ private: #endif // PHYSICS_2D_DISABLED #ifndef NAVIGATION_2D_DISABLED - bool _navigation_was_cleaned_up = false; + bool _navigation_was_cleaned_up = true; void _navigation_update(bool p_force_cleanup); void _navigation_notification(int p_what); void _navigation_clear_cell(CellData &r_cell_data); @@ -472,7 +473,7 @@ private: #endif // DEBUG_ENABLED #endif // NAVIGATION_2D_DISABLED - bool _scenes_was_cleaned_up = false; + bool _scenes_was_cleaned_up = true; void _scenes_update(bool p_force_cleanup); void _scenes_clear_cell(CellData &r_cell_data); void _scenes_update_cell(CellData &r_cell_data);