Add loading time recording functions

It is important to record when your game is performing loading events for two reasons:

  1. To avoid polluting your frame time data while loading.
  2. To analyze load times to see when and where load times are longer than acceptable.

A loading event can have associated metadata:

typedefstructTuningFork_LoadingTimeMetadata{
enumLoadingState{
UNKNOWN_STATE=0,
// The first time the game is run
FIRST_RUN=1,
// App is not backgrounded
COLD_START=2,
// App is backgrounded
WARM_START=3,
// App is backgrounded, least work needed
HOT_START=4,
// Asset loading between levels
INTER_LEVEL=5
}state;
enumLoadingSource{
UNKNOWN_SOURCE=0,
// Uncompressing data.
MEMORY=1,
// Reading assets from APK bundle.
APK=2,
// Reading assets from device storage.
DEVICE_STORAGE=3,
// Reading assets from external storage, e.g. SD card.
EXTERNAL_STORAGE=4,
// Loading assets from the network.
NETWORK=5,
// Shader compilation.
SHADER_COMPILATION=6,
// Time spent between process starting and onCreate.
PRE_ACTIVITY=7,
// Total time spent between process starting and first render frame.
FIRST_TOUCH_TO_FIRST_FRAME=8
}source;
int32_tcompression_level;// 0 = no compression, 100 = max compression
enumNetworkConnectivity{
UNKNOWN=0,
WIFI=1,
CELLULAR_NETWORK=2
}network_connectivity;
uint64_tnetwork_transfer_speed_bps;// bandwidth in bits per second
uint64_tnetwork_latency_ns;// latency in nanoseconds
}TuningFork_LoadingTimeMetadata;

Any fields that aren't relevant to your needs can be zero.

A loading event can also have an associated annotation. This is defined in the same way as frame time annotations, using one or more fields in the Annotation message in the dev_tuningfork.proto file.

TuningFork_ErrorCode TuningFork_startRecordingLoadingTime( const TuningFork_LoadingTimeMetadata* eventMetadata, uint32_t eventMetadataSize, const TuningFork_CProtobufSerialization* annotation, TuningFork_LoadingEventHandle* handle);

This function starts recording a loading time event associated with the given metadata and annotation, and fills in a handle to be used in the TuningFork_stopRecordingLoadingTime() function.

TuningFork_ErrorCode TuningFork_stopRecordingLoadingTime( TuningFork_LoadingEventHandle handle);

This function stops recording an event previously started by TuningFork_startRecordingLoadingTime(). The event is uploaded at the next session flush.

TuningFork_ErrorCode TuningFork_recordLoadingTime( uint64_t time_ns, const TuningFork_LoadingTimeMetadata* eventMetadata, uint32_t eventMetadataSize, const TuningFork_CProtobufSerialization* annotation);

We strongly recommend directly using the start and stop functions described previously. If you can't do this, however, you can call this function to record a duration and its associated metadata and annotation.

Loading group functions

In your game, you may record several loading events for a single loading period seen by the user. Some examples include (but aren't limited to) file loading, decompression, and shader compilation.

It is important to inform Tuning Fork that loading events are part of such a group so that it can provide better insights. Bracket your loading events with the following start and stop functions in order to do this.

TuningFork_ErrorCode TuningFork_startLoadingGroup( const TuningFork_LoadingTimeMetadata* eventMetadata, uint32_t eventMetadataSize, const TuningFork_CProtobufSerialization* annotation, TuningFork_LoadingEventHandle* handle);

This function starts a loading group associated with the given metadata and annotation, and fills in a handle to be used in the TuningFork_stopLoadingGroup() function. The metadata and annotation are currently not used by the Play backend and can be set to nullptr. All subsequent loading events will be tagged by a unique group ID.

TuningFork_ErrorCode TuningFork_stopLoadingGroup( TuningFork_LoadingEventHandle handle);

This function stops a loading group previously started by TuningFork_startLoadingGroup(). Subsequent loading events will not have a group ID until TuningFork_startLoadingGroup() is called again.

Figure 1. Example of the loading group.

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2025年08月26日 UTC.