Skip to main content

CommitReport

Struct CommitReport 

Source
#[non_exhaustive]
pub struct CommitReport {
Show 18 fields pub layers_total: usize, pub layers_assigned: usize, pub layers_composited: usize, pub layers_unassigned: usize, pub layers_skipped_no_frame: usize, pub composition_buckets: usize, pub pin_requests_unhonored: usize, pub properties_written: usize, pub fbs_attached: usize, pub damaged_layers: usize, pub in_fences_armed: usize, pub in_fence_cpu_waits: usize, pub test_commits_issued: usize, pub fb_delta_fast_path: bool, pub commit_seq: u64, pub budget_exhausted: bool, pub skipped_idle: bool, pub placements: Vec<LayerPlacement>,
}
Expand description

A snapshot of a single commit.

Every field starts at zero, false or empty. #[non_exhaustive] because the C++ has grown counters additively — layers_skipped_no_frame, fb_delta_fast_path, the fence counters — and keeping that freedom means a new counter is not a breaking change.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§layers_total: usize

Layers in the scene at commit time.

§Accounting invariant

layers_total == layers_assigned
              + layers_composited
              + layers_unassigned
              + layers_skipped_no_frame

Checked by accounting_balances. This is why a layer with no format is never placed: counting it as both assigned and skipped would break this.

§layers_assigned: usize

Layers the allocator put directly on a hardware plane.

§layers_composited: usize

Layers rescued by composition into the canvas. They do reach hardware — via the canvas plane rather than one of their own.

§layers_unassigned: usize

Layers neither placed nor composited: dropped this frame.

§layers_skipped_no_frame: usize

Layers whose source returned WouldBlock, and which held their previous frame – or stayed absent, if they had none.

Flow control, not failure — a live source with nothing to contribute this vblank. Graphable as a per-layer frame-stall signal.

§composition_buckets: usize

Composition buckets emitted. 0 or 1 with a single full-screen canvas.

§pin_requests_unhonored: usize

Layers that asked to be pinned to a plane but could not be.

The pin target was not on this CRTC, did not support the format, or was already claimed. The layer is not dropped — it falls back to normal allocation and is still counted in one of the placement tallies, so this does not affect the accounting invariant. Nonzero is a loud signal that a caller’s deterministic-plane assumption was violated, as opposed to a silent drop.

§properties_written: usize

Properties enqueued on the atomic request — plane, CRTC, and connector state together.

A regression signal for property minimization: it should drop meaningfully on a commit whose layers did not change.

§fbs_attached: usize

Subset of properties_written that are FB_ID attachments.

§damaged_layers: usize

Subset of properties_written: layers that got an FB_DAMAGE_CLIPS blob.

Zero on a full-frame commit — no damage reported, over budget, degenerate clips, or a plane without the property. Tells a bandwidth-sensitive consumer whether partial updates actually reach the kernel.

§in_fences_armed: usize

Layers whose acquire fence was handed to the kernel as IN_FENCE_FD — the real explicit-sync path, with no CPU stall.

The honest signal that explicit sync is live on this driver: a source may always produce a fence and the plane still not accept it, which shows up in in_fence_cpu_waits instead.

§in_fence_cpu_waits: usize

Layers that carried a fence the plane could not take, so the scene blocked on a CPU wait before committing.

Real commits only; a test never waits. Both counters zero means no source produced a fence at all.

§test_commits_issued: usize

Internal test commits the allocator issued while searching.

A cold start can spend the whole budget; a warm start is 1; the FB-only fast path is 0.

§fb_delta_fast_path: bool

Whether this commit took the FB-only fast path — only content changed on already-placed layers, so the cached assignment was reused and the TEST_ONLY skipped entirely.

Invariant 4’s observable signal. Implies test_commits_issued == 0, which a steady-state consumer asserts to confirm it is paying one atomic commit per frame rather than two.

§commit_seq: u64

Names this commit for LayerScene::release_displaced: real commits that the kernel took count from 1. 0 for a test commit and for a rejected one.

§budget_exhausted: bool

Whether the per-frame test-commit budget, not the hardware, is what stopped more layers reaching planes.

When this is set, some of layers_composited is a capacity decision rather than a plane shortage: there were compatible planes free and the allocator ran out of permitted round trips to the kernel before it could offer them. Composited layers still reach the screen, so this is not an error – but a caller tuning a scene needs to tell “this device has no more planes” from “raise the budget”, and layers_composited alone cannot. Raise it with Allocator::set_max_test_commits.

§skipped_idle: bool

Whether the frame was suppressed as idle – no commit was issued at all.

Set only by a caller that gates on content changing, such as ScanoutBackend::present_if_changed. When it is set every other field is zero, because there was no commit to count: no layers were walked, no properties written, no placements decided. A consumer reading layers_assigned == 0 without checking this would conclude the frame failed to reach a plane, when in fact the previous frame is still on screen and correct.

The first frame is never suppressed, whatever the caller says about content: nothing is on screen yet, so “unchanged” describes nothing.

§placements: Vec<LayerPlacement>

Per-layer outcomes.

Implementations§

Source§

impl CommitReport

Source

pub fn suppressed() -> Self

The report for a frame that was suppressed as idle.

Every count is zero because there was no commit to count, and skipped_idle says why. A constructor rather than a struct literal because this type is #[non_exhaustive]: a caller outside this crate cannot build one, and the suppressed frame is the one shape it legitimately needs to.

Source

pub fn placement_of(&self, layer: impl Into<LayerId>) -> Option<&LayerPlacement>

What became of one layer this commit.

None when the layer was not in the frame at all – it was never added, it was removed, or the handle is stale. A stale one cannot match by accident: LayerHandle::layer_id packs the slot’s generation, so a recycled slot yields a different id and a handle to the layer that used to live there resolves to nothing.

Source

pub fn was_composited(&self, layer: impl Into<LayerId>) -> bool

Whether the layer went into the canvas rather than onto a plane of its own.

False for a layer that was dropped as well as for one that got a plane: composited means it reached the screen the slow way, and unassigned means it did not reach the screen at all. A caller throttling its repaints on this distinction wants them separated.

Source

pub const fn accounting_balances(&self) -> bool

Whether the layer tallies add up to layers_total.

The C++ states this as a comment on the field. Making it checkable means the scene’s own tests can assert it every commit, which is how a layer counted twice — or not at all — gets caught at the point it happens.

Source

pub const fn fast_path_consistent(&self) -> bool

Whether the fast path’s implied contract holds: taking it means issuing no test commits.

Trait Implementations§

Source§

impl Clone for CommitReport

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CommitReport

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for CommitReport

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for CommitReport

Source§

impl PartialEq for CommitReport

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for CommitReport

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.