pub struct AtomicRequest { /* private fields */ }Expand description
An atomic modeset request under construction.
§Deviation: no libdrm request object
The C++ allocates a drmModeAtomicReq up front and appends to it, so its
valid() reports whether that allocation succeeded. Here the request is a
plain vector of PropertyWrites and the drm crate’s AtomicModeReq
is built at commit time. There is no allocation to fail, so there is no
valid() — construction is infallible.
Implementations§
Source§impl AtomicRequest
impl AtomicRequest
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
An empty request with room for capacity writes.
Sourcepub fn add_property(
&mut self,
object_id: u32,
property_id: u32,
value: u64,
) -> Result<()>
pub fn add_property( &mut self, object_id: u32, property_id: u32, value: u64, ) -> Result<()>
Append a property write.
Order is preserved and duplicates are kept: the kernel applies writes in order, so a later write to the same property wins, and collapsing them here would change what a replayed trace means.
§Errors
CoreError::Io with EINVAL if either id is zero. libdrm’s
drmModeAtomicAddProperty rejects a zero id the same way, and rejecting
at insertion is what keeps the commit path total: DRM resource handles
are non-zero by construction, so a zero id has no representation to
build a request from and could only be dropped silently — a commit going
out one property short, which is far worse than an error here.
Note that non-zero ids are not checked against real kernel objects. libdrm does not either; that check happens at commit time.
Sourcepub fn writes(&self) -> &[PropertyWrite]
pub fn writes(&self) -> &[PropertyWrite]
The accumulated writes, in submission order.
See PropertyWrite for why this exists rather than a raw request
pointer.
Sourcepub fn test(&self, device: &Device, flags: AtomicCommitFlags) -> Result<()>
pub fn test(&self, device: &Device, flags: AtomicCommitFlags) -> Result<()>
Validate the request without applying it (DRM_MODE_ATOMIC_TEST_ONLY).
PAGE_FLIP_EVENT is masked out of flags. The kernel rejects
TEST_ONLY | PAGE_FLIP_EVENT with EINVAL — a test applies nothing to
hardware, so there is no flip to queue an event on — and callers
routinely forward the same flags they would pass to
commit. The allocator replays caller flags for its
internal test commits, so masking here beats making every caller
remember.
§Errors
CoreError::NotMaster if the caller lost DRM master, otherwise
CoreError::Io with the kernel’s rejection reason.
Sourcepub fn commit(&self, device: &Device, flags: AtomicCommitFlags) -> Result<()>
pub fn commit(&self, device: &Device, flags: AtomicCommitFlags) -> Result<()>
Apply the request.
§Errors
CoreError::NotMaster if the caller is not DRM master — the one
failure a scene suspends on (invariant 2) — otherwise CoreError::Io.
Sourcepub fn dump(&self, device: &Device, why: &str)
pub fn dump(&self, device: &Device, why: &str)
Log every write this request carries, property ids resolved to names.
A rejected atomic request says only that the kernel disliked
something, and nothing in the error names which property. No-op
unless DRM_ATOMIC_DEBUG or DRM_ALLOC_DEBUG is set – upstream’s
switches, so one variable works on both implementations – and then
routed through log_channel!, since the
variable is already the opt-in. why labels the dump.
test and commit call it themselves on
a rejection other than CoreError::NotMaster, and on the first
request accepted after one: a rejected
request beside an accepted one is what shows the difference, where a
rejection alone is read as whatever looks suspicious. Upstream wires
the same two dumps into its allocator and scene; here every request
goes through these two methods, so wiring them once covers the
allocator, the present backend and the cursor alike.