Skip to main content

Crate drmkit_scene

Crate drmkit_scene 

Source
Expand description

Scene composition for drmkit.

Port of src/scene/ from drm-cxx @ dc2915b.

A LayerScene owns one CRTC’s stack of layers and the machinery that turns them into a frame: which plane each layer lands on, what to composite when there are more layers than planes, and when a buffer may go back to whoever produced it.

§Driving a frame

let mut scene = LayerScene::new(crtc_id);
let handle = scene.add_layer(Box::new(source));
scene.layer_mut(handle)?.set_display(DisplayParams { .. });

// per frame
let mut build = scene.build_frame(&registry, crtc_index, kind, &mut committer)?;
emit_frame(&mut request, &map, &mut build, modeset)?;
arm_acquire_fences(&mut build, &mut request, &map, true)?;
let result = request.commit(&device, flags);
let report = scene.finalize_frame(build, classify(&result));
// ... and when the page-flip event arrives
scene.flip_landed();

The split between build_frame and finalize_frame is the part worth understanding. build_frame acquires a buffer from every source, runs the allocator — which may issue TEST_ONLY commits through the committer to ask the kernel whether an arrangement is legal — and hands back a FrameBuild describing what to program. It does not commit: the caller owns the request, so it can add a modeset, arm fences, or refuse the frame. finalize_frame then takes the kernel’s answer and settles the bookkeeping, which is what arms the flip and what decides which buffers are now safe to release.

A FrameBuild dropped without finalize_frame leaks its acquisitions, and says so in a debug assertion rather than silently.

§A source with nothing ready

SourceError::WouldBlock from a source is not an error. It is the documented “no frame yet” signal — a V4L2 device before its first sample, an appsink mid-preroll — and the layer is skipped for that frame and counted in the report, keeping the plane it had and the framebuffer already on it. A frame does not fail because one producer was late, and a starved layer does not blink off screen.

§The release contract

Two of the four pinned invariants this crate carries are about when a buffer goes back to its source:

  • Invariant 1 — a buffer is released only after the page flip that stops scanning it out completes, two commits deep, never when the ioctl returns. Releasing early lets a producer overwrite a buffer the display engine is still reading, which tears on hardware whose producer driver attaches no reservation fence.
  • Invariant 2 — a failed commit releases that frame’s acquisitions immediately, because no flip is in flight to gate them on, and a non-EACCES failure does not suspend the scene. Self-healing producer rings depend on being able to reuse their buffers after a rejection.

AcquiredBuffer is move-only, so handing a buffer back early is a move and using it afterwards does not compile — the ownership half of invariant 1 is enforced by the type. The timing half cannot be, and is pinned against a real device in tests/release_invariants_vkms.rs.

Structs§

AcquireTally
Accounting for one build pass’s acquire loop.
AcquiredBuffer
A buffer handed over by LayerBufferSource::acquire, valid until the matching release.
Acquisition
One buffer held on behalf of a layer.
CommitReport
A snapshot of a single commit.
CompositeCanvas
A double-buffered software composition surface.
CompositeRect
A rectangle in whole pixels, half-open in extent.
CompositeSrc
A source surface to blend from.
DamageRect
A region of a buffer that changed since the slot was last scanned out, in buffer pixels with a top-left origin.
DeviceCommitter
A TestCommitter that issues real TEST_ONLY commits.
DisplayParams
How a layer should be displayed.
DmaBufDesc
A borrowed view of a buffer’s DMA-BUF planes, for a consumer that imports the buffer directly rather than reading CPU pixels.
FixedRect
A source rectangle in 16.16 fixed point: the kernel’s own SRC_* encoding, for a crop at sub-pixel precision. A Wayland viewport’s source rectangle, for one, is in 1/256ths of a pixel, and rounding it moves the image by up to half a pixel and changes its scale. 1.0 is 0x10000.
FrameBuild
A frame that has been built and is awaiting the kernel’s answer.
FrameLifecycle
Owns the state a commit reconciles: the release ring, the armed-flip tripwire, and whether the scene is suspended.
FrameOutcome
What the scene must do after a commit.
LayerHandle
Opaque, generation-tagged identity for a scene layer.
LayerIncompatibility
One layer the new output cannot display as it stands.
LayerPlacement
One layer’s outcome.
LayerScene
One CRTC’s layers and the commit machinery around them.
LayerWrites
What emitting one layer put on the wire.
LoweringInput
Everything lower_layer needs about a layer, without borrowing the scene.
Modeset
The CRTC and connector writes that bring a display up.
OutputSignaling
What the scene wants declared on the connector for one frame.
PendingDetach
Planes a scene left lit on the CRTC it moved away from.
PlanePlan
One plane’s share of a built frame.
PlanePropertyMap
Resolves a layer’s PropTags to the DRM property ids of a given plane.
RebindReport
What a rebind found that will not fit.
Rect
An axis-aligned rectangle in CRTC pixels.
ReleaseQueue
The two-deep ring of in-flight acquisitions.
Released
The buffers to hand back, and why.
SceneLayer
A layer’s live scene state.
ScenePendingFlip
Tracks whether a commit armed a page-flip event that has not been dispatched.
SourceFormat
What a source’s buffer intrinsically is.
Ycbcr
How a plane converts a layer’s YCbCr to RGB: its COLOR_ENCODING and COLOR_RANGE.

Enums§

BindingModel
How the scene and a source divide responsibility for FB_ID.
ColorEncoding
Plane COLOR_ENCODING: the YCbCr-to-RGB matrix applied when scanning out a YUV format. Ignored by the kernel for RGB.
ColorPrimaries
The container colorimetry a producer says its layer is in.
ColorRange
Plane COLOR_RANGE: whether 8-bit YCbCr is full-range (0..255) or limited-range (16..235 luma, 16..240 chroma).
CommitKind
What one commit was.
FenceAction
What to do with a layer’s acquire fence, given what its plane can take.
IncompatibilityReason
Why a layer does not fit its new output.
KernelResult
What the kernel said about a commit.
Placement
How a layer reached scanout.
ReleaseReason
Why a set of buffers is being handed back.
SceneError
Why a frame could not be built.
SourceError
Why an acquire did not produce a buffer.

Traits§

LayerBufferSource
Where a layer’s content comes from.

Functions§

arm_acquire_fences
Give each fenced layer’s fence to its plane, or wait on it here.
blend_into
Blend src over dst, premultiplied SRC_OVER.
canvas_format_for_plane
The best canvas format this plane can scan out, if any.
canvas_output_bpp
Bytes per pixel the canvas can write in fourcc, or zero.
classify
Classify a real commit’s outcome for FrameLifecycle.
clear_into
Zero-fill a rectangle of dst, clipped to its extents.
commit_detach
Turn off what a rebind left on the old CRTC.
convert_row
Convert one row of the ARGB8888 shadow into out_fourcc.
derive_output_signaling
Derive what the connector should signal for this frame’s layers.
derive_output_signallingDeprecated
The 0.1.0 name of derive_output_signaling, kept so code written against it still builds.
emit_disable
Emit the writes that detach a plane.
emit_frame
Emit a built frame’s apply commit.
emit_frame_damaged
emit_frame, plus the FB_DAMAGE_CLIPS blobs partial repaint needs.
emit_layer
Emit one layer’s properties onto a plane.
fence_action
Decide between the two, from whether the plane exposes a writable IN_FENCE_FD.
format_supported
Whether this module can blend from fourcc.
lower_layer
Copy a scene layer’s state into the plane property bag.
to_16_16
Convert whole pixels to the 16.16 fixed point KMS expects for SRC_*.
widest_gamut
The widest-gamut primaries any layer names.

Type Aliases§

OutputSignallingDeprecated
The 0.1.0 name of OutputSignaling, kept so code written against it still builds.