blob: 648daac8fe0d6c00fd6886209aab1f2bbeed1b92 [file] [log] [blame]
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cstdlib>
#include <cstring>
#include "jni/jni_helper.h"
#include "proto/protobuf_util.h"
#include "settings.h"
#include "tuningfork/tuningfork.h"
#include "tuningfork/tuningfork_extra.h"
#include "tuningfork_internal.h"
#include "tuningfork_utils.h"
extern "C" {
namespace tf = tuningfork;
namespace jni = gamesdk::jni;
TuningFork_ErrorCode TuningFork_init_internal(
const TuningFork_Settings *c_settings_in, JNIEnv *env, jobject context) {
tf::Settings settings{};
if (c_settings_in != nullptr) {
settings.c_settings = *c_settings_in;
}
jni::Init(env, context);
bool first_run = tf::CheckIfFirstRun();
TuningFork_ErrorCode err = tf::Settings::FindInApk(&settings);
if (err != TUNINGFORK_ERROR_OK) return err;
settings.Check();
err = tf::Init(settings, nullptr, nullptr, nullptr, nullptr, nullptr,
first_run);
if (err != TUNINGFORK_ERROR_OK) return err;
if (!(settings.default_fidelity_parameters_filename.empty() &&
settings.c_settings.training_fidelity_params == nullptr)) {
err = GetDefaultsFromAPKAndDownloadFPs(settings);
}
return err;
}
// Blocking call to get fidelity parameters from the server.
// Note that once fidelity parameters are downloaded, any timing information is
// recorded
// as being associated with those parameters.
TuningFork_ErrorCode TuningFork_getFidelityParameters(
const TuningFork_CProtobufSerialization *default_params,
TuningFork_CProtobufSerialization *params, uint32_t timeout_ms) {
tf::ProtobufSerialization defaults;
if (default_params) defaults = tf::ToProtobufSerialization(*default_params);
tf::ProtobufSerialization s;
TuningFork_ErrorCode result =
tf::GetFidelityParameters(defaults, s, timeout_ms);
if (result == TUNINGFORK_ERROR_OK && params)
tf::ToCProtobufSerialization(s, *params);
return result;
}
// Protobuf serialization of the current annotation
TuningFork_ErrorCode TuningFork_setCurrentAnnotation(
const TuningFork_CProtobufSerialization *annotation) {
if (annotation != nullptr)
return tf::SetCurrentAnnotation(
tf::ToProtobufSerialization(*annotation));
else
return TUNINGFORK_ERROR_INVALID_ANNOTATION;
}
// Record a frame tick that will be associated with the instrumentation key and
// the current
// annotation
TuningFork_ErrorCode TuningFork_frameTick(TuningFork_InstrumentKey id) {
return tf::FrameTick(id);
}
// Record a frame tick using an external time, rather than system time
TuningFork_ErrorCode TuningFork_frameDeltaTimeNanos(TuningFork_InstrumentKey id,
TuningFork_Duration dt) {
return tf::FrameDeltaTimeNanos(id, std::chrono::nanoseconds(dt));
}
// Start a trace segment
TuningFork_ErrorCode TuningFork_startTrace(TuningFork_InstrumentKey key,
TuningFork_TraceHandle *handle) {
if (handle == nullptr) return TUNINGFORK_ERROR_INVALID_TRACE_HANDLE;
return tf::StartTrace(key, *handle);
}
// Record a trace with the key and annotation set using startTrace
TuningFork_ErrorCode TuningFork_endTrace(TuningFork_TraceHandle h) {
return tf::EndTrace(h);
}
TuningFork_ErrorCode TuningFork_flush() { return tf::Flush(); }
TuningFork_ErrorCode TuningFork_destroy() {
tf::KillDownloadThreads();
return tf::Destroy();
}
TuningFork_ErrorCode TuningFork_setFidelityParameters(
const TuningFork_CProtobufSerialization *params) {
if (params != nullptr)
return tf::SetFidelityParameters(tf::ToProtobufSerialization(*params));
else
return TUNINGFORK_ERROR_BAD_PARAMETER;
}
TuningFork_ErrorCode TuningFork_enableMemoryRecording(bool enable) {
return tf::EnableMemoryRecording(enable);
}
// Take the C metadata structure passed in and copy to the C++ structure,
// taking into account any version changes indicated by changes in the size.
// Currently tf::LoadingTimeMetadata is typedefed to
// TuningFork_LoadingTimeMetadata so this does nothing.
static TuningFork_ErrorCode CheckLoadingMetaData(
const TuningFork_LoadingTimeMetadata *eventMetadata_in,
uint32_t eventMetadataSize, tf::LoadingTimeMetadata &eventMetadata) {
if (eventMetadata_in == nullptr ||
eventMetadataSize != sizeof(TuningFork_LoadingTimeMetadata))
return TUNINGFORK_ERROR_BAD_PARAMETER;
eventMetadata = *eventMetadata_in;
return TUNINGFORK_ERROR_OK;
}
TuningFork_ErrorCode TuningFork_recordLoadingTime(
uint64_t time_ns, const TuningFork_LoadingTimeMetadata *eventMetadata_in,
uint32_t eventMetadataSize,
const TuningFork_CProtobufSerialization *annotation) {
tf::LoadingTimeMetadata eventMetadata;
auto err = CheckLoadingMetaData(eventMetadata_in, eventMetadataSize,
eventMetadata);
if (err != TUNINGFORK_ERROR_OK) return err;
return tf::RecordLoadingTime(std::chrono::nanoseconds(time_ns),
eventMetadata,
tf::ToProtobufSerialization(*annotation));
}
TuningFork_ErrorCode TuningFork_startRecordingLoadingTime(
const TuningFork_LoadingTimeMetadata *eventMetadata_in,
uint32_t eventMetadataSize,
const TuningFork_CProtobufSerialization *annotation,
TuningFork_LoadingEventHandle *handle) {
tf::LoadingTimeMetadata eventMetadata;
auto err = CheckLoadingMetaData(eventMetadata_in, eventMetadataSize,
eventMetadata);
if (err != TUNINGFORK_ERROR_OK) {
return err;
}
if (handle == nullptr) return TUNINGFORK_ERROR_INVALID_LOADING_HANDLE;
return tf::StartRecordingLoadingTime(
eventMetadata, tf::ToProtobufSerialization(*annotation), *handle);
}
TuningFork_ErrorCode TuningFork_stopRecordingLoadingTime(
TuningFork_LoadingEventHandle handle) {
return tf::StopRecordingLoadingTime(handle);
}
TuningFork_ErrorCode TuningFork_reportLifecycleEvent(
TuningFork_LifecycleState state) {
return tf::ReportLifecycleEvent(state);
}
void TUNINGFORK_VERSION_SYMBOL() {
// Intentionally empty: this function is used to ensure that the proper
// version of the library is linked against the proper headers.
// In case of mismatch, a linker error will be triggered because of an
// undefined symbol, as the name of the function depends on the version.
}
} // extern "C" {