If there was a fullscreen surface using driver mode when a vt switch is
triggered, but something caused it to be gone when switching back (such
as the client being killed), a call to drm_output_switch_mode() is made
to restore the old mode, and that sets the output's current drm_fb to
NULL, so that the new mode is set drm_output_repaint(). This led to a
crash in vt_func(), because it tried to access output->current for
restoring the old mode.
Fix this by not setting the mode if there's no current fb. Instead,
schedule a repaint so that the mode is set in drm_output_repaint().
https://bugs.freedesktop.org/show_bug.cgi?id=60675
We always call enable_udev_monitor and add_devices together and always
disable_udev_monitor and remove_devices together. Let's just have one
entry point for enable and one for disable.
We used to have a bit of naming trouble when the protocol object was called
wl_input_device and the individual evdev devices were call evdev_device.
And we didn't have a drm_seat. Now that we've fixed all that, it's clear
that the drm_seat is all about udev discovery and hotplug of evdev devices,
so let's call it udev_seat instead.
Otherwise we'll kill whatever other display sever we're switching back to.
The tricky thing here is that we never explicitly set drm master in the
startup path, we get that implicitly from being the first to open the
drm device. Even so, we need to drop it before switching VTs.
The drm planes (sprites) only support translation and scaling. Now that
we have matrix.type, we can just look there to see if the transform is
compatible with kms.
Call drm_output_init_egl() instead of duplicating the gbm surface and
gl renderer state initialization code.
Note that this makes error handling a bit worse. Before, if we failed
to allocate a gbm surface we could still recover. Failing the renderer
state creation would lead to inconsisten state. Now we end up in
inconsistent state on both cases.
At this point, we reallocated the gbm surface, but we don't have an
fb with the right size to use. If we're going to a larger mode, the fb
would be too small and the mode set would fail. Besides, the repaint
logic will already do a mode set if necessary, so rely on that instead.
After a mode switch, the output region and transformation matrix need
to be updated. The call to weston_output_move() would do the former but
not the latter, but calling that when the output remains in the same
coordinate doesn't make much sense. Instead, update this state and the
transformation matrix in weston_output_mode_switch().
Trying to create a ARGB framebuffer for scanout results in EINVAL when
trying to queue the pageflip. This patch overrides the format we pass
to addfb2 in case of primary buffers like we do for sprites.
Since we always have to inspect and override the format, don't try to
look up the format in drm_fb_get_from_bo(). Instead return format from
drm_output_check_scanout_format().
Rename drm_surface_format_supported() to drm_output_check_sprite_format()
and make it follow the same convention.
We started scanning out ARGB surfaces in commit e920941032.
Since the call to drmModeSetPlane() fails with EINVAL if the supplied
fb has an unsupported format (which is the case of ARGB8888), the fb
format needs to be overridden.
Make overlays work when the client uses a buffer with the same
transformation as the output.
In order to calculate the destination rectangle, the same logic in
weston_surface_to_buffer_float() is needed, but with the output
dimensions instead. For that reason, this patch generalizes this
function into weston_transformed_{coord,rect} and moves it to util.c.
The surface functions are then implemented using those.
A client can reliably avoid allocating a second buffer per surface, if
the compositor sends the wl_buffer.release event before the frame
callback. To enable clients' single-buffering, release the wl_buffer
early if possible. Otherwise clients will double-buffer.
Releasing early is not possible, if the backend needs the buffer for
migrating a surface to or from a non-primary weston_plane. In that case,
a new buffer must arrive, before the old can be released. Backends will
indicate this by setting weston_surface:keep_buffer to 1 in
assign_planes().
A proper buffer reference in the backends would be better than the
keep_buffer flag, but that would require a per-surface backend private.
The rpi and DRM backends are updated to set keep_buffer, other backends
do not support planes, so do not have to set it.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
The wl_buffer reference counting API has been inconsistent. You would
manually increment the refcount and register a destroy listener, as
opposed to calling weston_buffer_post_release(), which internally
decremented the refcount, and then removing a list item.
Replace both cases with a single function:
weston_buffer_reference(weston_buffer_reference *ref, wl_buffer *buffer)
Buffer is assigned to ref->buffer, while taking care of all the refcounting
and release posting. You take a reference by passing a non-NULL buffer, and
release a reference by passing NULL as buffer. The function uses an
internal wl_buffer destroy listener, so the pointer gets reset on
destruction automatically.
This is inspired by the pipe_resource_reference() of Mesa, and modified
by krh's suggestion to add struct weston_buffer_reference.
Additionally, when a surface gets destroyed, the associated wl_buffer
will send a release event. Often the buffer is already destroyed on
client side, so the event will be discarded by libwayland-client.
Compositor-drm.c is converted to use weston_buffer_reference.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
Backends may move surfaces to different planes, in which case damage is
generated in the primary plane. This damage is usually passed to the
renderer, but in some cases the backend may decide to not render
anything (that's the case when drm compositor scans out a client
buffer). In that case the damage on the primary plane would be
discarded, leading to artifacts later.
This patch makes the backend's responsibility to clear the damage on
the primary plane, so that unrendered damage is kept for as long as
necessary.
This moves the EGLConfig, EGLContext and EGLDisplay fields into
gles2-renderer. It also moves EGLDisplay creation and EGLConfig
selection into gles2-renderer.
This introduces callbacks for output creation and destruction for the
gles2-renderer. This enables the gles2-renderer to have per-output
state. EGL surface creation is now done by the output_create callback
and the EGL surface is stored in the new per-output gles2-renderer
state. On the first output_create call, the gles2-renderer will setup
it's GL context. This is because EGL requires a EGL surface to be able
to use the GL context.
This makes drm_fb_get_from_bo() use drmModeAddFB2() if possible so that
drm_output_prepare_overlay_surface() can use this instead of keeping
track of the fbs and buffers itself.
Let the compositor generic code decide what to do when the buffer goes
away. We still have a valid reference do the bo, so we can still show
the client contents until something else triggers a repaint.
If the sprite is disabled and we're not enabling it on the next frame,
nothing is done in the vblank handler, so there's no need to ask for a
vblank event.
Add the concept of debug key bindings, that are bindings that activate
debug features in the compositor. The bindings are added to a list in
the compositor, but the triggering them is left to the shell.
On the shell side, a global debug key binding is added. When the user
presses mod-shift-space, the shell will invoke the debug bindings based
on the next key press.
This also converts the debug shortcuts for repaint debugging, fan
repaint debugging and the hide overlays shortcut in compositor-drm to
use the new infrastructure.
Pressing ctrl-alt-o will cause the overlays to be hidden, but surfaces
will still be assigned to different planes. This helps with debugging
of repaint culling below surfaces in other planes.
Culling of the repaint of a surface behind an opaque surface on the
same plane was broken by commit 547149a9 [1]. The idea of that commit
is that the damage obscured by an overlay would remain on the primary
plane damage and be repainted when the overlay moved. However, in the
case the two surfaces are on the same plane, the opaque one is not
obscured, so it ends up being repainted.
This commit adds an opaque field to struct weston_plane, that is built
incrementally when accumulating damage. The opaque region of surfaces
on the same plane are removed from the plane's damage, restoring the
previous culling behavior. But since damage behind opaque region of
other planes is maintained, the bug solved in the mentioned commit is
not regressed.
https://bugs.freedesktop.org/show_bug.cgi?id=56537
If we can find a boot_vga PCI GPU, we should prefer it over any other GPU
that is connected to the system. The boot_vga flag tells us that this GPU
is the primary system GPU.
This fixes problems on two-GPU-systems were the wrong GPU is used. It also
fixes systems were DisplayLink GPUs are available with lower IDs than PCI
GPUs (although, this seems unlikely).
Note that udev_enumerate guarantees that the entry-list is sorted. So for
systems that have platform-GPUs, these should almost always be reported
prior to hotpluggable (PCI, USB, ...) GPUs, as the kernel probes them
first.
https://bugs.freedesktop.org/show_bug.cgi?id=56237
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This comment became stale in:
commit 65a11e1039
Author: Kristian Høgsberg <krh@bitplanet.net>
Date: Fri Aug 3 11:30:18 2012 -0400
compositor: Accumulate damage per plane
Now it is just misleading. Remove it.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
If gbm_bo_import does not return a valid buffer for usage of
GBM_BO_USE_SCANOUT don't try and scan out the surface directly.
We've caught the SHM case explicitly earlier - this is to prevent other cases
where the bo cannot be scanned out.
Signed-off-by: Rob Bradford <rob@linux.intel.com>