aboutsummaryrefslogtreecommitdiff
path: root/src/scene/scene_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scene/scene_memory.c')
-rw-r--r--src/scene/scene_memory.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/scene/scene_memory.c b/src/scene/scene_memory.c
new file mode 100644
index 0000000..3a01325
--- /dev/null
+++ b/src/scene/scene_memory.c
@@ -0,0 +1,178 @@
1#include "scene_memory.h"
2
3#include <gfx/sizes.h>
4
5#include "animation_impl.h"
6#include "camera_impl.h"
7#include "llr/light_impl.h"
8#include "llr/material_impl.h"
9#include "llr/mesh_impl.h"
10#include "model_impl.h"
11#include "node_impl.h"
12#include "object_impl.h"
13#include "scene_impl.h"
14
15#include <log/log.h>
16#include <mempool.h>
17
18DEF_MEMPOOL(anima_pool, Anima, GFX_MAX_NUM_ANIMAS)
19DEF_MEMPOOL(animation_pool, Animation, GFX_MAX_NUM_ANIMATIONS)
20DEF_MEMPOOL(camera_pool, SceneCamera, GFX_MAX_NUM_CAMERAS)
21DEF_MEMPOOL(light_pool, Light, GFX_MAX_NUM_LIGHTS)
22DEF_MEMPOOL(material_pool, Material, GFX_MAX_NUM_MATERIALS)
23DEF_MEMPOOL(mesh_pool, Mesh, GFX_MAX_NUM_MESHES)
24DEF_MEMPOOL(mesh_link_pool, MeshLink, GFX_MAX_NUM_MESH_LINKS)
25DEF_MEMPOOL(model_pool, Model, GFX_MAX_NUM_MODELS)
26DEF_MEMPOOL(node_pool, SceneNode, GFX_MAX_NUM_NODES)
27DEF_MEMPOOL(object_pool, SceneObject, GFX_MAX_NUM_OBJECTS)
28DEF_MEMPOOL(scene_pool, Scene, GFX_MAX_NUM_SCENES)
29DEF_MEMPOOL(skeleton_pool, Skeleton, GFX_MAX_NUM_SKELETONS)
30
31/// Scene memory.
32///
33/// Holds memory pools for every type of scene object.
34typedef struct SceneMemory {
35 anima_pool animas;
36 animation_pool animations;
37 camera_pool cameras;
38 light_pool lights;
39 material_pool materials;
40 mesh_pool meshs; // Purposeful typo to make the PLURAL() macro work.
41 mesh_link_pool mesh_links;
42 model_pool models;
43 node_pool nodes;
44 object_pool objects;
45 scene_pool scenes;
46 skeleton_pool skeletons;
47} SceneMemory;
48
49static SceneMemory mem;
50
51#define ALLOC_DUMMY(POOL) \
52 { \
53 const void* object = mempool_alloc(POOL); \
54 (void)object; /* Silence warning in release builds. */ \
55 assert(mempool_get_block_index(POOL, object) == 0); \
56 }
57
58#define PLURAL(name) name##s
59#define MEM_FIELD(name) mem.PLURAL(name)
60
61void scene_mem_init() {
62 mempool_make(&mem.animas);
63 mempool_make(&mem.animations);
64 mempool_make(&mem.cameras);
65 mempool_make(&mem.lights);
66 mempool_make(&mem.materials);
67 mempool_make(&mem.meshs);
68 mempool_make(&mem.mesh_links);
69 mempool_make(&mem.models);
70 mempool_make(&mem.nodes);
71 mempool_make(&mem.objects);
72 mempool_make(&mem.scenes);
73 mempool_make(&mem.skeletons);
74
75 // Allocate dummy objects at index 0 to guarantee that no objects allocated by
76 // the caller map to index 0. This allows 0 to be used as a sentinel.
77 ALLOC_DUMMY(&mem.animas);
78 ALLOC_DUMMY(&mem.animations);
79 ALLOC_DUMMY(&mem.cameras);
80 ALLOC_DUMMY(&mem.lights);
81 ALLOC_DUMMY(&mem.materials);
82 ALLOC_DUMMY(&mem.meshs);
83 ALLOC_DUMMY(&mem.mesh_links);
84 ALLOC_DUMMY(&mem.models);
85 ALLOC_DUMMY(&mem.nodes);
86 ALLOC_DUMMY(&mem.objects);
87 ALLOC_DUMMY(&mem.scenes);
88 ALLOC_DUMMY(&mem.skeletons);
89}
90
91void scene_mem_destroy() {
92 // NOTE: the dummy objects are not constructed, so the destruction code below
93 // always skips index 0. (I don't really like the conditional inside the loop,
94 // but this gets the job done without having to specialize the loop macro.)
95#define DESTROY(NAME) \
96 mempool_foreach(&MEM_FIELD(NAME), obj, { \
97 if (i > 0) { \
98 gfx_destroy_##NAME(&obj); \
99 } \
100 })
101
102 // Print memory diagnostics.
103#define PRINT_POOL(POOL_NAME, POOL) \
104 { \
105 const size_t capacity = mempool_capacity(POOL); \
106 const size_t size = mempool_size(POOL); \
107 const size_t block_size_bytes = mempool_block_size_bytes(POOL); \
108 const size_t size_bytes = size * block_size_bytes; \
109 const size_t capacity_bytes = capacity * block_size_bytes; \
110 LOGI( \
111 "%s pool: %lu/%lu (%lu/%lu bytes)", POOL_NAME, size, capacity, \
112 size_bytes, capacity_bytes); \
113 }
114
115 LOGI("Pool diagnostics:");
116 PRINT_POOL("Animas", &mem.animas);
117 PRINT_POOL("Animations", &mem.animations);
118 PRINT_POOL("Cameras", &mem.cameras);
119 PRINT_POOL("Lights", &mem.lights);
120 PRINT_POOL("Materials", &mem.materials);
121 PRINT_POOL("Meshes", &mem.meshs);
122 PRINT_POOL("Mesh links", &mem.mesh_links);
123 PRINT_POOL("Models", &mem.models);
124 PRINT_POOL("Nodes", &mem.nodes);
125 PRINT_POOL("Objects", &mem.objects);
126 PRINT_POOL("Scenes", &mem.scenes);
127 PRINT_POOL("Skeletons", &mem.skeletons);
128
129 // Models contain scene elements. Destruction is handled by the remainder of
130 // scene destructionb elow.
131 //
132 // First destroy the scenes. This will recursively destroy the scene's nodes
133 // and their objects and avoid a double-free when we then destroy any stray
134 // scene elements.
135 DESTROY(scene);
136 // Then delete stray nodes. This will delete their children nodes and
137 // resource.
138 DESTROY(node);
139 // Destroy remaining scene elements.
140 DESTROY(anima);
141 // Animations are owned by animas and do not have a destructor.
142 DESTROY(camera);
143 DESTROY(light);
144 DESTROY(material);
145 DESTROY(mesh);
146 // Mesh links don't have a destructor.
147 DESTROY(object);
148 // Skeletons are owned by animas and do not have a destructor.
149}
150
151#define DEF_MEMORY(NAME, TYPE) \
152 /* xyz* mem_alloc_xyz(); */ \
153 TYPE* mem_alloc_##NAME() { return mempool_alloc(&MEM_FIELD(NAME)); } \
154 /* void mem_free_xyz(xyz**); */ \
155 void mem_free_##NAME(TYPE** obj) { mempool_free(&MEM_FIELD(NAME), obj); } \
156 /* xyz* mem_get_xyz(xyz_idx); */ \
157 TYPE* mem_get_##NAME(NAMED_INDEX(NAME) index) { \
158 assert(index.val != 0); /* 0 is the dummy allocation. */ \
159 return mempool_get_block(&MEM_FIELD(NAME), index.val); \
160 } \
161 /* xyz_idx mem_get_xyz_index(const xyz*); */ \
162 NAMED_INDEX(NAME) mem_get_##NAME##_index(const TYPE* obj) { \
163 return (NAMED_INDEX(NAME)){ \
164 .val = mempool_get_block_index(&MEM_FIELD(NAME), obj)}; \
165 }
166
167DEF_MEMORY(anima, Anima)
168DEF_MEMORY(animation, Animation)
169DEF_MEMORY(camera, SceneCamera)
170DEF_MEMORY(light, Light)
171DEF_MEMORY(material, Material)
172DEF_MEMORY(mesh, Mesh)
173DEF_MEMORY(mesh_link, MeshLink)
174DEF_MEMORY(model, Model)
175DEF_MEMORY(node, SceneNode)
176DEF_MEMORY(object, SceneObject)
177DEF_MEMORY(scene, Scene)
178DEF_MEMORY(skeleton, Skeleton)