diff options
| -rw-r--r-- | core/templates/lru.h | 4 | ||||
| -rw-r--r-- | scene/3d/label_3d.cpp | 21 | ||||
| -rw-r--r-- | scene/3d/label_3d.h | 24 | ||||
| -rw-r--r-- | scene/resources/primitive_meshes.cpp | 21 | ||||
| -rw-r--r-- | scene/resources/primitive_meshes.h | 26 | 
5 files changed, 65 insertions, 31 deletions
diff --git a/core/templates/lru.h b/core/templates/lru.h index 48ba318b12..55130cbeb0 100644 --- a/core/templates/lru.h +++ b/core/templates/lru.h @@ -35,7 +35,7 @@  #include "hash_map.h"  #include "list.h" -template <class TKey, class TData> +template <class TKey, class TData, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<TKey>>  class LRUCache {  private:  	struct Pair { @@ -52,7 +52,7 @@ private:  	typedef typename List<Pair>::Element *Element;  	List<Pair> _list; -	HashMap<TKey, Element> _map; +	HashMap<TKey, Element, Hasher, Comparator> _map;  	size_t capacity;  public: diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index 0849b2c631..1ae59451a1 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -370,15 +370,8 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset,  		bool msdf = TS->font_is_multichannel_signed_distance_field(p_glyph.font_rid); -		uint64_t mat_hash; -		if (tex != RID()) { -			mat_hash = hash_one_uint64(tex.get_id()); -		} else { -			mat_hash = hash_one_uint64(0); -		} -		mat_hash = hash_fmix32(hash_murmur3_one_64(p_priority | (p_outline_size << 31), mat_hash)); - -		if (!surfaces.has(mat_hash)) { +		SurfaceKey key = SurfaceKey(tex.get_id(), p_priority, p_outline_size); +		if (!surfaces.has(key)) {  			SurfaceData surf;  			surf.material = RenderingServer::get_singleton()->material_create();  			// Set defaults for material, names need to match up those in StandardMaterial3D @@ -407,9 +400,9 @@ void Label3D::_generate_glyph_surfaces(const Glyph &p_glyph, Vector2 &r_offset,  				surf.z_shift = p_priority * pixel_size;  			} -			surfaces[mat_hash] = surf; +			surfaces[key] = surf;  		} -		SurfaceData &s = surfaces[mat_hash]; +		SurfaceData &s = surfaces[key];  		s.mesh_vertices.resize((s.offset + 1) * 4);  		s.mesh_normals.resize((s.offset + 1) * 4); @@ -464,7 +457,7 @@ void Label3D::_shape() {  	aabb = AABB();  	// Clear materials. -	for (const KeyValue<uint64_t, SurfaceData> &E : surfaces) { +	for (const KeyValue<SurfaceKey, SurfaceData> &E : surfaces) {  		RenderingServer::get_singleton()->free(E.value.material);  	}  	surfaces.clear(); @@ -594,7 +587,7 @@ void Label3D::_shape() {  		offset.y -= (TS->shaped_text_get_descent(lines_rid[i]) + line_spacing + font->get_spacing(TextServer::SPACING_BOTTOM)) * pixel_size;  	} -	for (const KeyValue<uint64_t, SurfaceData> &E : surfaces) { +	for (const KeyValue<SurfaceKey, SurfaceData> &E : surfaces) {  		Array mesh_array;  		mesh_array.resize(RS::ARRAY_MAX);  		mesh_array[RS::ARRAY_VERTEX] = E.value.mesh_vertices; @@ -1018,7 +1011,7 @@ Label3D::~Label3D() {  	TS->free_rid(text_rid);  	RenderingServer::get_singleton()->free(mesh); -	for (KeyValue<uint64_t, SurfaceData> E : surfaces) { +	for (KeyValue<SurfaceKey, SurfaceData> E : surfaces) {  		RenderingServer::get_singleton()->free(E.value.material);  	}  	surfaces.clear(); diff --git a/scene/3d/label_3d.h b/scene/3d/label_3d.h index 7766bca068..7ac38a9f3c 100644 --- a/scene/3d/label_3d.h +++ b/scene/3d/label_3d.h @@ -76,7 +76,29 @@ private:  		RID material;  	}; -	HashMap<uint64_t, SurfaceData> surfaces; +	struct SurfaceKey { +		uint64_t texture_id; +		int32_t priority; +		int32_t outline_size; + +		bool operator==(const SurfaceKey &p_b) const { +			return (texture_id == p_b.texture_id) && (priority == p_b.priority) && (outline_size == p_b.outline_size); +		} + +		SurfaceKey(uint64_t p_texture_id, int p_priority, int p_outline_size) { +			texture_id = p_texture_id; +			priority = p_priority; +			outline_size = p_outline_size; +		} +	}; + +	struct SurfaceKeyHasher { +		_FORCE_INLINE_ static uint32_t hash(const SurfaceKey &p_a) { +			return hash_murmur3_buffer(&p_a, sizeof(SurfaceKey)); +		} +	}; + +	HashMap<SurfaceKey, SurfaceData, SurfaceKeyHasher> surfaces;  	HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER;  	VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_CENTER; diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index f4fd81b25f..9fa483bf36 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -2190,12 +2190,12 @@ RibbonTrailMesh::RibbonTrailMesh() {  /*  TextMesh                                                             */  /*************************************************************************/ -void TextMesh::_generate_glyph_mesh_data(uint32_t p_hash, const Glyph &p_gl) const { -	if (cache.has(p_hash)) { +void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph &p_gl) const { +	if (cache.has(p_key)) {  		return;  	} -	GlyphMeshData &gl_data = cache[p_hash]; +	GlyphMeshData &gl_data = cache[p_key];  	Dictionary d = TS->font_get_glyph_contours(p_gl.font_rid, p_gl.font_size, p_gl.index);  	Vector2 origin = Vector2(p_gl.x_off, p_gl.y_off) * pixel_size; @@ -2437,11 +2437,9 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {  			continue;  		}  		if (glyphs[i].font_rid != RID()) { -			uint32_t hash = hash_one_uint64(glyphs[i].font_rid.get_id()); -			hash = hash_murmur3_one_32(glyphs[i].index, hash); - -			_generate_glyph_mesh_data(hash, glyphs[i]); -			GlyphMeshData &gl_data = cache[hash]; +			GlyphMeshKey key = GlyphMeshKey(glyphs[i].font_rid.get_id(), glyphs[i].index); +			_generate_glyph_mesh_data(key, glyphs[i]); +			GlyphMeshData &gl_data = cache[key];  			p_size += glyphs[i].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1);  			i_size += glyphs[i].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); @@ -2496,10 +2494,9 @@ void TextMesh::_create_mesh_array(Array &p_arr) const {  			continue;  		}  		if (glyphs[i].font_rid != RID()) { -			uint32_t hash = hash_one_uint64(glyphs[i].font_rid.get_id()); -			hash = hash_murmur3_one_32(glyphs[i].index, hash); - -			const GlyphMeshData &gl_data = cache[hash]; +			GlyphMeshKey key = GlyphMeshKey(glyphs[i].font_rid.get_id(), glyphs[i].index); +			_generate_glyph_mesh_data(key, glyphs[i]); +			const GlyphMeshData &gl_data = cache[key];  			int64_t ts = gl_data.triangles.size();  			const Vector2 *ts_ptr = gl_data.triangles.ptr(); diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 38cc7db5fe..a6d8978c2d 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -475,6 +475,7 @@ private:  			sharp = p_sharp;  		};  	}; +  	struct ContourInfo {  		real_t length = 0.0;  		bool ccw = true; @@ -484,6 +485,27 @@ private:  			ccw = p_ccw;  		}  	}; + +	struct GlyphMeshKey { +		uint64_t font_id; +		uint32_t gl_id; + +		bool operator==(const GlyphMeshKey &p_b) const { +			return (font_id == p_b.font_id) && (gl_id == p_b.gl_id); +		} + +		GlyphMeshKey(uint64_t p_font_id, uint32_t p_gl_id) { +			font_id = p_font_id; +			gl_id = p_gl_id; +		} +	}; + +	struct GlyphMeshKeyHasher { +		_FORCE_INLINE_ static uint32_t hash(const GlyphMeshKey &p_a) { +			return hash_murmur3_buffer(&p_a, sizeof(GlyphMeshKey)); +		} +	}; +  	struct GlyphMeshData {  		Vector<Vector2> triangles;  		Vector<Vector<ContourPoint>> contours; @@ -491,7 +513,7 @@ private:  		Vector2 min_p = Vector2(INFINITY, INFINITY);  		Vector2 max_p = Vector2(-INFINITY, -INFINITY);  	}; -	mutable HashMap<uint32_t, GlyphMeshData> cache; +	mutable HashMap<GlyphMeshKey, GlyphMeshData, GlyphMeshKeyHasher> cache;  	RID text_rid;  	String text; @@ -517,7 +539,7 @@ private:  	mutable bool dirty_font = true;  	mutable bool dirty_cache = true; -	void _generate_glyph_mesh_data(uint32_t p_hash, const Glyph &p_glyph) const; +	void _generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph &p_glyph) const;  	void _font_changed();  protected:  |