GLES2 Batching - fix item reordering bug

There was a bug in the initial logic for item reordering, whereby it would check for overlaps between the mover (item being moved back) and sandwiched items, but there was no check for overlaps between the movee (item moved forward) and the sandwich items. This extra check is now done.

Also a minor addition to the diagnose frame info (godot texture ID).
This commit is contained in:
lawnjelly 2020-05-06 12:55:18 +01:00
parent 4d2c8ba922
commit bda20edb76
1 changed files with 20 additions and 6 deletions

View File

@ -746,7 +746,9 @@ void RasterizerCanvasGLES2::diagnose_batches(Item::Command *const *p_commands) {
bdata.frame_string += "R "; bdata.frame_string += "R ";
bdata.frame_string += itos(batch.first_command) + "-"; bdata.frame_string += itos(batch.first_command) + "-";
bdata.frame_string += itos(batch.num_commands); bdata.frame_string += itos(batch.num_commands);
bdata.frame_string += " [" + itos(batch.batch_texture_id) + "]";
int tex_id = (int)bdata.batch_textures[batch.batch_texture_id].RID_texture.get_id();
bdata.frame_string += " [" + itos(batch.batch_texture_id) + " - " + itos(tex_id) + "]";
bdata.frame_string += " " + batch.color.to_string(); bdata.frame_string += " " + batch.color.to_string();
@ -1751,7 +1753,7 @@ void RasterizerCanvasGLES2::sort_items() {
return; return;
} }
for (int s = 0; s < bdata.sort_items.size() - 1; s++) { for (int s = 0; s < bdata.sort_items.size() - 2; s++) {
if (sort_items_from(s)) { if (sort_items_from(s)) {
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
bdata.stats_items_sorted++; bdata.stats_items_sorted++;
@ -1789,8 +1791,11 @@ bool RasterizerCanvasGLES2::sort_items_from(int p_start) {
return false; return false;
} }
// local cached aabb
Rect2 second_AABB = second.item->global_rect_cache;
// if the start and 2nd items overlap, can do no more // if the start and 2nd items overlap, can do no more
if (start.item->global_rect_cache.intersects(second.item->global_rect_cache)) { if (start.item->global_rect_cache.intersects(second_AABB)) {
return false; return false;
} }
@ -1811,17 +1816,26 @@ bool RasterizerCanvasGLES2::sort_items_from(int p_start) {
return false; return false;
} }
Item *test_item = test_sort_item->item;
// if the test item overlaps the second item, we can't swap, AT ALL
// because swapping an item OVER this one would cause artefacts
if (second_AABB.intersects(test_item->global_rect_cache)) {
return false;
}
// do they match? // do they match?
if (!_sort_items_match(start, *test_sort_item)) // order is crucial, start first if (!_sort_items_match(start, *test_sort_item)) // order is crucial, start first
{ {
continue; continue;
} }
Item *test_item = test_sort_item->item;
// we can only swap if there are no AABB overlaps with sandwiched neighbours // we can only swap if there are no AABB overlaps with sandwiched neighbours
bool ok = true; bool ok = true;
for (int sn = 1; sn < test; sn++) {
// start from 2, no need to check 1 as the second has already been checked against this item
// in the intersection test above
for (int sn = 2; sn < test; sn++) {
BSortItem *sandwich_neighbour = &bdata.sort_items[p_start + sn]; BSortItem *sandwich_neighbour = &bdata.sort_items[p_start + sn];
if (test_item->global_rect_cache.intersects(sandwich_neighbour->item->global_rect_cache)) { if (test_item->global_rect_cache.intersects(sandwich_neighbour->item->global_rect_cache)) {
ok = false; ok = false;