Added a cap to how many finished tasks can be completed based on time.
This commit is contained in:
parent
caeda8c680
commit
ef079a2c55
@ -69,7 +69,4 @@ void GameInstance::draw() {
|
|||||||
for (auto &chunk : *world->getMeshChunks()) {
|
for (auto &chunk : *world->getMeshChunks()) {
|
||||||
renderer->draw(chunk.second);
|
renderer->draw(chunk.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GameInstance::~GameInstance() = default;
|
|
@ -23,8 +23,6 @@ public:
|
|||||||
void update(GLfloat deltaTime);
|
void update(GLfloat deltaTime);
|
||||||
|
|
||||||
void draw();
|
void draw();
|
||||||
|
|
||||||
~GameInstance();
|
|
||||||
public:
|
public:
|
||||||
//The renderer contains the camera, window, and draw methods.
|
//The renderer contains the camera, window, and draw methods.
|
||||||
Renderer* renderer;
|
Renderer* renderer;
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
World::World(BlockAtlas *atlas) {
|
World::World(BlockAtlas *atlas) {
|
||||||
blockAtlas = atlas;
|
blockAtlas = atlas;
|
||||||
|
|
||||||
for (int i = 0; i < CHUNK_THREADS; i++) {
|
for (int i = 0; i < GEN_THREADS; i++) {
|
||||||
chunkThreads.push_back(new ChunkThreadDef());
|
genThreads.push_back(new ChunkThreadDef());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MESH_THREADS; i++) {
|
for (int i = 0; i < MESH_THREADS; i++) {
|
||||||
@ -23,58 +23,63 @@ World::World(BlockAtlas *atlas) {
|
|||||||
|
|
||||||
void World::genNewChunk(glm::vec3 pos) {
|
void World::genNewChunk(glm::vec3 pos) {
|
||||||
if (!blockChunks.count(pos)) {
|
if (!blockChunks.count(pos)) {
|
||||||
chunkGenQueue.insert(pos);
|
pendingGen.insert(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::commitChunk(glm::vec3 pos, BlockChunk *c) {
|
void World::commitChunk(glm::vec3 pos, BlockChunk *c) {
|
||||||
blockChunks.insert(std::pair<glm::vec3, BlockChunk*>(pos, c));
|
blockChunks.insert(std::pair<glm::vec3, BlockChunk*>(pos, c));
|
||||||
if (!c->isEmpty()) {
|
if (!c->isEmpty()) {
|
||||||
meshGenQueue.insert(pos);
|
pendingMesh.insert(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::update() {
|
void World::update() {
|
||||||
|
Timer world("World update");
|
||||||
|
|
||||||
//Create / Finalize BlockChunks
|
//Create / Finalize BlockChunks
|
||||||
handleChunkGenQueue();
|
handleChunkGenQueue();
|
||||||
|
|
||||||
//Create / Finalize MeshChunks
|
//Create / Finalize MeshChunks
|
||||||
handleMeshGenQueue();
|
handleMeshGenQueue();
|
||||||
|
|
||||||
|
// world.printElapsedMs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::handleChunkGenQueue() {
|
void World::handleChunkGenQueue() {
|
||||||
std::vector<ChunkThreadData*> finishedThreads;
|
for (auto threadDef : genThreads) {
|
||||||
|
|
||||||
for (auto threadDef : chunkThreads) {
|
|
||||||
std::unique_lock<std::mutex> lock(threadDef->lock, std::defer_lock);
|
std::unique_lock<std::mutex> lock(threadDef->lock, std::defer_lock);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
for (auto iter = threadDef->tasks.begin(); iter != threadDef->tasks.end();) {
|
for (auto iter = threadDef->tasks.begin(); iter != threadDef->tasks.end();) {
|
||||||
|
if (finishedGen.size() > GEN_FINISHED_SIZE) break;
|
||||||
auto threadData = *iter;
|
auto threadData = *iter;
|
||||||
|
|
||||||
if (threadData->done) {
|
if (threadData->done) {
|
||||||
finishedThreads.push_back(threadData);
|
finishedGen.push_back(threadData);
|
||||||
iter = threadDef->tasks.erase(iter);
|
iter = threadDef->tasks.erase(iter);
|
||||||
} else iter++;
|
} else iter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!chunkGenQueue.empty() && threadDef->tasks.size() < CHUNK_THREAD_QUEUE) {
|
while (!pendingGen.empty() && threadDef->tasks.size() < GEN_QUEUE_SIZE) {
|
||||||
auto it = chunkGenQueue.begin();
|
auto it = pendingGen.begin();
|
||||||
chunkGenQueue.erase(it);
|
pendingGen.erase(it);
|
||||||
glm::vec3 pos = *it;
|
glm::vec3 pos = *it;
|
||||||
|
|
||||||
threadDef->tasks.push_back(new ChunkThreadData(*it, blockAtlas));
|
threadDef->tasks.push_back(new ChunkThreadData(*it, blockAtlas));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::cout << "Finished Chunks: " << finishedThreads.size() << std::endl;
|
Timer t("Chunk Initialization");
|
||||||
|
for (auto iter = finishedGen.begin(); iter != finishedGen.end(); ) {
|
||||||
|
if (t.elapsedNs() > 4000000) break;
|
||||||
|
|
||||||
for (auto iter = finishedThreads.begin(); iter != finishedThreads.end(); ) {
|
|
||||||
ChunkThreadData* threadData = *iter;
|
ChunkThreadData* threadData = *iter;
|
||||||
|
|
||||||
commitChunk(threadData->pos, threadData->chunk);
|
commitChunk(threadData->pos, threadData->chunk);
|
||||||
iter = finishedThreads.erase(iter);
|
iter = finishedGen.erase(iter);
|
||||||
delete threadData;
|
delete threadData;
|
||||||
}
|
}
|
||||||
|
// t.printElapsedMs();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Function that runs on each ChunkGenThread in the chunk generation threadpool.
|
//Function that runs on each ChunkGenThread in the chunk generation threadpool.
|
||||||
@ -138,32 +143,33 @@ void World::chunkGenThread(World::ChunkThreadDef* threadDef) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void World::handleMeshGenQueue() {
|
void World::handleMeshGenQueue() {
|
||||||
std::vector<MeshThreadData*> finishedThreads;
|
|
||||||
|
|
||||||
for (auto threadDef : meshThreads) {
|
for (auto threadDef : meshThreads) {
|
||||||
std::unique_lock<std::mutex> lock(threadDef->lock, std::defer_lock);
|
std::unique_lock<std::mutex> lock(threadDef->lock, std::defer_lock);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
for (auto iter = threadDef->tasks.begin(); iter != threadDef->tasks.end();) {
|
for (auto iter = threadDef->tasks.begin(); iter != threadDef->tasks.end();) {
|
||||||
|
if (finishedMesh.size() > MESH_FINISHED_SIZE) break;
|
||||||
|
|
||||||
auto threadData = *iter;
|
auto threadData = *iter;
|
||||||
|
|
||||||
if (threadData->done) {
|
if (threadData->done) {
|
||||||
finishedThreads.push_back(threadData);
|
finishedMesh.push_back(threadData);
|
||||||
iter = threadDef->tasks.erase(iter);
|
iter = threadDef->tasks.erase(iter);
|
||||||
} else iter++;
|
} else iter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!meshGenQueue.empty() && threadDef->tasks.size() < MESH_THREAD_QUEUE) {
|
while (!pendingMesh.empty() && threadDef->tasks.size() < MESH_QUEUE_SIZE) {
|
||||||
auto it = meshGenQueue.begin();
|
auto it = pendingMesh.begin();
|
||||||
meshGenQueue.erase(it);
|
pendingMesh.erase(it);
|
||||||
glm::vec3 pos = *it;
|
glm::vec3 pos = *it;
|
||||||
|
|
||||||
threadDef->tasks.push_back(new MeshThreadData(*it, blockChunks.at(pos), blockAtlas));
|
threadDef->tasks.push_back(new MeshThreadData(*it, blockChunks.at(pos), blockAtlas));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Finished Meshes: " << finishedThreads.size() << std::endl;
|
Timer t("Mesh Initialization");
|
||||||
|
for (auto iter = finishedMesh.begin(); iter != finishedMesh.end(); ) {
|
||||||
|
if (t.elapsedNs() > 4000000) break;
|
||||||
|
|
||||||
for (auto iter = finishedThreads.begin(); iter != finishedThreads.end(); ) {
|
|
||||||
MeshThreadData* threadData = *iter;
|
MeshThreadData* threadData = *iter;
|
||||||
|
|
||||||
if (!threadData->vertices->empty()) {
|
if (!threadData->vertices->empty()) {
|
||||||
@ -175,9 +181,10 @@ void World::handleMeshGenQueue() {
|
|||||||
meshChunks.insert(std::pair<glm::vec3, MeshChunk *>(threadData->pos, meshChunk));
|
meshChunks.insert(std::pair<glm::vec3, MeshChunk *>(threadData->pos, meshChunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
iter = finishedThreads.erase(iter);
|
iter = finishedMesh.erase(iter);
|
||||||
delete threadData;
|
delete threadData;
|
||||||
}
|
}
|
||||||
|
// t.printElapsedMs();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Function that runs on each MeshGenThread in the mesh generation threadpool.
|
//Function that runs on each MeshGenThread in the mesh generation threadpool.
|
||||||
@ -231,7 +238,7 @@ World::ChunkThreadData::ChunkThreadData(glm::vec3 pos, BlockAtlas *atlas) {
|
|||||||
World::ChunkThreadDef::ChunkThreadDef() {
|
World::ChunkThreadDef::ChunkThreadDef() {
|
||||||
thread = new std::thread(chunkGenThread, this);
|
thread = new std::thread(chunkGenThread, this);
|
||||||
|
|
||||||
sched_param sch_params;
|
sched_param sch_params{};
|
||||||
sch_params.sched_priority = 1;
|
sch_params.sched_priority = 1;
|
||||||
pthread_setschedparam(thread->native_handle(), SCHED_RR, &sch_params);
|
pthread_setschedparam(thread->native_handle(), SCHED_RR, &sch_params);
|
||||||
|
|
||||||
@ -259,7 +266,7 @@ World::MeshThreadData::~MeshThreadData() {
|
|||||||
World::MeshThreadDef::MeshThreadDef() {
|
World::MeshThreadDef::MeshThreadDef() {
|
||||||
thread = new std::thread(meshGenThread, this);
|
thread = new std::thread(meshGenThread, this);
|
||||||
|
|
||||||
sched_param sch_params;
|
sched_param sch_params{};
|
||||||
sch_params.sched_priority = 1;
|
sch_params.sched_priority = 1;
|
||||||
pthread_setschedparam(thread->native_handle(), SCHED_RR, &sch_params);
|
pthread_setschedparam(thread->native_handle(), SCHED_RR, &sch_params);
|
||||||
|
|
||||||
|
@ -52,15 +52,21 @@ private:
|
|||||||
void handleChunkGenQueue();
|
void handleChunkGenQueue();
|
||||||
void handleMeshGenQueue();
|
void handleMeshGenQueue();
|
||||||
|
|
||||||
const int CHUNK_THREADS = 8;
|
const int GEN_THREADS = 8;
|
||||||
const int CHUNK_THREAD_QUEUE = 16;
|
const int GEN_QUEUE_SIZE = 16;
|
||||||
std::unordered_set<glm::vec3, vec3cmp> chunkGenQueue;
|
const int GEN_FINISHED_SIZE = GEN_THREADS * GEN_QUEUE_SIZE;
|
||||||
std::vector<ChunkThreadDef*> chunkThreads;
|
|
||||||
|
std::unordered_set<glm::vec3, vec3cmp> pendingGen;
|
||||||
|
std::vector<ChunkThreadDef*> genThreads;
|
||||||
|
std::vector<ChunkThreadData*> finishedGen;
|
||||||
|
|
||||||
const int MESH_THREADS = 8;
|
const int MESH_THREADS = 8;
|
||||||
const int MESH_THREAD_QUEUE = 16;
|
const int MESH_QUEUE_SIZE = 16;
|
||||||
std::unordered_set<glm::vec3, vec3cmp> meshGenQueue;
|
const int MESH_FINISHED_SIZE = GEN_THREADS * GEN_QUEUE_SIZE;
|
||||||
|
|
||||||
|
std::unordered_set<glm::vec3, vec3cmp> pendingMesh;
|
||||||
std::vector<MeshThreadDef*> meshThreads;
|
std::vector<MeshThreadDef*> meshThreads;
|
||||||
|
std::vector<MeshThreadData*> finishedMesh;
|
||||||
|
|
||||||
BlockAtlas* blockAtlas;
|
BlockAtlas* blockAtlas;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user