forked from sin365/AxibugEmuOnline
NetReplay增加FrameProfiler(未实装)
This commit is contained in:
parent
7ed40210fd
commit
70fb6154ec
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace AxiReplay
|
||||
{
|
||||
public partial class FrameProfiler
|
||||
{
|
||||
private int m_headFrame;
|
||||
private int m_cacheCount;
|
||||
private int m_targetFrameRate;
|
||||
private RingBuffer<double> m_timePoints;
|
||||
private double m_lastTime;
|
||||
|
||||
private Stopwatch sw;
|
||||
|
||||
public void InputHead(int headFrame)
|
||||
{
|
||||
m_headFrame = headFrame;
|
||||
var currentTimeMs = GetCurrTime();
|
||||
|
||||
if (m_timePoints.Available() == 60)
|
||||
CalcCacheCount();
|
||||
m_timePoints.Write(currentTimeMs - m_lastTime);
|
||||
|
||||
m_lastTime = currentTimeMs;
|
||||
}
|
||||
public void Reset(int targetFrameRate = 60)
|
||||
{
|
||||
if (sw != null) sw.Stop();
|
||||
|
||||
sw = Stopwatch.StartNew();
|
||||
m_timePoints = new RingBuffer<double>(targetFrameRate);
|
||||
m_lastTime = 0;
|
||||
m_targetFrameRate = targetFrameRate;
|
||||
}
|
||||
|
||||
void CalcCacheCount()
|
||||
{
|
||||
double deltaMax = 0;
|
||||
while (m_timePoints.TryRead(out double delta))
|
||||
{
|
||||
deltaMax = Math.Max(deltaMax, delta);
|
||||
}
|
||||
|
||||
int minCacheCount = (int)Math.Ceiling(deltaMax * m_targetFrameRate);
|
||||
m_cacheCount = minCacheCount;
|
||||
}
|
||||
|
||||
double GetCurrTime()
|
||||
{
|
||||
if (sw == null) return 0;
|
||||
return sw.Elapsed.TotalMilliseconds;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfd4511a83ff0bf4ea7615b87e7d09aa
|
@ -0,0 +1,78 @@
|
||||
using System.Threading;
|
||||
|
||||
namespace AxiReplay
|
||||
{
|
||||
public partial class FrameProfiler
|
||||
{
|
||||
internal class RingBuffer<T>
|
||||
{
|
||||
private readonly T[] buffer;
|
||||
private readonly int capacity;
|
||||
private int writePos;
|
||||
private int readPos;
|
||||
private int count;
|
||||
|
||||
public RingBuffer(int capacity)
|
||||
{
|
||||
this.capacity = capacity;
|
||||
this.buffer = new T[capacity];
|
||||
this.writePos = 0;
|
||||
this.readPos = 0;
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
public void Write(T item)
|
||||
{
|
||||
int localWritePos;
|
||||
int localReadPos;
|
||||
|
||||
do
|
||||
{
|
||||
localWritePos = Volatile.Read(ref writePos);
|
||||
localReadPos = Volatile.Read(ref readPos);
|
||||
|
||||
int nextWritePos = (localWritePos + 1) % capacity;
|
||||
|
||||
if (nextWritePos == localReadPos)
|
||||
{
|
||||
// 缓冲区已满,覆盖最旧的未读数据
|
||||
Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos);
|
||||
}
|
||||
}
|
||||
while (Interlocked.CompareExchange(ref writePos, (localWritePos + 1) % capacity, localWritePos) != localWritePos);
|
||||
|
||||
buffer[localWritePos] = item;
|
||||
Interlocked.Increment(ref count);
|
||||
}
|
||||
|
||||
public bool TryRead(out T item)
|
||||
{
|
||||
item = default(T);
|
||||
|
||||
int localReadPos;
|
||||
int localWritePos;
|
||||
|
||||
do
|
||||
{
|
||||
localReadPos = Volatile.Read(ref readPos);
|
||||
localWritePos = Volatile.Read(ref writePos);
|
||||
|
||||
if (localReadPos == localWritePos)
|
||||
{
|
||||
return false; // 缓冲区为空
|
||||
}
|
||||
}
|
||||
while (Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos) != localReadPos);
|
||||
|
||||
item = buffer[localReadPos];
|
||||
Interlocked.Decrement(ref count);
|
||||
return true;
|
||||
}
|
||||
|
||||
public int Available()
|
||||
{
|
||||
return Volatile.Read(ref count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b17d83b69bd47094594c32fcff9715f4
|
@ -34,6 +34,8 @@ namespace AxiReplay
|
||||
/// </summary>
|
||||
ReplayStep mNextReplay;
|
||||
|
||||
FrameProfiler frameProfiler = new FrameProfiler();
|
||||
|
||||
bool bNetInit = false;
|
||||
public NetReplay()
|
||||
{
|
||||
@ -45,6 +47,8 @@ namespace AxiReplay
|
||||
mCurrReplay = default(ReplayStep);
|
||||
mCurrReplay.FrameStartID = int.MinValue;
|
||||
bNetInit = false;
|
||||
|
||||
frameProfiler.Reset();
|
||||
}
|
||||
public void InData(ReplayStep inputData, int ServerFrameIdx, uint ServerForwardCount)
|
||||
{
|
||||
@ -57,7 +61,10 @@ namespace AxiReplay
|
||||
bNetInit = true;
|
||||
mNextReplay = mNetReplayQueue.Dequeue();
|
||||
}
|
||||
|
||||
frameProfiler.InputHead(inputData.FrameStartID);
|
||||
}
|
||||
|
||||
public bool TryGetNextFrame(out ReplayStep data, out int frameDiff, out bool inputDiff)
|
||||
{
|
||||
if (!bNetInit)
|
||||
@ -93,13 +100,15 @@ namespace AxiReplay
|
||||
{
|
||||
bool result;
|
||||
inputDiff = false;
|
||||
|
||||
|
||||
//if (targetFrame == mNextReplay.FrameStartID && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count > 0)
|
||||
if (targetFrame == mNextReplay.FrameStartID && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count >= mRemoteForwardCount)
|
||||
{
|
||||
{
|
||||
//当前帧追加
|
||||
mCurrClientFrameIdx = targetFrame;
|
||||
ulong oldInput = mCurrReplay.InPut;
|
||||
mCurrReplay = mNextReplay;
|
||||
mCurrReplay = mNextReplay;
|
||||
if (oldInput != mCurrReplay.InPut)
|
||||
inputDiff = true;
|
||||
mNextReplay = mNetReplayQueue.Dequeue();
|
||||
|
Loading…
Reference in New Issue
Block a user