Skip to content

Commit dbea56a

Browse files
committed
no more performance regression
1 parent c872148 commit dbea56a

File tree

1 file changed

+110
-112
lines changed
  • crates/bevy_sprite/src/render

1 file changed

+110
-112
lines changed

crates/bevy_sprite/src/render/mod.rs

Lines changed: 110 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -339,130 +339,128 @@ pub fn prepare_sprites(
339339
sprite_meta.vertices.clear();
340340
sprite_meta.colored_vertices.clear();
341341

342-
// We divide the sprites according to their color
343-
let [mut white_sprites, mut colored_sprites] = extracted_sprites.sprites.drain(..).fold(
344-
[vec![], vec![]],
345-
|[mut colored, mut white], sprite| {
346-
if sprite.color == Color::WHITE {
347-
white.push(sprite);
348-
} else {
349-
colored.push(sprite)
350-
}
351-
[colored, white]
352-
},
353-
);
354-
355342
// Sort sprites by z for correct transparency and then by handle to improve batching
356-
let sort = |vec: &mut Vec<ExtractedSprite>| {
357-
vec.sort_unstable_by(|a, b| {
358-
match a
359-
.transform
360-
.translation
361-
.z
362-
.partial_cmp(&b.transform.translation.z)
343+
extracted_sprites.sprites.sort_unstable_by(|a, b| {
344+
match a
345+
.transform
346+
.translation
347+
.z
348+
.partial_cmp(&b.transform.translation.z)
349+
{
350+
Some(Ordering::Equal) | None => a.image_handle_id.cmp(&b.image_handle_id),
351+
Some(other) => other,
352+
}
353+
});
354+
355+
// Impossible starting values that will be replaced on the first iteration
356+
let mut current_batch_handle = HandleId::Id(Uuid::nil(), u64::MAX);
357+
let mut current_image_size = Vec2::ZERO;
358+
let mut current_batch_colored = false;
359+
let mut z_order = 0.0;
360+
361+
// Vertex buffer indices
362+
let [mut white_start, mut white_end] = [0, 0];
363+
let [mut colored_start, mut colored_end] = [0, 0];
364+
365+
for extracted_sprite in extracted_sprites.sprites.drain(..) {
366+
let colored = extracted_sprite.color != Color::WHITE;
367+
if extracted_sprite.image_handle_id != current_batch_handle
368+
|| colored != current_batch_colored
369+
{
370+
if let Some(gpu_image) = gpu_images.get(&Handle::weak(extracted_sprite.image_handle_id))
363371
{
364-
Some(Ordering::Equal) | None => a.image_handle_id.cmp(&b.image_handle_id),
365-
Some(other) => other,
366-
}
367-
});
368-
};
369-
sort(&mut white_sprites);
370-
sort(&mut colored_sprites);
371-
372-
for (colored, sprites) in [(false, white_sprites), (true, colored_sprites)] {
373-
// Impossible starting values that will be replaced on the first iteration
374-
let mut current_batch_handle = HandleId::Id(Uuid::nil(), u64::MAX);
375-
let mut current_image_size = Vec2::ZERO;
376-
let mut z_order = 0.0;
377-
378-
// Vertex buffer indices
379-
let mut index_start = 0;
380-
let mut index_end = 0;
381-
382-
for extracted_sprite in sprites {
383-
if extracted_sprite.image_handle_id != current_batch_handle {
384-
if let Some(gpu_image) =
385-
gpu_images.get(&Handle::weak(extracted_sprite.image_handle_id))
386-
{
387-
current_image_size = gpu_image.size;
388-
current_batch_handle = extracted_sprite.image_handle_id;
389-
if index_start != index_end {
390-
commands.spawn().insert(SpriteBatch {
391-
range: index_start..index_end,
392-
image_handle_id: current_batch_handle,
393-
colored,
394-
z_order,
395-
});
396-
index_start = index_end;
397-
}
398-
} else {
399-
// We skip loading images
400-
continue;
372+
current_image_size = gpu_image.size;
373+
current_batch_handle = extracted_sprite.image_handle_id;
374+
current_batch_colored = colored;
375+
let [start, end] = match colored {
376+
true => [&mut colored_start, &mut colored_end],
377+
false => [&mut white_start, &mut white_end],
378+
};
379+
if *start != *end {
380+
commands.spawn().insert(SpriteBatch {
381+
range: *start..*end,
382+
image_handle_id: current_batch_handle,
383+
colored: current_batch_colored,
384+
z_order,
385+
});
386+
*start = *end;
401387
}
388+
} else {
389+
// We skip loading images
390+
continue;
402391
}
403-
// Calculate vertex data for this item
404-
let mut uvs = QUAD_UVS;
405-
if extracted_sprite.flip_x {
406-
uvs = [uvs[1], uvs[0], uvs[3], uvs[2]];
407-
}
408-
if extracted_sprite.flip_y {
409-
uvs = [uvs[3], uvs[2], uvs[1], uvs[0]];
410-
}
411-
412-
// By default, the size of the quad is the size of the texture
413-
let mut quad_size = current_image_size;
392+
}
393+
// Calculate vertex data for this item
394+
let mut uvs = QUAD_UVS;
395+
if extracted_sprite.flip_x {
396+
uvs = [uvs[1], uvs[0], uvs[3], uvs[2]];
397+
}
398+
if extracted_sprite.flip_y {
399+
uvs = [uvs[3], uvs[2], uvs[1], uvs[0]];
400+
}
414401

415-
// If a rect is specified, adjust UVs and the size of the quad
416-
if let Some(rect) = extracted_sprite.rect {
417-
let rect_size = rect.size();
418-
for uv in &mut uvs {
419-
*uv = (rect.min + *uv * rect_size) / current_image_size;
420-
}
421-
quad_size = rect_size;
422-
}
402+
// By default, the size of the quad is the size of the texture
403+
let mut quad_size = current_image_size;
423404

424-
// Override the size if a custom one is specified
425-
if let Some(custom_size) = extracted_sprite.custom_size {
426-
quad_size = custom_size;
405+
// If a rect is specified, adjust UVs and the size of the quad
406+
if let Some(rect) = extracted_sprite.rect {
407+
let rect_size = rect.size();
408+
for uv in &mut uvs {
409+
*uv = (rect.min + *uv * rect_size) / current_image_size;
427410
}
411+
quad_size = rect_size;
412+
}
428413

429-
// Apply size and global transform
430-
let positions = QUAD_VERTEX_POSITIONS.map(|quad_pos| {
431-
extracted_sprite
432-
.transform
433-
.mul_vec3(((quad_pos - extracted_sprite.anchor) * quad_size).extend(0.))
434-
.into()
435-
});
414+
// Override the size if a custom one is specified
415+
if let Some(custom_size) = extracted_sprite.custom_size {
416+
quad_size = custom_size;
417+
}
436418

437-
if colored {
438-
for i in QUAD_INDICES {
439-
sprite_meta.colored_vertices.push(ColoredSpriteVertex {
440-
position: positions[i],
441-
uv: uvs[i].into(),
442-
color: extracted_sprite.color.as_linear_rgba_f32(),
443-
});
444-
}
445-
} else {
446-
for i in QUAD_INDICES {
447-
sprite_meta.vertices.push(SpriteVertex {
448-
position: positions[i],
449-
uv: uvs[i].into(),
450-
});
451-
}
419+
// Apply size and global transform
420+
let positions = QUAD_VERTEX_POSITIONS.map(|quad_pos| {
421+
extracted_sprite
422+
.transform
423+
.mul_vec3(((quad_pos - extracted_sprite.anchor) * quad_size).extend(0.))
424+
.into()
425+
});
426+
if colored {
427+
for i in QUAD_INDICES {
428+
sprite_meta.colored_vertices.push(ColoredSpriteVertex {
429+
position: positions[i],
430+
uv: uvs[i].into(),
431+
color: extracted_sprite.color.as_linear_rgba_f32(),
432+
});
452433
}
453-
index_end += QUAD_INDICES.len() as u32;
454-
z_order = extracted_sprite.transform.translation.z;
455-
}
456-
// if start != end, there is one last batch to process
457-
if index_start != index_end {
458-
commands.spawn().insert(SpriteBatch {
459-
range: index_start..index_end,
460-
image_handle_id: current_batch_handle,
461-
colored,
462-
z_order,
463-
});
434+
colored_end += QUAD_INDICES.len() as u32;
435+
} else {
436+
for i in QUAD_INDICES {
437+
sprite_meta.vertices.push(SpriteVertex {
438+
position: positions[i],
439+
uv: uvs[i].into(),
440+
});
441+
}
442+
white_end += QUAD_INDICES.len() as u32;
464443
}
444+
z_order = extracted_sprite.transform.translation.z;
465445
}
446+
// if start != end, there is one last batch to process
447+
if white_start != white_end {
448+
commands.spawn().insert(SpriteBatch {
449+
range: white_start..white_end,
450+
image_handle_id: current_batch_handle,
451+
colored: false,
452+
z_order,
453+
});
454+
}
455+
if colored_start != colored_end {
456+
commands.spawn().insert(SpriteBatch {
457+
range: colored_start..colored_end,
458+
image_handle_id: current_batch_handle,
459+
colored: true,
460+
z_order,
461+
});
462+
}
463+
466464
sprite_meta
467465
.vertices
468466
.write_buffer(&render_device, &render_queue);

0 commit comments

Comments
 (0)