[Bf-blender-cvs] [c195be846de] temp-T97352-3d-texturing-seam-bleeding-b2: Improve pixel extraction performance by removing nested for loops.
Jeroen Bakker
noreply at git.blender.org
Wed Jul 6 12:11:38 CEST 2022
Commit: c195be846de4d70ae0b00bccd7e2d300b4aa5d94
Author: Jeroen Bakker
Date: Wed Jul 6 12:11:03 2022 +0200
Branches: temp-T97352-3d-texturing-seam-bleeding-b2
https://developer.blender.org/rBc195be846de4d70ae0b00bccd7e2d300b4aa5d94
Improve pixel extraction performance by removing nested for loops.
===================================================================
M source/blender/blenkernel/intern/pbvh_pixels.cc
===================================================================
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index a13e87544e6..c01ed4f05fc 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -110,14 +110,42 @@ static void update_geom_primitives(PBVH &pbvh, const uv_islands::MeshData &mesh_
}
}
+struct UVPrimitiveLookup {
+ struct Entry {
+ uv_islands::UVPrimitive *uv_primitive;
+ uint64_t uv_island_index;
+
+ Entry(uv_islands::UVPrimitive *uv_primitive, uint64_t uv_island_index)
+ : uv_primitive(uv_primitive), uv_island_index(uv_island_index)
+ {
+ }
+ };
+
+ Vector<Vector<Entry>> lookup;
+
+ UVPrimitiveLookup(const uint64_t geom_primitive_len, uv_islands::UVIslands &uv_islands)
+ {
+ lookup.append_n_times(Vector<Entry>(), geom_primitive_len);
+
+ uint64_t uv_island_index = 0;
+ for (uv_islands::UVIsland &uv_island : uv_islands.islands) {
+ for (uv_islands::UVPrimitive &uv_primitive : uv_island.uv_primitives) {
+ lookup[uv_primitive.primitive->index].append_as(Entry(&uv_primitive, uv_island_index));
+ }
+ uv_island_index++;
+ }
+ }
+};
+
struct EncodePixelsUserData {
Image *image;
ImageUser *image_user;
PBVH *pbvh;
Vector<PBVHNode *> *nodes;
const MLoopUV *ldata_uv;
- const uv_islands::UVIslands *uv_islands;
const uv_islands::UVIslandsMask *uv_masks;
+ /** Lookup to retrieve the UV primitives based on the primitive index. */
+ const UVPrimitiveLookup *uv_primitive_lookup;
};
static void do_encode_pixels(void *__restrict userdata,
@@ -146,49 +174,43 @@ static void do_encode_pixels(void *__restrict userdata,
for (int pbvh_node_prim_index = 0; pbvh_node_prim_index < node->totprim;
pbvh_node_prim_index++) {
int64_t geom_prim_index = node->prim_indices[pbvh_node_prim_index];
- int64_t uv_island_index = 0;
- for (const uv_islands::UVIsland &island : data->uv_islands->islands) {
- for (const uv_islands::UVPrimitive &uv_primitive : island.uv_primitives) {
- if (uv_primitive.primitive->index != geom_prim_index) {
- continue;
- }
- uv_islands::UVBorder uv_border = uv_primitive.extract_border();
- float2 uvs[3] = {
- uv_primitive.get_uv_vertex(0)->uv - tile_offset,
- uv_primitive.get_uv_vertex(1)->uv - tile_offset,
- uv_primitive.get_uv_vertex(2)->uv - tile_offset,
- };
- const float minv = clamp_f(min_fff(uvs[0].y, uvs[1].y, uvs[2].y), 0.0f, 1.0f);
- const int miny = floor(minv * image_buffer->y);
- const float maxv = clamp_f(max_fff(uvs[0].y, uvs[1].y, uvs[2].y), 0.0f, 1.0f);
- const int maxy = min_ii(ceil(maxv * image_buffer->y), image_buffer->y);
- const float minu = clamp_f(min_fff(uvs[0].x, uvs[1].x, uvs[2].x), 0.0f, 1.0f);
- const int minx = floor(minu * image_buffer->x);
- const float maxu = clamp_f(max_fff(uvs[0].x, uvs[1].x, uvs[2].x), 0.0f, 1.0f);
- const int maxx = min_ii(ceil(maxu * image_buffer->x), image_buffer->x);
-
- /* TODO: Perform bounds check */
- int64_t uv_prim_index = node_data->uv_primitives.size();
- node_data->uv_primitives.append(geom_prim_index);
- UVPrimitivePaintInput &paint_input = node_data->uv_primitives.last();
-
- /* Calculate barycentric delta */
- paint_input.delta_barycentric_coord_u = calc_barycentric_delta_x(
- image_buffer, uvs, minx, miny);
-
- /* Extract the pixels. */
- extract_barycentric_pixels(tile_data,
- image_buffer,
- uv_masks,
- uv_island_index,
- uv_prim_index,
- uvs,
- minx,
- miny,
- maxx,
- maxy);
- }
- uv_island_index++;
+ for (const UVPrimitiveLookup::Entry &entry :
+ data->uv_primitive_lookup->lookup[geom_prim_index]) {
+ uv_islands::UVBorder uv_border = entry.uv_primitive->extract_border();
+ float2 uvs[3] = {
+ entry.uv_primitive->get_uv_vertex(0)->uv - tile_offset,
+ entry.uv_primitive->get_uv_vertex(1)->uv - tile_offset,
+ entry.uv_primitive->get_uv_vertex(2)->uv - tile_offset,
+ };
+ const float minv = clamp_f(min_fff(uvs[0].y, uvs[1].y, uvs[2].y), 0.0f, 1.0f);
+ const int miny = floor(minv * image_buffer->y);
+ const float maxv = clamp_f(max_fff(uvs[0].y, uvs[1].y, uvs[2].y), 0.0f, 1.0f);
+ const int maxy = min_ii(ceil(maxv * image_buffer->y), image_buffer->y);
+ const float minu = clamp_f(min_fff(uvs[0].x, uvs[1].x, uvs[2].x), 0.0f, 1.0f);
+ const int minx = floor(minu * image_buffer->x);
+ const float maxu = clamp_f(max_fff(uvs[0].x, uvs[1].x, uvs[2].x), 0.0f, 1.0f);
+ const int maxx = min_ii(ceil(maxu * image_buffer->x), image_buffer->x);
+
+ /* TODO: Perform bounds check */
+ int64_t uv_prim_index = node_data->uv_primitives.size();
+ node_data->uv_primitives.append(geom_prim_index);
+ UVPrimitivePaintInput &paint_input = node_data->uv_primitives.last();
+
+ /* Calculate barycentric delta */
+ paint_input.delta_barycentric_coord_u = calc_barycentric_delta_x(
+ image_buffer, uvs, minx, miny);
+
+ /* Extract the pixels. */
+ extract_barycentric_pixels(tile_data,
+ image_buffer,
+ uv_masks,
+ entry.uv_island_index,
+ uv_prim_index,
+ uvs,
+ minx,
+ miny,
+ maxx,
+ maxy);
}
}
BKE_image_release_ibuf(image, image_buffer, nullptr);
@@ -348,13 +370,15 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
islands.extend_borders(uv_masks);
update_geom_primitives(*pbvh, mesh_data);
+ UVPrimitiveLookup uv_primitive_lookup(mesh_data.looptri_len, islands);
+
EncodePixelsUserData user_data;
user_data.pbvh = pbvh;
user_data.image = image;
user_data.image_user = image_user;
user_data.ldata_uv = ldata_uv;
user_data.nodes = &nodes_to_update;
- user_data.uv_islands = &islands;
+ user_data.uv_primitive_lookup = &uv_primitive_lookup;
user_data.uv_masks = &uv_masks;
TaskParallelSettings settings;
More information about the Bf-blender-cvs
mailing list