Some graphics drivers (currently at least VMware and AMD) will give a 0
timestamp for the atomic mode flip completion event when turning off
the display. This causes us to trip an assertion in
weston_output_frame_finish() because the clock jumps backwards, which
isn't a condition the presentation feedback code should be dealing with.
This is a good assertion and we'd like to keep it. And there's some
expectation that this is buggy behaviour in the graphics drivers that will
be fixed at some point.
Pragmatically speaking though, there's nothing productive we can do with a
correct timestamp for the display shutdown. So let's just flag the
event sent for DPMS off as invalid so presentation feedback doesn't have
to worry about it, and the assert doesn't fire.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Fixes a minor leak due to launcher-libseatd:
Direct leak of 32 byte(s) in 1 object(s) allocated from:
#0 0x7f15664e5037 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xaa037)
#1 0x7f156305c59f in zalloc ../include/libweston/zalloc.h:38
#2 0x7f156305c99b in seat_open_device ../libweston/launcher-libseat.c:114
#3 0x7f1563056341 in weston_launcher_open ../libweston/launcher-util.c:79
#4 0x7f156302f1e2 in drm_device_is_kms ../libweston/backend-drm/drm.c:2616
#5 0x7f156302f751 in find_primary_gpu ../libweston/backend-drm/drm.c:2715
#6 0x7f15630309a5 in drm_backend_create ../libweston/backend-drm/drm.c:2970
#7 0x7f15630317ab in weston_backend_init ../libweston/backend-drm/drm.c:3162
#8 0x7f1566025b61 in weston_compositor_load_backend ../libweston/compositor.c:8201
#9 0x7f156640cb9e in load_drm_backend ../compositor/main.c:2596
#10 0x7f156641193c in load_backend ../compositor/main.c:3079
#11 0x7f1566413cc3 in wet_main ../compositor/main.c:3356
#12 0x562ba484b179 in main ../compositor/executable.c:33
#13 0x7f156624fcc9 in __libc_start_main ../csu/libc-start.c:308
But also use the launcher interface to actually close the DRM fd, in
mirror to what weston_launcher_open() does.
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
The DRM backend uses changes in the cursor view memory address and
surface damage to detect when it needs to re-upload to a cursor plane
framebuffer.
However, when a cursor view is destroyed and then recreated, e.g., when
the pointer cursor surface is updated, the newly created view may have
the same memory address as the just destroyed one. If no new cursor
buffer is provided (because it was attached, committed and used
previously) when this address reuse occurs, then there also isn't any
updated surface damage and the backend doesn't update the cursor plane
framebuffer at all.
To fix this issue utilize the destroy signal to track when the cursor
view is destroyed, and clear the cached cursor_view value in drm_output.
After clearing the cached value, the next cursor view is always
considered new and thus uploaded to the plane properly.
Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
See: https://gitlab.freedesktop.org/wayland/weston/-/issues/467#note_814985
This starts building the framework required for implementing color
management.
The main new interface is struct weston_color_manager. This commit also
adds a no-op color manager implementation, which is used if no other
color manager is loaded. This no-op color manager simply provides
identity color transforms for everything, so that Weston keeps running
exactly like before.
weston_color_manager interface is incomplete and will be extended later.
Colorspace objects are not introduced in this commit. However, when
client content colorspace and output colorspace definitions are
combined, they will produce color transformations from client content to
output blending space and from output blending space to output space.
This commit introduces a placeholder struct for color transforms,
weston_color_transform. Objects of this type are expected to be heavy to
create and store, which is why they are designed to be shared as much as
possible, ideally making their instances unique. As color transform
description is intended to be generic in libweston core, renderers and
backends are expected to derive their own state for each transform
object as necessary. Creating and storing the derived state maybe be
expensive as well, more the reason to re-use these objects as much as
possible. E.g. GL-renderer might upload a 3D LUT into a texture and keep
the texture around. DRM-backend might create a KMS blob for a LUT and
keep that around.
As a color transform depends on both the surface and the output, a
transform object may need to be created for each unique pair of them.
Therefore color transforms are referenced from weston_paint_node. As
paint nodes exist for not just surface+output but surface+view+output
triplets, the code ensures that all paint nodes (having different view)
for the same surface+output have the same color transform state.
As a special case, if weston_color_transform is NULL, it means identity
transform. This short-circuits some checks and memory allocations, but
it does mean we use a separate member on weston_paint_node to know if
the color transform has been initialized or not.
Color transformations are pre-created at the weston_output
paint_node_z_order_list creation step. Currently the z order lists
contain all views globally, which means we populate color transforms we
may never need, e.g. a view is never shown on a particular output.
This problem should get fixed naturally when z order lists are
constructed "pruned" in the future: to contain only those paint nodes
that actually contribute to the output's image.
As nothing actually supports color transforms yet, both renderers and
the DRM-backend assert that they only get identity transforms. This
check has the side-effect that all surface-output pairs actually get a
weston_surface_color_transform_ref even though it points to NULL
weston_color_transform.
This design is inspired by Sebastian Wick's Weston color management
work.
Co-authored-by: Sebastian Wick <sebastian@sebastianwick.net>
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Remove all the backend code to support drivers without universal planes.
From[1]:
"The code needed to support kernels where DRM does not support uiniversal
planes makes the DRM-backend a little more complicated, because it needs
to create fake planes for primary and cursor. The lifetimes of the fake
planes does not match the lifetime of "proper" planes, which is surprising."
And since the universal planes left the experimetal flag in 2014[2] it is
safe to remove the support now.
[1] https://gitlab.freedesktop.org/wayland/weston/-/issues/427
[2] https://cgit.freedesktop.org/drm/drm-tip/commit/?id=c7dbc6c9ae5c3baa3be755a228a349374d043b5b
Signed-off-by: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
Iterate paint nodes instead of the global view list. Right now this does
not change behavior.
This is a step towards using per-output view lists that can then be
optimized for the output in libweston core.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
If sprites_are_broken, then we will only ever arrive in renderer_only
mode, so this case will be caught by the checks above.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Weston internals and Wayland clients assume that output presentation
clock cannot go backwards. Therefore require unconditionally that KMS
uses the monotonic clock.
The kernel unconditionally supports DRM_CAP_TIMESTAMP_MONOTONIC. See:
commit 25e1a79874eb3821d93310c908cc0a81b47af060
Author: Arnd Bergmann <arnd@arndb.de>
Date: Wed Oct 11 17:20:13 2017 +0200
drm: vblank: remove drm_timestamp_monotonic parameter
That one removed the final possibility of DRM_CAP_TIMESTAMP_MONOTONIC
being false, by removing the module option. But even before that, all
drivers have been supporting monotonic, since
commit c61eef726a78ae77b6ce223d01ea2130f465fe5c
Author: Imre Deak <imre.deak@intel.com>
Date: Tue Oct 23 18:53:26 2012 +0000
drm: add support for monotonic vblank timestamps
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
fb->format is *pixel_format_info, whereas fb->format->format is the
actual DRM/wl_shm format code we want to see here. Fix the drm_debug()
call accordingly.
Signed-off-by: Bastian Krause <bst@pengutronix.de>
In drm_fb_get_from_dmabuf() we have some compile time array copies, and
multiple static_assert() calls are needed (for safety). This makes the
code unpleasant to read.
Add ARRAY_COPY macro, to simplify the code.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In commit "backend-drm: do not import dmabuf buffers with no modifiers
to KMS" we've stopped to import dmabuf with no modifiers to KMS.
In this patch we document why we can still import wl_drm buffers with no
modifiers to KMS.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
We can't tell the layout of a buffer that has been allocated with no
modifiers. Although usually drivers use linear layouts to allocate in
these cases, it is not a rule. It can use a tiling layout, for instance,
under the hood.
So it is not safe to import a buffer with no modifiers to KMS, as it
can't tell the buffer layout and this may result in garbage being
displayed. In this patch we start to require explicit modifiers to
import buffers to KMS.
In most cases things just work as expected, but just because both sides
(display and render driver) usually end up using the linear layout when
modifiers are not exposed. It also works on systems where the display
and render devices are tied (desktops with Intel or AMD, for instance),
as there's only one driver and it knows the layout of the buffer (no
need to guess).
But in SoC's where the display and render device are split, things can
go wrong. It is better to lose performance and not break things. To
solve the problem, drivers should be updated to expose modifiers (even
if only DRM_FORMAT_MOD_LINEAR), as the concept of implicit modifiers is
the root of the problem.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In commit "backend-drm: add DRM_FORMAT_MOD_INVALID to modifier sets when
no modifiers are supported" we've changed the code that iterates through
the IN_FORMATS blob property. Now it adds DRM_FORMAT_MOD_INVALID for
formats exposed without modifiers.
But the thing is that there shouldn't be formats in the IN_FORMATS blob
exposed without modifiers, as the blob has been added after the
introduction of the explicit modifiers API in the kernel. For now,
there's nothing in the kernel to ensure this correct behavior. So
instead of adding DRM_FORMAT_MOD_INVALID in this case, ignore these
formats, as userspace can't do much in this case.
In the future this may be fixed by the kernel. Or maybe the following MR
in libdrm, which adds an iterator API for the IN_FORMATS blob:
https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/146
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
From now on, when we can't know the modifiers supported for a certain
format, we add DRM_FORMAT_MOD_INVALID to its modifier set.
There is some parts where nothing is being added an others where
DRM_FORMAT_MOD_LINEAR is being added, so fix them.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In create_gbm_surface() we may allocate with no modifiers in the
following situations:
1. old GBM version, so HAVE_GBM_MODIFIERS is false;
2. the KMS driver does not support modifiers;
3. if allocating with modifiers failed, what can happen when the KMS
display device supports modifiers but the GBM driver does not, e.g.
the old i915 Mesa driver.
The comment was only stating the third situation, so add the other two.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
The function drm_output_init_egl() is too big, so move the code to
create the gbm surface to a separate function: create_gbm_surface().
Also made some minor style changes to the code that has been moved, in
order to improve readability.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In commit "libweston: add struct weston_drm_format" struct
weston_drm_format and its helper functions were added to libweston.
Also, unit tests for this API have been added in commit "tests: add unit
tests for struct weston_drm_format".
Start to use this API in the DRM-backend, as it enhances the code by
avoiding repetition and ensuring correctness.
Signed-off-by: Scott Anderson <scott.anderson@collabora.com>
Co-authored-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In drm_output_prepare_plane_view() we iterate the list of planes and add
them as candidates to promote the view to one of them.
Cursor planes do not support buffers other than wl_shm (at least for
now). So when we have a dmabuf or an EGL buffer in the view, the
function drm_output_plane_cursor_has_valid_format() returns false and
the cursor plane is not added to the candidate list.
In this patch we move the responsibility of doing this from
drm_output_plane_cursor_has_valid_format() to
drm_output_prepare_plane_view() itself, as the incompatibility between
other types of buffers and cursor planes is different from the
incompatibility between formats. This makes the code easier to read
and also documents the current incompatibility between cursor planes
and buffers that are not created through wl_shm.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In the absence of universal planes support,
drm_output_find_special_plane() sets the plane format to zero as a
placeholder. Then in drm_output_init_planes() it sets the format to
output->gbm_format.
As output->gbm_format is already set by the time we call
drm_output_find_special_plane(), simply set the plane format to it
directly in this function. This makes the code clearer, as there is no
reason to use the placeholder.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In some situations, like positioning a sub-surface that exceeds the
output's dimensions we would adjust the plane state dimensions to some
lower values to that of the buffer. That would ultimately trip the cursor
update function because the buffer itself actually exceeds the maximum
size/dimension of the cursor.
The plane state destination co-ordinates is the area of the view which
is visible on the output, which in some situations, would actually be
smaller than the original buffer dimensions (making it so that it will
pass the cropping/scaling check), but depending on of
how large is the surface buffer, it would tripping the assert wrt to
cursor width/height dimensions.
This hasn't been seen so far due to the fact that until recently we had
a cursor surface that always reached the cursor plane and that was
already being set-up by default (with desktop-shell, which is no longer
the case), and also because kiosk-shell, which doesn't set-up a cursor
surface, was not available.
This adds a check to skip placing the view in the cursor plane if the
buffer dimensions exceed the cursor permitted width/height.
(Suggested-by Daniel Stone).
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Tearing down the drm-backend when there are no input devices, would call
for the gbm device destruction before compositor shutdown. The latter
would call into the renderer detroy function and assume that the
EGLDisplay, which was created using the before-mentioned gbm device, is
still available. This patch re-orders the gbm destruction after the
compositor shutdown when no one would make use of it.
Fixes: #314
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Suggested-by: Daniel Stone <daniel.stone@collabora.com>
This header is for sharing fallback definitions for drm_fourcc.h. A new
test in tests/yuv-buffer-test.c is going to be needing XYUV8888 format,
and more new formats will be expected with HDR supports.
Share these fallback definitions in one place instead of copying them
all over.
All users of drm_fourcc.h are converted to include weston-drm-fourcc.h
instead for consistency: have the same definitions available everywhere.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
MOD_INVALID came with libdrm 2.4.83 and MOD_LINEAR came with libdrm
2.4.82. libweston unconditionally depends on libdrm >= 2.4.95, so the
fallback is not necessary.
Since linux-dmabuf.h itself has no use for these and also forgets to
include drm_fourcc.h, .c files including drm_fourcc.h after this header
would trigger compiler warnings.
linux-dmabuf.c does need these, so add the proper include.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
The renderer must be called for any pending screen capture to complete.
Previously this was guaranteed by weston_screenshooter_shoot() forcing
full output damage, so damage was never empty. If the future,
screenshooting stops inflicting damage, and the damage on the primary
plane even after disabling hardware planes may be empty.
This patch ensures that screenshots do not get stuck until damage
occurs.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Without this patch, the DRM-backend would rewrite the 'require-input',
core section option given by the user.
This removes 'continue_without_input' DRM-backend option and takes into
consideration the cmd line option only if that was passed (Pekka Paalanen).
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
gbm-drm.c includes gl-renderer.h. When EGL is enabled, that in turns
includes egl.h. As such, dependencies for drm should include EGL if
it is available.
This condition is modelled after a similar one in libweston/meson.build
Reported-by: Gary Bisson <gary.bisson@boundarydevices.com>
Reported-by: Heiko Thiery <heiko.thiery@gmail.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Refik Tuzakli <tuzakli.refik@gmail.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
Rework some functions in `drm.c` to reuse the `drmModeRes` and
reduce the usage of `drmModeGetResources` and `drmModeGetResources`.
Signed-off-by: Igor Matheus Andrade Torrente <igormtorrente@gmail.com>
96bef0517e "drm-backend: add support for
writeback connectors" started using DRM_MODE_CONNECTOR_WRITEBACK and
DRM_CLIENT_CAP_WRITEBACK_CONNECTORS. These were introduced in libdrm
2.4.95.
According to
https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/311
Ubunut Xenial is the only mentioned distribution that does not provide a
libdrm new enough. I think that is fine to drop now, 2016 was a good
while ago.
Libdrm 2.4.95 also introduced DRM_CLIENT_CAP_ASPECT_RATIO,
DRM_MODE_PICTURE_ASPECT_64_27, DRM_MODE_PICTURE_ASPECT_256_135.
The fallback definitions for the above are dropped.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Recognize writeback connectors and add 'struct drm_writeback'
objects in order to store them.
These objects are created and stored in a list by the time
that DRM-backend is initialized. This list is updated if a
writeback connector dynamically appears or is disconnected.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Instead of directly creating heads for the connectors in functions
drm_backend_create_heads() and drm_backend_update_connectors(),
add drm_backend_add_connector() that will handle this.
This split makes the code look better and will also make our lives
easier when we introduce writeback connectors.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Add helper function resources_has_connector(), what makes
the function drm_backend_update_connectors() look better.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
To deal with appearing/disappearing connectors we have the
function drm_backend_update_heads(). Rename it to
drm_backend_update_connectors(), as it is more in line with
what it does.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In case of success, drm_head_create() and drm_head_update_info()
take ownership of a connector. As this is an important
information, update the description of these functions
to include this.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
The function drm_connector_assign_connector_info() should
not be calling functions to handle drm_head, as connectors
and heads are not the same thing after patch "drm-backend:
move connector data from struct drm_head to struct drm_connector".
Move drm_head specific calls to drm_head_update_info(). This
is more in line with the hierarchy of the objects and also
allow us to drop drm_head pointer from drm_connector.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Instead of calling drmModeGetConnector() in drm_head_create()
and drm_head_update_info(), it is better to call it in
drm_backend_create_heads() and drm_backend_update_heads().
Then we can pass the drmModeConnector object as parameter.
This does not change the behavior of the code, but help us
to avoid unnecessarily calling drmModeGetConnector().
Besides that, in the future we will have support for writeback
connectors. And so drm_backend_create_heads() will be reworked
to also populate a list of writeback connectors. To make this
work, we are going to need to know if a connector is of the
writeback type or not, to know if we should call drm_head_create()
or drm_writeback_create(). We can only tell the type of connector
if we have the drmModeConnector object.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Instead of calling drmModeObjectGetProperties() each time that we need
the connector properties, it is better to keep a reference for it in
struct drm_connector. This reference is only updated when is necessary.
E.g. hotplug events.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This is the first step in order to add support for writeback
connector in Weston. We don't want writeback connectors data
to be stored in 'struct drm_head' objects, as these objects are
used to output content and we should not use writeback connectors
for this purpose.
The writeback connectors will be stored in a new 'struct
drm_writeback', but the connector data is common between
'struct drm_head' and 'struct drm_writeback'.
So move connector data from 'struct drm_head' to 'struct
drm_connector'. This helps to avoid code duplication and makes
the code clearer.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
In commit c1e89ba2 "compositor-drm: move connector fields into
drm_head" the function drm_head_assign_connector_info() was
introduced. By that time it was being used only at drm_head
creation, and not to handle connector changes.
In d2e6242e "compositor-drm: create heads for all connectors"
it started to be used also to handle connector changes. In
this scenario we replace old connector props with newer data.
Before doing this, free the old connector data to avoid memory
leak.
Note that as drm_property_info_free() is safe to be called on
a zero-initialized struct, we can call it even in the case where
the head is being created and there are no props yet.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Commit "drm-backend: move code to init/deinit planes to specific
functions" lost a chunk of drm_output_deinit() when moving code into
drm_output_deinit_planes(). Reinstate the missing chunk.
This fixes an endless loop over weston_compositor::plane_list when you
start with three monitors connected, unplug and re-plug one.
Fixes: 3be23eff99
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
After commit "drm-backend: move code to init/deinit planes to specific
functions" we have a specific function to init planes. As this function
does not set output->crtc, it should not set it to NULL in case of
failure. This is caller's responsibility.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
There are some places where we can make some cosmetic changes
to make code simpler and easier to read. Make these cosmetic
changes. Note that they do not change the code behavior.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
The code to init/deinit scanout and cursor planes was in
drm_output_init() and drm_output_deinit(). Move this code
to specific functions drm_output_init_planes() and
drm_output_deinit_planes(), as it makes the code clearer
and easier to maintain.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Now that we have a CRTC list in the DRM-backend, we can
iterate through it and look for the CRTCs that do not have
assigned outputs in order to find unused CRTCS.
So we can drop unused_crtcs from struct drm_backend and also
drop the functions drm_backend_update_unused_outputs() and
wl_array_remove_uint32().
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
There are no 'struct drm_output' for CRTCs that are not active.
Also, CRTC data lives in 'struct drm_output'. This is causing
us some trouble, as the DRM-backend needs to program those
unnactive CRTCs to be off.
If the DRM-backend had the reference for every CRTC (being
active or not), it would make certain functions (e.g.
drm_pending_state_apply_atomic()) more simple and efficient.
Move CRTC data from 'struct drm_output' to 'struct drm_crtc',
as this is the first step to allow the DRM-backend to have
references for every CRTC.
Also, add list of CRTCs to DRM-backend object. Now the
DRM-backend is responsible for allocating/deallocating the CRTC
objects. The outputs will only reference, init and fini the CRTCs
in this list.
Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
Try to make drm_output_state_propose a little more clear by reducing
divergence between plane and renderer modes towards the end, removing
a possibly-surprising conditional continue.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Reduce the scope of surface_overlap to where it's actually used, which
is only in the per-view loop, where it gets initialised and destroyed
every time.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Previously we assumed that cursor planes occluded nothing and would
always be blended, but overlay and scanout planes would always occlude
what's behind them. This is not actually true, as we can support alpha
blending on any kind of plane type now.
Remove the special case, which might hopefully fix some weird display
issues along the way. (Noticed by inspection.)
Signed-off-by: Daniel Stone <daniels@collabora.com>
We used to use planes_region for the output regions which were being
displayed on hardware planes; before we grew zpos awareness, we couldn't
have any planes overlapping with each other, since the ordering would be
undefined.
Since the zpos awareness though, this region is unused, so we can just
remove it.
Signed-off-by: Daniel Stone <daniels@collabora.com>