godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.11k stars 69 forks source link

Integrate Perfetto Profiler into Godot Engine #5346

Open kisg opened 2 years ago

kisg commented 2 years ago

Describe the project you are working on

Various AR / VR projects using Godot Engine in the automotive industry and on Oculus Quest 2.

Describe the problem or limitation you are having in your project

For AR / VR projects the desired performance target is sustained 90 - 120 fps, without sudden performance drops, lags ... etc. For such projects it is important to have tools that allow us to have a unified view of the system's performance, including:

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Perfetto, an open source system profile framework originally developed by Google is such a tool. It is the standard system profiling solution for Android based devices, and it is part of the Android platform since version 9 and enabled on Oculus Quest devices as well if the device is configured in Development Mode. Perfetto is also used as the profiling framework for Chromium development.

It fulfills all the above requirements, has a very low overhead, and allows fine grained configuration to only focus on the parts of the engine where the bottlenecks were identified. It also has a very intuitive web based user interface that turns the collected trace files into a database that can be queried with SQL and also provides nice visualization capabilities. The UI runs fully on the client side, with its engine compiled as a WASM library. For larger traces (above 1-2GB), a local, natively compiled trace processor engine can be used by the UI for increased performance.

Perfetto's SDK component is implemented as a standalone C++ library with practically no external dependencies, and it has 0 overhead when it is disabled at compile time. When compiled in, trace points that are not being used only have around 1-2 ns overhead.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

We already implemented the integration for Godot 3.x as part of client projects, and a Godot 4.0 implementation is also already in progress. A PR for Godot 3.x and Godot-CPP is provided for easy testing and evaluation. https://github.com/godotengine/godot/pull/65382 https://github.com/godotengine/godot-cpp/pull/830

The PR adds a new option to scons perfetto=true. When this option is specified, Perfetto support is built into Godot. It is usually recommended to build Godot in release mode, when the profiler is going to be used. The PR also includes a second option perfetto_sync_opengl=true, which synchronizes all OpenGL draw commands. This option was used during the debugging of the performance bottlenecks of 2D rendering of the Oculus Quest platform, resulting in 2x - 3.5x speedups after fixing (more details will be shared in an upcoming proposal / PR).

The Godot-CPP PR adds a new option to the Godot-CPP test application build perfetto=/path/to/godot/thirdparty/perfetto/include. This folder stores the header files required when the GDNative extensions are compiled with profiling enabled.

The PR currently implements system mode profiling, which means that a separate tracing daemon will collect the profile data from our app and possibly other sources as well (e.g. kernel or GPU counters). This is how Perfetto works on Android based devices. The Perfetto daemons are available for Linux as well:

The Perfetto documentation provides extensive information on how to start the daemons and collect tracing information.

Perfetto also has a standalone mode. In this case the tracing data is saved into a file descriptor provided by the application itself. This mode will work on operating systems where the system wide Perfetto daemons are not available (e.g. Windows, MacOS or console platforms). This mode is not supported in the current PR, but could be added with small effort in a follow-up PR.

The current PR mostly concentrates on the rendering areas of the Engine. Additional hooks were added to different parts of the Engine, so the identifiers of the rendered meshes and 2D elements could be included in the trace data.

A different area where more trace points could be added, is the processing of the Godot SceneTree, in particular the various notifications and Object::call. These were implemented in an earlier incarnation of the patch, and could be added to this one as well (or a follow-up PR). These different trace points are added to different categories, and the user may select which categories to enable during a profiling session.

Another future planned enhancement is to provide trace_event hooks as a singleton object that is available in GDScript and other GDNative / GDExtension languages where C++ macro level integration is not possible or desired at the cost of higher overhead.

We have been using incarnations of this PR in AR projects in the automotive industry and on the Oculus Quest devices with great success. We are certain that this feature would provide great benefits for the Godot community as well.

The current and previous incarnations of the PR were developed by @konczg and @kisg at Migeran.

The work was sponsored by Voxels.

If this enhancement will not be used often, can it be worked around with a few lines of script?

No

Is there a reason why this should be core and not an add-on in the asset library?

This is a core feature.

kisg commented 2 years ago

@Calinou @KoBeWi Thank you for tagging, I just want to make sure that it is clear:

clayjohn commented 2 years ago

I am very interested to see how the integration goes. As you will have noticed in 4.0, we have a built-in visual profiling system that uses a very similar API to what you have implemented in the 3.x backend. It would be wonderful if Perfetto could piggyback on that and then be compiled in as an optional feature (even better if we can make it an optional dependency as 220,000 lines of code is pretty tough to swallow)

kisg commented 1 year ago

I am very interested to see how the integration goes. As you will have noticed in 4.0, we have a built-in visual profiling system that uses a very similar API to what you have implemented in the 3.x backend. It would be wonderful if Perfetto could piggyback on that and then be compiled in as an optional feature (even better if we can make it an optional dependency as 220,000 lines of code is pretty tough to swallow)

It is not a problem to take the Perfetto SDK out, in our internal version we are using it like that, I actually thought it would be easier to get it accepted if it is self-contained :)

Regarding the integrated profiler: I feel that it is way more limited than what Perfetto can offer. For example: the integrated profiler only works in debug builds, while Perfetto is usable in release builds. It also outputs all data into a trace file that can be used by the Perfetto web UI to run queries, compute metrics ... etc.

I think that the integrated profiler is a good option to do simple profiling integrated into the Godot Editor. But when more detailed traces and possibly system level analysis is required, Perfetto is a great tool to have.