Cómo agregar funciones de latencia de fotogramas

Usa las funciones de este tema para integrar la biblioteca de Tuning Fork al código de tu juego.

El archivo de encabezado en include/tuningfork/tuningfork.h contiene la interfaz principal de la biblioteca de Tuning Fork. El archivo en include/tuningfork/tuningfork_extra.h contiene funciones de utilidad.

Varias funciones toman serializaciones de búferes de protocolo. Para obtener más información sobre el uso de búferes de protocolo en tu juego, consulta Acerca de los búferes de protocolo.

Los parámetros de función y los valores que se muestran se explican en los encabezados y en la documentación de referencia de la API.

Funciones del ciclo de vida de Android Performance Tuner

Usa las siguientes funciones para controlar el ciclo de vida de una instancia de Tuning Fork.

Inicialización

TFErrorCode TuningFork_init(const TFSettings* settings, JNIEnv* env, jobject context);

Debes llamar a esta función una vez durante el inicio, por lo general, desde el código nativo ejecutado por el método onCreate() de la app. Esto asigna los datos que necesita la biblioteca de Tuning Fork.

Debes tener un archivo tuningfork_settings.bin presente en assets/tuningfork dentro de tu app, que contiene la configuración de histogramas y anotaciones. Para convertir el archivo de texto a un archivo binario, consulta Diferencias entre las representaciones de texto y las binarias.

Los campos que completas en settings determinan la manera en la que se inicializa la biblioteca.

/**
 * @brief Initialization settings
 *   Zero any values that are not being used.
 */
struct TFSettings {
  /**
   * Cache object to be used for upload data persistence.
   * If unset, data is persisted to /data/local/tmp/tuningfork
   */
  const TFCache* persistent_cache;
  /**
   * The address of the Swappy_injectTracers function.
   * If this is unset, you need to call TuningFork_tick explicitly.
   * If it is set, telemetry for 4 instrument keys is automatically recorded.
   */
  SwappyTracerFn swappy_tracer_fn;
  /**
   * Callback
   * If set, this is called with the fidelity parameters that are downloaded.
   * If unset, you need to call TuningFork_getFidelityParameters explicitly.
   */
  ProtoCallback fidelity_params_callback;
  /**
   * A serialized protobuf containing the fidelity parameters to be uploaded
   *  for training.
   * Set this to nullptr if you are not using training mode. Note that these
   *  are used instead of the default parameters loaded from the APK, if they
   *  are present and there are neither a successful download nor saved parameters.
   */
  const CProtobufSerialization* training_fidelity_params;
  /**
   * A null-terminated UTF-8 string containing the endpoint that Tuning Fork
   * will connect to for parameter, upload, and debug requests. This overrides
   * the value in base_uri in the settings proto and is intended for debugging
   * purposes only.
   */
  const char* endpoint_uri_override;
  /**
   * The version of Swappy that swappy_tracer_fn comes from.
   */
  uint32_t swappy_version;
  /**
   * The number of each metric that is allowed to be allocated at any given
   * time. If any element is zero, the default for that metric type is used.
   * Memory for all metrics is allocated up-front at initialization. When all
   * metrics of a given type are allocated, further requested metrics are not
   * added and data is lost.
   */
  TuningFork_MetricLimits max_num_metrics;
};

Si pasas la función Swappy_injectTracer() (OpenGL, Vulkan) desde la API de Frame Pacing durante la inicialización, la biblioteca de Tuning Fork graba automáticamente la latencia de fotogramas sin que llames de forma explícita a las funciones de marca. Esto se hace en la app de demostración:

void InitTf(JNIEnv* env, jobject activity) {
   SwappyGL_init(env, activity);
   swappy_enabled = SwappyGL_isEnabled();
   TFSettings settings {};
   if (swappy_enabled) {
       settings.swappy_tracer_fn = &SwappyGL_injectTracer;
       settings.swappy_version = Swappy_version();
   }
...
}

Destrucción

TFErrorCode TuningFork_destroy();

Puedes llamar a esta función en el momento de apagado. Ella intenta enviar todos los datos de histogramas almacenados actualmente para su posterior carga antes de anular la asignación de la memoria usada por la biblioteca de Tuning Fork.

Vaciado

TFErrorCode TuningFork_flush();

Esta función vacía los histogramas grabados (por ejemplo, cuando el juego se envía al primer o segundo plano). No vacía los datos si el período mínimo de carga, que tiene un valor predeterminado de un minuto, todavía no transcurrió desde la carga anterior.

Configuración de parámetros de fidelidad

TFErrorCode TuningFork_setFidelityParameters(const CProtobufSerialization* params);

Esta función anula los parámetros de fidelidad actuales con los que se asocian los datos de fotogramas. Debes llamar a esta función cuando un jugador cambie en forma manual la configuración de calidad del juego.

Anotaciones

TFErrorCode TuningFork_setCurrentAnnotation(const CProtobufSerialization* annotation);

Esta función establece la anotación que se asociará con las marcas sucesivas. Muestra TFERROR_INVALID_ANNOTATION si se produjo un error mientras se decodificaba la anotación; de lo contrario, muestra TFERROR_OK.

Funciones por fotograma

TFErrorCode TuningFork_frameTick(TFInstrumentKey key);

Esta función graba el tiempo entre la marca anterior con la key especificada y la hora actual del histograma asociado con key y la anotación actual.

TFErrorCode TuningFork_frameDeltaTimeNanos(TFInstrumentKey key, TFDuration dt);

Esta función graba la duración en el histograma asociado con key y la anotación actual.

TFErrorCode TuningFork_startTrace(TFInstrumentKey key, TraceHandle* handle);

Esta función establece un controlador para realizar el seguimiento asociado con la key especificada.

TFErrorCode TuningFork_endTrace(TraceHandle handle);

Esta función graba el intervalo de tiempo desde la llamada TuningFork_startTrace() correspondiente en el histograma asociado con la key usada hasta la anotación actual.

Funciones del ciclo de vida de la app

typedef enum TuningFork_LifecycleState {
    TUNINGFORK_STATE_UNINITIALIZED = 0,
    TUNINGFORK_STATE_ONCREATE = 1,
    TUNINGFORK_STATE_ONSTART = 2,
    TUNINGFORK_STATE_ONSTOP = 3,
    TUNINGFORK_STATE_ONDESTROY = 4,
} TuningFork_LifecycleState;

TFErrorCode TuningFork_reportLifecycleEvent(TuningForkLifecycleState state);

Llama a esta función desde los métodos del ciclo de vida adecuados en la Actividad principal de tu juego y pasa la enumeración correspondiente. Mediante el registro de los eventos de ciclo de vida del juego, el APT puede comprender mejor cuándo puede fallar tu juego o cuándo los usuarios pueden salir de la app (por ejemplo, durante eventos de carga prolongados).

Funciones avanzadas

Las siguientes funciones están disponibles en tuningfork_extra.h.

Cómo buscar y cargar archivos en un APK

TFErrorCode TuningFork_findFidelityParamsInApk(JNIEnv* env, jobject context, const char* filename, CProtobufSerialization* fidelityParams);

Esta función carga fidelityParams desde el directorio assets/tuningfork en el APK con el nombre de archivo dado. fidelityParams debe ser una serialización de un mensaje FidelityParams. Para obtener más información, consulta Cómo definir niveles de calidad.

La propiedad de la serialización se pasa al llamador, que debe llamar a CProtobufSerialization_Free para anular la asignación de la memoria retenida.

Cómo descargar parámetros de fidelidad en un subproceso independiente

void TuningFork_startFidelityParamDownloadThread(const CProtobufSerialization* defaultParams, ProtoCallback fidelity_params_callback);

Activa un subproceso de descarga a fin de recuperar parámetros de fidelidad. El subproceso vuelve a intentar la solicitud hasta que se descargan los parámetros o se agota el tiempo de espera. Los parámetros descargados se almacenan de forma local. Cuando se reinicia la app, esta usa los parámetros descargados en lugar de los predeterminados.

Cómo guardar y borrar los parámetros de fidelidad almacenados en el dispositivo

TFErrorCode TuningFork_saveOrDeleteFidelityParamsFile(JNIEnv* env, jobject context, const CProtobufSerialization* fidelity_params);

Esta función solo es necesaria en el modo experto, en el cual se descargan los parámetros de fidelidad desde un servidor. Guarda o borra (si fidelity_params es nulo) los archivos almacenados localmente que se usan cuando no se puede acceder al servidor.

Solicitudes web

La biblioteca realiza los siguientes tipos de solicitudes al extremo del servidor:

  • Se hace una solicitud generateTuningParameters durante la inicialización.
  • Durante el juego, se realiza una solicitud uploadTelemetry de forma periódica para enviar datos al servidor.
  • Los APK de depuración también pueden enviar solicitudes debugInfo, que informan al servidor de depuración sobre la configuración, los parámetros de fidelidad predeterminados y la estructura dev_tuningfork.proto.

Jugadores sin conexión

Si no hay una conexión disponible en la inicialización, se volverá a realizar la solicitud varias veces con un tiempo de espera creciente.

Si no hay conexión durante la carga, esta se almacenará en caché. Puedes proporcionar tu propio mecanismo de almacenamiento en caché si pasas un objeto TFCache en la inicialización. Si no proporcionas tu propia caché, las cargas se almacenarán como archivos en el almacenamiento temporal.