mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 16:51:31 +00:00
[client] metrics: expose cadence pipeline stages
This commit is contained in:
@@ -221,11 +221,14 @@ struct FrameTimingRecord
|
|||||||
unsigned readyMask;
|
unsigned readyMask;
|
||||||
bool producerValid;
|
bool producerValid;
|
||||||
bool phaseValid;
|
bool phaseValid;
|
||||||
|
bool transportValid;
|
||||||
|
|
||||||
uint64_t captureTime;
|
uint64_t captureTime;
|
||||||
uint64_t postProcessTime;
|
uint64_t postProcessTime;
|
||||||
uint64_t copyTime;
|
uint64_t copyTime;
|
||||||
uint64_t readyTime;
|
uint64_t readyTime;
|
||||||
|
uint64_t holdTime;
|
||||||
|
uint64_t readyLeadTime;
|
||||||
uint64_t importTime;
|
uint64_t importTime;
|
||||||
uint64_t importWaitTime;
|
uint64_t importWaitTime;
|
||||||
uint64_t dispatchTime;
|
uint64_t dispatchTime;
|
||||||
@@ -385,6 +388,8 @@ static void frameTimingFinishFrame(LG_RendererFrameToken token,
|
|||||||
record->postProcessTime = timing->postProcessTime;
|
record->postProcessTime = timing->postProcessTime;
|
||||||
record->copyTime = timing->copyTime;
|
record->copyTime = timing->copyTime;
|
||||||
record->readyTime = timing->readyTime;
|
record->readyTime = timing->readyTime;
|
||||||
|
record->holdTime = timing->holdTime;
|
||||||
|
record->readyLeadTime = timing->readyLeadTime;
|
||||||
if (record->timestamp < timestamp)
|
if (record->timestamp < timestamp)
|
||||||
record->timestamp = timestamp;
|
record->timestamp = timestamp;
|
||||||
record->readyMask |= FRAME_TIMING_FRAME_READY;
|
record->readyMask |= FRAME_TIMING_FRAME_READY;
|
||||||
@@ -422,12 +427,14 @@ static void frameTimingFinishRender(const LG_RendererFrameTiming * timing,
|
|||||||
record->swapTime = timing->swapTime;
|
record->swapTime = timing->swapTime;
|
||||||
record->readyMask |= FRAME_TIMING_RENDER_READY;
|
record->readyMask |= FRAME_TIMING_RENDER_READY;
|
||||||
|
|
||||||
|
record->transportValid = record->phaseValid &&
|
||||||
|
timing->frameToken == cadenceToken;
|
||||||
|
|
||||||
feedbackFrameSerial = record->frameSerial;
|
feedbackFrameSerial = record->frameSerial;
|
||||||
feedbackGeneration = record->scheduleGeneration;
|
feedbackGeneration = record->scheduleGeneration;
|
||||||
feedbackEpoch = record->scheduleEpoch;
|
feedbackEpoch = record->scheduleEpoch;
|
||||||
feedbackDeadline = record->scheduleDeadlineSerial;
|
feedbackDeadline = record->scheduleDeadlineSerial;
|
||||||
feedbackValid = record->phaseValid &&
|
feedbackValid = record->transportValid;
|
||||||
timing->frameToken == cadenceToken;
|
|
||||||
feedbackQueueStart = record->queueStart;
|
feedbackQueueStart = record->queueStart;
|
||||||
|
|
||||||
if (unlikely(
|
if (unlikely(
|
||||||
@@ -500,10 +507,19 @@ static void frameTimingPublishReady(void)
|
|||||||
const uint64_t queueTime =
|
const uint64_t queueTime =
|
||||||
record->prepareStart > record->queueStart ?
|
record->prepareStart > record->queueStart ?
|
||||||
record->prepareStart - record->queueStart : 0;
|
record->prepareStart - record->queueStart : 0;
|
||||||
const uint32_t validMask =
|
const uint64_t transportAccounted =
|
||||||
|
record->importTime + record->dispatchTime + queueTime;
|
||||||
|
const uint64_t transportTime =
|
||||||
|
record->readyLeadTime > transportAccounted ?
|
||||||
|
record->readyLeadTime - transportAccounted : 0;
|
||||||
|
uint32_t validMask =
|
||||||
OVERLAY_FRAME_TIMING_VALID_ALL &
|
OVERLAY_FRAME_TIMING_VALID_ALL &
|
||||||
(record->producerValid ? UINT32_MAX :
|
~OVERLAY_FRAME_TIMING_VALID_PRESENT;
|
||||||
~OVERLAY_FRAME_TIMING_VALID_PRODUCER);
|
if (!record->producerValid)
|
||||||
|
validMask &= ~OVERLAY_FRAME_TIMING_VALID_PRODUCER;
|
||||||
|
if (!record->producerValid || !record->transportValid)
|
||||||
|
validMask &= ~OVERLAY_FRAME_TIMING_VALID_TRANSPORT;
|
||||||
|
|
||||||
const OverlayFrameTiming timing = {
|
const OverlayFrameTiming timing = {
|
||||||
.timestamp = record->timestamp,
|
.timestamp = record->timestamp,
|
||||||
.validMask = validMask,
|
.validMask = validMask,
|
||||||
@@ -511,6 +527,8 @@ static void frameTimingPublishReady(void)
|
|||||||
.postProcess = record->postProcessTime * 1e-6f,
|
.postProcess = record->postProcessTime * 1e-6f,
|
||||||
.copy = record->copyTime * 1e-6f,
|
.copy = record->copyTime * 1e-6f,
|
||||||
.ready = record->readyTime * 1e-6f,
|
.ready = record->readyTime * 1e-6f,
|
||||||
|
.hold = record->holdTime * 1e-6f,
|
||||||
|
.transport = transportTime * 1e-6f,
|
||||||
.import = (record->importTime +
|
.import = (record->importTime +
|
||||||
(record->producerValid ? 0 : record->importWaitTime)) * 1e-6f,
|
(record->producerValid ? 0 : record->importWaitTime)) * 1e-6f,
|
||||||
.dispatch = record->dispatchTime * 1e-6f,
|
.dispatch = record->dispatchTime * 1e-6f,
|
||||||
@@ -521,6 +539,7 @@ static void frameTimingPublishReady(void)
|
|||||||
.desktop = record->desktopTime * 1e-6f,
|
.desktop = record->desktopTime * 1e-6f,
|
||||||
.compose = record->composeTime * 1e-6f,
|
.compose = record->composeTime * 1e-6f,
|
||||||
.swap = record->swapTime * 1e-6f,
|
.swap = record->swapTime * 1e-6f,
|
||||||
|
.present = 0.0f,
|
||||||
};
|
};
|
||||||
ringbuffer_push(g_state.frameLatency, &timing);
|
ringbuffer_push(g_state.frameLatency, &timing);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,6 +226,8 @@ static const char * const frameTimingLabels[FRAME_TIMING_STAGE_COUNT] = {
|
|||||||
"Post",
|
"Post",
|
||||||
"Copy",
|
"Copy",
|
||||||
"Ready",
|
"Ready",
|
||||||
|
"Hold",
|
||||||
|
"Transport",
|
||||||
"Import",
|
"Import",
|
||||||
"Dispatch",
|
"Dispatch",
|
||||||
"Queue",
|
"Queue",
|
||||||
@@ -235,6 +237,7 @@ static const char * const frameTimingLabels[FRAME_TIMING_STAGE_COUNT] = {
|
|||||||
"Desktop",
|
"Desktop",
|
||||||
"Compose",
|
"Compose",
|
||||||
"Swap",
|
"Swap",
|
||||||
|
"Present",
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TimingPlotData
|
struct TimingPlotData
|
||||||
@@ -296,6 +299,8 @@ static bool accumulateFrameTimingSample(int index, void * value_, void * udata_)
|
|||||||
timing->postProcess,
|
timing->postProcess,
|
||||||
timing->copy,
|
timing->copy,
|
||||||
timing->ready,
|
timing->ready,
|
||||||
|
timing->hold,
|
||||||
|
timing->transport,
|
||||||
timing->import,
|
timing->import,
|
||||||
timing->dispatch,
|
timing->dispatch,
|
||||||
timing->queue,
|
timing->queue,
|
||||||
@@ -305,6 +310,7 @@ static bool accumulateFrameTimingSample(int index, void * value_, void * udata_)
|
|||||||
timing->desktop,
|
timing->desktop,
|
||||||
timing->compose,
|
timing->compose,
|
||||||
timing->swap,
|
timing->swap,
|
||||||
|
timing->present,
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint64_t offset = timing->timestamp - data->windowStart;
|
const uint64_t offset = timing->timestamp - data->windowStart;
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ typedef struct OverlayFrameTiming
|
|||||||
float postProcess;
|
float postProcess;
|
||||||
float copy;
|
float copy;
|
||||||
float ready;
|
float ready;
|
||||||
|
float hold;
|
||||||
|
float transport;
|
||||||
float import;
|
float import;
|
||||||
float dispatch;
|
float dispatch;
|
||||||
float queue;
|
float queue;
|
||||||
@@ -61,6 +63,7 @@ typedef struct OverlayFrameTiming
|
|||||||
float desktop;
|
float desktop;
|
||||||
float compose;
|
float compose;
|
||||||
float swap;
|
float swap;
|
||||||
|
float present;
|
||||||
}
|
}
|
||||||
OverlayFrameTiming;
|
OverlayFrameTiming;
|
||||||
|
|
||||||
@@ -70,6 +73,8 @@ enum OverlayFrameTimingStage
|
|||||||
OVERLAY_FRAME_TIMING_POST_PROCESS,
|
OVERLAY_FRAME_TIMING_POST_PROCESS,
|
||||||
OVERLAY_FRAME_TIMING_COPY,
|
OVERLAY_FRAME_TIMING_COPY,
|
||||||
OVERLAY_FRAME_TIMING_READY,
|
OVERLAY_FRAME_TIMING_READY,
|
||||||
|
OVERLAY_FRAME_TIMING_HOLD,
|
||||||
|
OVERLAY_FRAME_TIMING_TRANSPORT,
|
||||||
OVERLAY_FRAME_TIMING_IMPORT,
|
OVERLAY_FRAME_TIMING_IMPORT,
|
||||||
OVERLAY_FRAME_TIMING_DISPATCH,
|
OVERLAY_FRAME_TIMING_DISPATCH,
|
||||||
OVERLAY_FRAME_TIMING_QUEUE,
|
OVERLAY_FRAME_TIMING_QUEUE,
|
||||||
@@ -79,13 +84,18 @@ enum OverlayFrameTimingStage
|
|||||||
OVERLAY_FRAME_TIMING_DESKTOP,
|
OVERLAY_FRAME_TIMING_DESKTOP,
|
||||||
OVERLAY_FRAME_TIMING_COMPOSE,
|
OVERLAY_FRAME_TIMING_COMPOSE,
|
||||||
OVERLAY_FRAME_TIMING_SWAP,
|
OVERLAY_FRAME_TIMING_SWAP,
|
||||||
|
OVERLAY_FRAME_TIMING_PRESENT,
|
||||||
OVERLAY_FRAME_TIMING_COUNT,
|
OVERLAY_FRAME_TIMING_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OVERLAY_FRAME_TIMING_VALID_ALL \
|
#define OVERLAY_FRAME_TIMING_VALID_ALL \
|
||||||
((1U << OVERLAY_FRAME_TIMING_COUNT) - 1U)
|
((1U << OVERLAY_FRAME_TIMING_COUNT) - 1U)
|
||||||
#define OVERLAY_FRAME_TIMING_VALID_PRODUCER \
|
#define OVERLAY_FRAME_TIMING_VALID_PRODUCER \
|
||||||
((1U << OVERLAY_FRAME_TIMING_IMPORT) - 1U)
|
((1U << OVERLAY_FRAME_TIMING_TRANSPORT) - 1U)
|
||||||
|
#define OVERLAY_FRAME_TIMING_VALID_TRANSPORT \
|
||||||
|
(1U << OVERLAY_FRAME_TIMING_TRANSPORT)
|
||||||
|
#define OVERLAY_FRAME_TIMING_VALID_PRESENT \
|
||||||
|
(1U << OVERLAY_FRAME_TIMING_PRESENT)
|
||||||
|
|
||||||
GraphHandle overlayGraph_register(const char * name, RingBuffer buffer,
|
GraphHandle overlayGraph_register(const char * name, RingBuffer buffer,
|
||||||
float min, float max, GraphFormatFn formatFn);
|
float min, float max, GraphFormatFn formatFn);
|
||||||
|
|||||||
Reference in New Issue
Block a user