This adds a buffer struct and some utility functions for continously logging
into a small buffer. In the end the buffer is flushed as a single line to the
specified log channel.
Logigng the list of planes being disabled at the beginning of an apply does not
really give useful information.
Planes are disabled (and by that become in theory ready for layer-assignment)
if they do not have a layer associated at the moment or if they are compatible
with the output.
That is uninteresting since in this list the subset of planes that are
compatible with the output stay constant. And while the subset of planes being
reset not compatible with the output might vary from apply to apply it is also
of less interest since by definition they are not compatible with what the
apply is about.
It is only of interest to log the currently active layers when debugging.
A layer is inactive when it does not have an fb and composition is not forced.
Check layers for that and otherwise skip them. Also tell if composition is
actually forced on the layer.
The CRTC_X and CRTC_Y values can be negative. Log respectively. Additionally
the SRC_W and SRC_H values are shifted. Shift these values back for the log.
Similar to reuse log print debug information only when the priority of a layer
changes not whenever priority gets updated but without change.
Otherwise the debug log is spammed (depending on LIFTOFF_PRIORITY_PERIOD).
On debug verbosity logging every reuse of planes is spamming the log making it
difficult to debug the process.
With this patch only the change of reusing the same allocation is logged and
how often the allocation was reused after this changed back again.
From the kernel docs:
> -EINTR, -EAGAIN or -ERESTARTSYS, if the IOCTL should be restarted. This can
> either be due to a pending signal, or because the driver needs to completely
> bail out to recover from an exceptional situation like a GPU hang. From a
> userspace point of view all errors are treated equally.
We're not handling ERESTARTSYS because it's non-POSIX.
The previous mock library assumed the DRM client would always set all
properties in the atomic request. However, if a previous test-only commit
has set a property, there's no need to set it again.
Accomodate for this in libdrm_mock. This will be useful when we'll skip
setting properties that haven't changed in libliftoff.
References: https://github.com/emersion/libliftoff/issues/37
Makes sure libliftoff doesn't allocate a plane for the layer and doesn't crash.
References: 799f694587 ("Fix segfault when FB_ID isn't set")
References: 53a7bfebc9 ("Don't allocate planes for layers without a FB")
This would previously result in a crash:
==169727==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000028 (pc 0x7f3e0c4d7dc7 bp 0x7ffc97f8aff0 sp 0x7ffc97f8afc0 T0)
==169727==The signal is caused by a READ memory access.
==169727==Hint: address points to the zero page.
#0 0x7f3e0c4d7dc6 in layer_update_priority ../subprojects/libliftoff/layer.c:152
#1 0x7f3e0c4d3a4c in update_layers_priority ../subprojects/libliftoff/alloc.c:573
#2 0x7f3e0c4d3d7f in liftoff_output_apply ../subprojects/libliftoff/alloc.c:590
…
Compositors need to drive multiple connectors, each with its own vblank timings.
For each device, there's one separate rendering loop per output.
It's not possible to call liftoff_device_apply each time we want to submit a new
frame to one output, because this could touch another's output state, submitting
a new frame there in the process. When the other output will submit a new frame,
it'll get EBUSY (can't submit two frames without waiting for vblank).
Closes: https://github.com/emersion/libliftoff/issues/21
Start from scratch since we may be able to come up with a better allocation
(if the layer made another layer fall back to composition for instance).
Closes: https://github.com/emersion/libliftoff/issues/30
Keep track of the number of layer updates per 60 page-flips.
We could implement a more fine-grained tracking, for instance with a sliding
window. However it's a lot more complex than the current solution and the gains
are not clear. I'd prefer to keep the current solution and experiment with other
solutions once we have a good test-bed.
References: https://github.com/emersion/libliftoff/issues/22
Add a fallback case for finding an eligible CRTC for the
selected connector. The encoder picked may not have been
wired up to that connector by the previous DRM master.
This is a pretty basic benchmark measuring the time spent in
liftoff_display_apply.
The current behaviour tries to reproduce the worst case scenario: layers don't
intersect and one plane is incompatible with all layers.
This test continuously updates a layer's FB for some time, and keeps another
layer static. The continously updated layer should be put in a plane.
The test is disabled for now because priorities aren't implemented yet.
This example demonstrates how incremental layer updates should be applied. It
contains a basic rendering loop. Each layers has a back-buffer and a
front-buffer. The color of one of the layers will change at each frame.
This commit adds basic per-property change tracking.
When only FB_ID has changed, we try to re-use the previous allocation. If that
fails, go on with regular plane allocation.
Closes: https://github.com/emersion/libliftoff/issues/6