Open NB13 opened 5 years ago
You mean that in the "wrongCase" method, you're ending up with one draw call per display object, correct?
That's unfortunately a negative side effect of the overhaul of the rendering architecture I introduced in Starling 2.
Short description: the current behavior is a trade off that allowed simplification of the render API in lots of places. It's unlikely to change anytime soon.
Long description:
During the lifetime of Starling 1.x, I ran into countless bugs related to the blend mode. The main reason was that, basically, whenever I drew one object, I had to check the blend mode of the previous object, and that would decide if a new batch (draw call) was started. That happened at lots of different places, and complicated things quite a bit.
So, in Starling 2.0, I simplified the blend mode logic by making it part of the general render state logic. Basically, when iterating over the display list, I "push" a new render state when moving down the list (i.e. from a parent to a child), and I "pop" to the previews render state when moving up (i.e. from child to parent). For every push and pop, the following logic is executed:
if (blendModeChanges || targetChanges || clipRectChanges || cullingChanges || depthMaskChanges || depthTestChanges)
{
drawCurrentBatch();
}
And that's what's responsible for those draw calls. When iterating over the children of a container during rendering, I have to restore the previous (parent) state after every child, to undo the changes the previous child did to the render state. In the example you provided, this means that each child uses its own draw call.
Which is unfortunate — but I haven't found an elegant way around it, that's not so complicated that it would mean lots of fragile code elsewhere.
I hope you understand my reasons for keeping it like this for now! At least there is a rather simple workaround, as you discovered yourself (setting the blend mode on the complete container instead of the individual children).
Hi, Daniel! Sorry for writing issue in a hurry, yes - separate draw call for each child is the issue. Thank you for detailed answer. Maybe I'll try to fix this issue, but I'm afraid to break "fragile code" you've mentioned. Do you have some auto tests?
Unfortunately, I don't have any automated tests for rendering - I'd have to set up something that would allow me to read and compare actual pixels, and I never quite pushed myself to do that. In cases like this, it would definitely have been worth it, though. :bowtie:
A part of the issues that came up with blending over time can be found by looking through the commit messages that mention blending, like here. Perhaps that helps.
Otherwise, I could look into it again when I find some time to squeeze it in. And that workaround with the additional container is always an option, too.
Starling 2.4 has problems with batching animated display objects having one mesh style. Here is demo of error and hot fix for current (2.4) version. In first case we will get 100 draw calls, in the second only 1.