CocosSharp icon indicating copy to clipboard operation
CocosSharp copied to clipboard

Provide a way for games to determine how many render state changes are occurring and why

Open vchelaru opened this issue 9 years ago • 2 comments

In my experience on mobile, render state changes are often what kills framerate. When this occurs I need to know how many render state changes I'm having per frame, which objects are causing them to happen (such as which CCSprites), and why (different texture/blend state/raster state/viewport/etc).

Preferably some object (perhaps the root CCScene) would contain a list of some object (like RenderStateChange), where each RenderStateChange would have the reason it was changed, a full record of its render states, and the object that caused it to be created.

I realize this may cause all rendering code to be touched, but it's incredibly useful for optimizing games, and I see it as a requirement for larger games.

vchelaru avatar Dec 06 '15 21:12 vchelaru

@vchelaru As of CocosSharp 1.5.0.0, we have centralised all our rendering commands to be processed within a single CCRenderer class that's associated with the view, so adding this feature is certainly doable.

It would definitely help if you could flesh out the design a bit more, so that it's clear that we're capturing what you have in mind.

rtabbara avatar Dec 08 '15 09:12 rtabbara

@rtabbara Sure, here's how I've done it in the past.

First, you'd need to create an object which would store information about a render state change. As I understand it, you can change multiple values between a render state, so you might do something as follows:

public class StateChange
{
    // Maybe this could be a CCNode instead of object?
    public object ObjectCausingChange { get; set; }
    public Texture2D Texture { get; set;}
    // Don't remember what the blend operation variable type is:
    public BlendOperation BlendOperation { get; set;}
    // Is there a "color operation" variable type? I don't remember...
    public ColorOperation ColorOperation { get; set;}
    public Rectangle? ViewportBounds { get; set;}
    public TextureAddressMode TextureAddressMode { get; set;}
    public TextureFilter TextureFilter { get; set;}
    // Add anything else which may cause a state change
}

Then the root object (CCScene?) would have:

public List<StateChange> StateChangesThisFrame { get; private set;}

This list would get emptied and re-filled every frame when the rendering occurs. Also, since this may be heavy, recording of this could be optional:

myCCSceneInstance.RecordsRenderStateChanges = true;

Once these are recorded, there are lots of options on how to make it easier for the user to consume, but the first step would be just having them in the first place.

For example, here's how FlatRedBall uses this information and exposes it as the app is running through an accompanying Windows UI:

image

Furthermore, in FlatRedBall the state change objects can be easily exported to an .XML file, which can be loaded by the profiler shown above, in case users want to record a play session and review it later, or send it to some other programmer for evaluation.

vchelaru avatar Dec 11 '15 20:12 vchelaru