[HN Gopher] Accessing a DRM Framebuffer to display an image
___________________________________________________________________
Accessing a DRM Framebuffer to display an image
Author : compressedgas
Score : 104 points
Date : 2024-11-30 12:29 UTC (8 days ago)
(HTM) web link (embear.ch)
(TXT) w3m dump (embear.ch)
| mdp2021 wrote:
| In case anyone misinterprets it:
|
| DRM here is for Direct Rendering Manager (not e.g. interfaces
| studied to limit access to content).
| Varriount wrote:
| I've always wondered why the name "Direct Rendering Manager"
| was chosen, given the existing definition of DRM. It could have
| just as easily been "Direct Rendering Layer" or some other
| alternative.
| thebruce87m wrote:
| Excellent, succinct article. Having fought to understand this
| process years ago I would have loved to find this exact article
| at the time.
| rjsw wrote:
| For a bit more complicated application also using DRM directly
| there is kmscube [1].
|
| [1] https://gitlab.freedesktop.org/mesa/kmscube
| dividuum wrote:
| I've worked a lot this year on writing DRM/KMS code while porting
| my digital signage player (https://info-beamer.com) to support
| the Raspberry Pi5. Since they moved away from their proprietary
| Broadcom provided graphical APIs (OMX/dispmanx) the Pi now fully
| supports DRM and the implementation is really solid by now.
|
| There is a ton more to learn: KMS (kernel mode setting) allows
| fine control over the video mode in case you cannot or do not
| want to rely on auto-detection.
|
| Then there's the atomic API: Unlike in the blog post, all changes
| applied to the output (from video mode to plane positions or
| assigned framebuffers...) are gathered and then applied
| atomically in a single commit. If necessary you can test if your
| atomic commit is correct and will work by doing a "Test only
| commit" before doing the real commit. Making changes atomically
| avoids all kinds of race conditions resulting in, for example,
| screen tearing.
|
| Then there's the interaction with video decoding: Using FFmpeg on
| the Pi allows you to access to hardware decoder. They produce DRM
| framebuffers for each video frame. You can then directly assign
| them to planes and position them on the screen. The resulting
| playback is zero-copy and as fast as it gets on the Pi.
|
| Another fun feature is the Writeback connector, which unlike the
| one ending up as an HDMI signal allows you to write your output
| to a new DRM framebuffer. This can, for example, be used to take
| screenshots of your output or even feed the buffer back into a
| video encoder.
|
| One very frustration aspect is that there is basically no real
| documentation, especially about semantics. I guess it makes sense
| if you consider that there's probably only a limited number of
| API consumers (like desktop compositors, special video players).
| casta wrote:
| The drm atomic test is not only to verify if it's "correct", it
| is also used to check if the display controller can scan out
| that configuration of planes/buffers, given buffer modifiers,
| plane properties/sizes, etc. and current status of the display
| controller. If it can't, you probably need to simplify the
| configuration via some GPU compositing.
|
| This is what we were doing on ChromeOS.
| dividuum wrote:
| Right. The number of times I got an EINVAL just to discover
| yet another reason was quiet something :) (Is there a better
| way to discover the true reason other than scrolling back
| through dmesg?)
|
| I'm also falling back to GL composition in some cases or
| while taking screenshots to avoid composing twice (HDMI +
| Writeback) if the scene is too complex or if other
| restrictions make that mandatory: Planes can only be rotated
| 0/180 degrees on the Pi HVS, so rotating a video to a
| portrait orientation is done on the GPU.
| casta wrote:
| When I worked on it, there was no other way to check if a
| configuration could be set. I remember suggesting to kernel
| folks to add some another way, in particular 'cause
| sometimes we had to allocate some massive buffer just to be
| told you had to composite.
|
| Also, you could not cache a config as valid. The
| configuration validity depends on the current state of the
| display controller. For example, if a configuration of
| planes on one CRTC can be set might depend on how much
| bandwidth is currently required by another one. I remember
| having to get rid of framebuffer compression on one monitor
| if another monitor had a resolution above a certain
| threshold.
|
| Planes rotation property can be 0,90, 180 and 270, you can
| also flip them:
| https://www.kernel.org/doc/html/v4.12/gpu/drm-
| kms.html#c.drm.... If I remember correctly I
| implemented/upstreamed a few of these properties support
| for Rockchip display controllers.
|
| If you can rotate a specific buffer will likely depend on
| your display controller plus if it's tiled or not though,
| since rotating a linear buffer is going to destroy BW.
|
| If you are writing code only for one specific display
| controller you can look at the drivers and just figure out
| which configs are ok.
|
| If your DP supports it, you don't need to GPU composite for
| screenshots, you can use the write back connector.
| dividuum wrote:
| > The configuration validity depends on the current state
| of the display controller.
|
| Yep. At least now the Pi's implementation does cause
| kernel tracebacks or lockups any more. Was rough in the
| beginning :-}
|
| Flipping is supported (but not 90/270 rotation) and I use
| that together with a recently added transpose feature in
| the Writeback connector to support mirroring the primary
| VC4's output to the minimal DRM implementation of the
| official 7" display.
|
| I'm using the Writeback connector to support screenshots,
| but copying every plane's configuration would be too much
| sometimes, so I heuristically compose some framebuffers
| via GL and then only place the remaining framebuffers
| (including the GL one) on Writeback and HDMI.
| ge96 wrote:
| Is an entire pi for signage affordable? I saw someone add VGA
| to an Arduino but I've seen some holiday cards have a video
| player in them, bare bones Linux
| mananaysiempre wrote:
| "Digital signage" refers to screens showing ads on
| billboards, announcements on public transport, menus in fast-
| food restaurants, and the like. Those aren't cheap devices:
| consider that not so long ago you'd encounter humongous
| plasma displays there. Using a full (industrial) PC to drive
| one is totally normal, and the cost of an RPi is likely
| negligible. Don't know if an RPi is well-built enough though,
| as some signage installations may need to exist in pretty
| hostile environments (vibration, dirt, EMI, etc.).
| mrgriffin wrote:
| > One very frustration aspect is that there is basically no
| real documentation
|
| I looked at DRM/KMS briefly earlier in the year and this is
| what made me abandon it in the end. Can you recommend any
| sources of information?
|
| The atomic API and "test only commit" both sound really useful.
| dividuum wrote:
| My main source was reading other source and sometimes asking
| questions in the Pi forum. The already linked kmscube shows
| how some of mentioned techniques work. It was then mainly
| following up on API calls names and parameters
| (DRM_MODE_ATOMIC_TEST_ONLY) to find other snippets of code
| that use them. Felt a bit more like code archeology :-)
| maplant wrote:
| DRM Framebuffers are also the preferred way to interface with
| Vulkan renderers in GTK. For example, if you wanted to make a
| game scene editor with gnome, you could render the scene to a DRM
| Framebuffer and use a GTKGraphicsOffload widget to indicate that
| it will continue to be updated outside of the event loop.
|
| In practice I've never been able to get this work. Static images
| totally fine. Graphics offloading fails and manually refreshing
| the image causes some sort of memory leak in the GPU
| sunk1st wrote:
| Can this be done on Mac OS?
| krackers wrote:
| Only before 10.7 from userspace with CGDisplayBaseAddress
|
| https://developer.apple.com/library/archive/documentation/Gr...
|
| After 10.7 (and certainly post-Metal) I don't think the
| framebuffer is accessible via userspace, you'd probably need to
| create a kernel extension to expose it somehow.
|
| Although windowserver must write to the framebuffer somehow so
| there's probably a private API as well
| leighleighleigh wrote:
| Really helpful introduction to DRM for the uninitiated, thanks
| ghosty141 wrote:
| I had the pleasure to access the framebuffer via the DRM and pull
| the data with DMA for a vnc server I wrote at work. Learning how
| to use the api was like half the work, an article like this
| would've certainly helped!
| sylware wrote:
| Have not looked deeply into the code, but I know it is important
| to work with the "DRM MODIFIERS" in order to work with a native
| (efficient) framebuffer format for the GPU (usually hardware
| custom tiling).
|
| The hard part is to "blit" from a well-known framebuffer format
| to that native framebuffer format.
|
| If I recall properly, on AMD GPU, you would use a 'DMA engine'
| which will perform the conversion (it may be obsolete and you may
| have to use the full GPU pipeline with texture image formats).
|
| I dunno how much hardware abstraction there is in libdrm (and
| this is my own dawn fault as I should have dug deeper a long time
| ago in libdrm interface), do we have to "know" how to deal with
| the native format, or is there some (expensive) hardware
| abstraction to deal with this conversion?
___________________________________________________________________
(page generated 2024-12-08 23:02 UTC)