Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Objective
Items to be drawn for the UI are added to batches in order of their position in the UiStack but the batches themselves are sorted by the z depth of the last item added to each batch. If a user modifies the z translation of the transform of a UI node it can result in batches being drawn in the wrong order.
This can potentially lead to very confusing bugs. A UI node with an invalid transform and all of its descendants may still display correctly, while another seemingly unrelated UI node that isn't even in the same transform hierarchy can disappear.
ZIndex
Also, there is a second issue if ZIndex is used. With ZIndex the draw order for UI items may not correspond to their depth in the UI layout parent-child hierarchy, in which case the transform propagation system will not propagate the z translations correctly.
ZIndex is the reason why it's not enough to just fix the sort order for TransparentUI and the z-components need to be overwritten.
Example
An app that draws three rows of text.
As expected:
The text nodes are leaf nodes in a tree:
Changes to any node's transform will be propagated down the tree.
So, if we change the z-component of the translation of the first child node to
-100
:The z translation of -100 is propagated down the transform hierarchy and none of the text is shown:
But now look what happens if we set the z translation of the third text bundle to -100 instead:
You'd naturally expect only the third text section to vanish. But the second section is also gone.
What has happened is that
prepare_ui_nodes
sorts the extracted UI items by their stack index, which results in an ordering of:Next, the items are separated into batches for each texture. This example uses two texture atlases: one to store the glyphs used by the red text section and one to store the glyphs for the smaller green and blue text sections. Each texture atlas has one texture, so there are two UI batches:
These batches are then sorted by the z depth of the last item added to each batch.
Since the blue text has the highest stack index, the last glyph from the blue text section is the last item added to the second batch. But since it also has a z coordinate of -100, the second batch will be drawn first, and then painted over by the black background when the first batch is drawn.
This is only a simple example. If you set a
ZIndex
as well, it can get extremely complicated.Solution
Set the z translation for UI nodes to zero every time the layout is updated.
Sort the UI batches so that the batches with the lowest stack index are drawn first.
Changelog
ui_layout_system
TransparentUi
UiBatch
z
field.order: u32
. The batches are now sorted by this field.prepare_uinodes