CNA-BUG-093: HeadlessRenderer::GetLastFrameStatistics() reports the frame in progress, not the finished frame its documentation names

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

GetLastFrameStatistics() is documented as the statistics of the frame ending at the most recent Present(), but it subtracts the snapshot taken at that Present from the running totals, and a test pins that behaviour.

Identifier
CNA-BUG-093
Category
Bug
Subsystem
Graphics & renderers
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Low (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
CNA::Internal::Renderers::Headless::HeadlessRenderer::GetLastFrameStatistics() (HEADLESS debugging API)

Expected behaviour

The declaration's comment: "Statistics for the frame ending at the most recent Present() call (diffed against the cumulative totals as of the Present() before that)." The name says the same, and CNA's docs/headless-renderer.md calls the pair "cumulative and per-frame" counters.

Actual behaviour at TARGET

HeadlessRenderer::Present copies the running counters into statsAtLastPresent, and GetLastFrameStatistics() returns the running counters minus that snapshot. Called right after a Present() it returns zeros; called during a frame it returns that frame's work so far. No snapshot of the previous Present is kept, so the documented "last finished frame" figure cannot be produced. Headless_CoverageGaps checks B and C assert the current-frame behaviour (zero at the top of a frame, exactly two draw calls after two draws), so the code is the intended behaviour and the comment and name are what is wrong.

Source locations

Evidence

Checked by reading at 009d40f5; not executed. The test file states its intent: the diff "genuinely isolates the current frame". A caller that reads the statistics from a Game after EndDraw() (which presents) always sees an empty frame.

Focused reproduction

// Illustrative; not compiled or run for this entry. HEADLESS renderer.
auto& headless = dynamic_cast<CNA::Internal::Renderers::Headless::HeadlessRenderer&>(device.GetRenderer());
// ... one DrawPrimitives call in this frame ...
device.Present();
auto last = headless.GetLastFrameStatistics();
// Documented: last.drawCallCount == 1 (the frame that just ended). Actual: 0.

Current tests

Headless_CoverageGaps (headless_coverage_gaps_test.cpp) checks B and C pin the current-frame semantics; nothing reads the statistics after a Present expecting the previous frame.

Regression test

Correct the comment (and preferably the name, or add a current-frame alias) to say "since the most recent Present()"; if a finished-frame figure is wanted, keep a second snapshot at each Present and add a check that reads it immediately after Present.

Blast radius

Tests and tools that use the HEADLESS statistics API and read it after Present() get zeros. GetStatistics() (cumulative) is unaffected; no other renderer has this API.

Workaround

Read GetLastFrameStatistics() before the frame's Present(), or diff two GetStatistics() snapshots.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Tests and validation
Test architecture: groups
Known issues
Bug index