Merge pull request #78241 from bruvzg/rtl_mt_resize

[RTL] Fix multithreaded resizing.
This commit is contained in:
Rémi Verschelde 2023-06-15 15:26:27 +02:00
commit f9e0c64905
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 64 additions and 71 deletions

View File

@ -2781,6 +2781,44 @@ int RichTextLabel::get_progress_bar_delay() const {
return progress_delay;
}
_FORCE_INLINE_ float RichTextLabel::_update_scroll_exceeds(float p_total_height, float p_ctrl_height, float p_width, int p_idx, float p_old_scroll, float p_text_rect_height) {
updating_scroll = true;
float total_height = p_total_height;
bool exceeds = p_total_height > p_ctrl_height && scroll_active;
if (exceeds != scroll_visible) {
if (exceeds) {
scroll_visible = true;
scroll_w = vscroll->get_combined_minimum_size().width;
vscroll->show();
vscroll->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -scroll_w);
} else {
scroll_visible = false;
scroll_w = 0;
vscroll->hide();
}
main->first_resized_line.store(0);
total_height = 0;
for (int j = 0; j <= p_idx; j++) {
total_height = _resize_line(main, j, theme_cache.normal_font, theme_cache.normal_font_size, p_width, total_height);
main->first_resized_line.store(j);
}
}
vscroll->set_max(total_height);
vscroll->set_page(p_text_rect_height);
if (scroll_follow && scroll_following) {
vscroll->set_value(total_height);
} else {
vscroll->set_value(p_old_scroll);
}
updating_scroll = false;
return total_height;
}
bool RichTextLabel::_validate_line_caches() {
if (updating.load()) {
return false;
@ -2790,7 +2828,7 @@ bool RichTextLabel::_validate_line_caches() {
MutexLock data_lock(data_mutex);
Rect2 text_rect = _get_text_rect();
int ctrl_height = get_size().height;
float ctrl_height = get_size().height;
// Update fonts.
float old_scroll = vscroll->get_value();
@ -2814,40 +2852,7 @@ bool RichTextLabel::_validate_line_caches() {
float total_height = (fi == 0) ? 0 : _calculate_line_vertical_offset(main->lines[fi - 1]);
for (int i = fi; i < (int)main->lines.size(); i++) {
total_height = _resize_line(main, i, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height);
updating_scroll = true;
bool exceeds = total_height > ctrl_height && scroll_active;
if (exceeds != scroll_visible) {
if (exceeds) {
scroll_visible = true;
scroll_w = vscroll->get_combined_minimum_size().width;
vscroll->show();
vscroll->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -scroll_w);
} else {
scroll_visible = false;
scroll_w = 0;
vscroll->hide();
}
main->first_resized_line.store(0);
total_height = 0;
for (int j = 0; j <= i; j++) {
total_height = _resize_line(main, j, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height);
main->first_resized_line.store(j);
}
}
vscroll->set_max(total_height);
vscroll->set_page(text_rect.size.height);
if (scroll_follow && scroll_following) {
vscroll->set_value(total_height);
} else {
vscroll->set_value(old_scroll);
}
updating_scroll = false;
total_height = _update_scroll_exceeds(total_height, ctrl_height, text_rect.get_size().width - scroll_w, i, old_scroll, text_rect.size.height);
main->first_resized_line.store(i);
}
@ -2886,47 +2891,34 @@ void RichTextLabel::_process_line_caches() {
MutexLock data_lock(data_mutex);
Rect2 text_rect = _get_text_rect();
int ctrl_height = get_size().height;
float ctrl_height = get_size().height;
int fi = main->first_invalid_line.load();
int total_chars = main->lines[fi].char_offset;
float old_scroll = vscroll->get_value();
float total_height = 0;
if (fi != 0) {
// Update fonts.
for (int i = main->first_invalid_font_line.load(); i < fi; i++) {
_update_line_font(main, i, theme_cache.normal_font, theme_cache.normal_font_size);
}
// Resize lines without reshaping.
int sr = MIN(main->first_invalid_font_line.load(), main->first_resized_line.load());
main->first_invalid_font_line.store(fi);
for (int i = sr; i < fi; i++) {
total_height = _resize_line(main, i, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height);
total_height = _update_scroll_exceeds(total_height, ctrl_height, text_rect.get_size().width - scroll_w, i, old_scroll, text_rect.size.height);
main->first_resized_line.store(i);
}
}
float total_height = (fi == 0) ? 0 : _calculate_line_vertical_offset(main->lines[fi - 1]);
for (int i = fi; i < (int)main->lines.size(); i++) {
total_height = _shape_line(main, i, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height, &total_chars);
updating_scroll = true;
bool exceeds = total_height > ctrl_height && scroll_active;
if (exceeds != scroll_visible) {
if (exceeds) {
scroll_visible = true;
scroll_w = vscroll->get_combined_minimum_size().width;
vscroll->show();
vscroll->set_anchor_and_offset(SIDE_LEFT, ANCHOR_END, -scroll_w);
} else {
scroll_visible = false;
scroll_w = 0;
vscroll->hide();
}
main->first_invalid_line.store(0);
main->first_resized_line.store(0);
main->first_invalid_font_line.store(0);
// since scroll was added or removed we need to resize all lines
total_height = 0;
for (int j = 0; j <= i; j++) {
total_height = _resize_line(main, j, theme_cache.normal_font, theme_cache.normal_font_size, text_rect.get_size().width - scroll_w, total_height);
main->first_invalid_line.store(j);
main->first_resized_line.store(j);
main->first_invalid_font_line.store(j);
}
}
vscroll->set_max(total_height);
vscroll->set_page(text_rect.size.height);
if (scroll_follow && scroll_following) {
vscroll->set_value(total_height);
}
updating_scroll = false;
total_height = _update_scroll_exceeds(total_height, ctrl_height, text_rect.get_size().width - scroll_w, i, old_scroll, text_rect.size.height);
main->first_invalid_line.store(i);
main->first_resized_line.store(i);

View File

@ -421,6 +421,7 @@ private:
void _stop_thread();
bool _validate_line_caches();
void _process_line_caches();
_FORCE_INLINE_ float _update_scroll_exceeds(float p_total_height, float p_ctrl_height, float p_width, int p_idx, float p_old_scroll, float p_text_rect_height);
void _add_item(Item *p_item, bool p_enter = false, bool p_ensure_newline = false);
void _remove_item(Item *p_item, const int p_line, const int p_subitem_line);