Phase 7.5 timing logs
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "RenderEngine.h"
|
||||
#include "RuntimeEventDispatcher.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <windows.h>
|
||||
@@ -294,6 +295,13 @@ void VideoBackend::StartOutputCompletionWorker()
|
||||
mPendingOutputCompletions.clear();
|
||||
mReadyOutputQueue.Clear();
|
||||
mNextReadyOutputFrameIndex = 0;
|
||||
mHasReadyQueueDepthBaseline = false;
|
||||
mMinReadyQueueDepth = 0;
|
||||
mMaxReadyQueueDepth = 0;
|
||||
mReadyQueueZeroDepthCount = 0;
|
||||
mOutputRenderMilliseconds = 0.0;
|
||||
mSmoothedOutputRenderMilliseconds = 0.0;
|
||||
mMaxOutputRenderMilliseconds = 0.0;
|
||||
mOutputCompletionWorkerStopping = false;
|
||||
mOutputCompletionWorkerRunning = true;
|
||||
mOutputCompletionWorker = std::thread(&VideoBackend::OutputCompletionWorkerMain, this);
|
||||
@@ -347,7 +355,9 @@ void VideoBackend::ProcessOutputFrameCompletion(const VideoIOCompletion& complet
|
||||
{
|
||||
RecordFramePacing(completion.result);
|
||||
PublishOutputFrameCompleted(completion);
|
||||
const VideoPlayoutRecoveryDecision recoveryDecision = AccountForCompletionResult(completion.result, mReadyOutputQueue.GetMetrics().depth);
|
||||
const RenderOutputQueueMetrics initialQueueMetrics = mReadyOutputQueue.GetMetrics();
|
||||
RecordReadyQueueDepthSample(initialQueueMetrics);
|
||||
const VideoPlayoutRecoveryDecision recoveryDecision = AccountForCompletionResult(completion.result, initialQueueMetrics.depth);
|
||||
|
||||
FillReadyOutputQueue(completion);
|
||||
if (!ScheduleReadyOutputFrame())
|
||||
@@ -364,9 +374,15 @@ void VideoBackend::RecordBackendPlayoutHealth(VideoIOCompletionResult result, co
|
||||
queueMetrics.depth,
|
||||
queueMetrics.capacity,
|
||||
queueMetrics.pushedCount,
|
||||
mMinReadyQueueDepth,
|
||||
mMaxReadyQueueDepth,
|
||||
mReadyQueueZeroDepthCount,
|
||||
queueMetrics.poppedCount,
|
||||
queueMetrics.droppedCount,
|
||||
queueMetrics.underrunCount,
|
||||
mOutputRenderMilliseconds,
|
||||
mSmoothedOutputRenderMilliseconds,
|
||||
mMaxOutputRenderMilliseconds,
|
||||
recoveryDecision.completedFrameIndex,
|
||||
recoveryDecision.scheduledFrameIndex,
|
||||
recoveryDecision.scheduledLeadFrames,
|
||||
@@ -391,12 +407,14 @@ bool VideoBackend::FillReadyOutputQueue(const VideoIOCompletion& completion)
|
||||
return filledAny;
|
||||
filledAny = true;
|
||||
metrics = mReadyOutputQueue.GetMetrics();
|
||||
RecordReadyQueueDepthSample(metrics);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VideoBackend::RenderReadyOutputFrame(const VideoIOState& state, const VideoIOCompletion& completion)
|
||||
{
|
||||
const auto renderStart = std::chrono::steady_clock::now();
|
||||
VideoIOOutputFrame outputFrame;
|
||||
if (!BeginOutputFrame(outputFrame))
|
||||
return false;
|
||||
@@ -409,9 +427,16 @@ bool VideoBackend::RenderReadyOutputFrame(const VideoIOState& state, const Video
|
||||
if (!rendered)
|
||||
{
|
||||
ApplyLifecycleTransition(VideoBackendLifecycleState::Degraded, "Output frame render request failed; skipping schedule for this frame.");
|
||||
const double renderMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
|
||||
std::chrono::steady_clock::now() - renderStart).count();
|
||||
RecordOutputRenderDuration(renderMilliseconds);
|
||||
return false;
|
||||
}
|
||||
|
||||
const double renderMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(
|
||||
std::chrono::steady_clock::now() - renderStart).count();
|
||||
RecordOutputRenderDuration(renderMilliseconds);
|
||||
|
||||
RenderOutputFrame readyFrame;
|
||||
readyFrame.frame = outputFrame;
|
||||
readyFrame.frameIndex = ++mNextReadyOutputFrameIndex;
|
||||
@@ -423,6 +448,7 @@ bool VideoBackend::ScheduleReadyOutputFrame()
|
||||
RenderOutputFrame readyFrame;
|
||||
if (!mReadyOutputQueue.TryPop(readyFrame))
|
||||
return false;
|
||||
RecordReadyQueueDepthSample(mReadyOutputQueue.GetMetrics());
|
||||
|
||||
if (!ScheduleOutputFrame(readyFrame.frame))
|
||||
return false;
|
||||
@@ -488,6 +514,37 @@ void VideoBackend::RecordFramePacing(VideoIOCompletionResult completionResult)
|
||||
PublishTimingSample("VideoBackend", "smoothedCompletionInterval", mSmoothedCompletionIntervalMilliseconds, "ms");
|
||||
}
|
||||
|
||||
void VideoBackend::RecordReadyQueueDepthSample(const RenderOutputQueueMetrics& metrics)
|
||||
{
|
||||
if (!mHasReadyQueueDepthBaseline)
|
||||
{
|
||||
mHasReadyQueueDepthBaseline = true;
|
||||
mMinReadyQueueDepth = metrics.depth;
|
||||
mMaxReadyQueueDepth = metrics.depth;
|
||||
}
|
||||
else
|
||||
{
|
||||
mMinReadyQueueDepth = (std::min)(mMinReadyQueueDepth, metrics.depth);
|
||||
mMaxReadyQueueDepth = (std::max)(mMaxReadyQueueDepth, metrics.depth);
|
||||
}
|
||||
|
||||
if (metrics.depth == 0)
|
||||
++mReadyQueueZeroDepthCount;
|
||||
}
|
||||
|
||||
void VideoBackend::RecordOutputRenderDuration(double renderMilliseconds)
|
||||
{
|
||||
mOutputRenderMilliseconds = (std::max)(renderMilliseconds, 0.0);
|
||||
if (mSmoothedOutputRenderMilliseconds <= 0.0)
|
||||
mSmoothedOutputRenderMilliseconds = mOutputRenderMilliseconds;
|
||||
else
|
||||
mSmoothedOutputRenderMilliseconds = mSmoothedOutputRenderMilliseconds * 0.9 + mOutputRenderMilliseconds * 0.1;
|
||||
mMaxOutputRenderMilliseconds = (std::max)(mMaxOutputRenderMilliseconds, mOutputRenderMilliseconds);
|
||||
|
||||
PublishTimingSample("VideoBackend", "outputRender", mOutputRenderMilliseconds, "ms");
|
||||
PublishTimingSample("VideoBackend", "smoothedOutputRender", mSmoothedOutputRenderMilliseconds, "ms");
|
||||
}
|
||||
|
||||
bool VideoBackend::ApplyLifecycleTransition(VideoBackendLifecycleState state, const std::string& message)
|
||||
{
|
||||
const VideoBackendLifecycleTransition transition = mLifecycle.TransitionTo(state, message);
|
||||
|
||||
Reference in New Issue
Block a user