LineArt: Use safe lineart_discard_duplicated_edges

The old method doesn't check e for array boundary.
The new method ensures it only access valid elements.

Reviewed By: Sebastian Parborg (zeddb)

Differential Revision: https://developer.blender.org/D14903
This commit is contained in:
YimingWu
2022-05-18 15:29:27 +08:00
parent 2719869a2a
commit 369f652c80
2 changed files with 15 additions and 10 deletions

View File

@@ -757,13 +757,12 @@ static bool lineart_edge_match(LineartTriangle *tri, LineartEdge *e, int v1, int
(tri->v[v2] == e->v1 && tri->v[v1] == e->v2));
}
static void lineart_discard_duplicated_edges(LineartEdge *old_e, int v1id, int v2id)
static void lineart_discard_duplicated_edges(LineartEdge *old_e)
{
LineartEdge *e = old_e;
e++;
while (e->v1_obindex == v1id && e->v2_obindex == v2id) {
e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
while (e->flags & LRT_EDGE_FLAG_NEXT_IS_DUPLICATION) {
e++;
e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
}
}
@@ -832,7 +831,7 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
old_e = ta->e[e_num]; \
new_flag = old_e->flags; \
old_e->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
lineart_discard_duplicated_edges(old_e, old_e->v1_obindex, old_e->v2_obindex); \
lineart_discard_duplicated_edges(old_e); \
INCREASE_EDGE \
e->v1 = (v1_link); \
e->v2 = (v2_link); \
@@ -853,15 +852,15 @@ static void lineart_triangle_cull_single(LineartRenderBuffer *rb,
#define REMOVE_TRIANGLE_EDGE \
if (ta->e[0]) { \
ta->e[0]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
lineart_discard_duplicated_edges(ta->e[0], ta->e[0]->v1_obindex, ta->e[0]->v2_obindex); \
lineart_discard_duplicated_edges(ta->e[0]); \
} \
if (ta->e[1]) { \
ta->e[1]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
lineart_discard_duplicated_edges(ta->e[1], ta->e[1]->v1_obindex, ta->e[1]->v2_obindex); \
lineart_discard_duplicated_edges(ta->e[1]); \
} \
if (ta->e[2]) { \
ta->e[2]->flags = LRT_EDGE_FLAG_CHAIN_PICKED; \
lineart_discard_duplicated_edges(ta->e[2], ta->e[2]->v1_obindex, ta->e[2]->v2_obindex); \
lineart_discard_duplicated_edges(ta->e[2]); \
}
switch (in0 + in1 + in2) {
@@ -2188,7 +2187,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
continue;
}
bool edge_added = false;
LineartEdge *edge_added = NULL;
/* See eLineartEdgeFlag for details. */
for (int flag_bit = 0; flag_bit < LRT_EDGE_FLAG_TYPE_MAX_BITS; flag_bit++) {
@@ -2221,7 +2220,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, LineartRend
lineart_add_edge_to_list_thread(ob_info, la_edge);
}
edge_added = true;
if (edge_added) {
edge_added->flags |= LRT_EDGE_FLAG_NEXT_IS_DUPLICATION;
}
edge_added = la_edge;
la_edge++;
la_seg++;

View File

@@ -57,6 +57,8 @@ typedef enum eLineartEdgeFlag {
/** For object loading code to use only. */
LRT_EDGE_FLAG_INHIBIT = (1 << 14),
/** For discarding duplicated edge types in culling stage. */
LRT_EDGE_FLAG_NEXT_IS_DUPLICATION = (1 << 15),
} eLineartEdgeFlag;
#define LRT_EDGE_FLAG_ALL_TYPE 0x3f