Vastly improve performance of DefaultShader#canRender(..) #4531
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.
Explanation:
DefaultShader#canRender(..)
used to callcombineAttributes(..)
on the renderable, and then only use the mask.combineAttributes(..)
is very expensive (around O(n2log(n)) where n is the number of unique attributes, because it sorts after adding each attribute). But all the function really needs is the combined mask, and since we keep the masks for both Attributes objects around anyway we can get it with just a bitwise or.Our game uses a large number of ModelInstances with about 15 shaders, which meant every time it added a renderable to the batch (several times per ModelInstance) it would have to iterate ~7 shaders on average and combineAttributes(..) for each one, which was a major hit to pre-render time. Implementing this change brought the frame render time on our min spec phone from 40ms to 30ms, a major performance gain that made the game playable.