mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-04 06:12:04 +00:00
[client/host/idd/lgmp] add additional timing metrics
This commit is contained in:
@@ -97,6 +97,12 @@ typedef struct CaptureFrame
|
||||
|
||||
uint32_t damageRectsCount;
|
||||
FrameDamageRect damageRects[KVMFR_MAX_DAMAGE_RECTS];
|
||||
|
||||
// Producer-local durations. Absolute timestamps must not cross KVMFR as the
|
||||
// client and producer use different monotonic clock domains.
|
||||
uint64_t captureTime;
|
||||
uint64_t postProcessTime;
|
||||
uint64_t copyTime;
|
||||
}
|
||||
CaptureFrame;
|
||||
|
||||
@@ -146,8 +152,9 @@ typedef struct CaptureInterface
|
||||
CaptureFrame * frame,
|
||||
const size_t maxFrameSize);
|
||||
CaptureResult (*getFrame )(
|
||||
unsigned frameBufferIndex,
|
||||
unsigned frameBufferIndex,
|
||||
FrameBuffer * frame,
|
||||
const size_t maxFrameSize);
|
||||
const size_t maxFrameSize,
|
||||
CaptureFrame * captureFrame);
|
||||
}
|
||||
CaptureInterface;
|
||||
|
||||
@@ -299,10 +299,12 @@ static CaptureResult xcb_waitFrame(
|
||||
}
|
||||
|
||||
static CaptureResult xcb_getFrame(
|
||||
unsigned frameBufferIndex,
|
||||
unsigned frameBufferIndex,
|
||||
FrameBuffer * frame,
|
||||
const size_t maxFrameSize)
|
||||
const size_t maxFrameSize,
|
||||
CaptureFrame * captureFrame)
|
||||
{
|
||||
(void)captureFrame;
|
||||
DEBUG_ASSERT(this);
|
||||
DEBUG_ASSERT(this->initialized);
|
||||
|
||||
|
||||
@@ -463,10 +463,12 @@ static CaptureResult pipewire_waitFrame(
|
||||
}
|
||||
|
||||
static CaptureResult pipewire_getFrame(
|
||||
unsigned frameBufferIndex,
|
||||
unsigned frameBufferIndex,
|
||||
FrameBuffer * frame,
|
||||
const size_t maxFrameSize)
|
||||
const size_t maxFrameSize,
|
||||
CaptureFrame * captureFrame)
|
||||
{
|
||||
(void)captureFrame;
|
||||
if (this->stop || !this->frameData)
|
||||
return CAPTURE_RESULT_REINIT;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "common/rects.h"
|
||||
#include "common/vector.h"
|
||||
#include "common/display.h"
|
||||
#include "common/time.h"
|
||||
#include "com_ref.h"
|
||||
|
||||
#include "backend.h"
|
||||
@@ -771,8 +772,11 @@ exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
static CaptureResult d12_getFrame(unsigned frameBufferIndex,
|
||||
FrameBuffer * frameBuffer, const size_t maxFrameSize)
|
||||
static CaptureResult d12_getFrame(
|
||||
unsigned frameBufferIndex,
|
||||
FrameBuffer * frameBuffer,
|
||||
const size_t maxFrameSize,
|
||||
CaptureFrame * captureFrame)
|
||||
{
|
||||
CaptureResult result = CAPTURE_RESULT_ERROR;
|
||||
comRef_scopePush(3);
|
||||
@@ -808,6 +812,7 @@ static CaptureResult d12_getFrame(unsigned frameBufferIndex,
|
||||
if (result != CAPTURE_RESULT_OK)
|
||||
goto exit;
|
||||
|
||||
const uint64_t postProcessStart = nanotime();
|
||||
ID3D12Resource * next = *src;
|
||||
D12Effect * effect;
|
||||
vector_forEach(effect, &this->effects)
|
||||
@@ -934,6 +939,8 @@ static CaptureResult d12_getFrame(unsigned frameBufferIndex,
|
||||
ID3D12CommandQueue_Wait(*this->copyQueue,
|
||||
*this->computeCommand.fence, this->computeCommand.fenceValue);
|
||||
}
|
||||
captureFrame->postProcessTime = this->effectsActive ?
|
||||
nanotime() - postProcessStart : 0;
|
||||
|
||||
// execute the copy commands
|
||||
DEBUG_TRACE("Execute copy commands");
|
||||
|
||||
@@ -1504,9 +1504,13 @@ static CaptureResult dxgi_waitFrame(unsigned frameBufferIndex,
|
||||
return CAPTURE_RESULT_OK;
|
||||
}
|
||||
|
||||
static CaptureResult dxgi_getFrame(unsigned frameBufferIndex,
|
||||
FrameBuffer * frame, const size_t maxFrameSize)
|
||||
static CaptureResult dxgi_getFrame(
|
||||
unsigned frameBufferIndex,
|
||||
FrameBuffer * frame,
|
||||
const size_t maxFrameSize,
|
||||
CaptureFrame * captureFrame)
|
||||
{
|
||||
(void)captureFrame;
|
||||
DEBUG_ASSERT(this);
|
||||
DEBUG_ASSERT(this->initialized);
|
||||
|
||||
|
||||
@@ -718,9 +718,13 @@ static CaptureResult nvfbc_waitFrame(unsigned frameBufferIndex,
|
||||
return CAPTURE_RESULT_OK;
|
||||
}
|
||||
|
||||
static CaptureResult nvfbc_getFrame(unsigned frameBufferIndex,
|
||||
FrameBuffer * frame, const size_t maxFrameSize)
|
||||
static CaptureResult nvfbc_getFrame(
|
||||
unsigned frameBufferIndex,
|
||||
FrameBuffer * frame,
|
||||
const size_t maxFrameSize,
|
||||
CaptureFrame * captureFrame)
|
||||
{
|
||||
(void)captureFrame;
|
||||
const unsigned int h = DIFF_MAP_DIM(this->grabHeight, this->diffShift);
|
||||
const unsigned int w = DIFF_MAP_DIM(this->grabWidth, this->diffShift);
|
||||
uint8_t * frameData = framebuffer_get_data(frame);
|
||||
|
||||
@@ -109,6 +109,7 @@ struct app
|
||||
bool frameValid;
|
||||
uint32_t frameSerial;
|
||||
uint32_t formatVer;
|
||||
uint64_t captureTime[LGMP_Q_FRAME_LEN];
|
||||
unsigned int captureFormatVer;
|
||||
bool hdr;
|
||||
bool hdrPQ;
|
||||
@@ -291,6 +292,7 @@ static bool sendFrame(CaptureResult result, bool * restart)
|
||||
}
|
||||
|
||||
KVMFRFrame * fi = app.frame[app.captureIndex];
|
||||
frame.captureTime = app.captureTime[app.captureIndex];
|
||||
const uint32_t sdrWhiteLevel = frame.sdrWhiteLevel ?
|
||||
frame.sdrWhiteLevel : KVMFR_SDR_WHITE_LEVEL_DEFAULT;
|
||||
const bool metadataChanged =
|
||||
@@ -396,6 +398,11 @@ static bool sendFrame(CaptureResult result, bool * restart)
|
||||
// fi->offset is initialized at startup
|
||||
fi->flags = flags;
|
||||
fi->sdrWhiteLevel = sdrWhiteLevel;
|
||||
fi->captureTime = frame.captureTime;
|
||||
fi->postProcessTime = 0;
|
||||
fi->copyTime = 0;
|
||||
fi->timingSerial = 0;
|
||||
__atomic_store_n(&fi->timingValid, 0, __ATOMIC_RELAXED);
|
||||
if (frame.hdrMetadata)
|
||||
{
|
||||
memcpy(fi->hdrDisplayPrimary, frame.hdrDisplayPrimary,
|
||||
@@ -433,10 +440,20 @@ static bool sendFrame(CaptureResult result, bool * restart)
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint64_t copyStart = nanotime();
|
||||
app.iface->getFrame(
|
||||
app.captureIndex,
|
||||
app.frameBuffer[app.captureIndex],
|
||||
app.maxFrameSize);
|
||||
app.maxFrameSize,
|
||||
&frame);
|
||||
const uint64_t copyEnd = nanotime();
|
||||
|
||||
fi->postProcessTime = frame.postProcessTime;
|
||||
frame.copyTime = copyEnd - copyStart > frame.postProcessTime ?
|
||||
copyEnd - copyStart - frame.postProcessTime : 0;
|
||||
fi->copyTime = frame.copyTime;
|
||||
fi->timingSerial = fi->frameSerial;
|
||||
__atomic_store_n(&fi->timingValid, 1, __ATOMIC_RELEASE);
|
||||
|
||||
app.readIndex = app.captureIndex;
|
||||
if (++app.captureIndex == LGMP_Q_FRAME_LEN)
|
||||
@@ -1108,13 +1125,15 @@ int app_main(int argc, char * argv[])
|
||||
nsleep(us * 1000);
|
||||
}
|
||||
|
||||
const uint64_t captureStartTime = microtime();
|
||||
const uint64_t captureStartTime = nanotime();
|
||||
|
||||
const CaptureResult result = app.iface->capture(
|
||||
app.captureIndex, app.frameBuffer[app.captureIndex]);
|
||||
|
||||
app.captureTime[app.captureIndex] = nanotime() - captureStartTime;
|
||||
|
||||
if (likely(result == CAPTURE_RESULT_OK))
|
||||
previousFrameTime = captureStartTime;
|
||||
previousFrameTime = captureStartTime / 1000;
|
||||
else if (likely(result == CAPTURE_RESULT_TIMEOUT))
|
||||
{
|
||||
if (!app.iface->asyncCapture)
|
||||
|
||||
Reference in New Issue
Block a user