GUI: implement canvas caching
This commit is contained in:
parent
29519406be
commit
6110fb59db
4 changed files with 45 additions and 8 deletions
|
@ -47,6 +47,8 @@ Version 1.13.8+dev:
|
||||||
* Fixed delay or clients gettings stuck when starting a mp game (Bug #1674)
|
* Fixed delay or clients gettings stuck when starting a mp game (Bug #1674)
|
||||||
* Performance:
|
* Performance:
|
||||||
* Rewrote the FPS cap implementation. This greatly improves smoothness ingame.
|
* Rewrote the FPS cap implementation. This greatly improves smoothness ingame.
|
||||||
|
* Implemented GUI canvas caching. It speeds up multiple areas, but especially
|
||||||
|
the story screen.
|
||||||
* Units:
|
* Units:
|
||||||
* Added new lvl0 Giant Scorpling, leveling into the Giant Scorpion.
|
* Added new lvl0 Giant Scorpling, leveling into the Giant Scorpion.
|
||||||
* User Interface:
|
* User Interface:
|
||||||
|
|
|
@ -32,6 +32,8 @@ Version 1.13.8+dev:
|
||||||
|
|
||||||
* Performance:
|
* Performance:
|
||||||
* Rewrote the FPS cap implementation. This greatly improves smoothness ingame.
|
* Rewrote the FPS cap implementation. This greatly improves smoothness ingame.
|
||||||
|
* Implemented GUI canvas caching. It speeds up multiple areas, but especially
|
||||||
|
the story screen.
|
||||||
|
|
||||||
* User Interface:
|
* User Interface:
|
||||||
* Unit recall dialog now sorts the units by both level and required XP for
|
* Unit recall dialog now sorts the units by both level and required XP for
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include "video.hpp"
|
#include "video.hpp"
|
||||||
#include "wml_exception.hpp"
|
#include "wml_exception.hpp"
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
namespace gui2
|
namespace gui2
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1391,9 +1393,13 @@ void canvas::draw(const bool force)
|
||||||
variables_.add("height", wfl::variant(h_));
|
variables_.add("height", wfl::variant(h_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!canvas_.null()) {
|
||||||
|
DBG_GUI_D << "Canvas: use cached canvas.\n";
|
||||||
|
} else {
|
||||||
// create surface
|
// create surface
|
||||||
DBG_GUI_D << "Canvas: create new empty canvas.\n";
|
DBG_GUI_D << "Canvas: create new empty canvas.\n";
|
||||||
canvas_.assign(create_neutral_surface(w_, h_));
|
canvas_.assign(create_neutral_surface(w_, h_));
|
||||||
|
}
|
||||||
|
|
||||||
SDL_DestroyRenderer(renderer_);
|
SDL_DestroyRenderer(renderer_);
|
||||||
|
|
||||||
|
@ -1407,6 +1413,10 @@ void canvas::draw(const bool force)
|
||||||
shape->draw(canvas_, renderer_, variables_);
|
shape->draw(canvas_, renderer_, variables_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The shapes have been drawn and the draw result has been cached. Clear the list.
|
||||||
|
std::copy(shapes_.begin(), shapes_.end(), std::back_inserter(drawn_shapes_));
|
||||||
|
shapes_.clear();
|
||||||
|
|
||||||
SDL_RenderPresent(renderer_);
|
SDL_RenderPresent(renderer_);
|
||||||
|
|
||||||
is_dirty_ = false;
|
is_dirty_ = false;
|
||||||
|
@ -1484,12 +1494,29 @@ void canvas::parse_cfg(const config& cfg)
|
||||||
|
|
||||||
void canvas::clear_shapes(const bool force)
|
void canvas::clear_shapes(const bool force)
|
||||||
{
|
{
|
||||||
const auto iter = std::remove_if(shapes_.begin(), shapes_.end(), [&force](const shape_ptr s)
|
auto iter = std::remove_if(shapes_.begin(), shapes_.end(), [force](const shape_ptr s)
|
||||||
{
|
{
|
||||||
return !s->immutable() && !force;
|
return !s->immutable() && !force;
|
||||||
});
|
});
|
||||||
|
|
||||||
shapes_.erase(iter, shapes_.end());
|
shapes_.erase(iter, shapes_.end());
|
||||||
|
|
||||||
|
iter = std::remove_if(drawn_shapes_.begin(), drawn_shapes_.end(), [force](const shape_ptr s)
|
||||||
|
{
|
||||||
|
return !s->immutable() && !force;
|
||||||
|
});
|
||||||
|
drawn_shapes_.erase(iter, drawn_shapes_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void canvas::invalidate_cache()
|
||||||
|
{
|
||||||
|
canvas_.assign(nullptr);
|
||||||
|
|
||||||
|
if(shapes_.empty()) {
|
||||||
|
shapes_.swap(drawn_shapes_);
|
||||||
|
} else {
|
||||||
|
std::copy(drawn_shapes_.begin(), drawn_shapes_.end(), std::inserter(shapes_, shapes_.begin()));
|
||||||
|
drawn_shapes_.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** ***** ***** ***** ***** SHAPE ***** ***** ***** ***** *****/
|
/***** ***** ***** ***** ***** SHAPE ***** ***** ***** ***** *****/
|
||||||
|
|
|
@ -35,9 +35,6 @@ namespace gui2
|
||||||
*
|
*
|
||||||
* The class has a config which contains what to draw.
|
* The class has a config which contains what to draw.
|
||||||
*
|
*
|
||||||
* NOTE we might add some caching in a later state, for now every draw cycle
|
|
||||||
* does a full redraw.
|
|
||||||
*
|
|
||||||
* The copy constructor does a shallow copy of the shapes to draw.
|
* The copy constructor does a shallow copy of the shapes to draw.
|
||||||
* a clone() will be implemented if really needed.
|
* a clone() will be implemented if really needed.
|
||||||
*/
|
*/
|
||||||
|
@ -121,6 +118,7 @@ public:
|
||||||
void set_cfg(const config& cfg, const bool force = false)
|
void set_cfg(const config& cfg, const bool force = false)
|
||||||
{
|
{
|
||||||
clear_shapes(force);
|
clear_shapes(force);
|
||||||
|
invalidate_cache();
|
||||||
parse_cfg(cfg);
|
parse_cfg(cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +140,7 @@ public:
|
||||||
{
|
{
|
||||||
w_ = width;
|
w_ = width;
|
||||||
set_is_dirty(true);
|
set_is_dirty(true);
|
||||||
|
invalidate_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_width() const
|
unsigned get_width() const
|
||||||
|
@ -153,6 +152,7 @@ public:
|
||||||
{
|
{
|
||||||
h_ = height;
|
h_ = height;
|
||||||
set_is_dirty(true);
|
set_is_dirty(true);
|
||||||
|
invalidate_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_height() const
|
unsigned get_height() const
|
||||||
|
@ -169,6 +169,7 @@ public:
|
||||||
{
|
{
|
||||||
variables_.add(key, value);
|
variables_.add(key, value);
|
||||||
set_is_dirty(true);
|
set_is_dirty(true);
|
||||||
|
invalidate_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_is_dirty(const bool is_dirty)
|
void set_is_dirty(const bool is_dirty)
|
||||||
|
@ -180,6 +181,10 @@ private:
|
||||||
/** Vector with the shapes to draw. */
|
/** Vector with the shapes to draw. */
|
||||||
std::vector<shape_ptr> shapes_;
|
std::vector<shape_ptr> shapes_;
|
||||||
|
|
||||||
|
/** All shapes which have been already drawn. Kept around in case
|
||||||
|
* the cache needs to be invalidated. */
|
||||||
|
std::vector<shape_ptr> drawn_shapes_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The depth of the blur to use in the pre committing.
|
* The depth of the blur to use in the pre committing.
|
||||||
*
|
*
|
||||||
|
@ -223,6 +228,7 @@ private:
|
||||||
void parse_cfg(const config& cfg);
|
void parse_cfg(const config& cfg);
|
||||||
|
|
||||||
void clear_shapes(const bool force);
|
void clear_shapes(const bool force);
|
||||||
|
void invalidate_cache();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui2
|
} // namespace gui2
|
||||||
|
|
Loading…
Add table
Reference in a new issue