Age | Commit message (Collapse) | Author |
|
Imagine a constructor like this:
int object_new(void **out) {
void *my_object;
int r;
...
r = ioctl(...);
if (r < 0)
return -errno;
...
*out = my_object;
return 0;
}
We have a lot of those in systemd. If you now call those, gcc might inline
the call and optimize it. However, gcc cannot know that "errno" is
negative if "r" is. Therefore, a caller like this will produce warnings:
r = object_new(&obj);
if (r < 0)
return r;
obj->xyz = "foobar";
In case the ioctl in the constructor fails, gcc might assume "errno" is 0
and thus the error-handling is not triggered. Therefore, "obj" is
uninitialized, but accessed. Gcc will warn about that.
The new negative_errno() helper can be used to mitigate those warnings.
The helper is guaranteed to return a negative integer. Furthermore, it
spills out runtime warnings if "errno" is non-negative.
Instead of returning "-errno", you can use:
return negative_errno();
gcc will no longer assume that this can return >=0, thus, it will not warn
about it.
Use this new helper in libsystemd-terminal to fix some grdev-drm warnings.
|
|
Usually, when our session is activated (or re-configurated) we should be
able to try a page-flip to our buffer. The kernel driver should reject it
if it is incompatible. As it turns out, drivers don't do this. Therefore,
we now force a deep modeset if we're not sure what mode is set.
This has the side-effect that we might get glitches on session-switches
(depending on driver behavior). However, there's no way around this and it
is what everyone does so far. Most drivers still detect if we keep the
mode and so don't touch the clocks. Therefore, we just get a regular async
flip.
|
|
If a pipe is enabled/disabled, we have to clear crtc->applied of the
linked CRTC. Otherwise, we will not run a deep modeset, but leave the crtc
in the pre-configured state.
|
|
Instead of limiting fb-aging to 64bit integers, allow any arbitrary
context together with a release function to free it once the FB is
destroyed.
|
|
Instead of looking for available back-buffers on each operation, set it to
NULL and wait for the next frame request. It will call back into the pipe
to request the back-buffer via ->target(), where we can do the same and
look for an available backbuffer.
This simplifies the code and avoids double lookups if we run short of
buffers.
|
|
Coverity complained about this code and is partially right. We are not
really protected against integer overflows. Sure, unlikely, but lets just
avoid any overflows and properly protect our parser loop.
|
|
We currently select front-buffers as new back-buffer if they happen to be
the last buffer in our framebuffer-array. Fix this by never selecting a
new front buffer as back buffer.
|
|
Make sure the kernel always returns events properly. This is guaranteed
right now, otherwise, we do something really wrong. But lets be sure and
verify the received values properly. This also silences some coverity
warnings.
|
|
This adds some log-messages to ioctl() calls where we don't really care
for the return value. It isn't strictly necessary to look for those, but
lets be sure and print warnings. This silences gcc and coverity, and also
makes sure we get reports in case something goes wrong and we didn't
expect it to fail that way.
|
|
The GETXY ioctls of DRM are usually called twice by libdrm: Once to
retrieve the number of objects, a second time with suitably sized buffers
to actually retrieve all objects. In grdrm, we avoid these excessive calls
and instead just call ioctls with cached buffers and resize them if they
were too small.
However, connectors need to read the mode list via EDID, which is horribly
slow. As the kernel still cannot do that asynchronously (seriously, we
need to fix this!), it has a hack to only do it if count_modes==0. This is
fine with libdrm, as it calls every ioctl twice, anyway. However, we fail
horribly with this as we usually never pass 0.
Fix this by calling into GETCONNECTOR ioctls twice in case we received an
hotplug event. Only in those cases, we need to re-read modes, so this
should be totally fine.
|
|
Multiple issues here:
1) Don't print excessive card dumps on each resync. Disable it and make
developers add it themselves.
2) Ignore EINVAL on page-flips. Some cards don't support page-flips, so
we'd print it on each frame. Maybe, at some point, the kernel will add
support to retrieve capabilities for that. Until then, simply ignore
it.
3) Replace the now dropped card-dump with a short message about resyncing
the card.
|
|
Whenever we cannot use hardware frame events, we now schedule a virtual
frame event to make sure applications don't have to do this. Usually,
applications render only on data changes, but we can further reduce
render-time by also limiting rendering to vsyncs.
|
|
This helper is quite huge, split it apart to make it easier to follow.
|
|
Whenever we get udev hotplug events, re-read the device state so we
properly detect any changed in the display setups.
|
|
The grdev-drm backend manages DRM cards for grdev. Any DRM card with
DUMB_BUFFER support can be used. So far, our policy is to configure all
available connectors, but keep pipes inactive as long as users don't
enable the displays on top.
We hard-code double-buffering so far, but can easily support
single-buffering or n-buffering. We also require XRGB8888 as format as
this is required to be supported by all DRM drivers and it is what VTs
use. This allows us to switch from VTs to grdev via page-flips instead of
deep modesets.
There is still a lot room for improvements in this backend, but it works
smoothly so far so more enhanced features can be added later.
|