diff options
Diffstat (limited to 'src/scene')
-rw-r--r-- | src/scene/scene_graph.h | 42 | ||||
-rw-r--r-- | src/scene/scene_memory.c | 59 |
2 files changed, 68 insertions, 33 deletions
diff --git a/src/scene/scene_graph.h b/src/scene/scene_graph.h index a26f828..0b1f7d0 100644 --- a/src/scene/scene_graph.h +++ b/src/scene/scene_graph.h | |||
@@ -6,35 +6,41 @@ | |||
6 | // NOTE: SceneMemory guarantees that index 0 can be regarded as an invalid | 6 | // NOTE: SceneMemory guarantees that index 0 can be regarded as an invalid |
7 | // index. | 7 | // index. |
8 | 8 | ||
9 | #define MEM_GET(INDEX) \ | 9 | #define MEM_GET(INDEX) \ |
10 | _Generic((INDEX), camera_idx \ | 10 | _Generic( \ |
11 | : mem_get_camera, material_idx \ | 11 | (INDEX), \ |
12 | : mem_get_material, mesh_idx \ | 12 | camera_idx: mem_get_camera, \ |
13 | : mem_get_mesh, mesh_link_idx \ | 13 | material_idx: mem_get_material, \ |
14 | : mem_get_mesh_link, node_idx \ | 14 | mesh_idx: mem_get_mesh, \ |
15 | : mem_get_node, object_idx \ | 15 | mesh_link_idx: mem_get_mesh_link, \ |
16 | : mem_get_object, scene_idx \ | 16 | node_idx: mem_get_node, \ |
17 | : mem_get_scene)(INDEX) | 17 | object_idx: mem_get_object, \ |
18 | scene_idx: mem_get_scene)(INDEX) | ||
18 | 19 | ||
19 | #define MEM_GET_INDEX(ITEM) \ | 20 | #define MEM_GET_INDEX(ITEM) \ |
20 | _Generic((ITEM), SceneCamera * \ | 21 | _Generic( \ |
21 | : mem_get_camera_index, Material * \ | 22 | (ITEM), \ |
22 | : mem_get_material_index, Mesh * \ | 23 | SceneCamera *: mem_get_camera_index, \ |
23 | : mem_get_mesh_index, MeshLink * \ | 24 | Material *: mem_get_material_index, \ |
24 | : mem_get_mesh_link_index, SceneNode * \ | 25 | Mesh *: mem_get_mesh_index, \ |
25 | : mem_get_node_index, SceneObject * \ | 26 | MeshLink *: mem_get_mesh_link_index, \ |
26 | : mem_get_object_index, Scene * \ | 27 | SceneNode *: mem_get_node_index, \ |
27 | : mem_get_scene_index)(ITEM) | 28 | SceneObject *: mem_get_object_index, \ |
29 | Scene *: mem_get_scene_index)(ITEM) | ||
28 | 30 | ||
29 | /// Assert the list node invariant. | 31 | /// Assert the list node invariant. |
30 | /// | 32 | /// |
31 | /// - A node does not point to itself. | 33 | /// - A node does not point to itself. |
34 | #if NDEBUG | ||
35 | #define ASSERT_LIST_NODE_INVARIANT(ITEM) | ||
36 | #else | ||
32 | #define ASSERT_LIST_NODE_INVARIANT(ITEM) \ | 37 | #define ASSERT_LIST_NODE_INVARIANT(ITEM) \ |
33 | { \ | 38 | { \ |
34 | const gfx_idx item_idx = MEM_GET_INDEX(ITEM).val; \ | 39 | const gfx_idx item_idx = MEM_GET_INDEX(ITEM).val; \ |
35 | assert((ITEM)->prev.val != item_idx); \ | 40 | assert((ITEM)->prev.val != item_idx); \ |
36 | assert((ITEM)->next.val != item_idx); \ | 41 | assert((ITEM)->next.val != item_idx); \ |
37 | } | 42 | } |
43 | #endif | ||
38 | 44 | ||
39 | /// Assert the tree node invariant. | 45 | /// Assert the tree node invariant. |
40 | /// | 46 | /// |
diff --git a/src/scene/scene_memory.c b/src/scene/scene_memory.c index 85c27e7..d1d81a9 100644 --- a/src/scene/scene_memory.c +++ b/src/scene/scene_memory.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "object_impl.h" | 12 | #include "object_impl.h" |
13 | #include "scene_impl.h" | 13 | #include "scene_impl.h" |
14 | 14 | ||
15 | #include <log/log.h> | ||
15 | #include <mempool.h> | 16 | #include <mempool.h> |
16 | 17 | ||
17 | DEF_MEMPOOL(anima_pool, Anima, GFX_MAX_NUM_ANIMAS) | 18 | DEF_MEMPOOL(anima_pool, Anima, GFX_MAX_NUM_ANIMAS) |
@@ -47,10 +48,11 @@ typedef struct SceneMemory { | |||
47 | 48 | ||
48 | static SceneMemory mem; | 49 | static SceneMemory mem; |
49 | 50 | ||
50 | #define ALLOC_DUMMY(POOL) \ | 51 | #define ALLOC_DUMMY(POOL) \ |
51 | { \ | 52 | { \ |
52 | const void* object = mempool_alloc(POOL); \ | 53 | const void* object = mempool_alloc(POOL); \ |
53 | assert(mempool_get_block_index(POOL, object) == 0); \ | 54 | (void)object; /* Silence warning in release builds. */ \ |
55 | assert(mempool_get_block_index(POOL, object) == 0); \ | ||
54 | } | 56 | } |
55 | 57 | ||
56 | #define PLURAL(name) name##s | 58 | #define PLURAL(name) name##s |
@@ -90,13 +92,40 @@ void scene_mem_destroy() { | |||
90 | // NOTE: the dummy objects are not constructed, so the destruction code below | 92 | // NOTE: the dummy objects are not constructed, so the destruction code below |
91 | // always skips index 0. (I don't really like the conditional inside the loop, | 93 | // always skips index 0. (I don't really like the conditional inside the loop, |
92 | // but this gets the job done without having to specialize the loop macro.) | 94 | // but this gets the job done without having to specialize the loop macro.) |
93 | #define DESTROY(name) \ | 95 | #define DESTROY(NAME) \ |
94 | mempool_foreach(&MEM_FIELD(name), obj, { \ | 96 | mempool_foreach(&MEM_FIELD(NAME), obj, { \ |
95 | if (i > 0) { \ | 97 | if (i > 0) { \ |
96 | gfx_destroy_##name(&obj); \ | 98 | gfx_destroy_##NAME(&obj); \ |
97 | } \ | 99 | } \ |
98 | }) | 100 | }) |
99 | 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 | |||
100 | // Models contain scene elements. Destruction is handled by the remainder of | 129 | // Models contain scene elements. Destruction is handled by the remainder of |
101 | // scene destructionb elow. | 130 | // scene destructionb elow. |
102 | // | 131 | // |
@@ -119,20 +148,20 @@ void scene_mem_destroy() { | |||
119 | // Skeletons are owned by animas and do not have a destructor. | 148 | // Skeletons are owned by animas and do not have a destructor. |
120 | } | 149 | } |
121 | 150 | ||
122 | #define DEF_MEMORY(name, type) \ | 151 | #define DEF_MEMORY(NAME, TYPE) \ |
123 | /* xyz* mem_alloc_xyz(); */ \ | 152 | /* xyz* mem_alloc_xyz(); */ \ |
124 | type* mem_alloc_##name() { return mempool_alloc(&MEM_FIELD(name)); } \ | 153 | TYPE* mem_alloc_##NAME() { return mempool_alloc(&MEM_FIELD(NAME)); } \ |
125 | /* void mem_free_xyz(xyz**); */ \ | 154 | /* void mem_free_xyz(xyz**); */ \ |
126 | void mem_free_##name(type** obj) { mempool_free(&MEM_FIELD(name), obj); } \ | 155 | void mem_free_##NAME(TYPE** obj) { mempool_free(&MEM_FIELD(NAME), obj); } \ |
127 | /* xyz* mem_get_xyz(xyz_idx); */ \ | 156 | /* xyz* mem_get_xyz(xyz_idx); */ \ |
128 | type* mem_get_##name(NAMED_INDEX(name) index) { \ | 157 | TYPE* mem_get_##NAME(NAMED_INDEX(NAME) index) { \ |
129 | assert(index.val != 0); /* 0 is the dummy allocation. */ \ | 158 | assert(index.val != 0); /* 0 is the dummy allocation. */ \ |
130 | return mempool_get_block(&MEM_FIELD(name), index.val); \ | 159 | return mempool_get_block(&MEM_FIELD(NAME), index.val); \ |
131 | } \ | 160 | } \ |
132 | /* xyz_idx mem_get_xyz_index(const xyz*); */ \ | 161 | /* xyz_idx mem_get_xyz_index(const xyz*); */ \ |
133 | NAMED_INDEX(name) mem_get_##name##_index(const type* obj) { \ | 162 | NAMED_INDEX(NAME) mem_get_##NAME##_index(const TYPE* obj) { \ |
134 | return (NAMED_INDEX(name)){ \ | 163 | return (NAMED_INDEX(NAME)){ \ |
135 | .val = mempool_get_block_index(&MEM_FIELD(name), obj)}; \ | 164 | .val = mempool_get_block_index(&MEM_FIELD(NAME), obj)}; \ |
136 | } | 165 | } |
137 | 166 | ||
138 | DEF_MEMORY(anima, Anima) | 167 | DEF_MEMORY(anima, Anima) |