Why does director visit/draw all nodes in a scene when nothing has changed?

I implemented a custom node to do openGL drawing, similar to CCDrawNode, including use of a _vao/_vbo and no need to keep buffering vertices that have not changed.

My custom node is working great - so that’s not the nature of my question.

However, I was surprised to find that the draw(…) method on my node is called repeatedly, even though absolutely nothing in the scene has changed, with perhaps the exception of the need to draw the frame rate stats.

I walked through all the director code to get an idea of how it works, and I know the model in openGL has everything render when it renders a camera view (rather than only drawing some “dirty” rects)

As a software engineer this bothered me enough to wonder if I’m not understanding something.

I see that a scene can be paused, and animation can be stopped, which will stop the tight drawing loop, so freezing a scene is possible this way.

Shouldn’t any “events” driven by the animation loop be separate from processing the drawing of nodes, and let the results of such events cause marking as need for drawing?

Wouldn’t it be better if director does not erase and redraw a scene where absolutely nothing has changed?

Shouldn’t frame rate stats be in a separate buffer so they don’t force the entire scene to redraw repeatedly? Shouldn’t any of the many objects that get a state change just set a flag on a scene marking that it needs a redraw, and if no flag is set, shouldn’t cocos2d just leave the current rendered scene as is? (Saves cycles, saves power, etc.)

Or is there a way to do this already that I missed?

Dirty-rectangles: In simplistic terms they aren’t used because modern GPU hardware rendering works best by just redrawing everything.

Rest assured the FPS stats are only for debugging, you should only profile, optimize, and worry about performance with release builds which disables the FPS stats (edit: by default).

As for visiting every node, well the engine doesn’t know if a node has changed until it visits it. There are a number of things that have a “dirty” flag in the engine which when false are skipped over (recalculating a node’s parent transform matrices among other things). If the node is outside the frustum it is skipped over if culling is enabled. If you don’t want a ton of visits in your scene then you should create a custom node that will only be visited once per scene and have it customize how it handles the vertex buffer objects and draw commands for all the nodes that would have been visited otherwise.

You don’t really have to worry about much of this if your game is relatively simple or you’re running on low-end devices. The engine provides many means of optimizing your scene if you need to, and you’ve already figured out one means to do so with your custom node.

There is definitely some opinion within the design of cocos2d-x and if you wrote your own engine you could do things differently.

Why would FPS stats not work on release builds?

Well you could enable them if you want. And they are NOT a resource hog. However, most people don’t want the FPS taking up screen space and covering up their awesome game!