Cleanup: render: Replace 'void' MEM_[cm]allocN with templated, type-safe MEM_[cm]allocN<T>.

The main issue of 'type-less' standard C allocations is that there is no check on
allocated type possible.

This is a serious source of annoyance (and crashes) when making some
low-level structs non-trivial, as tracking down all usages of these
structs in higher-level other structs and their allocation is... really
painful.

MEM_[cm]allocN<T> templates on the other hand do check that the
given type is trivial, at build time (static assert), which makes such issue...
trivial to catch.

NOTE: New code should strive to use MEM_new (i.e. allocation and
construction) as much as possible, even for trivial PoD types.

Pull Request: https://projects.blender.org/blender/blender/pulls/135813
This commit is contained in:
Bastien Montagne 2025-03-12 10:31:06 +01:00 committed by Bastien Montagne
parent f3b1c9b2cd
commit 9f697c7cc6
7 changed files with 19 additions and 23 deletions

View File

@ -744,8 +744,7 @@ void RE_bake_pixels_populate(Mesh *mesh,
}
const int tottri = poly_to_tri_count(mesh->faces_num, mesh->corners_num);
blender::int3 *corner_tris = static_cast<blender::int3 *>(
MEM_mallocN(sizeof(*corner_tris) * tottri, __func__));
blender::int3 *corner_tris = MEM_malloc_arrayN<blender::int3>(size_t(tottri), __func__);
blender::bke::mesh::corner_tris_calc(
mesh->vert_positions(), mesh->faces(), mesh->corner_verts(), {corner_tris, tottri});

View File

@ -436,8 +436,8 @@ class Context : public compositor::Context {
IMB_assign_float_buffer(ibuf, output_buffer, IB_TAKE_OWNERSHIP);
}
else {
float *data = static_cast<float *>(
MEM_malloc_arrayN(rr->rectx * rr->recty, 4 * sizeof(float), __func__));
float *data = MEM_malloc_arrayN<float>(4 * size_t(rr->rectx) * size_t(rr->recty),
__func__);
IMB_assign_float_buffer(ibuf, data, IB_TAKE_OWNERSHIP);
std::memcpy(
data, output_result_.cpu_data().data(), rr->rectx * rr->recty * 4 * sizeof(float));

View File

@ -1142,8 +1142,8 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data)
raytree = ao_data->raytree = RE_rayobject_create(
bkr->raytrace_structure, faces_num, bkr->octree_resolution);
face = ao_data->rayfaces = (RayFace *)MEM_callocN(faces_num * sizeof(RayFace),
"ObjectRen faces");
face = ao_data->rayfaces = MEM_calloc_arrayN<RayFace>(size_t(faces_num),
"ObjectRen faces");
for (i = 0; i < grids_num; i++) {
int x, y;
@ -1172,11 +1172,10 @@ static void *init_ao_data(MultiresBakeRender *bkr, ImBuf * /*ibuf*/)
MAOBakeData *ao_data;
DerivedMesh *lodm = bkr->lores_dm;
ushort *temp_permutation_table;
size_t permutation_size;
init_ao_random();
ao_data = MEM_callocN(sizeof(MAOBakeData), "MultiresBake aoData");
ao_data = MEM_callocN<MAOBakeData>("MultiresBake aoData");
ao_data->number_of_rays = bkr->number_of_rays;
ao_data->bias = bkr->bias;
@ -1186,10 +1185,9 @@ static void *init_ao_data(MultiresBakeRender *bkr, ImBuf * /*ibuf*/)
create_ao_raytree(bkr, ao_data);
/* initialize permutation tables */
permutation_size = sizeof(ushort) * bkr->number_of_rays;
ao_data->permutation_table_1 = MEM_callocN(permutation_size, "multires AO baker perm1");
ao_data->permutation_table_2 = MEM_callocN(permutation_size, "multires AO baker perm2");
temp_permutation_table = MEM_callocN(permutation_size, "multires AO baker temp perm");
ao_data->permutation_table_1 = MEM_calloc_arrayN<ushort>(size_t(bkr->number_of_rays), "multires AO baker perm1");
ao_data->permutation_table_2 = MEM_calloc_arrayN<ushort>(size_t(bkr->number_of_rays), "multires AO baker perm2");
temp_permutation_table = MEM_calloc_arrayN<ushort>(size_t(bkr->number_of_rays), "multires AO baker temp perm");
build_permutation_table(
ao_data->permutation_table_1, temp_permutation_table, bkr->number_of_rays, 1);

View File

@ -1149,8 +1149,8 @@ void RE_render_result_rect_from_ibuf(RenderResult *rr, const ImBuf *ibuf, const
rr->have_combined = true;
if (!rv_ibuf->float_buffer.data) {
float *data = static_cast<float *>(
MEM_malloc_arrayN(rr->rectx * rr->recty, sizeof(float[4]), "render_seq float"));
float *data = MEM_malloc_arrayN<float>(4 * size_t(rr->rectx) * size_t(rr->recty),
"render_seq float");
IMB_assign_float_buffer(rv_ibuf, data, IB_TAKE_OWNERSHIP);
}
@ -1166,8 +1166,8 @@ void RE_render_result_rect_from_ibuf(RenderResult *rr, const ImBuf *ibuf, const
rr->have_combined = true;
if (!rv_ibuf->byte_buffer.data) {
uint8_t *data = static_cast<uint8_t *>(
MEM_malloc_arrayN(rr->rectx * rr->recty, sizeof(uint8_t[4]), "render_seq byte"));
uint8_t *data = MEM_malloc_arrayN<uint8_t>(4 * size_t(rr->rectx) * size_t(rr->recty),
"render_seq byte");
IMB_assign_byte_buffer(rv_ibuf, data, IB_TAKE_OWNERSHIP);
}

View File

@ -520,7 +520,7 @@ static void generate_margin(ImBuf *ibuf,
mask = (char *)MEM_dupallocN(mask);
}
else {
mask = (char *)MEM_callocN(sizeof(char) * ibuf->x * ibuf->y, __func__);
mask = MEM_calloc_arrayN<char>(size_t(ibuf->x) * size_t(ibuf->y), __func__);
draw_new_mask = true;
}

View File

@ -149,8 +149,8 @@ static void alloc_point_data(PointDensity *pd)
}
if (data_size) {
pd->point_data = static_cast<float *>(
MEM_callocN(sizeof(float) * data_size * totpoints, "particle point data"));
pd->point_data = MEM_calloc_arrayN<float>(size_t(data_size) * size_t(totpoints),
"particle point data");
}
}
@ -292,8 +292,7 @@ static void pointdensity_cache_vertex_color(PointDensity *pd,
}
/* Stores the number of MLoops using the same vertex, so we can normalize colors. */
int *mcorners = static_cast<int *>(
MEM_callocN(sizeof(int) * pd->totpoints, "point density corner count"));
int *mcorners = MEM_calloc_arrayN<int>(size_t(pd->totpoints), "point density corner count");
for (i = 0; i < totloop; i++) {
int v = corner_verts[i];

View File

@ -37,8 +37,8 @@ void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty)
zspan->rectx = rectx;
zspan->recty = recty;
zspan->span1 = static_cast<float *>(MEM_mallocN(recty * sizeof(float), "zspan"));
zspan->span2 = static_cast<float *>(MEM_mallocN(recty * sizeof(float), "zspan"));
zspan->span1 = MEM_malloc_arrayN<float>(recty, "zspan");
zspan->span2 = MEM_malloc_arrayN<float>(recty, "zspan");
}
void zbuf_free_span(ZSpan *zspan)