piense
Posts: 51
Joined: Thu Jun 09, 2016 4:11 am

Atomic Plane updates with drm & fkms

Mon Sep 09, 2019 4:25 am

I started with kmscube to understand the stack and started reworking my existing code to use libdrm. I'm looking at doing double buffering with an overlay on top of the primary plane. Wading through the drm kernel code and libdrm it seems that the proper way that should be done is with an atomic update the the "FB_ID" property of the plane, but the fkms driver doesn't expose that property. It looks like the drmModeSetPlane call might actually operate atomically and asynchronously, but that call's behavior is driver specific and I'm not sure I've read the drm kernel code correctly and quite understand what all the hooks are doing. I've got a bit of refactoring to do in general so it'll be a few days before I get to testing and timing those calls the way I want to, but I figure I'd ask and see if I'm on the right track.

User avatar
Raspberry-3.14
Posts: 4
Joined: Sun Jan 07, 2018 9:54 pm

Re: Atomic Plane updates with drm & fkms

Fri Sep 13, 2019 6:58 pm

You can glean a lot of good information from the Modetest source code. Modetest can access the FB_ID property on vc4 and perform other functions with or without Atomic support. Other good sources of information are the Linux DRM Developer's Guide and the DRM KMS Overview.
Raspberry-3.14

piense
Posts: 51
Joined: Thu Jun 09, 2016 4:11 am

Re: Atomic Plane updates with drm & fkms

Sat Sep 14, 2019 2:03 am

I'll have to dig through that code a bit. It's the most detailed example I've seen for doing those operations. I'm currently iterating over the planes properties with this:

drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(drm.fd, overlayPlane, DRM_MODE_OBJECT_PLANE);
for(int i = 0;i<props->count_props;i++)
{
drmModePropertyPtr prop = drmModeGetProperty(drm.fd, props->props);
printf("Property: %s\n",prop->name);
if(strcmp(prop->name,"alpha") == 0){
alphaProp = prop->prop_id;
}
drmModeFreeProperty(prop);
}
drmModeFreeObjectProperties(props);

which doesn't turn up a FB_ID property. the drmModeSetPlane call is synchronous and blocking so I was planning to try some more creative ways to get it mostly sync'd up with the page flip to the primary plane. Basically I want to do a cross dissolve between the two planes with all the page flips & syncs lined up for a nice smooth transition.

piense
Posts: 51
Joined: Thu Jun 09, 2016 4:11 am

Re: Atomic Plane updates with drm & fkms

Sat Sep 14, 2019 3:35 am

Found that parameter. Now I have some other interesting rendering issues but that problem was that I had to call:

drmSetClientCap(drm.fd, DRM_CLIENT_CAP_ATOMIC, 1);

Before looking for the property.

piense
Posts: 51
Joined: Thu Jun 09, 2016 4:11 am

Re: Atomic Plane updates with drm & fkms

Mon Sep 16, 2019 4:26 am

Well I got most things working. Only issue seems to be that if I update multiple planes in one atomic commit it takes longer than it should, ie 2 frames (well vblanks) instead of one.

User avatar
dividuum
Posts: 168
Joined: Sun Jun 16, 2013 1:18 pm
Location: Germany
Contact: Website

Re: Atomic Plane updates with drm & fkms

Mon Sep 16, 2019 12:32 pm

piense wrote:
Mon Sep 16, 2019 4:26 am
Well I got most things working. Only issue seems to be that if I update multiple planes in one atomic commit it takes longer than it should, ie 2 frames (well vblanks) instead of one.
I would be interested if you find a solution for that. I haven't tried using the atomic API yet, but with the legacy drmModePageFlip API, I also run into issues syncing two displays: The drmModePageFlip doesn't always return immediately and instead seems to wait for up to 16ms for one of the displays. I tried to solve this with a threaded approach, but i'm not happy with that. If you closely monitor the vsync timestamps of both displays, I also notice that they are more or less randomly shifted by up to 8ms. If you're lucky, they flip at the same time. If you're unlucky, they are up to 8ms apart and I've not yet figured out how to handle/predict this.
info-beamer hosted - A user and programmer friendly digital signage platform for the Pi: https://info-beamer.com/hosted

piense
Posts: 51
Joined: Thu Jun 09, 2016 4:11 am

Re: Atomic Plane updates with drm & fkms

Mon Sep 16, 2019 5:25 pm

Interesting. 16ms would be a full frame at 60 fps. In my case both layers are on the same display. I've been reading through the kernel code but I'm definitely still learning what it all does and exactly how the Pi driver interacts with the drm framework and it's helper functions. My next step is probably to try and trace the atomic calls all the way through the stacks and see where it's waiting for a sync signal. From what I understand of the atomic APIs they're supposed to be batched per-CRTC so I'd expect both planes to update simultaneously. In theory you could update multiple displays with non-blocking atomic calls in one loop. Then you have to figure out when the call has actually been executed. From the kmscube atomic example it looks like fencing might be able to signal event completions but I didn't get far enough into that and the atomic code didn't seem to want to run on the Pi without some tweaking.

User avatar
Raspberry-3.14
Posts: 4
Joined: Sun Jan 07, 2018 9:54 pm

Re: Atomic Plane updates with drm & fkms

Mon Sep 16, 2019 11:12 pm

There was a similar issue recently with SDL’s kmsdrm driver. I don’t know if this will solve the issues at hand but it might offer some clues.

https://hg.libsdl.org/SDL/rev/33bcd45f0447
Raspberry-3.14

piense
Posts: 51
Joined: Thu Jun 09, 2016 4:11 am

Re: Atomic Plane updates with drm & fkms

Tue Sep 17, 2019 4:16 am

dividuum wrote:
Mon Sep 16, 2019 12:32 pm
piense wrote:
Mon Sep 16, 2019 4:26 am
Well I got most things working. Only issue seems to be that if I update multiple planes in one atomic commit it takes longer than it should, ie 2 frames (well vblanks) instead of one.
I would be interested if you find a solution for that. I haven't tried using the atomic API yet, but with the legacy drmModePageFlip API, I also run into issues syncing two displays: The drmModePageFlip doesn't always return immediately and instead seems to wait for up to 16ms for one of the displays. I tried to solve this with a threaded approach, but i'm not happy with that. If you closely monitor the vsync timestamps of both displays, I also notice that they are more or less randomly shifted by up to 8ms. If you're lucky, they flip at the same time. If you're unlucky, they are up to 8ms apart and I've not yet figured out how to handle/predict this.
Found this comment which may be what's happening in your case:

drm_atomic.c line 1663:

* This way explicit fencing can be used to overrule implicit fencing, which is
* important to make explicit fencing use-cases work: One example is using one
* buffer for 2 screens with different refresh rates. Implicit fencing will
* clamp rendering to the refresh rate of the slower screen, whereas explicit
* fence allows 2 independent render and display loops on a single buffer. If a
* driver allows obeys both implicit and explicit fences for plane updates, then
* it will break all the benefits of explicit fencing.


I could be wrong, still figuring all this out. I have some guesses on my problem, but I'm not quite convinced I understand enough of the code to be sure.

Return to “Graphics programming”