-
Notifications
You must be signed in to change notification settings - Fork 265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test/tree: hitting 'select all' hangs the application #300
Comments
Hmm, it does recover after about 30 or more seconds. Seems to be the Fl_Simple_Terminal() code taking a really long time to handle all the info print messages triggered by select all (there's 500 items in one of the tree's children) Still, printing 500 lines shouldn't be a problem. Possibly platform specific; this is linux, and according to gdb, apparently xft calls are involved during the printf() operations, probably doing label measurements. Still investigating. |
Yikes, yeah, this is actually a problem in Fl_Simple_Terminal. I modified examples/simple-terminal.cxx to just print 300 dots and a crlf every second, e.g.
..and that's causing really large delays in e.g. resizing and such. This doesn't seem to be xft specific; even rebuilding FLTK with --disable-xft still causes severe slowness. |
Hmm, I copied Fl_Simple_Terminal's code over to 1.3.x (this widget is new in 1.4.x), and am /not/ seeing slowness, so perhaps something has changed in FLTK 1.4.x that's slowing down drawing text. I checked OSX + 1.4.x, and I see the problem there too with test/tree, but to a lesser extent. On an old mac mini, I'm seeing a ~10 sec hang when hitting the "Select All" button. So this seems to be a cross platform issue. Might need help with this one -- has anything changed in 1.4.x recently that might affect text drawing speed? I'll try to determine if this is a regression with bisect.. might take a while. |
Yeesh, I've gone back to a commit from late 2017 and still seeing slowness with test/tree "Select All" so it's not a recent thing. But it's still more efficient somehow in 1.3.x? Decided not to go back any further in 1.4.x and see if I can optimize Fl_Simple_Terminal's operation. It inherits from Fl_Text_Display which is a touchy beast, so looking to design around Fl_Text_Display's behavior. |
Adding Thus, the slowness seems connected to computations that support line wrapping Still, it's very strange that the same Simple-Terminal code is fast under 1.3, |
I would suggest the culprit is in changes in the Fl_Text_Display widget between 1.3 and 1.4, |
OK. The culprit is eb772d0. Luckily, this is a one-liner : add This is visible as follows : Comment out the single line #495 in src/Fl_Text_Display.cxx to get Greg: I propose to stop here and let you continue the analysis of this issue, if you agree. |
@ManoloFLTK Thank you very much, these are great findings. Since that particular commit was done for a reason (STR 3412 which is still open ("pending")) we need to find a better solution to address both issues. FTR: As the commit message of eb772d0 (svn 12526) mentions this commit disabled "a part of the optimization" introduced in commit 7e94d76 (svn r11208) which obviously causes the observed slowness. Sigh. :-( @erco77 I'm too busy to look into this further right now and I can't promise that this may happen soon. I just wanted to give feedback since the mentioned commits were my work. |
Yes, thanks Manolo, I found there's a few issues that I can maybe optimize in Fl_Simple_Terminal too; there's three calls that seem to use a lot of CPU, and are called each time its printf() method is called:
I'm not sure how I can optimize all that though.. it'd probably be easier to implement the terminal code myself rather than try to fix Fl_Text_Editor lol. |
FWIW I'm attaching a profiler report for running To use the profiler:
|
@Albrecht-S yes, we want to avoid a "bug fix oscillation" where one bug's fix is another bug's bug. Luckily the commits show the related bugs clearly. This is going to be really annoying to fix, but the penalty in time is huge; just doing 500 string appends, let alone the calls to scroll() and remove(). We've known for a while Fl_Text_Xxx can get really slow just because of the scrollbar calculations. There must really be a way to do this better, keeping a running maximum for the width and height so these recalcs don't involve so much cpu. |
One way out of the dilemma would be to defer buffer updates in Fl_Text_Display. Following works: |
@wcout Great idea, thank you very much for the patch. I can't test it right now but I'm sure Greg (@erco77) will do. I have one question: wouldn't it make sense to just set a flag in Disclaimer: I only "read" the patch, I didn't look at the underlying code and don't know if this is feasible. Maybe you, Chris, know better? |
Wow! That's a great idea! And it works: Note: Just changed my patch to test it quickly. But maybe it can now be written still easier. I'll leave this to someone else (@erco77 ?). |
Wow, that's a quick reaction! Thanks again, Chris. |
Sure, I'll give this a spin. Anything to avoid actually fixing Fl_Text_Xxx, lol |
A similar phenomenon can be observed with the Again these lags are cured with the above patch of Fl_Text_Display. |
Lost my momentum on this, but am taking a look now. |
Delaying recalc seems a fine solution, but it can have some obvious side effects; if recalc is deferred, apps (and derived classes) that depended on the calculations of scrollbar sizes be updated will now not see these calculations done until the first draw(). An example I can think of is an app that repeatedly append()s text to the widget, and tries to keep the screen scrolled to show the last line of text based on the scrollbar position, which now with this new change wouldn't be calculated until the next draw(). We can't be certain existing apps (and derived classes) won't break in interesting ways if these calculations are suddenly deferred unconditionally. I'd suggest for backwards compatibility this be considered an "option" that is off by default, and can be turned on by apps (and derived classes like Fl_Simple_Terminal) that need it. We could add some docs to the Fl_Text_Display/Editor intro that warns if editor operations seem slow during repeat calls to methods that manipulate the editor, to recommend turning on this "deferred recalc" option, and reference the benefits and drawbacks. I'm not really sure what to call such an option.. whatever we come up with should be forward thinking, in case we want other complex widgets to have a similar flag.
|
Attaching a v2 patch: textdisplay_trigger_recalc_display_v2.diff.txt
TODO: Awaiting comments on if we need to make this behavior optional/default off, and if so, will do code implementation + docs. |
Perhaps changing I've noted now, that diff --git a/FL/Fl_Simple_Terminal.H b/FL/Fl_Simple_Terminal.H
index 158bf7d48..ac3d9c539 100644
--- a/FL/Fl_Simple_Terminal.H
+++ b/FL/Fl_Simple_Terminal.H
@@ -138,6 +138,7 @@ private:
int stable_size_; // active style table size (in bytes)
int normal_style_index_; // "normal" style used by "\033[0m" reset sequence
int current_style_index_; // current style used for drawing text
+ bool recalc_display_needed_; // true if recalc of display is needed
public:
Fl_Simple_Terminal(int X,int Y,int W,int H,const char *l=0);
@@ -181,6 +182,7 @@ private:
protected:
// Fltk
virtual void draw();
+ virtual void recalc_display();
// Internal methods
void enforce_stay_at_bottom();
diff --git a/src/Fl_Simple_Terminal.cxx b/src/Fl_Simple_Terminal.cxx
index 3d776f2d8..b3c28042a 100644
--- a/src/Fl_Simple_Terminal.cxx
+++ b/src/Fl_Simple_Terminal.cxx
@@ -110,6 +110,7 @@ Fl_Simple_Terminal::Fl_Simple_Terminal(int X,int Y,int W,int H,const char *l) :
orig_vscroll_cb = mVScrollBar->callback();
orig_vscroll_data = mVScrollBar->user_data();
mVScrollBar->callback(vscroll_cb, (void*)this);
+ recalc_display_needed_ = false;
}
/**
@@ -732,6 +733,10 @@ void Fl_Simple_Terminal::draw() {
//
#define LEFT_MARGIN 3
#define RIGHT_MARGIN 3
+ if (recalc_display_needed_) {
+ recalc_display_needed_ = false;
+ Fl_Text_Display::recalc_display();
+ }
int buflen = buf->length();
// Force cursor to EOF so it doesn't draw at user's last left-click
insert_position(buflen);
@@ -746,3 +751,8 @@ void Fl_Simple_Terminal::draw() {
if (position_to_xy(buflen, &X, &Y)) draw_cursor(X, Y);
fl_pop_clip();
}
+
+void Fl_Simple_Terminal::recalc_display() {
+ recalc_display_needed_ = true; // set flag only
+ redraw(); // ensure draw() gets called
+}
I don't think many folks have based their classes on |
@wcout Thanks, Chris, this is a smart idea. However, although it would likely solve the issue at hand, i.e. in FTR: I'm also working on a patch based on Greg's (@erco77's) latest version of your (@wcout's) patch. I'm thinking about the option Greg mentioned to switch the deferred calculation on (and off) in the user program because I'm concerned about backwards compatibility of unmodified programs - which means that the default would be off (non-deferred, or "direct"). I'll post more in a follow-up, but please don't hold your breath, I need some more time for testing. |
@erco77 Great findings, delaying calculation of internals until the widget gets drawn can have unwanted effects. As you may know I'm working on Using |
Ya, I'd guess if |
OK, here's some [bad] news. As it stands, While I'm at it I'm also trying to profile the code and I found some interesting hotspots. For instance, with my current test file (480,000 lines) there are some code sequences that use lots of CPU time, e.g. I'm investigating further... |
There was a flaw in my original patch (and @erco77's modified patch). void Fl_Text_Display::needs_recalc_display() {
needs_recalc_display_ = true;
redraw(); // ensure draw() gets called
} With this change moving the scrollbar works in editor. |
@wcout Thanks again for your support. I was going to test with your/Greg's original patches but I can now save this time. I'll add this to my patch (or see how it will be fixed otherwise). Correction: my observation posted above that |
So uh, did we come to a consensus on how to fix this? |
@erco77 Sorry, I can't remember what the current status is/was and what patch I mentioned above. I'd need some time to come back to this because I'm currently concentrating on other stuff. Maybe @MatthiasWM will find improvements in #596? |
I feel so free to update @erco77 's v2 patch with my change of adding textdisplay_trigger_recalc_display_v3.diff.txt Try
before: hangs "for ever" (had to kill the demo) |
See also issue #617 that reports the same issue. |
This issue will surely be solved when the new Fl_Terminal code is pulled in from my fork. |
@erco77 can this be closed? |
Yep, closed |
Investigating..
The text was updated successfully, but these errors were encountered: