//
// Copyright (c) 2019-2020 Ryujinx
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see .
//
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Parameter;
using System;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Server.Performance
{
public abstract class PerformanceManager
{
///
/// Get the required size for a single performance frame.
///
/// The audio renderer configuration.
/// The behaviour context.
/// The required size for a single performance frame.
public static ulong GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref AudioRendererConfiguration parameter, ref BehaviourContext behaviourContext)
{
uint version = behaviourContext.GetPerformanceMetricsDataFormat();
if (version == 2)
{
return (ulong)PerformanceManagerGeneric.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter);
}
else if (version == 1)
{
return (ulong)PerformanceManagerGeneric.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter);
}
throw new NotImplementedException($"Unknown Performance metrics data format version {version}");
}
///
/// Copy the performance frame history to the supplied user buffer and returns the size copied.
///
/// The supplied user buffer to store the performance frame into.
/// The size copied to the supplied buffer.
public abstract uint CopyHistories(Span performanceOutput);
///
/// Set the target node id to profile.
///
/// The target node id to profile.
public abstract void SetTargetNodeId(int target);
///
/// Check if the given target node id is profiled.
///
/// The target node id to check.
/// Return true, if the given target node id is profiled.
public abstract bool IsTargetNodeId(int target);
///
/// Get the next buffer to store a performance entry.
///
/// The output .
/// The info.
/// The node id of the entry.
/// Return true, if a valid was returned.
public abstract bool GetNextEntry(out PerformanceEntryAddresses performanceEntry, PerformanceEntryType entryType, int nodeId);
///
/// Get the next buffer to store a performance detailed entry.
///
/// The output .
/// The info.
/// The info.
/// The node id of the entry.
/// Return true, if a valid was returned.
public abstract bool GetNextEntry(out PerformanceEntryAddresses performanceEntry, PerformanceDetailType detailType, PerformanceEntryType entryType, int nodeId);
///
/// Finalize the current performance frame.
///
/// Indicate if the DSP is running behind.
/// The count of voices that were dropped.
/// The start ticks of the audio rendering.
public abstract void TapFrame(bool dspRunningBehind, uint voiceDropCount, ulong startRenderingTicks);
///
/// Create a new .
///
/// The backing memory available for use by the manager.
/// The audio renderer configuration.
/// The behaviour context;
/// A new .
public static PerformanceManager Create(Memory performanceBuffer, ref AudioRendererConfiguration parameter, BehaviourContext behaviourContext)
{
uint version = behaviourContext.GetPerformanceMetricsDataFormat();
switch (version)
{
case 1:
return new PerformanceManagerGeneric(performanceBuffer,
ref parameter);
case 2:
return new PerformanceManagerGeneric(performanceBuffer,
ref parameter);
default:
throw new NotImplementedException($"Unknown Performance metrics data format version {version}");
}
}
}
}