proper state, handling of fans
This commit is contained in:
parent
990135105a
commit
559ff9fedc
@ -341,5 +341,7 @@ void issue_deferred_draw_commands(void);
|
|||||||
|
|
||||||
bool model_load_workers_thread(void);
|
bool model_load_workers_thread(void);
|
||||||
void finally_draw_models(void);
|
void finally_draw_models(void);
|
||||||
|
void free_model_cache(void);
|
||||||
|
void model_state_deinit(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "twn_draw_c.h"
|
#include "twn_draw_c.h"
|
||||||
#include "twn_draw.h"
|
#include "twn_draw.h"
|
||||||
#include "twn_util.h"
|
|
||||||
#include "twn_workers_c.h"
|
#include "twn_workers_c.h"
|
||||||
|
|
||||||
#define FAST_OBJ_IMPLEMENTATION
|
#define FAST_OBJ_IMPLEMENTATION
|
||||||
@ -13,7 +12,7 @@
|
|||||||
|
|
||||||
|
|
||||||
static struct ModelCacheItem {
|
static struct ModelCacheItem {
|
||||||
char const *key;
|
char *key;
|
||||||
struct ModelCacheItemValue {
|
struct ModelCacheItemValue {
|
||||||
fastObjMesh *mesh;
|
fastObjMesh *mesh;
|
||||||
} value;
|
} value;
|
||||||
@ -29,7 +28,7 @@ static struct ModelDrawCommand {
|
|||||||
|
|
||||||
/* deferred queue of model files to load from worker threads */
|
/* deferred queue of model files to load from worker threads */
|
||||||
static SDL_mutex *model_load_mutex;
|
static SDL_mutex *model_load_mutex;
|
||||||
static char **model_load_queue;
|
static char const **model_load_queue;
|
||||||
static bool model_load_initialized;
|
static bool model_load_initialized;
|
||||||
|
|
||||||
/* use streaming via callbacks to reduce memory congestion */
|
/* use streaming via callbacks to reduce memory congestion */
|
||||||
@ -69,7 +68,7 @@ static bool model_load_workers_finished(void) {
|
|||||||
/* returns false if there was nothing to do */
|
/* returns false if there was nothing to do */
|
||||||
bool model_load_workers_thread(void) {
|
bool model_load_workers_thread(void) {
|
||||||
/* attempt to grab something to work on */
|
/* attempt to grab something to work on */
|
||||||
char *load_request = NULL;
|
char const *load_request = NULL;
|
||||||
SDL_LockMutex(model_load_mutex);
|
SDL_LockMutex(model_load_mutex);
|
||||||
if (arrlenu(model_load_queue) != 0)
|
if (arrlenu(model_load_queue) != 0)
|
||||||
load_request = arrpop(model_load_queue);
|
load_request = arrpop(model_load_queue);
|
||||||
@ -107,26 +106,26 @@ void draw_model(const char *model,
|
|||||||
model_load_initialized = true;
|
model_load_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure not to reference parameter longer than duration of this function */
|
struct ModelCacheItem const *item;
|
||||||
char *model_copy = SDL_strdup(model);
|
|
||||||
model = NULL; /* trap */
|
/* if model is missing, queue it up for loading */
|
||||||
|
SDL_LockMutex(model_load_mutex);
|
||||||
|
if (!(item = shgetp_null(model_cache, model))) {
|
||||||
|
model = SDL_strdup(model);
|
||||||
|
shput(model_cache, model, (struct ModelCacheItemValue){0});
|
||||||
|
arrpush(model_load_queue, model);
|
||||||
|
SDL_SemPost(workers_job_semaphore);
|
||||||
|
} else
|
||||||
|
model = item->key;
|
||||||
|
SDL_UnlockMutex(model_load_mutex);
|
||||||
|
|
||||||
struct ModelDrawCommand const command = {
|
struct ModelDrawCommand const command = {
|
||||||
.model = model_copy,
|
.model = (char *)model,
|
||||||
.position = position,
|
.position = position,
|
||||||
.rotation = rotation,
|
.rotation = rotation,
|
||||||
.scale = scale
|
.scale = scale
|
||||||
};
|
};
|
||||||
arrpush(model_draw_commands, command);
|
arrpush(model_draw_commands, command);
|
||||||
|
|
||||||
/* if model is missing, queue it up for loading */
|
|
||||||
SDL_LockMutex(model_load_mutex);
|
|
||||||
if (!(shgetp_null(model_cache, model_copy))) {
|
|
||||||
shput(model_cache, model_copy, (struct ModelCacheItemValue){0});
|
|
||||||
arrpush(model_load_queue, model_copy);
|
|
||||||
SDL_SemPost(workers_job_semaphore);
|
|
||||||
}
|
|
||||||
SDL_UnlockMutex(model_load_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -147,20 +146,57 @@ void finally_draw_models(void) {
|
|||||||
// fastObjTexture const *const texture = &mesh->textures[group->face_offset + f];
|
// fastObjTexture const *const texture = &mesh->textures[group->face_offset + f];
|
||||||
// log_info("material: %s", material->name);
|
// log_info("material: %s", material->name);
|
||||||
/* TODO: support arbitrary fans */
|
/* TODO: support arbitrary fans */
|
||||||
SDL_assert(vertices == 4);
|
unsigned int const material_index = mesh->face_materials[group->index_offset + f];
|
||||||
fastObjIndex i0 = mesh->indices[group->index_offset + idx + 0];
|
fastObjMaterial const *const material = mesh->materials ? &mesh->materials[material_index] : NULL;
|
||||||
fastObjIndex i1 = mesh->indices[group->index_offset + idx + 1];
|
if (vertices == 4) {
|
||||||
fastObjIndex i2 = mesh->indices[group->index_offset + idx + 2];
|
fastObjIndex const i0 = mesh->indices[group->index_offset + idx + 0];
|
||||||
fastObjIndex i3 = mesh->indices[group->index_offset + idx + 3];
|
fastObjIndex const i1 = mesh->indices[group->index_offset + idx + 1];
|
||||||
draw_quad(
|
fastObjIndex const i2 = mesh->indices[group->index_offset + idx + 2];
|
||||||
"asd",
|
fastObjIndex const i3 = mesh->indices[group->index_offset + idx + 3];
|
||||||
(Vec3) { mesh->positions[3 * i0.p + 0], mesh->positions[3 * i0.p + 1], mesh->positions[3 * i0.p + 2] },
|
draw_quad(
|
||||||
(Vec3) { mesh->positions[3 * i1.p + 0], mesh->positions[3 * i1.p + 1], mesh->positions[3 * i1.p + 2] },
|
material ? mesh->textures[material->map_Kd].name : NULL,
|
||||||
(Vec3) { mesh->positions[3 * i2.p + 0], mesh->positions[3 * i2.p + 1], mesh->positions[3 * i2.p + 2] },
|
(Vec3) { mesh->positions[3 * i0.p + 0] * command->scale.x, mesh->positions[3 * i0.p + 1] * command->scale.y, mesh->positions[3 * i0.p + 2] * command->scale.z },
|
||||||
(Vec3) { mesh->positions[3 * i3.p + 0], mesh->positions[3 * i3.p + 1], mesh->positions[3 * i3.p + 2] },
|
(Vec3) { mesh->positions[3 * i1.p + 0] * command->scale.x, mesh->positions[3 * i1.p + 1] * command->scale.y, mesh->positions[3 * i1.p + 2] * command->scale.z },
|
||||||
(Rect) { .w = 64, .h = 64 },
|
(Vec3) { mesh->positions[3 * i2.p + 0] * command->scale.x, mesh->positions[3 * i2.p + 1] * command->scale.y, mesh->positions[3 * i2.p + 2] * command->scale.z },
|
||||||
(Color) { 255, 255, 255, 255 }
|
(Vec3) { mesh->positions[3 * i3.p + 0] * command->scale.x, mesh->positions[3 * i3.p + 1] * command->scale.y, mesh->positions[3 * i3.p + 2] * command->scale.z },
|
||||||
);
|
(Rect) { .w = 64, .h = 64 },
|
||||||
|
(Color) { 255, 255, 255, 255 }
|
||||||
|
);
|
||||||
|
} else if (vertices == 3) {
|
||||||
|
fastObjIndex const i0 = mesh->indices[group->index_offset + idx + 0];
|
||||||
|
fastObjIndex const i1 = mesh->indices[group->index_offset + idx + 1];
|
||||||
|
fastObjIndex const i2 = mesh->indices[group->index_offset + idx + 2];
|
||||||
|
draw_triangle(
|
||||||
|
material ? mesh->textures[material->map_Kd].name : NULL,
|
||||||
|
(Vec3) { mesh->positions[3 * i0.p + 0] * command->scale.x, mesh->positions[3 * i0.p + 1] * command->scale.y, mesh->positions[3 * i0.p + 2] * command->scale.z },
|
||||||
|
(Vec3) { mesh->positions[3 * i1.p + 0] * command->scale.x, mesh->positions[3 * i1.p + 1] * command->scale.y, mesh->positions[3 * i1.p + 2] * command->scale.z },
|
||||||
|
(Vec3) { mesh->positions[3 * i2.p + 0] * command->scale.x, mesh->positions[3 * i2.p + 1] * command->scale.y, mesh->positions[3 * i2.p + 2] * command->scale.z },
|
||||||
|
(Vec2) {0,0},
|
||||||
|
(Vec2) {0,0},
|
||||||
|
(Vec2) {0,0},
|
||||||
|
(Color){255, 255, 255, 255},
|
||||||
|
(Color){255, 255, 255, 255},
|
||||||
|
(Color){255, 255, 255, 255}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
fastObjIndex const i0 = mesh->indices[group->index_offset + idx];
|
||||||
|
for (unsigned int z = 0; z < vertices - 2; ++z) {
|
||||||
|
fastObjIndex const i1 = mesh->indices[group->index_offset + idx + 1 + z];
|
||||||
|
fastObjIndex const i2 = mesh->indices[group->index_offset + idx + 2 + z];
|
||||||
|
draw_triangle(
|
||||||
|
material ? mesh->textures[material->map_Kd].name : NULL,
|
||||||
|
(Vec3) { mesh->positions[3 * i0.p + 0] * command->scale.x, mesh->positions[3 * i0.p + 1] * command->scale.y, mesh->positions[3 * i0.p + 2] * command->scale.z },
|
||||||
|
(Vec3) { mesh->positions[3 * i1.p + 0] * command->scale.x, mesh->positions[3 * i1.p + 1] * command->scale.y, mesh->positions[3 * i1.p + 2] * command->scale.z },
|
||||||
|
(Vec3) { mesh->positions[3 * i2.p + 0] * command->scale.x, mesh->positions[3 * i2.p + 1] * command->scale.y, mesh->positions[3 * i2.p + 2] * command->scale.z },
|
||||||
|
(Vec2) {0,0},
|
||||||
|
(Vec2) {0,0},
|
||||||
|
(Vec2) {0,0},
|
||||||
|
(Color){255, 255, 255, 255},
|
||||||
|
(Color){255, 255, 255, 255},
|
||||||
|
(Color){255, 255, 255, 255}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
idx += vertices;
|
idx += vertices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,3 +204,27 @@ void finally_draw_models(void) {
|
|||||||
|
|
||||||
arrsetlen(model_draw_commands, 0);
|
arrsetlen(model_draw_commands, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* drop model caches */
|
||||||
|
void free_model_cache(void) {
|
||||||
|
while (!model_load_workers_finished()) {
|
||||||
|
(void)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < shlenu(model_cache); ++i) {
|
||||||
|
fast_obj_destroy(model_cache[i].value.mesh);
|
||||||
|
SDL_free(model_cache[i].key);
|
||||||
|
}
|
||||||
|
|
||||||
|
shfree(model_cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void model_state_deinit(void) {
|
||||||
|
SDL_assert(model_load_initialized);
|
||||||
|
free_model_cache();
|
||||||
|
arrfree(model_load_queue);
|
||||||
|
SDL_DestroyMutex(model_load_mutex);
|
||||||
|
model_load_initialized = false;
|
||||||
|
}
|
||||||
|
@ -726,6 +726,7 @@ static void clean_up(void) {
|
|||||||
toml_free(ctx.config_table);
|
toml_free(ctx.config_table);
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
workers_deinit();
|
workers_deinit();
|
||||||
|
model_state_deinit();
|
||||||
SDL_free(ctx.base_dir);
|
SDL_free(ctx.base_dir);
|
||||||
SDL_free(ctx.title);
|
SDL_free(ctx.title);
|
||||||
SDL_GL_DeleteContext(ctx.gl_context);
|
SDL_GL_DeleteContext(ctx.gl_context);
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
SDL_sem *workers_job_semaphore;
|
SDL_sem *workers_job_semaphore;
|
||||||
|
|
||||||
static SDL_Thread *workers_pool[MAX_WORKERS];
|
|
||||||
static size_t workers_pool_size;
|
static size_t workers_pool_size;
|
||||||
static SDL_mutex *workers_mutex;
|
static SDL_mutex *workers_mutex;
|
||||||
static bool workers_should_exit;
|
static bool workers_should_exit;
|
||||||
|
static SDL_sem *workers_exit_semaphore; /* should come to count of `workers_pool_size` */
|
||||||
|
|
||||||
/* logic is such that when job is posted, worker threads attempt to grab it from any possible entry point */
|
/* logic is such that when job is posted, worker threads attempt to grab it from any possible entry point */
|
||||||
/* if it did something, which is signaled by `true` return, go back to waiting on semaphore, so that it's decremented properly */
|
/* if it did something, which is signaled by `true` return, go back to waiting on semaphore, so that it's decremented properly */
|
||||||
@ -31,6 +31,9 @@ static int worker_thread(void *udata) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* let the main thread collect it */
|
||||||
|
SDL_SemPost(workers_exit_semaphore);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +55,7 @@ bool workers_init(size_t worker_count) {
|
|||||||
|
|
||||||
workers_pool_size = worker_count;
|
workers_pool_size = worker_count;
|
||||||
workers_job_semaphore = SDL_CreateSemaphore(0);
|
workers_job_semaphore = SDL_CreateSemaphore(0);
|
||||||
|
workers_exit_semaphore = SDL_CreateSemaphore(0);
|
||||||
workers_mutex = SDL_CreateMutex();
|
workers_mutex = SDL_CreateMutex();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -62,8 +66,12 @@ void workers_deinit(void) {
|
|||||||
workers_should_exit = true;
|
workers_should_exit = true;
|
||||||
SDL_UnlockMutex(workers_mutex);
|
SDL_UnlockMutex(workers_mutex);
|
||||||
|
|
||||||
/* TODO: that's not correct */
|
for (size_t i = 0; i < workers_pool_size; ++i) {
|
||||||
|
SDL_SemWait(workers_exit_semaphore);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_DestroyMutex(workers_mutex);
|
SDL_DestroyMutex(workers_mutex);
|
||||||
SDL_DestroySemaphore(workers_job_semaphore);
|
SDL_DestroySemaphore(workers_job_semaphore);
|
||||||
|
SDL_DestroySemaphore(workers_exit_semaphore);
|
||||||
workers_pool_size = 0;
|
workers_pool_size = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user