Display: avoid unnecessarily (potentially) creating millions of temp vectors
I've moved the terrain hex drawing code directly into draw_visible_hexes instead of relying on get_terrain_images to return a vector of all the necessary images for each visible hex and then drawing them. Instead, we now draw each hex's images immediately without any intermediary container. With the old method, after about 10 to 15 seconds of drawing we had already allocated (and destroyed) almost 180,000 temporary vectors (a new one was created for each hex, twice per draw cycle). It's obvious how quickly that would add up over a normal play session, and though in this case the performance hit for creating each vector was probably tiny, creating them likely would have added up.
This commit is contained in:
parent
e9a8813b67
commit
f8e71f4d9a
2 changed files with 154 additions and 170 deletions
310
src/display.cpp
310
src/display.cpp
|
@ -997,163 +997,6 @@ std::vector<texture> display::get_fog_shroud_images(const map_location& loc, ima
|
|||
return res;
|
||||
}
|
||||
|
||||
void display::get_terrain_images(const map_location &loc,
|
||||
const std::string& timeid,
|
||||
TERRAIN_TYPE terrain_type)
|
||||
{
|
||||
terrain_image_vector_.clear();
|
||||
|
||||
terrain_builder::TERRAIN_TYPE builder_terrain_type = terrain_type == FOREGROUND
|
||||
? terrain_builder::FOREGROUND
|
||||
: terrain_builder::BACKGROUND;
|
||||
|
||||
assert(builder_);
|
||||
const terrain_builder::imagelist* const terrains = builder_->get_terrain_at(loc, timeid, builder_terrain_type);
|
||||
|
||||
#if 0
|
||||
image::light_string lt;
|
||||
|
||||
const time_of_day& tod = get_time_of_day(loc);
|
||||
|
||||
//get all the light transitions
|
||||
adjacent_loc_array_t adjs;
|
||||
std::array<const time_of_day*, 6> atods;
|
||||
get_adjacent_tiles(loc, adjs.data());
|
||||
for(size_t d = 0; d < adjs.size(); ++d){
|
||||
atods[d] = &get_time_of_day(adjs[d]);
|
||||
}
|
||||
|
||||
for(int d=0; d<6; ++d){
|
||||
/* concave
|
||||
_____
|
||||
/ \
|
||||
/ atod1 \_____
|
||||
\ !tod / \
|
||||
\_____/ atod2 \
|
||||
/ \__\ !tod /
|
||||
/ \_____/
|
||||
\ tod /
|
||||
\_____/*/
|
||||
|
||||
const time_of_day& atod1 = *atods[d];
|
||||
const time_of_day& atod2 = *atods[(d + 1) % 6];
|
||||
|
||||
if(atod1.color == tod.color || atod2.color == tod.color || atod1.color != atod2.color)
|
||||
continue;
|
||||
|
||||
if(lt.empty()) {
|
||||
//color the full hex before adding transitions
|
||||
tod_color col = tod.color + color_adjust_;
|
||||
lt = image::get_light_string(0, col.r, col.g, col.b);
|
||||
}
|
||||
|
||||
// add the directional transitions
|
||||
tod_color acol = atod1.color + color_adjust_;
|
||||
lt += image::get_light_string(d + 1, acol.r, acol.g, acol.b);
|
||||
}
|
||||
for(int d=0; d<6; ++d){
|
||||
/* convex 1
|
||||
_____
|
||||
/ \
|
||||
/ atod1 \_____
|
||||
\ !tod / \
|
||||
\_____/ atod2 \
|
||||
/ \__\ tod /
|
||||
/ \_____/
|
||||
\ tod /
|
||||
\_____/*/
|
||||
|
||||
const time_of_day& atod1 = *atods[d];
|
||||
const time_of_day& atod2 = *atods[(d + 1) % 6];
|
||||
|
||||
if(atod1.color == tod.color || atod1.color == atod2.color)
|
||||
continue;
|
||||
|
||||
if(lt.empty()) {
|
||||
//color the full hex before adding transitions
|
||||
tod_color col = tod.color + color_adjust_;
|
||||
lt = image::get_light_string(0, col.r, col.g, col.b);
|
||||
}
|
||||
|
||||
// add the directional transitions
|
||||
tod_color acol = atod1.color + color_adjust_;
|
||||
lt += image::get_light_string(d + 7, acol.r, acol.g, acol.b);
|
||||
}
|
||||
for(int d=0; d<6; ++d){
|
||||
/* convex 2
|
||||
_____
|
||||
/ \
|
||||
/ atod1 \_____
|
||||
\ tod / \
|
||||
\_____/ atod2 \
|
||||
/ \__\ !tod /
|
||||
/ \_____/
|
||||
\ tod /
|
||||
\_____/*/
|
||||
|
||||
const time_of_day& atod1 = *atods[d];
|
||||
const time_of_day& atod2 = *atods[(d + 1) % 6];
|
||||
|
||||
if(atod2.color == tod.color || atod1.color == atod2.color)
|
||||
continue;
|
||||
|
||||
if(lt.empty()) {
|
||||
//color the full hex before adding transitions
|
||||
tod_color col = tod.color + color_adjust_;
|
||||
lt = image::get_light_string(0, col.r, col.g, col.b);
|
||||
}
|
||||
|
||||
// add the directional transitions
|
||||
tod_color acol = atod2.color + color_adjust_;
|
||||
lt += image::get_light_string(d + 13, acol.r, acol.g, acol.b);
|
||||
}
|
||||
|
||||
if(lt.empty()){
|
||||
tod_color col = tod.color + color_adjust_;
|
||||
if(!col.is_zero()){
|
||||
// no real lightmap needed but still color the hex
|
||||
lt = image::get_light_string(-1, col.r, col.g, col.b);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(terrains != nullptr) {
|
||||
// Pre-allocate storage appropriately.
|
||||
// Since this function is called extremely often this should save some time.
|
||||
res.reserve(terrains->size());
|
||||
|
||||
// Cache the offmap name.
|
||||
// Since it is themeable it can change, so don't make it static.
|
||||
const std::string off_map_name = "terrain/" + theme_.border().tile_image;
|
||||
|
||||
for(const auto& terrain : *terrains) {
|
||||
const image::locator &image = animate_map_
|
||||
? terrain.get_current_frame()
|
||||
: terrain.get_first_frame();
|
||||
|
||||
// We prevent ToD coloring and brightening of off-map tiles,
|
||||
// We need to test for the tile to be rendered and
|
||||
// not the location, since the transitions are rendered
|
||||
// over the offmap-terrain and these need a ToD coloring.
|
||||
texture tex = image::get_texture(image, image::HEXED); // TODO: scaled to hex?
|
||||
|
||||
//const bool off_map = (image.get_filename() == off_map_name || image.get_modifications().find("NO_TOD_SHIFT()") != std::string::npos);
|
||||
#if 0
|
||||
if(off_map) {
|
||||
surf = image::get_image(image, image::SCALED_TO_HEX);
|
||||
} else if(lt.empty()) {
|
||||
surf = image::get_image(image, image::SCALED_TO_HEX);
|
||||
} else {
|
||||
surf = image::get_lighted_image(image, lt, image::SCALED_TO_HEX);
|
||||
}
|
||||
|
||||
if(!tex.null()) {
|
||||
terrain_image_vector_.push_back(std::move(tex));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display::toggle_benchmark()
|
||||
{
|
||||
benchmark = !benchmark;
|
||||
|
@ -2474,19 +2317,164 @@ void display::draw_hex_overlays()
|
|||
// DO NOTHING
|
||||
}
|
||||
|
||||
void display::draw_visible_hexes(const rect_of_hexes& visible_hexes, TERRAIN_TYPE terrain_type)
|
||||
void display::draw_visible_hexes(const rect_of_hexes& visible_hexes, TERRAIN_TYPE layer)
|
||||
{
|
||||
assert(builder_);
|
||||
|
||||
drawn_hexes_ = 0;
|
||||
|
||||
terrain_builder::TERRAIN_TYPE builder_terrain_type = layer == FOREGROUND
|
||||
? terrain_builder::FOREGROUND
|
||||
: terrain_builder::BACKGROUND;
|
||||
|
||||
for(const map_location& loc : visible_hexes) {
|
||||
if(shrouded(loc)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
image::TYPE image_type = get_image_type(loc);
|
||||
//image::TYPE image_type = get_image_type(loc);
|
||||
const time_of_day& tod = get_time_of_day(loc);
|
||||
|
||||
for(const texture& t : get_terrain_images(loc, tod.id, image_type, terrain_type)) {
|
||||
render_scaled_to_zoom(t, loc);
|
||||
// Get the image list for this location.
|
||||
const terrain_builder::imagelist* const terrains = builder_->get_terrain_at(loc, tod.id, builder_terrain_type);
|
||||
if(!terrains) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 0
|
||||
image::light_string lt;
|
||||
|
||||
const time_of_day& tod = get_time_of_day(loc);
|
||||
|
||||
//get all the light transitions
|
||||
map_location adjs[6];
|
||||
get_adjacent_tiles(loc,adjs);
|
||||
|
||||
for(int d=0; d<6; ++d){
|
||||
/* concave
|
||||
_____
|
||||
/ \
|
||||
/ atod1 \_____
|
||||
\ !tod / \
|
||||
\_____/ atod2 \
|
||||
/ \__\ !tod /
|
||||
/ \_____/
|
||||
\ tod /
|
||||
\_____/*/
|
||||
|
||||
const time_of_day& atod1 = get_time_of_day(adjs[d]);
|
||||
const time_of_day& atod2 = get_time_of_day(adjs[(d + 1) % 6]);
|
||||
|
||||
if(atod1.color == tod.color || atod2.color == tod.color || atod1.color != atod2.color)
|
||||
continue;
|
||||
|
||||
if(lt.empty()) {
|
||||
//color the full hex before adding transitions
|
||||
tod_color col = tod.color + color_adjust_;
|
||||
lt = image::get_light_string(0, col.r, col.g, col.b);
|
||||
}
|
||||
|
||||
// add the directional transitions
|
||||
tod_color acol = atod1.color + color_adjust_;
|
||||
lt += image::get_light_string(d + 1, acol.r, acol.g, acol.b);
|
||||
}
|
||||
for(int d=0; d<6; ++d){
|
||||
/* convex 1
|
||||
_____
|
||||
/ \
|
||||
/ atod1 \_____
|
||||
\ !tod / \
|
||||
\_____/ atod2 \
|
||||
/ \__\ tod /
|
||||
/ \_____/
|
||||
\ tod /
|
||||
\_____/*/
|
||||
|
||||
const time_of_day& atod1 = get_time_of_day(adjs[d]);
|
||||
const time_of_day& atod2 = get_time_of_day(adjs[(d + 1) % 6]);
|
||||
|
||||
if(atod1.color == tod.color || atod1.color == atod2.color)
|
||||
continue;
|
||||
|
||||
if(lt.empty()) {
|
||||
//color the full hex before adding transitions
|
||||
tod_color col = tod.color + color_adjust_;
|
||||
lt = image::get_light_string(0, col.r, col.g, col.b);
|
||||
}
|
||||
|
||||
// add the directional transitions
|
||||
tod_color acol = atod1.color + color_adjust_;
|
||||
lt += image::get_light_string(d + 7, acol.r, acol.g, acol.b);
|
||||
}
|
||||
for(int d=0; d<6; ++d){
|
||||
/* convex 2
|
||||
_____
|
||||
/ \
|
||||
/ atod1 \_____
|
||||
\ tod / \
|
||||
\_____/ atod2 \
|
||||
/ \__\ !tod /
|
||||
/ \_____/
|
||||
\ tod /
|
||||
\_____/*/
|
||||
|
||||
const time_of_day& atod1 = get_time_of_day(adjs[d]);
|
||||
const time_of_day& atod2 = get_time_of_day(adjs[(d + 1) % 6]);
|
||||
|
||||
if(atod2.color == tod.color || atod1.color == atod2.color)
|
||||
continue;
|
||||
|
||||
if(lt.empty()) {
|
||||
//color the full hex before adding transitions
|
||||
tod_color col = tod.color + color_adjust_;
|
||||
lt = image::get_light_string(0, col.r, col.g, col.b);
|
||||
}
|
||||
|
||||
// add the directional transitions
|
||||
tod_color acol = atod2.color + color_adjust_;
|
||||
lt += image::get_light_string(d + 13, acol.r, acol.g, acol.b);
|
||||
}
|
||||
|
||||
if(lt.empty()){
|
||||
tod_color col = tod.color + color_adjust_;
|
||||
if(!col.is_zero()){
|
||||
// no real lightmap needed but still color the hex
|
||||
lt = image::get_light_string(-1, col.r, col.g, col.b);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Cache the offmap name.
|
||||
// Since it is themeable it can change, so don't make it static.
|
||||
//const std::string off_map_name = "terrain/" + theme_.border().tile_image;
|
||||
|
||||
for(const auto& terrain : *terrains) {
|
||||
const image::locator& image = animate_map_
|
||||
? terrain.get_current_frame()
|
||||
: terrain.get_first_frame();
|
||||
|
||||
// We prevent ToD coloring and brightening of off-map tiles,
|
||||
// We need to test for the tile to be rendered and
|
||||
// not the location, since the transitions are rendered
|
||||
// over the offmap-terrain and these need a ToD coloring.
|
||||
texture tex = image::get_texture(image, image::HEXED); // TODO: scaled to hex?
|
||||
|
||||
//const bool off_map = (image.get_filename() == off_map_name || image.get_modifications().find("NO_TOD_SHIFT()") != std::string::npos);
|
||||
#if 0
|
||||
if(off_map) {
|
||||
surf = image::get_image(image, off_map ? image::SCALED_TO_HEX : image_type);
|
||||
} else if(lt.empty()) {
|
||||
surf = image::get_image(image, image::SCALED_TO_HEX);
|
||||
} else {
|
||||
surf = image::get_lighted_image(image, lt, image::SCALED_TO_HEX);
|
||||
}
|
||||
#endif
|
||||
if(!tex.null()) {
|
||||
render_scaled_to_zoom(tex, loc);
|
||||
}
|
||||
}
|
||||
|
||||
++drawn_hexes_;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -744,8 +744,6 @@ public:
|
|||
/** Checks if location @a loc or one of the adjacent tiles is visible on screen. */
|
||||
bool tile_nearly_on_screen(const map_location& loc) const;
|
||||
|
||||
enum TERRAIN_TYPE { BACKGROUND, FOREGROUND };
|
||||
|
||||
map_labels& labels();
|
||||
const map_labels& labels() const;
|
||||
|
||||
|
@ -865,7 +863,7 @@ protected:
|
|||
* Hook for actions to take right after draw() renders the drawing buffer.
|
||||
* No action here by default.
|
||||
*/
|
||||
DEPRECATED() virtual void post_commit()
|
||||
DEPRECATED("") virtual void post_commit()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -893,15 +891,17 @@ protected:
|
|||
void draw_minimap();
|
||||
|
||||
private:
|
||||
enum TERRAIN_TYPE { FOREGROUND, BACKGROUND };
|
||||
|
||||
/** Draws the visible map hex terrains. Used by @ref draw_gamemap. */
|
||||
void draw_visible_hexes(const rect_of_hexes& visible_hexes, TERRAIN_TYPE terrain_type);
|
||||
void draw_visible_hexes(const rect_of_hexes& visible_hexes, TERRAIN_TYPE layer);
|
||||
|
||||
/** Draws the gamemap itself and its various components, such as units, items, fog/shroud, etc. */
|
||||
void draw_gamemap();
|
||||
|
||||
protected:
|
||||
/** Draws a single gamemap location. */
|
||||
DEPRECATED() virtual void draw_hex(const map_location& /*loc*/)
|
||||
DEPRECATED("") virtual void draw_hex(const map_location& /*loc*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -984,10 +984,6 @@ protected:
|
|||
*/
|
||||
virtual const SDL_Rect& get_clip_rect();
|
||||
|
||||
/** Gets all the associated terrain textures for a specific hex. */
|
||||
std::vector<texture> get_terrain_images(
|
||||
const map_location& loc, const std::string& timeid, image::TYPE type, TERRAIN_TYPE terrain_type);
|
||||
|
||||
/** Gets the appropriate fog or shroud images for a specific hex. */
|
||||
std::vector<texture> get_fog_shroud_images(const map_location& loc, image::TYPE image_type);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue