commit c4a2f03f9b99d7ca7811096a60df706579ecc156
parent 1cfdc2309880e5d96eabd7fafb2a246e00019693
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 9 Jul 2026 18:42:22 +0200
Test the delayed removal of geometries from the view cache
Diffstat:
2 files changed, 141 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
@@ -134,8 +134,9 @@ TEST_SRC =\
src/test_s3d_sampler.c\
src/test_s3d_sample_sphere.c\
src/test_s3d_scene.c\
- src/test_s3d_scene_view_aabb.c\
src/test_s3d_scene_view.c\
+ src/test_s3d_scene_view_aabb.c\
+ src/test_s3d_scene_view_delayed_cache_update.c\
src/test_s3d_seams.c\
src/test_s3d_shape.c\
src/test_s3d_sphere_box.c\
@@ -175,8 +176,9 @@ test_s3d_device \
test_s3d_primitive \
test_s3d_sampler \
test_s3d_scene \
-test_s3d_scene_view_aabb \
test_s3d_scene_view \
+test_s3d_scene_view_aabb \
+test_s3d_scene_view_delayed_cache_update \
test_s3d_shape \
: config.mk s3d-local.pc $(LIBNAME)
$(CC) -std=c89 $(CFLAGS_EXE) -o $@ src/$@.o $(LDFLAGS_EXE) $(S3D_LIBS)
diff --git a/src/test_s3d_scene_view_delayed_cache_update.c b/src/test_s3d_scene_view_delayed_cache_update.c
@@ -0,0 +1,137 @@
+/* Copyright (C) 2015-2023 |Méso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "s3d.h"
+
+#include <rsys/float3.h>
+#include <rsys/mem_allocator.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+get_ids(const unsigned itri, unsigned ids[3], void* data)
+{
+ (void)itri, (void)ids, (void)data;
+ ids[0] = 0;
+ ids[1] = 1;
+ ids[2] = 2;
+}
+
+static void
+get_pos(const unsigned ivtx, float pos[3], void* data)
+{
+ (void)data;
+
+ switch(ivtx) {
+ case 0: f3(pos, 0.f, 0.f, 0.f); break;
+ case 1: f3(pos, 1.f, 0.f, 0.f); break;
+ case 2: f3(pos, 1.f, 1.f, 0.f); break;
+ default: FATAL("Unreachable code\n"); break;
+ }
+}
+
+static struct s3d_shape*
+create_triangle(struct s3d_device* dev)
+{
+ struct s3d_vertex_data vdata;
+ struct s3d_shape* tri = NULL;
+
+ vdata.type = S3D_FLOAT3;
+ vdata.usage = S3D_POSITION;
+ vdata.get = get_pos;
+
+ CHK(s3d_shape_create_mesh(dev, &tri) == RES_OK);
+ CHK(s3d_mesh_setup_indexed_vertices(tri, 1, get_ids, 3, &vdata, 1, NULL)
+ == RES_OK);
+
+ return tri;
+}
+
+/* Detach, attach and re-attach the same shape while the view is active */
+static void
+test_scenario1(struct s3d_device* dev)
+{
+ struct s3d_shape* triangle;
+ struct s3d_scene* scn = NULL;
+ struct s3d_scene_view* view = NULL;
+ const int mask = S3D_SAMPLE | S3D_TRACE;
+
+ CHK(s3d_scene_create(dev, &scn) == RES_OK);
+
+ triangle = create_triangle(dev);
+ CHK(s3d_scene_attach_shape(scn, triangle) == RES_OK);
+ CHK(s3d_scene_view_create(scn, mask, &view) == RES_OK);
+
+ CHK(s3d_scene_detach_shape(scn, triangle) == RES_OK);
+ CHK(s3d_scene_attach_shape(scn, triangle) == RES_OK);
+ CHK(s3d_scene_detach_shape(scn, triangle) == RES_OK);
+
+ CHK(s3d_shape_ref_put(triangle) == RES_OK);
+ CHK(s3d_scene_ref_put(scn) == RES_OK);
+
+ CHK(s3d_scene_view_ref_put(view) == RES_OK);
+}
+
+/* Detach and delete a shape. Then create a new one that in doing so could reuse
+ * the Id of the previous shape, before attaching it and detach it from the
+ * scene. All this while a view of the scene continues to rely on the geometry
+ * of the first shape */
+static void
+test_scenario2(struct s3d_device* dev)
+{
+ struct s3d_scene* scn = NULL;
+ struct s3d_scene_view* view;
+ struct s3d_shape* triangle;
+ const int mask = S3D_SAMPLE | S3D_TRACE;
+
+ CHK(s3d_scene_create(dev, &scn) == RES_OK);
+
+ triangle = create_triangle(dev);
+ CHK(s3d_scene_attach_shape(scn, triangle) == RES_OK);
+ CHK(s3d_scene_view_create(scn, mask, &view) == RES_OK);
+
+ CHK(s3d_scene_detach_shape(scn, triangle) == RES_OK);
+ CHK(s3d_shape_ref_put(triangle) == RES_OK);
+
+ triangle = create_triangle(dev);
+ CHK(s3d_scene_attach_shape(scn, triangle) == RES_OK);
+ CHK(s3d_scene_detach_shape(scn, triangle) == RES_OK);
+ CHK(s3d_shape_ref_put(triangle) == RES_OK);
+
+ CHK(s3d_scene_ref_put(scn) == RES_OK);
+
+ CHK(s3d_scene_view_ref_put(view) == RES_OK);
+}
+
+
+/*******************************************************************************
+ * The test
+ ******************************************************************************/
+int
+main(void)
+{
+ struct s3d_device* dev = NULL;
+
+ CHK(s3d_device_create(NULL, NULL, 0, &dev) == RES_OK);
+
+ test_scenario1(dev);
+ test_scenario2(dev);
+
+ CHK(s3d_device_ref_put(dev) == RES_OK);
+
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}