Browse Source

optimization

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
08d7346d5b

+ 4
- 1
CMakeLists.txt View File

@@ -28,7 +28,10 @@ if(CMAKE_BUILD_TYPE STREQUAL Sanitize OR CMAKE_BUILD_TYPE STREQUAL "")
add_link_options(-fsanitize=address -fsanitize=undefined)
elseif(CMAKE_BUILD_TYPE STREQUAL Debug)
message(STATUS "Build mode: Debug")
add_compile_options(-g -O0)
add_compile_options(-g -Og)
elseif(CMAKE_BUILD_TYPE STREQUAL DebugRelease)
message(STATUS "Build mode: DebugRelease")
add_compile_options(-g -O3)
elseif(CMAKE_BUILD_TYPE STREQUAL Release)
message(STATUS "Build mode: Release")
add_compile_options(-O3 -flto)

+ 1
- 1
libswan/include/swan/Chunk.h View File

@@ -40,7 +40,7 @@ public:
TickAction tick(float dt);

bool isActive() { return deactivate_timer_ > 0; }
bool keepActive(); // Returns true if chunk was inactive
void keepActive();
void markModified() { is_modified_ = true; }

ChunkPos pos_;

+ 1
- 1
libswan/include/swan/WorldPlane.h View File

@@ -67,7 +67,7 @@ public:

private:
std::map<std::pair<int, int>, Chunk> chunks_;
std::set<Chunk *> active_chunks_;
std::vector<Chunk *> active_chunks_;
std::vector<std::unique_ptr<Entity>> entities_;

std::deque<Chunk *> chunk_init_list_;

+ 2
- 8
libswan/src/Chunk.cc View File

@@ -16,7 +16,7 @@ namespace Swan {
uint8_t *Chunk::renderbuf = new uint8_t[CHUNK_WIDTH * TILE_SIZE * CHUNK_HEIGHT * TILE_SIZE * 4];

Tile::ID *Chunk::getTileData() {
keepActive();
assert(isActive());
return (Tile::ID *)data_.get();
}

@@ -184,15 +184,9 @@ Chunk::TickAction Chunk::tick(float dt) {
return TickAction::NOTHING;
}

bool Chunk::keepActive() {
bool wasActive = isActive();
void Chunk::keepActive() {
deactivate_timer_ = DEACTIVATE_INTERVAL;

if (wasActive)
return false;

decompress();
return true;
}

}

+ 40
- 11
libswan/src/WorldPlane.cc View File

@@ -2,6 +2,7 @@

#include <math.h>
#include <iostream>
#include <algorithm>

#include "log.h"
#include "World.h"
@@ -68,18 +69,52 @@ bool WorldPlane::hasChunk(ChunkPos pos) {
return chunks_.find(pos) != chunks_.end();
}

// This function will be a bit weird because it's a really fucking hot function.
Chunk &WorldPlane::getChunk(ChunkPos pos) {

// This branch should be really predictable, there should basically never
// be no active chunks
if (active_chunks_.size() != 0) {

// The last chunk should be the most actively used chunk
Chunk *chunk = active_chunks_.back();
if (chunk->pos_ == pos) {
chunk->keepActive();
return *chunk;
}

// Linear search through a small array is probably faster than tree lookup.
// Loop backwards because the hottest chunks should be at the end.
for (ssize_t i = active_chunks_.size() - 2; i >= 0; --i) {
chunk = active_chunks_[i];
if (chunk->pos_ == pos) {
chunk->keepActive();

// Ensure that the hot chunk is at the end by bubbling this one up
active_chunks_[i] = active_chunks_[i + 1];
active_chunks_[i + 1] = chunk;
return *chunk;
}
}
}

// Slow path: Find a chunk in our global chunk map,
// creating a new one if necessary
auto iter = chunks_.find(pos);

// Create chunk if that turns out to be necessary
if (iter == chunks_.end()) {
iter = chunks_.emplace(pos, Chunk(pos)).first;
Chunk &chunk = iter->second;

gen_->genChunk(*this, chunk);
active_chunks_.insert(&chunk);
active_chunks_.push_back(&chunk);
chunk_init_list_.push_back(&chunk);
} else if (iter->second.keepActive()) {
active_chunks_.insert(&iter->second);

// Otherwise, tell it that it should keep itself alive a bit longer
} else {
iter->second.keepActive();
active_chunks_.push_back(&iter->second);
chunk_init_list_.push_back(&iter->second);
}

@@ -95,11 +130,6 @@ void WorldPlane::setTileID(TilePos pos, Tile::ID id) {
chunk.setTileID(rp, id, world_->getTileByID(id).image_.texture_.get());
chunk.markModified();
}

if (active_chunks_.find(&chunk) == active_chunks_.end()) {
active_chunks_.insert(&chunk);
chunk_init_list_.push_back(&chunk);
}
}

void WorldPlane::setTile(TilePos pos, const std::string &name) {
@@ -109,9 +139,6 @@ void WorldPlane::setTile(TilePos pos, const std::string &name) {
Tile::ID WorldPlane::getTileID(TilePos pos) {
Chunk &chunk = getChunk(chunkPos(pos));

if (active_chunks_.find(&chunk) == active_chunks_.end())
active_chunks_.insert(&chunk);

return chunk.getTileID(relPos(pos));
}

@@ -242,11 +269,13 @@ void WorldPlane::tick(float dt) {
info << "Compressing inactive modified chunk " << chunk->pos_;
chunk->compress();
iter = active_chunks_.erase(iter);
last = active_chunks_.end();
break;
case Chunk::TickAction::DELETE:
info << "Deleting inactive unmodified chunk " << chunk->pos_;
chunks_.erase(chunk->pos_);
iter = active_chunks_.erase(iter);
last = active_chunks_.end();
break;
case Chunk::TickAction::NOTHING:
++iter;

Loading…
Cancel
Save