Merge pull request #62175 from bruvzg/custom_keys

This commit is contained in:
Rémi Verschelde 2022-07-04 10:09:59 +02:00 committed by GitHub
commit c32646c1c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 31 deletions

View file

@ -35,7 +35,7 @@
#include "hash_map.h" #include "hash_map.h"
#include "list.h" #include "list.h"
template <class TKey, class TData> template <class TKey, class TData, class Hasher = HashMapHasherDefault, class Comparator = HashMapComparatorDefault<TKey>>
class LRUCache { class LRUCache {
private: private:
struct Pair { struct Pair {
@ -52,7 +52,7 @@ private:
typedef typename List<Pair>::Element *Element; typedef typename List<Pair>::Element *Element;
List<Pair> _list; List<Pair> _list;
HashMap<TKey, Element> _map; HashMap<TKey, Element, Hasher, Comparator> _map;
size_t capacity; size_t capacity;
public: public:

View file

@ -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); bool msdf = TS->font_is_multichannel_signed_distance_field(p_glyph.font_rid);
uint64_t mat_hash; SurfaceKey key = SurfaceKey(tex.get_id(), p_priority, p_outline_size);
if (tex != RID()) { if (!surfaces.has(key)) {
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)) {
SurfaceData surf; SurfaceData surf;
surf.material = RenderingServer::get_singleton()->material_create(); surf.material = RenderingServer::get_singleton()->material_create();
// Set defaults for material, names need to match up those in StandardMaterial3D // 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; 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_vertices.resize((s.offset + 1) * 4);
s.mesh_normals.resize((s.offset + 1) * 4); s.mesh_normals.resize((s.offset + 1) * 4);
@ -464,7 +457,7 @@ void Label3D::_shape() {
aabb = AABB(); aabb = AABB();
// Clear materials. // Clear materials.
for (const KeyValue<uint64_t, SurfaceData> &E : surfaces) { for (const KeyValue<SurfaceKey, SurfaceData> &E : surfaces) {
RenderingServer::get_singleton()->free(E.value.material); RenderingServer::get_singleton()->free(E.value.material);
} }
surfaces.clear(); 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; 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; Array mesh_array;
mesh_array.resize(RS::ARRAY_MAX); mesh_array.resize(RS::ARRAY_MAX);
mesh_array[RS::ARRAY_VERTEX] = E.value.mesh_vertices; mesh_array[RS::ARRAY_VERTEX] = E.value.mesh_vertices;
@ -1018,7 +1011,7 @@ Label3D::~Label3D() {
TS->free_rid(text_rid); TS->free_rid(text_rid);
RenderingServer::get_singleton()->free(mesh); 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); RenderingServer::get_singleton()->free(E.value.material);
} }
surfaces.clear(); surfaces.clear();

View file

@ -76,7 +76,29 @@ private:
RID material; 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; HorizontalAlignment horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER;
VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_CENTER; VerticalAlignment vertical_alignment = VERTICAL_ALIGNMENT_CENTER;

View file

@ -2190,12 +2190,12 @@ RibbonTrailMesh::RibbonTrailMesh() {
/* TextMesh */ /* TextMesh */
/*************************************************************************/ /*************************************************************************/
void TextMesh::_generate_glyph_mesh_data(uint32_t p_hash, const Glyph &p_gl) const { void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph &p_gl) const {
if (cache.has(p_hash)) { if (cache.has(p_key)) {
return; 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); 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; 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; continue;
} }
if (glyphs[i].font_rid != RID()) { if (glyphs[i].font_rid != RID()) {
uint32_t hash = hash_one_uint64(glyphs[i].font_rid.get_id()); GlyphMeshKey key = GlyphMeshKey(glyphs[i].font_rid.get_id(), glyphs[i].index);
hash = hash_murmur3_one_32(glyphs[i].index, hash); _generate_glyph_mesh_data(key, glyphs[i]);
GlyphMeshData &gl_data = cache[key];
_generate_glyph_mesh_data(hash, glyphs[i]);
GlyphMeshData &gl_data = cache[hash];
p_size += glyphs[i].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); 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); 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; continue;
} }
if (glyphs[i].font_rid != RID()) { if (glyphs[i].font_rid != RID()) {
uint32_t hash = hash_one_uint64(glyphs[i].font_rid.get_id()); GlyphMeshKey key = GlyphMeshKey(glyphs[i].font_rid.get_id(), glyphs[i].index);
hash = hash_murmur3_one_32(glyphs[i].index, hash); _generate_glyph_mesh_data(key, glyphs[i]);
const GlyphMeshData &gl_data = cache[key];
const GlyphMeshData &gl_data = cache[hash];
int64_t ts = gl_data.triangles.size(); int64_t ts = gl_data.triangles.size();
const Vector2 *ts_ptr = gl_data.triangles.ptr(); const Vector2 *ts_ptr = gl_data.triangles.ptr();

View file

@ -475,6 +475,7 @@ private:
sharp = p_sharp; sharp = p_sharp;
}; };
}; };
struct ContourInfo { struct ContourInfo {
real_t length = 0.0; real_t length = 0.0;
bool ccw = true; bool ccw = true;
@ -484,6 +485,27 @@ private:
ccw = p_ccw; 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 { struct GlyphMeshData {
Vector<Vector2> triangles; Vector<Vector2> triangles;
Vector<Vector<ContourPoint>> contours; Vector<Vector<ContourPoint>> contours;
@ -491,7 +513,7 @@ private:
Vector2 min_p = Vector2(INFINITY, INFINITY); Vector2 min_p = Vector2(INFINITY, INFINITY);
Vector2 max_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; RID text_rid;
String text; String text;
@ -517,7 +539,7 @@ private:
mutable bool dirty_font = true; mutable bool dirty_font = true;
mutable bool dirty_cache = 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(); void _font_changed();
protected: protected: