Redraw windows on top when any window changes
This commit restores redraws of entire windows, but only if a window below
has actually changed. It should fix most regressions from commit c6d8692ac6
with a much smaller CPU usage cost.
The commit also includes a check for the situation where the title screen
changes all the time, which would restore the high CPU usage (that the
developer would be unlikely to notice immediately).
This commit is contained in:
parent
61bbd51f3a
commit
e5fb29dba6
2 changed files with 44 additions and 0 deletions
|
@ -65,6 +65,10 @@
|
|||
|
||||
#include "utils/functional.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace wfl { class function_symbol_table; }
|
||||
namespace gui2 { class button; }
|
||||
|
||||
|
@ -719,9 +723,23 @@ void window::draw()
|
|||
}
|
||||
|
||||
if (dirty_list_.empty()) {
|
||||
consecutive_changed_frames_ = 0u;
|
||||
return;
|
||||
}
|
||||
|
||||
++consecutive_changed_frames_;
|
||||
if(consecutive_changed_frames_ >= 100u && id_ == "title_screen") {
|
||||
/* The title screen has changed in 100 consecutive frames, i.e. every
|
||||
frame for two seconds. It looks like the screen is constantly changing
|
||||
or at least marking widgets as dirty.
|
||||
|
||||
That's a severe problem. Every time the title screen changes, all
|
||||
other GUI windows need to be fully redrawn, with huge CPU usage cost.
|
||||
For that reason, this situation is a hard error. */
|
||||
throw std::logic_error("The title screen is constantly changing, "
|
||||
"which has a huge CPU usage cost. See the code comment.");
|
||||
}
|
||||
|
||||
for(auto & item : dirty_list_)
|
||||
{
|
||||
|
||||
|
@ -812,6 +830,8 @@ void window::draw()
|
|||
|
||||
dirty_list_.clear();
|
||||
|
||||
redraw_windows_on_top();
|
||||
|
||||
std::vector<widget*> call_stack;
|
||||
populate_dirty_list(*this, call_stack);
|
||||
assert(dirty_list_.empty());
|
||||
|
@ -1203,6 +1223,20 @@ void window_swap_grid(grid* g,
|
|||
|
||||
} // namespace
|
||||
|
||||
void window::redraw_windows_on_top() const
|
||||
{
|
||||
auto me = std::find(open_window_stack.begin(), open_window_stack.end(), this);
|
||||
if(me == open_window_stack.end()) {
|
||||
// Known to happen for tooltips.
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto it = std::next(me); it != open_window_stack.end(); ++it) {
|
||||
// Note that setting an entire window dirty like this is expensive.
|
||||
(*it)->set_is_dirty(true);
|
||||
}
|
||||
}
|
||||
|
||||
void window::finalize(const std::shared_ptr<builder_grid>& content_grid)
|
||||
{
|
||||
window_swap_grid(nullptr, &get_grid(), content_grid->build(), "_window_content_grid");
|
||||
|
|
|
@ -684,6 +684,16 @@ private:
|
|||
*/
|
||||
std::vector<std::vector<widget*> > dirty_list_;
|
||||
|
||||
/**
|
||||
* In how many consecutive frames the window has changed. This is used to
|
||||
* detect the situation where the title screen changes in every frame,
|
||||
* forcing all other windows to redraw everything all the time.
|
||||
*/
|
||||
unsigned int consecutive_changed_frames_ = 0u;
|
||||
|
||||
/** Schedules windows on top of us (if any) to redraw. */
|
||||
void redraw_windows_on_top() const;
|
||||
|
||||
/**
|
||||
* Finishes the initialization of the grid.
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue