You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Merge pull request #102129 from Ivorforce/optimize-text-server-adv-break-iter
Optimize text rendering by caching `UBreakIterator` instances.
This commit is contained in:
@@ -5664,8 +5664,12 @@ bool TextServerAdvanced::_shaped_text_update_breaks(const RID &p_shaped) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
int r_end = sd->spans[i].end;
|
int r_end = sd->spans[i].end;
|
||||||
UBreakIterator *bi = ubrk_open(UBRK_LINE, (language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale().ascii().get_data() : language.ascii().get_data(), data + _convert_pos_inv(sd, r_start), _convert_pos_inv(sd, r_end - r_start), &err);
|
UBreakIterator *bi = sd->_get_break_iterator_for_locale(language, &err);
|
||||||
if (U_FAILURE(err)) {
|
if (!U_FAILURE(err) && bi) {
|
||||||
|
ubrk_setText(bi, data + _convert_pos_inv(sd, r_start), _convert_pos_inv(sd, r_end - r_start), &err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (U_FAILURE(err) || !bi) {
|
||||||
// No data loaded - use fallback.
|
// No data loaded - use fallback.
|
||||||
for (int j = r_start; j < r_end; j++) {
|
for (int j = r_start; j < r_end; j++) {
|
||||||
char32_t c = sd->text[j - sd->start];
|
char32_t c = sd->text[j - sd->start];
|
||||||
@@ -5694,7 +5698,6 @@ bool TextServerAdvanced::_shaped_text_update_breaks(const RID &p_shaped) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ubrk_close(bi);
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
sd->break_ops_valid = true;
|
sd->break_ops_valid = true;
|
||||||
@@ -6142,6 +6145,15 @@ _FORCE_INLINE_ void TextServerAdvanced::_add_featuers(const Dictionary &p_source
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UBreakIterator *TextServerAdvanced::ShapedTextDataAdvanced::_get_break_iterator_for_locale(const String &p_language, UErrorCode *r_err) {
|
||||||
|
HashMap<String, UBreakIterator *>::Iterator key_value = line_break_iterators_per_language.find(p_language);
|
||||||
|
if (key_value) {
|
||||||
|
return key_value->value;
|
||||||
|
}
|
||||||
|
UBreakIterator *brk = ubrk_open(UBRK_LINE, p_language.is_empty() ? TranslationServer::get_singleton()->get_tool_locale().ascii().get_data() : p_language.ascii().get_data(), nullptr, 0, r_err);
|
||||||
|
return line_break_iterators_per_language.insert(p_language, brk)->value;
|
||||||
|
}
|
||||||
|
|
||||||
void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, TypedArray<RID> p_fonts, int64_t p_span, int64_t p_fb_index, int64_t p_prev_start, int64_t p_prev_end, RID p_prev_font) {
|
void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, TypedArray<RID> p_fonts, int64_t p_span, int64_t p_fb_index, int64_t p_prev_start, int64_t p_prev_end, RID p_prev_font) {
|
||||||
RID f;
|
RID f;
|
||||||
int fs = p_sd->spans[p_span].font_size;
|
int fs = p_sd->spans[p_span].font_size;
|
||||||
|
|||||||
@@ -545,6 +545,11 @@ class TextServerAdvanced : public TextServerExtension {
|
|||||||
bool js_ops_valid = false;
|
bool js_ops_valid = false;
|
||||||
bool chars_valid = false;
|
bool chars_valid = false;
|
||||||
|
|
||||||
|
HashMap<String, UBreakIterator *> line_break_iterators_per_language;
|
||||||
|
|
||||||
|
// Creating UBreakIterator is surprisingly costly. To improve efficiency, we cache them.
|
||||||
|
UBreakIterator *_get_break_iterator_for_locale(const String &p_language, UErrorCode *r_err);
|
||||||
|
|
||||||
~ShapedTextDataAdvanced() {
|
~ShapedTextDataAdvanced() {
|
||||||
for (int i = 0; i < bidi_iter.size(); i++) {
|
for (int i = 0; i < bidi_iter.size(); i++) {
|
||||||
if (bidi_iter[i]) {
|
if (bidi_iter[i]) {
|
||||||
@@ -557,6 +562,9 @@ class TextServerAdvanced : public TextServerExtension {
|
|||||||
if (hb_buffer) {
|
if (hb_buffer) {
|
||||||
hb_buffer_destroy(hb_buffer);
|
hb_buffer_destroy(hb_buffer);
|
||||||
}
|
}
|
||||||
|
for (const KeyValue<String, UBreakIterator *> &bi : line_break_iterators_per_language) {
|
||||||
|
ubrk_close(bi.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user