Repository navigation
Releases: jwinarske/drmkit
Releases · jwinarske/drmkit
Release list
drmkit 0.1.3
Added
drmkit-cursor:Renderer::prepare, which redraws the sprite when a move near the top or left edge needs it shifted, andedge_shift, the shift itself.Renderer::commitcallsprepare; a caller coalescing throughstage_intocalls it first (drm-cxx#384, P-101).drmkit-display:CrtcColorPipeline::pauseandPausedPipeline::resume, the port of the reference'sclear_for_session_lossand newon_session_resumed. A paused pipeline forgets its blobs and has no setters; resumed on the new device, it keeps the CRTC's property ids and stages there (drm-cxx#372, P-82).
Changed
- The upstream baseline moves to drm-cxx
d7641ed(v5.0.0 and thirteen fixes since). Every upstream change tosrc/in2b260d0..d7641edis ported.
Deprecated
drmkit-display:CrtcColorPipeline::forget_for_session_loss, which kept the pipeline on the device whose session was lost. UsepauseandPausedPipeline::resume. It remains until 0.2.
Fixed
drmkit-display:DriverProfile::vrr_capableis true only when a connected sink reportsvrr_capable. It was true whenever a CRTC hadVRR_ENABLED, which the DRM core gives every CRTC of an atomic driver, soVrrPolicy::Autoarmed variable refresh on sinks that cannot do it. The reference has the same bug, filed as drm-cxx#371 (P-76).drmkit-display:ToneMapperinterpolates its tables as the reference does, taking the difference of two entries inf32before widening it. Widening first left some 16-bit pixels one step higher than the reference's (P-77).drmkit-display: aToneMapperreports zero for the parameter its direction does not use, as the reference does:target_max_nitson a mapper up to PQ,sdr_white_nitson one down to SDR. It reported 100 (P-78).drmkit-display:curves::bt1886_oetfreturns NaN for NaN, as the reference does, rather than 0.0 (P-79).drmkit-display: the hotplug monitor reads the kernel'sCONNECTOR=hint as digits only, as the reference does, so a leading+means re-enumerate rather than a connector id (P-80).drmkit-capture:snapshotcloses the GEM handles its framebuffer queries open. Each capture left one open per plane, pinning every buffer it had read until the descriptor closed. The reference has the same bug, filed as drm-cxx#373 (P-83).drmkit-cursor: a cursor near the top or left edge commits. A negative plane origin was written as a 32-bit two's complement, which the kernel range-checks as a 64-bit signed value and refuses, so with a buffer of the driver's size every commit within about half a buffer of either edge failed withEINVAL. It is now sign-extended, as the reference does (P-84).drmkit-scene: a layer partly off the top or left edge is placed on a plane. Its negative position was written as a 32-bit two's complement, which the kernel range-checks as a 64-bit signed value and refuses, so the layer was left unassigned and did not appear. It is now sign-extended, as the reference does (P-85).drmkit-capture:snapshotreads a plane from where its framebuffer starts. It read from byte 0 of the buffer object and ignored the framebuffer's offset, so a framebuffer starting partway in came out shifted and short of its last rows. The reference has the same bug, filed as drm-cxx#374 (P-86).drmkit-capture:snapshotexports each plane's buffer close-on-exec, as the reference does, so a child spawned on another thread during a capture does not inherit the descriptor (P-87).drmkit-capture:snapshotreports a CRTC that does not exist asCaptureError::IocarryingENOENT, as the reference does. Id 0 was reported asNoMode, and an unknown id as an I/O error with its errno turned into text (P-88).drmkit-capture:write_jpgaverages chroma over each two-by-two block, as the reference's libjpeg does. The encoder took one pixel of each block, so one-pixel color detail decoded in the wrong hue (P-89).drmkit-cursor: dropping aRenderertakes its cursor off the CRTC, as the reference's destructor does. On the legacy path the sprite stayed on screen after the renderer was gone, since the kernel holds its own reference to the cursor's framebuffer (P-90).drmkit-cursor:Renderer::set_cursormakes the next commit hand the buffer to the CRTC again, as the reference does. On the legacy path a new shape was only moved, which leaves the old one showing on a driver that uploads the sprite only when given a buffer (P-91).drmkit-cursor: a cursor falling back to an overlay passes over one this CRTC is already showing, as the reference does. It treated only an overlay on another CRTC as taken, and could take the compositor's own layer (P-92).drmkit-cursor: a hotspot on the frame's far edge is placed as the reference places it when the cursor is rotated in software. It was clamped to the sprite before the centering offset was added, one pixel off (P-93).drmkit-cursor: a cursor file is read as the reference's libxcursor reads it. A chunk's length and version fields are no longer checked, a chunk must match its table-of-contents entry, more than 65,536 entries or a file header under 16 bytes is refused, a requested size pasti32::MAXis refused, a tie between two sizes goes to the one listed first rather than the smaller, and a nominal size of zero is never chosen (P-94).drmkit-cursor: a theme'sindex.themeis read as bytes, as the reference reads it. One that is not UTF-8, such as an older theme with a Latin-1Comment=, lost itsInherits=line and resolved through the wrong theme (P-95).drmkit-capture: each color channel of anARGB8888plane is clamped to its alpha before the blend, as the reference now does. A pixel with color above its alpha, such as a transparent pixel that kept its color, carried past 255 into the next channel and came out the wrong color (drm-cxx#375, P-96).drmkit-capture: a scaled plane is resampled as the reference's Blend2D resamples it, bilinearly and to the bit, rather than nearest-neighbor. One deliberate exception: a scaledXRGB8888plane stays opaque, where the reference's alpha comes from the undefined top byte, filed as drm-cxx#376 (P-98).drmkit-scene: a plane written in full has the downstream SDE driver's private state zeroed first (scaler_v2,csc_v1,excl_rect_v1and the LUT blobs), as the reference now does. State another client left there, such as weston's scaler setup on the SA8155P, made every test commit placing a small layer on that plane fail (drm-cxx#382, P-99).drmkit-scene: a layer whose destination starts above or left of the CRTC is clipped to it, with its source trimmed to match as the kernel's own clip would, instead of being written with a negative position. The SA8155P's driver refuses a negativeCRTC_X/CRTC_Y, so such a layer got no plane. The reference has the same bug, drm-cxx#384 (P-100).drmkit-cursor: a cursor near the top or left edge commits on drivers that refuse a negative plane position, such as the SA8155P's. The sprite is drawn moved up and left inside its buffer and the plane starts at the edge, with no source offset, which i915 and amdgpu refuse on a cursor plane. The reference has the same bug, drm-cxx#384 (P-101).drmkit-fmt: a vendor-0x0bmodifier is told apart as MediaTek's or VeriSilicon's by its body, as the reference now does. Every one was read as VeriSilicon, so a MediaTek modifier was classified and described as a VS tile mode.vendor_0b_is_mtkis new (drm-cxx#365, P-102).drmkit-planes: a CRTC's blend-stage limit is read as the reference reads it.use_baselayer_for_stage=1now counts the base stage, and asec_ui_blendstageof 0 no longer leaves the CRTC with no limit (drm-cxx#363, P-103).drmkit-scene: the canvas is reserved only a plane that scans it out in its own format, linear, as the reference asks. A plane that took only some other canvas format could be reserved and then refuse the canvas (drm-cxx#364, P-104).drmkit-planes:PlaneCapabilities::scans_outreads a plane withoutIN_FORMATSas linear only, as the reference does (drm-cxx#364, P-104).drmkit-planes: on a CRTC that blends fewer planes than it offers, the allocator keeps the layers with the highestkeep_prioritywithin the limit, counting pinned and externally bound layers and leaving one stage for the canvas when anything composites, as the reference now does. The layers it kept were the ones its search happened to place first, so high-priority layers could be composited while low-priority ones held planes (drm-cxx#363, P-105).drmkit-cursor: the cursor's plane is written with the top of itszposrange, capped below the CRTC's blend-stage limit, as the reference's cursor fix does. Left at an overlay's default of 0 it shared the primary's blend stage, which the SA8155P refuses, so the cursor never committed there (drm-cxx#384, P-106).drmkit-scene: the off-screen clip skips the formats the reference skips, a list of chroma-subsampled ones, and nothing else, so a 4:4:4 YUV layer such asNV24is clipped too. A source extent past 32 bits is left as given (drm-cxx#384, P-107).drmkit-cursor: an overlay picked for the cursor is never a multirect virtual plane, which the driver refuses unless its parent is armed too (drm-cxx#387, P-108).
All 21 crates are on crates.io at 0.1.3. Full diff: v0.1.2...v0.1.3.
drmkit 0.1.2
Added
drmkit-scene:LayerBufferSource::with_mapping, a provided method that runs a closure over a CPU view of the pixels. The scene's composition reads through it; its default maps withmap, so existing sources need nothing.drmkit-scene:LayerScene::on_session_pausedandon_session_resumed, as the reference has them. A pause hands every held buffer back and pauses each source and the canvas; a resume rebuilds the allocator's view of the output, resumes each source on the new device, makes the canvas again, and lifts any suspension. Every caller had to walk the layers itself (P-74).
Deprecated
drmkit-scene:OutputSignallingandderive_output_signallingare nowOutputSignalingandderive_output_signaling, in the US spelling the rest of the API uses. The old names remain as deprecated aliases until 0.2.
Fixed
drmkit-scene: a source's damage is bounded before it reaches the kernel, as the reference does. More than 16 rectangles repaints the whole frame, each rectangle is clipped to the buffer, and one left empty is dropped. A clip outside the buffer could otherwise make the kernel refuse the whole commit (P-53).drmkit-scene: the first fast-path frame the kernel refuses is logged as a warning, once, as the reference does. The latch was set but nothing logged (P-54).drmkit-core:Device::openreports a node the caller may not open asCoreError::Io(EACCES), the errno as the reference returns it, rather thanCoreError::NotMaster, whose "not DRM master" misdiagnosed a permissions problem.drmkit-display:DriverProfile::probeturns on universal planes and atomic before scanning, as the reference does, sofb_damage_clipsno longer reads false on a descriptor that has not gone atomic yet; and a node whose resource list cannot be read probes to defaults rather than failing.ScanoutTargetdiscovery no longer fails when a driver refuses universal planes (P-55).drmkit-planes:Allocation::compositedreports transient-composited layers, which were neither placed nor reported, and no longer reports an unplaced composition layer, as the reference marks them (P-56).drmkit-cursor: an animated cursor with many sizes loads, as it does in the reference. The 256-frame cap counted every size in the file, so Adwaita's busy cursors (six sizes of sixty frames) were refused as too large; the size is now chosen first and only its frames count (P-57).drmkit-capture: JPEG output is 4:2:0 at every quality, as the reference's libjpeg writes it; from quality 90 up it was 4:4:4. A dimension past 65,500 pixels is refused rather than cropped or sheared and reported as written (P-58).drmkit-cursor:Renderer::set_rotationrefuses a rotation on the legacy path withUnsupported, ascreatedoes and as the reference does, rather than pre-rotating the pixels in software (P-59).drmkit-sync: converting aSyncErrortoio::Errorgives the reference's errno --EBADFfor an empty fence or an empty merge,ETIMEDOUTfor a timeout -- where it gave errno-less kinds. An empty fence'sErrorKindis no longerInvalidInput(P-60).drmkit-capture: the warning for a capture with nothing readable gives the enumerated and unbound plane counts, as the reference's does, so a missing client cap can be told from a blank CRTC (P-61).drmkit-scene-sources: a dma-buf import closes its GEM handles when it goes, and when it fails, as the reference does. They were never closed, so every buffer a producer had handed over stayed pinned until the device was closed (P-62).drmkit-scene-sources: an external dma-buf source and an external ring re-import their buffers on a session resume, as the reference does. After a VT switch the source's layer failed every commit and the ring's went blank. The GBM source no longer tears its old import down through the dead descriptor when it re-allocates (P-63).drmkit-session: a device that cannot be reopened on resume no longer costs the others. It is reported as the newSessionEvent::DeviceLostand the rest resume, as the reference reports it throughresume_failed_cb;dispatchreturned the first failure and left every later device closed (P-64).drmkit-scene-sources:DumbBufferSourceallocates for its format, as the reference does: a packed format at its own depth, soRGB565gets a 16-bit stride, and the semi-planar 4:2:0 formats as two planes. Every format was sized at 32 bits a pixel in one plane, soRGB565scanned out sheared andNV12could not be created. A format with no known depth is refused asInvalidConfig, and a resume that cannot re-allocate reports the kernel's errno rather thanENOMEM(P-65).drmkit-present: when nothing is negotiated -- no plane advertisesIN_FORMATS, or none takes a layout the producer can make --ScanoutBackend::createallows the producerLINEAR, as the reference does and asScanoutProducerdocumented. It passed an empty set, which a producer reads as no constraint, so a tiled or compressed buffer no plane takes could reach the first commit (P-66).drmkit-scene-gbm: the producer's acquire fence covers one frame, as the reference hands it over: the acquire that takes it clears it. Every later frame got a copy, so the display engine waited on a render long finished, and a frame the producer had not fenced was never told apart. A framebuffer the kernel refuses reports the kernel's errno rather thanEINVAL(P-67).drmkit-present:FrameEconomy::default()is the same asnew(); its first decision commits in full. The derived default started as though a frame had gone out already, so an unchanged first frame was skipped (P-67).drmkit-scene-set: a mirrored layer's plane binding reaches its source, as the reference forwards it, and a removed layer's slot is reused, so a set whose layers come and go no longer grows by one slot each time (P-68).drmkit-present:DumbRingSourceforgets its repaint history when the session pauses, along with its buffers. The first paint after a resume could be asked for a partial repaint of a freshly allocated, blank buffer, leaving the rest of it blank on screen; every slot now starts over with a full repaint (P-69).drmkit-csd: seven small departures from the reference, each now as the reference has it (P-70):ShadowCache::blit_intoandblit_cross_fadecomposite source-over onto the destination rather than overwriting it;blit_cross_faderefuses two keys of different sizes, and its endpoints are exactlyblit_into;theme_idhashes each 32-bit field most significant byte first, so it is the reference's hash;Color::from_hexrefuses a sign, so#+1+2+3is no longer a color;- a noise amplitude past one is full strength;
Surface::exportis close-on-exec and reports a refusal as the newSurfaceError::Export, with the kernel's errno, where it wasEmpty;decoration_geometryno longer overflows, and panics, on a shadow extent or title bar pasti32::MAX / 2.
drmkit-input:Keyboard::process_keytreats a repeat as a read, as the reference does, rather than feeding xkb another press of a key it holds; and keymap names with no options take the user'sXKB_DEFAULT_OPTIONS, which an empty options string had been overriding (P-71).drmkit-session: a seat that cannot be opened is logged as an error, as the reference logs it, where it was debug; and a dispatch that fails before the seat activates isSessionError::NoBackend, the "no seat" a caller falls back on, rather thanSessionError::Seat(P-71).drmkit-scene-sources: a GBM source that cannot re-allocate on resume reports the errno, as the reference does, rather thanUnsupported(P-71).drmkit-present:DumbRingSource::newrefuses a zero width, height or slot count as the newPaintError::Zero, as the reference refuses it withEINVAL, rather than failing at the first paint (P-72).drmkit-scene-sources: a dma-buf import tears down on the device file it was made on, through a descriptor of its own, rather than through the caller's descriptor number. After a session loss the next open can take that number, and clearing aDmaBufSourceCache-- documented for session loss -- removed the new file's framebuffer (P-73).drmkit-input:InputError::Seatsays libinput could not enumerate the seat through udev, which is what it reports. It said "no such seat, or no permission for it", but libinput accepts an unknown seat name and finds no devices on it.drmkit-scene-set: a mirrored layer that falls to composition, or is forced there, is blended from the shared source, as the reference blends it. It was dropped from every frame, since a shared source could not be mapped (P-68).drmkit-dumb,drmkit-scene-gbm: a dumb buffer, and a GBM surface source's framebuffers, are torn down on the device file they were made on, through a descriptor of their own, as dma-buf imports are since P-73. A buffer dropped after a session loss destroyed the buffer of whatever file reused its descriptor number (P-75).
All 21 crates are on crates.io at 0.1.2. Full diff: v0.1.1...v0.1.2.
drmkit 0.1.1
Fixed
drmkit-session: libseat's own diagnostics (why a seat could not be opened) now arrive throughdrmkit-log, tagged[libseat], at error level, as the reference routes them. They went to thelogcrate at debug level, whichdrmkit-logdoes not read. Thelibseat-logfeature no longer does anything beyondlibseat, and is kept for 0.1.x.
All 21 crates are on crates.io at 0.1.1. Full diff: v0.1.0...v0.1.1.
drmkit 0.1.0
The first release: a behavioral-parity port of drm-cxx v5.0.0 (2b260d0), as twenty-one crates.
Added
drmkit-core,-modeset,-dumb,-fmt,-sync,-log,-time: device handles and cached properties, atomic requests, mode selection and page-flip dispatch, dumb buffers, format modifiers andIN_FORMATS,sync_filefences, diagnostics, and a swappable presentation clock.drmkit-planes: the plane registry and the allocator that assigns layers to planes, with reading planes off a device behinddevice.drmkit-scene,-scene-sources,-scene-set,-scene-gbm: a layer stack lowered to a frame and committed, composition for what does not fit, the sources a layer's pixels come from, several scenes committed together, and layers fed by a GBM surface.drmkit-present: the scanout spine — buffer rings, modifier negotiation, frame pacing, and a backend that drives them.drmkit-display: EDID through libdisplay-info (edid), the hotplug watch (hotplug), driver and connector capabilities, colour pipelines and tone mapping.drmkit-cursor,-capture,-csd: cursor themes and cursor planes, readback of what a CRTC is scanning out, and client-side decorations.drmkit-gbm: GBM allocation, with libgbm opened at run time.drmkit-session,-input: holding devices across a VT switch through libseat, and libinput devices with xkb key resolution.drmkit: every member crate re-exported as a module behind a feature of the same name, with the system libraries as features of their own.
What the port leaves out, and why, is recorded per test file in TEST_PARITY.md and per divergence in docs/parity-findings.md.
All 21 crates are on crates.io, with documentation on docs.rs. Start with the drmkit crate, whose features pick the member crates.