Wrap all keyboard state updates, and all pointer/stylus/touch cursor
position with a write lock, and ::query_state() (The only entrypoint
to this state from other threads) with a read lock.
The principle is that query_state may be called from different threads
(UI so far, but maybe KMS too in the future), while the input thread
may (or may not) be updating it. This state is fetched "atomically"
(eg. x/y will be consistently old or new, if the input thread were
updating it at the same time).
There's other places deep in backends/native that read this state,
they all will run in the input thread, so they count as "other readers"
to the other thread. Those changes are already mutually exclusive with
updates, so they don't explicitly need the RW lock.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
While barriers will be added from the main thread, the native barrier
manager will sit close to the MetaSeatImpl in its own thread. Add the
necessary locking so that we can pass MetaBarrierImplNative from the
UI thread to the input thread, and ensure the MetaBarrier signals are
still emitted in the UI thread.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Depending on the backend, we want to integrate this object at different
levels. It will sit close to the MetaBackendX11/MetaSeatX11 in X11, but
it will be put deep down with MetaSeatImpl in the native backend, in a
separate thread.
Since we can't depend on a single object type, nor are able to track
ClutterSeat signals neatly, make this API something to be called
explicitly by backends.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
These changes will happen in the input event management code, so let them
be emitted via the MetaSeatImpl, as that's what we'll have neat access to.
The ClutterSeat signals are now emitted from there.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Move most of the functional bits (those meant to run on a standalone
thread) to a MetaSeatImpl object. This object is managed by the MetaSeatImpl
and not exposed outside the friend MetaSeatNative/MetaInputDeviceNative/
MetaInputSettings classes.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Banish MetaInputSettings from MetaBackend "public" API, it's now meant to
spend the rest of its days in the backend dungeons, maybe hanging
off a thread.
MetaInputMapper replaces all external uses.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Rename the set_tablet_keep_aspect() vfunc into a set_tablet_aspect_ratio()
one that takes an aspect ratio double, instead of leaking monitor info
into subclasses to let them all figure out this number themselves.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
We have 2 sources (this one in MetaSeatNative, and the one in
MetaBackend) dispatching ClutterEvents to the stage. Make the
MetaSeatNative one exclusively about dispatching the libinput
queue, and leave ClutterEvents to the other.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
This will resort to SW rendering if this cursor renderer does not
own the MetaKmsCursorRenderer, so it's pretty much equivalent thus
far, except we may now implement logic to flip the kms cursor renderer
around.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
We are aiming for a split of HW and SW cursor rendering management.
Given the HW plane is a limited resource and the amount of cursor
renderers may be >1 (due to tablets, even though we currently use an
always-software cursor renderer there), it would ideally be able to
switch between renderers.
Being MetaCursorRenderer not really a singleton, having cursor
inhibitor accounting here doesn't pan out. Make it MetaBackend API
so all cursor renderers get the same picture.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
These use now more of a "pull" model, where they receive update
notifications and the relevant input position is queried, instead
of the coordinates being passed along.
This allows to treat cursor renderers all the same independently
of the device they track. This notifying of position changes should
ideally be more backend-y than core-y, a better location will be
figured out in future commits.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Instead of letting the wayland bits maintain an always-software
cursor renderer, let the cursor renderer be managed by the backend,
and only hook to it (as we do for pointer cursor) in the wayland
bits.
ATM, make the cursor renderer still always-software, although
ideally we should allow moving the HW cursor management between
renderers.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Different devices may get standalone cursor renderers, add this API
to adapt slowly to this. The meta_backend_get_cursor_renderer() call
still exists, but shortcuts to the mouse pointer's renderer (as it
actually did before).
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
Use a new set in MetaInputDeviceNative, this coexists with
ClutterInputDevice coords for the time being. This API will
eventually be only accessed from the input thread.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1403>
xkb recently gained support for user-specified keymaps, which means we
can no longer assume that the configuration data is necessarily fully
complete or correct; and the configuration language is quite a labyrinth,
so it's easy to get wrong. If setting the keymap fails, leave it in
whatever state it previously had, since that seems preferable to crashing
with a NULL pointer dereference.
Resolves: https://gitlab.gnome.org/GNOME/mutter/-/issues/1555
Signed-off-by: Simon McVittie <smcv@debian.org>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1605>
Sometimes the automatically selected primary GPU isn't suitable with no
way to make an well educated guess to do it better. To make it possible
for the user to override the automatically calculated default, make it
possible to override it using a udev rule.
E.g. to select /dev/dri/card1 as the primary GPU, add a file e.g.
/usr/lib/udev/rules.d/61-mutter-primary-gpu.rules (path my vary
depending on distribution) containing the fellowing line:
ENV{DEVNAME}=="/dev/dri/card1", TAG+="mutter-device-preferred-primary"
Reboot or manual triggering of udev rules to make it take effect may be
required.
Related: https://gitlab.gnome.org/GNOME/mutter/merge_requests/1057https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1562
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1562>
At startup, libinput dispatch is called from the MetaSeatNative
constructed callback.
That means that we may get libinput events even before the default seat
is set.
In turn, processing those events may trigger the use the default seat
while it's still not set yet, and cause a crash of gnome-shell/mutter
at startup.
A simple reproducer for this is to start gnome-shell/mutter with a
tablet connected and the stylus in proximity, the proximity event will
cause gnome-shell/mutter to crash at startup.
To avoid that issue, avoid dispatching libinput events early from the
MetaSeatNative constructed callback, those events will eventually get
processed when the seat and the backend are all setup.
https://gitlab.gnome.org/GNOME/mutter/-/issues/1501https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1534
Rely on the seat stage, or other ways to fetch it. Also rely that
there is actually a single stage, so that we assign the right stage
to all events going out of the seat, in a single place.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1486
This is a bit scattered around, with the setter/getter in Clutter, and
it only being only directly honored in Wayland (it goes straight through
device properties in X11).
Make this private native API, and out of public ClutterInputDevice API.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1486
Make the upper part agnostic about the device being relative in order
to avoid applying keep-aspect. The X11 bits already are, so make it
sure it's also the case for the native backend.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1486
As it does seem from a read to libinput code, TOUCH_CANCEL events
actually do contain slot information, and are emitted per-slot.
This means we can avoid iterating over the slots ourselves, they
are still expected to be sent altogether.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1486
Add support for the (mostly theoretical) case of an input-device
offering tablet-mode-switch functionality being unplugged.
This makes the has_tablet_switch handling identical to the has_touchscreen
handling, leading to more consistent code.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
Detect if a tablet-mode-switch device is already present when mutter
starts by checking for this from meta_seat_native_constructed. This
mirrors how we also set has_touchscreen from meta_seat_native_constructed.
This fixes tablet-mode-switches only being recognized when they are added
at runtime.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
Unconditionally setting has_touchscreen to check_touch_mode
when a new device gets added leads to has_touchscreen becoming
false when during runtime e.g. an USB keyboard gets plugged in.
Fix this by setting has_touchscreen to TRUE when check_touch_mode
is TRUE and leaving it alone otherwise.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1506
A first step towards abandoning the CoglObject type system: convert
CoglFramebuffer, CoglOffscreen and CoglOnscreen into GObjects.
CoglFramebuffer is turned into an abstract GObject, while the two others
are currently final. The "winsys" and "platform" are still sprinkled
'void *' in the the non-abstract type instances however.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1496
During seat initialization, we process early libinput events (adding all known
devices) before the seat gets a stage assigned. This causes warnings when trying
to handle the corresponding CLUTTER_DEVICE_ADDED events, as they are sent
stageless.
As it is definitely too soon to have those events sent meaningfully, filter
those events out and instead handle the CLUTTER_DEVICE_ADDED emission for all
known devices after the seat receives an stage. This makes the events guaranteed
to be emitted early in initialization, but not so soon that they can't be
handled yet.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1472
In X, buttons 1, 2, 3 are left, middle, right. In evdev, the order is
BTN_LEFT, BTN_RIGHT, BTN_MIDDLE. So setting a scroll button to 2 gave us a
middle button in the X session and a right button in a wayland session.
Fix that by hard-coding the LMR buttons handling.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1433
Even when a direct client buffer has a compatible format, stride and
modifier for direct scanout, drmModePageFlip() may still fail sometimes.
From testing, it has been observed that it may seemingly randomly fail
with ENOSPC, where all subsequent attempts later on the same CRTC
failing with EBUSY.
Handle this by falling back to flipping after having composited a full
frame again.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1410
It's enabled by default when using the i915 driver, but disabled
everywhere else until it can be made reliably an improvement. Until
then, for anyone want to force-enable it, add the string
'dma-buf-screen-sharing' to the experimental features list in GSettings.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1442
Seems DMA buffer based interprocess buffer sharing is more broken than
not, so for now only enable it when using the i915 driver.
For example vmwgfx, qxl and radeon, it results in mmap() failing to mmap the
memory region. Other drivers, e.g. amdgpu will function, but may hit
very slow memory download paths, resulting in worse performance.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1442
This will be used when screencasting monitors so that if
there's scanout in place, it'll still be possible to blit
it to a PipeWire-owned framebuffer, and stream it.
Add a new 'blit_to_framebuffer' vfunc to CoglScanout, and
implement it in MetaDrmBufferGbm.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1421
Just because X11/XI uses a particular terminology doesn't mean we
have to use the same terms in our own API. The replacement terms
are in line with gtk@1c856a208, which seems a better precedent
for consistency.
Follow-up to commit 17417a82a5.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1425
QXL doesn't support mmap():ing a DMA buffer allocated in mutter inside
the PipeWire stream consumer process. To make screen casting work again
on QXL, disable DMA buffer based screen casting for QXL.
Eventually, it should be the client that renegotiates the supported
buffer types, but until then we need this list.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1318
Delay the addition and removal of devices using ClutterDeviceEvent's so that
they are processed following the libinput event order, and that we don't
have to flush the events on removal.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1371
We checked if we were using the usig the X11 backend to decide when to
deal with a11y event posting - in order to make the clutter code less
windowing system dependent, make this check a check whether we're a
display server or not, in contrast to a window/compositing manager
client. This is made into a vfunc ot ClutterBackendClass, implemented by
MetaClutterBackendNative and MetaClutterBackendX11.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1364
Detect displays marked as 'non-desktop' by the kernel and skip them when
creating the outputs. Mutter is not able to render images that are shown
properly on those devices anyway.
This avoids lighting up attached VR HMDs and showing the GDM login
screen between the eyes in a VR HMD instead of on the monitor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1393
The new "id" properties for the MetaCrtc* and MetaOuput* objects are 64-bit
values, so take care to pass 64-bit values when calling g_object_new.
Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1343.
When using its EGLStream-based presentation path with the proprietary NVIDIA
driver, mutter will use a different function to process page flips -
custom_egl_stream_page_flip. If that fails due to an EBUSY error, it will
attempt to retry the flip. However, when retrying, it unconditionally uses the
libdrm-based path. In practice, this causes a segfault when attempting to
access plane_assignments->fb_id, since plane_assignments will be NULL in the
EGLStream case. The issue can be reproduced reliably by VT-switching away from
GNOME and back again while an EGL application is running.
This patch has mutter also use the custom page flip function when retrying the
failed flip.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1375
Replace the default master clock with multiple frame clocks, each
driving its own stage view. As each stage view represents one CRTC, this
means we draw each CRTC with its own designated frame clock,
disconnected from all the others.
For example this means we when using the native backend will never need
to wait for one monitor to vsync before painting another, so e.g. having
a 144 Hz monitor next to a 60 Hz monitor, things including both Wayland
and X11 applications and shell UI will be able to render at the
corresponding monitor refresh rate.
This also changes a warning about missed frames when sending
_NETWM_FRAME_TIMINGS messages to a debug log entry, as it's expected
that we'll start missing frames e.g. when a X11 window (via Xwayland) is
exclusively within a stage view that was not painted, while another one
was, still increasing the global frame clock.
Addititonally, this also requires the X11 window actor to schedule
timeouts for _NET_WM_FRAME_DRAWN/_NET_WM_FRAME_TIMINGS event emitting,
if the actor wasn't on any stage views, as now we'll only get the frame
callbacks on actors when they actually were painted, while in the past,
we'd invoke that vfunc when anything was painted.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/903
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The mutexes was used by ClutterTexture's async upload and to match GDK's
mutexes on X11. GDK's X11 connection does not share anything with
Clutter's, we don't have the Gdk Clutter backend left, and we have
already removed ClutterTexture, so lets remove these mutexes as well.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The native backend had a plain counter, and the X11 backend used the
CoglOnscreen of the screen; change it into a plain counter in
ClutterStageCogl. This also moves the global frame count setting to the
frame info constuctor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
We currently have mutter set a global frame counter on the frame info in
the native backend, but in order to do this from clutter, change the
frame info construction from being implicitly done so when swapping
buffers to having the caller create the frame info and passing that to
the swap buffers call.
While this commit doesn't introduce any other changes than the API, the
intention is later to have the caller be able to pass it's own state
(e.g. the global frame count) along with the frame info.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
We had time unit conversion helpers (e.g. us2ms(), ns2us(), etc) in
multiple places. Clean that up by moving them all to a common file. That
file is clutter-private.h, as it's accessible by both from clutter/ and
src/.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
Currently unused, but it's intention is to use as a initial refresh rate
for a with the stage view associated frame clock. It defaults to 60 Hz
if nothing sets it, but the native backend sets it to the associated
CRTCs current mode's refresh rate.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
This avoids some issues which could happen on some setups[0] due to
meta-native-renderer.c:dummy_power_save_page_flip →
meta_onscreen_native_swap_drm_fb implicitly turning of the primary
plane (by destroying the KMS framebuffer assigned to it):
* drmModeObjectSetProperty could return an "Invalid argument" error
between setting a non-empty cursor with drmModeSetCursor(2) and
enabling the primary plane again:
Failed to DPMS: Failed to set connector 69 property 2: Invalid argument
(This was harmless other than the error message, as we always re-set
a mode on the CRTC after setting the DPMS property to on, which
enables the primary plane and implicitly sets the DRM property to on)
* drmModeSetCursor(2) could return an "Invalid argument" error between
setting the DPMS property to on and enabling the primary plane again:
Failed to set hardware cursor (drmModeSetCursor failed: Invalid argument), using OpenGL from now on
[0] E.g. with the amdgpu DC display code.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1240
Add a method to ClutterSeat that allows peeking the list of input
devices and allow looping through devices a bit faster. The API left is
private so we can make use of peeking the GList internally, but don't
have to expose any details to the outside, which means we'd have to
eventually stick with a GList forever to avoid breaking API.
Since we now have the peek_devices() API internally, we can implement
ClutterSeats public list_devices() API using g_list_copy() on the list
returned by peek_devices().
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1275
Trying to figure out what this comment was actually about, it turns out
that MSC means Media Stream Counter, and as mentioned in an article[0]
is related to DRI3 and the X11 Present extension. Anyway, the comment
has been there raising questions for some years now, I think we can
remove it.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287
The ID and name are just moved into the instance private, while the rest
is moved to a `MetaCrtcModeInfo` struct which is used during
construction and retrieved via a getter. Opens up the possibility to
add actual sub types.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287
Just as with MetaOutput, instead of the home baked "inheritance" system,
using a gpointer and a GDestroyNotify function to keep the what
effectively is sub type details, make MetaCrtc an abstract derivable
type, and make the implementations inherit it.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287
Instead of the home baked "inheritance" system, using a gpointer and a
GDestroyNotify function to keep the what effectively is sub type
details, make MetaOutput an abstract derivable type, and make the
implementations inherit it.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287
Now set as a property during construction. Only actually set by the
Xrandr backend, as it's the only one currently not supporting all
transforms, which is the default.
While at it, move the 'ALL_TRANFORMS' macro to meta-monitor-tranforms.h.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287
The output info is established during construction and will stay the
same for the lifetime of the MetaOutput object. Moving it out of the
main struct enables us to eventually clean up the MetaOutput type
inheritence to use proper GObject types.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287
MetaCrtcInfo and MetaOutputInfo did not represent information about
MetaCrtc and MetaOutput, but the result of the monitor configuration
assignment algorithm, thus rename it to MetaCrtcAssignment and
MetaOutputAssignment.
The purpose for this is to be able to introduce a struct that actually
carries information about the CRTCs and outputs, as retrieved from the
backend implementations.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287
That is is_presentation, is_primary, is_underscanning and backlight.
The first three are set during CRTC assignment as they are only valid
when active. The other is set separately, as it is untied to
monitor configuration.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287
It was used during configuration to ensure that we always dealt with
every output and CRTC. Do this without polluting the MetaOutput and
MetaCrtc structs with intermediate variables not used by the
corresponding types themself.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1287
When the stage views the stage is shown on are changed, ClutterStage
currently provides a clutter_stage_update_resource_scales() method
that allows invalidating the resource scales of all actors. With the new
stage-views API that's going to be added to ClutterActor, we also need a
method to invalidate the stage-views lists of actors in case the stage
views are rebuilt and fortunately we can re-use the infrastructure for
invalidating resource scales for that.
So since resource scales depend on the stage views an actor is on,
rename clutter_stage_update_resource_scales() and related methods to
clutter_stage_clear_stage_views(), which also covers resource scales.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1196
Using XDG_CONFIG_HOME allows users to place their keyboard configuration into
their home directory and have them loaded automatically.
libxkbcommon now defaults to XDG_CONFIG_HOME/xkb/ first, see
https://github.com/xkbcommon/libxkbcommon/pull/117
However - libxkbcommon uses secure_getenv() to obtain XDG_CONFIG_HOME and thus
fails to load this for the mutter context which has cap_sys_nice.
We need to manually add that search path as lookup path.
As we can only append paths to libxkbcommon's context, we need to start with
an empty search path set, add our custom path, then append the default search
paths.
The net effect is nil where a user doesn't have XDG_CONFIG_HOME/xkb/.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/936
When we created the DMA buffer backed CoglFramebuffer, we handed it over
to CoglDmaBufHandle which took its own reference. What we failed to do
was to release our own reference to it, effectively leaking it.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1283
This cannot be made to work reliably. Some factoids:
- Internal devices may be connected via USB.
- The ACPI spec provides the _PLD (Physical location of device) hook to
determine how is an USB device connected, with an anecdotal success
rate. Internal devices may be seen as external and vice-versa, there is
also an "unknown" value that is widely used.
- There may be non-USB keyboards, the old "AT Translated Set 2 Keyboard"
interface does not change on hotplugging.
- Libinput has an internal series of quirks to classify keyboards as
internal of external, also with an "unknown" value.
These heuristics are kinda hopeless to get right by our own hand. Drop
this external keyboard detection in the hope that there will be something
more deterministic to rely on in the future (e.g. the libinput quirks
made available to us directly or indirectly).
Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2378
Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2353https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1277
Move Wayland support (i.e. the MetaWaylandCompositor object) made to be
part of the backend. This is due to the fact that it is needed by the
backend initialization, e.g. the Wayland EGLDisplay server support.
The backend is changed to be more involved in Wayland and clutter
initialization, so that the parts needed for clutter initialization
happens before clutter itself initialization happens, and the rest
happens after. This simplifies the setup a bit, as clutter and Wayland
init now happens as part of the backend initialization.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1218
Will be used for logging to identify what view a log entry concerns. For
the native and nested backend this is the name of the output the CRTC is
assigned to drive; for X11 it's just "X11 screen", and for the legacy
"X11 screen" emulation mode of the nested backend it's called "legacy
nested".
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1237
We were iterating through evcodes, but using API that expects Clutter button
numbers. Instead of transforming those to Clutter numbers to have those translated
back, use the inner seat API that already takes evcodes.
Fixes stuck buttons keys after a virtual device is destroyed while those are
pressed.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1239
If drmModePageFlip() or custom_page_flip_func fails, process_page_flip() was
forgetting to undo the ref taken for that call. This would leak page_flip_data.
The reference counting works like this:
- when created, ref count is 1
- when calling drmModePageFlip, ref count is increased to 2
- new: if flip failed, ref count is decreased back to 1
- if calling schedule_retry_page_flip(), it takes a ref internally
- if calling mode_set_fallback(), it takes a ref internally
- all return FALSE paths have an explicit unref
- return TRUE path has an explicit unref
This issue was found by code inspection and while debugging an unrelated issue
with debug prints sprinkled around. I am not aware of any end-user visible
issues being fixed by this, as the leak is small and probably very rare.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1209
When testing a laptop with intel and DisplayLink devices, attempting to set the
DL output as the only active output resulted in GNOME/Wayland freezing. The
main event loop was running fine, but nothing on screen would get updated once
the DL output become the only one. This patch fixes that issue.
DisplayLink USB 3 devices use an out-of-tree kernel DRM driver called EVDI.
EVDI can sometimes fail drmModePageFlip(). For me, the flip fails reliably when
hotplugging the DL dock and when changing display configuration to DL only.
Mutter has a workaround for failing flips, it just calls drmModeSetCrtc() and
that succeeds.
What does not work reliably in the fallback path is Mutter keeping track of the
pageflip. Since drmModePageFlip() failed, there will not be a pageflip event
coming and instead Mutter queues a callback in its stead. When you have more
than one output, some other output repainting will attempt to swap buffers and
calls wait_for_pending_flips() which has the side-effect of dispatching any
queued flip callbacks. With multiple outputs, you don't get stuck (unless they
all fail the exact same way at the same time?). When you have only one output,
it cannot proceed to repaint and buffer swap because the pageflip is not marked
complete yet. Nothing dispatches the flip callback, leading to the freeze.
The flip callback is intended to be an idle callback, implemented with a
GSource. It is supposed to be called as soon as execution returns to the main
event loop. The setup of the GSource is incomplete, so it will never dispatch.
Fix the GSource setup by setting its ready-time to be always in the past. That
gets it dispatched on the next cycle of the main event loop. This is now the
default behavior for all sources created by meta_kms_add_source_in_impl().
Sources that need a delay continue to do that by overriding the ready-time
explicitly.
An alternative solution could have been to implement GSource prepare and check
callbacks returning TRUE. However, since meta_kms_add_source_in_impl() is used
by flip retry code as well, and that code needs a delay through the ready-time,
I was afraid I might break the flip retry code. Hence I decided to use
ready-time instead.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1209
While this is fairly incomplete, as to check things fully we need to use
TEST_ONLY in atomic to try out a complete assignment on the device, but
this works well enough for legacy non-modifier cases.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
Instead of always swapping buffers and flipping the back buffer, make it
possible to scan out a provided buffer directly without swapping any EGL
buffers.
A buffer is passed as an object implementing the empty CoglScanout
interface. It is only possible to do this in the native backend; and the
interface is implemented by MetaDrmBufferGbm. When directly scanned out,
instead of calling gbm_surface_lock_front_buffer() to get the gbm_bo and
fbid, get it directly from the MetaDrmBufferGbm, and use that to create
the page flip KMS update.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
Surface buffers are created with meta_drm_buffer_new_acquire(), taking a
gbm_surface acquiring the gbm itself, and meta_drm_buffer_new_take()
that takes over ownership of a passed gbm_bo.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
The CRTC level transform (not necessarily the hw transform) must be
taken into account when calculating the position of the CRTC in the
stage coordinate space, when placing the hw cursor, otherwise we'll
place the cursor as if the monitor was not rotated.
This wasn't a problem in the past, as with rotation, we always used the
OpenGL cursor, so the issue newer showed.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199
The port to per CRTC views was incomplete; we still used the logical
monitor layout as the stage view layout, while still using one view per
CRTC.
This worked fine for most cases, e.g. regular monitors, tiled or
non-tiled, transformed or non-transformed. Where it broke, however, was
when a monitor consists of multiple CRTCs. We already have the layout a
CRTC corresponds to on the stage kept with the CRTC metadata, so use
this directly.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1170https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199`
The motion events of tablets for example need to be mapped on the
selected screen area if the input device is configured to use only a
part of the active logical monitor.
To achieve this behavior each motion event is transformed using the
transformation matrix set for the input device.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1118
GObject recommends to break references to other objects on dispose
instead of finalize, also we want to release the pressed virtual buttons
as early as possible if we know the object is getting destroyed.
So release the pressed buttons and unref our virtual
MetaInputDeviceNative when the dispose vfunc is called, which also
allows us to release the buttons immediately from javascript instead of
waiting for the garbage collector by calling run_dispose() on the
object.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1157
When calculating the transform we should apply to the cursor sprite
before uploading it to the cursor plane, we must also take into
account non upright mounted LCD panels.
Otherwise the cursor ends up 90 degrees rotated on devices where the
LCD panel is mounted 90 degrees rotated in its enclosure.
This commit fixes this by calling meta_monitor_logical_to_crtc_transform
in get_common_crtc_sprite_transform_for_logical_monitors to adjust the
transform for each Monitor in the LogicalMonitor.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1123https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1153
The transactional KMS API has been modelled after atomic KMS. Atomic KMS
currently doesn't support forwarding cursor hotspot metadata, thus it
was left out of the transactional KMS API having the user set the simply
create a plane assigment with the cursor sprite assigned to a cursor
plane using regular coordinates.
This, however, proved to be inadequate for virtual machines using
"seamless mouse mode" where they rely on the cursor position to
correspond to the actual cursor position of the virtual machine, not the
cursor plane. In effect, this caused cursor positions to look "shifted".
Fix this by adding back the hotspot metadata, right now as a optional
field to the plane assignment. In the legacy KMS implementation, this is
translated into drmModeSetCursor2() just as before, while still falling
back to drmModeSetCursor() with the plane coordinates, if either there
was no hotspot set, or if drmModeSetCursor2() failed.
Eventually, the atomic KMS API will learn about hotspots, but when
adding our own atomic KMS backend to the transacitonal KMS API, we must
until then still fall back to legacy KMS for virtual machines.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1136
This is so that cogl-trace.h can start using things from cogl-macros.h,
and so that it doesn't leak cogl-config.h into the world, while exposing
it to e.g. gnome-shell so that it can make use of it as well. There is
no practical reason why we shouldn't just include cogl-trace.h via
cogl.h as we do with everything else.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1059
This class sits between ClutterInputDevice and the backend implementations,
it will be the despositary of features we need across both backends, but
don't need to offer through Clutter's API.
As a first thing to have there, add a getter for a WacomDevice. This is
something scattered across and somewhat inconsistent (eg. different places
of the code create wacom devices for different device types). Just make it
here for all devices, so users can pick.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1109
When a page flip fails with a certain error code, we've treated this as
a hint that page flipping is broken and we should try to use mode
setting instead.
On some drivers, it seems that this error is also reported when there
was no mode set, which means we'll have no cached mode set to use in the
fallback. The lack of prior mode set tends to happen when we hit a race
when the DRM objects change before we have the time to process a hotplug
event.
Handle the lack a missing mode set in the flip fallback path, with the
assumption that we'll get a hotplug event that'll fix things up for us
eventually.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/917
If the CRTCs the cursor is visible on do not share a common scale
and transform, we can't use the cursor hardware plane as we only have one.
We therefore fall back to software / gl cursor.
The check for that currently happens after we tried to upload the cursor image
to the hardware plane though.
This is made worse by the fact that in the scaling step, where we scale the
cursor image to the desired size, until now we expected a valid common scale -
otherwise scaling the image by an uninitialized float.
Make sure we bail out early during the scale/upload step if we don't have common
scales and transforms - to avoid that bug and save some unnecessary work.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1125
Listen for GPU hotplug events to initialize their cursor support.
This fixes one reason for why DisplayLink devices may not be using a hardware
cursor. Particularly, when a DisplayLink device is hotplugged for the first
time such that EVDI creates a new DRM device node after gnome-shell has already
started, we used to forget to initialize the cursor support.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1097
Extract the code to initialize a single GPU cursor support into its own
function. The new function will be used by GPU hotplug in the future.
This is a pure refactoring without any behavioral changes.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1097
While we will always have cursor planes, as we'll currently create fake
ones when real ones are missing (See #1058), eventually we will run into
situations where we can't create fake ones, for example for atomic KMS
drivers that don't advertise any cursor planes.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1079
Create a new gbm_bo using the same given geometry, and export the new
bo's DMA buffer fd. The new bo lives as long as necessary to be used,
and reused, by PipeWire.
Unfortunately, PipeWire doesn't support modifiers properly, so use the
linear format for now. For now, a hardcoded format of DRM_FORMAT_XRGB8888
is set, so we don't need to negotiate the format with PipeWire early.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
If the cursor sprite does not match the scale factor or transformation
of the monintor, we currently fall back to a software cursor, causing
redraws of the shell. This commit implements scaling and transforming
of the cursor sprite, so we can use it with hardware planes, too.
This commit does the following steps:
1. Make sure we reupload the cursor image if the cursor is over
a logical monitor not matching the scale or transform from the previous
update.
2. Before upload to the hardware plane, scale and transform the cursor
image if possible and necessary.
3. Make sure we always use the hardware cursor if possible (only fall
back to software/OGL cursor if it is visible on multiple logical monitors
with differet scales/transforms).
4. Transform or scale the cursor coordinates if necessary.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/526
This may be used indirectly before creation as we dispatch libinput events
right after creation (to let input devices be known), so those device
additions would trigger the touch-mode checks.
Creating it in advance results in checks being correctly performed, although
redundantly.
Spotted by Bastien Nocera.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1067
Prior to this commit the stage was drawn separately for each logical
monitor. This allowed to draw different parts of the stage with
different transformations, e.g. with a different viewport to implement
HiDPI support.
Go even further and have one view per CRTC. This causes the stage to
e.g. draw two mirrored monitors twice, instead of using the same
framebuffer on both. This enables us to do two things: one is to support
tiled monitors and monitor mirroring using the EGLStreams backend; the
other is that it'll enable us to tie rendering directly to the CRTC it
will render for. It is also a requirement for rendering being affected
by CRTC state, such as gamma.
It'll be possible to still inhibit re-drawing of the same content
twice, but it should be implemented differently, so that it will still
be possible to implement features requiring the CRTC split.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
To make it more reliable to distinguish between values that are read
from the backend implementation (which is likely to be irrelevant for
anything but the backend implementation), split out those values (e.g.
layout).
This changes the meaning of what was MetaCrtc::rect, to a
MetaCrtcConfig::layout which is the layout the CRTC has in the global
coordinate space.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
On a Surface Pro 2017, touch-mode is currently only detected correctly
after detaching and attaching the Type Cover (detachable keyboard) once,
it seems that `has_external_keyboard` is only set to the correct value
after MetaSeatNative is initialized.
So fix that and call `update_touch_mode()` once again when the object is
initialized and the `has_external_keyboard` and `has_touchscreen`
properties have been finally updated.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1075
Devices have capabilities that other parts need to know about. Instead
of having them probe using drmMode* API, outsource this to
MetaKmsDevice. Currently the only capability tracked is HW cursor size.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
Turns the cursor setting and movement into cursor plane assignment
primitives. In the current simple implementation, this in turn
translates into legacy drmModeSetCursor() and drmModeMoveCursor() calls.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
A cursor plane can now be assigned, and for the simple KMS
implementation, it'll translate into drmModeSetCursor() and
drmModeMoveCursor() calls.
When assignments failed, the cursor planes that failed to be assigned
are communicated via the feedback object.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
The current API as all synchronous, so they can be made to return
feedback immediately. This will be needed for the cursor renderer which
needs to know whether it should fall back to OpenGL cursor rendering.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
meta_kms_update_process_..() makes it sound like it's a MetaKmsUpdate
function called update_..() but in fact it's a MetaKms function that
calls the corresponding process-update impl function. Clear up this
naming confusion.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
This taps on:
1) Touchscreen availability
2) Availability of external keyboards
3) Tablet mode switch, if existent
So we get this property enabled whenever it makes sense to show touch
focused features (eg. the OSK).
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1044
During compilation, gen_default_modes.py shows two warnings that
say that a comparison is using 'is' instead of '=='.
This patch fixes this bug.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/985
When creating a virtual device for the native backend, no "device-added"
is emitted.
Similarly, no "device-removed" signal is emitted either when the virtual
device is disposed.
However, the backend plugs into the "device-added" signal to set the
monitor device. Without the "device-added" signal being emitted, the
monitor associated with a virtual device remains NULL.
That later will cause a crash in `meta_idle_monitor_reset_idlettime()`
called from `handle_idletime_for_event()` when processing events from a
virtual device because the device monitor is NULL.
Make sure to emit the "device-added" signal when creating a virtual
device, and the "device-removed" when the virtual device is disposed.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1037
e9fbbd5853 changed meta_backend_get_idle_monitor() to use
ClutterInputDevice pointers instead of device IDs, but did not adjust
the call in meta_backend_native_resume() which was still using 0 to get
the core idle monitor resulting in a NULL pointer dereference.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1029
The meta_seat_native_constrain_pointer() function receives the current
pointer position, and the new pointer position as in/out parameters.
We were however calculating the new coordinates based on the last pointer
position if there was no pointer constrain in place.
Fortunately to us, this didn't use to happen often/ever, as a pointer
constrain function is set on MetaBackend initialization. This behavior
did also exist previously in MetaDeviceManagerNative.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1028
The backend being initialized triggers a pointer warp (and motion event)
where we want to observe the callbacks put in place. So ensure we set
up the hooks before that could happen.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
Just go ATM through backend checks, and looking up directly the
native event data, pretty much like the rest of the places do that...
Eventually would be nice to have this information in ClutterEvent,
but let's not have it clutter the MetaBackend class.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/852
The gamma value pointers of the current_state are overwritten by the
calls to memdup causing a small leak. while the leak itself is small, it
can be triggered quite often from things like night light.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1020
Where possible, try to export the buffer rendered by the primary GPU as a
dmabuf and import it to the secondary GPU and turn it into a DRM FB for
scanout. If this works, we get a zero-copy path to secondary GPU outputs.
This is especially useful on virtual drivers like EVDI (used for DisplayLink
devices) which are not picky at all about what kind of FBs they can handle.
The zero-copy path is prioritised after the secondary GPU copy path, which
should avoid regressions for existing working systems. Attempting zero-copy
would have the risk of being less performant than doing the copy on the
secondary GPU. This does not affect the DisplayLink use case, because there is
no GPU in a DisplayLink device.
The zero-copy path is prioritised before the primary GPU and CPU copy paths. It
will be tried on the first frame of an output and the copy path is executed
too. If zero-copy fails, the result from the copy path will take over on that
frame. Furthermore, zero-copy will not be attemped again on that output. If
zero-copy succeeds, the copy path is de-initialized.
Zero-copy is assumed to be always preferable over the primary GPU and CPU copy
paths. Whether this is universally true remains to be seen.
This patch has one unhandled failure mode: if zero-copy path first succeeds and
then fails later, there is no fallback and the output is left frozen or black.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
With all the three paths this is quite a handful of code, and it was mostly
duplicated in two places. A follow-up patch would need to introduce a third
copy of it. Therefore move the code into a helper function.
There are two behavioral changes:
- The format error now prints the string code as well, because it is easy to
read.
- The g_debug() in init_dumb_fb() is removed. Did not seem useful.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
There will be another place where I need to release the dumb buffers but not
destroy the whole secondary_gpu_state, so extract this bit of code into a
helper.
The checks of fb_id are dropped as redundant with the check already in in
release_dumb_fb ().
https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
release_dumb_fb () checks 'map' to see if anything needs freeing. Other places
are checking fb_id instead. The checks maybe redundant, but let's reset all
fields here while at it, so that all the checks work as expected.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
Simplify the bo freeing functions by not checking what the copy mode is. This
matches what swap_secondary_drm_fb () already does. g_clear_object () is safe
to call even if the value is already NULL.
The copy mode does not change mid-operation. If it did, this change would
ensure we still clean up everything. So this is more future-proof too.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
To mirror what happens in meta_onscreen_native_swap_buffers_with_damage(), warn
here too if next_fb is not NULL. This makes it clear to the reader of what the
expectations are inside this function.
Ensuring next_fb is NULL as the first thing in the function will make all error
paths equal: no longer some failures reset next_fb while others don't. Removing
such special cases should reduce surprises.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/810
If we end up trying to do a mode set on a DRM state that has already
changed behind our back without us yet having seen the hotplug event we
may fail with `EINVAL`. Since the renderer layer doesn't handle mode set
failure, it'll still try to page flip later on, which will then also
fail. When failing, it'll try to look up the cached mode set in order to
retry the mode set later on, as is needed to handle other error
conditions. However, if the mode set prior to the page flip failed, we
won't cache the mode set, and the page flip error handling code will get
confused.
Instead of asserting that a page flip always has a valid cached mode set
ready to look up, handle it being missing more gracefully by failing to
mode set. It is expected that things will correct themself as there
should be a hotplug event waiting around the the corner, to reconfigure
the monitor configuration setting new modes.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/917https://gitlab.gnome.org/GNOME/mutter/merge_requests/1007
The method `relative_motion_across_outputs` is used to adjust the
distance/delta of a mouse movement across multiple monitors to take the
different scale factors of those monitors into account. This works by
getting the adjacent monitors that the movement-line/vector intersects
with and adjusting the final position (or end point of the
movement-line) by multiplying the parts of the line spanning across
different monitors with the scale factors of those monitors.
In the end of this calculation, we always want to set the new end
coordinates of the relative motion to the new end coordinates of the
adjusted movement-line. We currently only do that if all adjacent
monitors the line is crossing actually exist, because only then we end
up inside the "We reached the dest logical monitor" else-block and set
`x` and `y` to the correct values. Fix that and make sure the returned
values are also correct in case an adjacent monitor doesn't exist by
adding separate `target_x` and `target_y` variables which we update during
each pass of the while loop so we're always prepared for the while loop
exiting before the destination monitor was found.
Thanks to Axel Kittenberger for reporting the initial bug and tracking
the issue down to `relative_motion_across_outputs`.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/774
Presumably this function is supposed to be like
meta_kms_impl_simple_handle_page_flip_callback() but the condition in the
if-statement is inverted. Fix the inversion to make these two functions look
alike.
This is part 2 of 2 fixing a complete desktop freeze when drmModePageFlip()
fails with EINVAL and the fallback to drmModeSetCrtc() succeeds but the success
is not registered correctly as completed "flip". The freeze occurs under
wait_for_pending_flips() which calls down into meta_kms_impl_device_dispatch()
which ends up poll()'ing the DRM fd even though drmModeSetCrtc() will not
produce a DRM event, hence the poll() never returns. The freeze was observed
when hotplugging a DisplayLink dock for the first time on Ubuntu 19.10.
This patch makes meta_set_fallback_feedback_idle() actually end up calling into
notify_view_crtc_presented() which decrements
secondary_gpu_state->pending_flips so that wait_for_pending_flips() can finish.
CC stable: gnome-3-34
https://gitlab.gnome.org/GNOME/mutter/merge_requests/953
mode_set_fallback() schedules a call to mode_set_fallback_feedback_idle(), but
it is possible for Mutter to repaint before the idle callbacks are dispatched.
If that happens, mode_set_fallback_feedback_idle() does not get called before
Mutter enters wait_for_pending_flips(), leading to a deadlock.
Add the needed interfaces so that meta_kms_device_dispatch_sync() can flush all
the implementation idle callbacks before it checks if any "events" are
available. This prevents the deadlock by ensuring
mode_set_fallback_feedback_idle() does get called before potentially waiting
for actual DRM events.
Presumably this call would not be needed if the implementation was running in
its own thread, since it would eventually dispatch its idle callbacks before
going to sleep polling on the DRM fd. This call might even be unnecessary
overhead in that case, synchronizing with the implementation thread needlessly.
But the thread does not exist yet, so this is needed for now.
This is part 1 of 2 fixing a complete desktop freeze when drmModePageFlip()
fails with EINVAL and the fallback to drmModeSetCrtc() succeeds but the success
is not registered correctly as completed "flip". The freeze occurs under
wait_for_pending_flips() which calls down into meta_kms_impl_device_dispatch()
which ends up poll()'ing the DRM fd even though drmModeSetCrtc() will not
produce a DRM event, hence the poll() never returns. The freeze was observed
when hotplugging a DisplayLink dock for the first time on Ubuntu 19.10.
CC stable: gnome-3-34
https://gitlab.gnome.org/GNOME/mutter/merge_requests/953
This is inspired by 98892391d7 where the usage of
`g_signal_handler_disconnect()` without resetting the corresponding
handler id later resulted in a bug. Using `g_clear_signal_handler()`
makes sure we avoid similar bugs and is almost always the better
alternative. We use it for new code, let's clean up the old code to
also use it.
A further benefit is that it can get called even if the passed id is
0, allowing us to remove a lot of now unnessecary checks, and the fact
that `g_clear_signal_handler()` checks for the right type size, forcing us
to clean up all places where we used `guint` instead of `gulong`.
No functional changes intended here and all changes should be trivial,
thus bundled in one big commit.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/940
Properly take the panel_orientation_transform into account in
update_monitor_crtc_cursor. This fixes us sometimes drawing the cursor
on two monitors at the same time as we did not properly swap the crtc
width/height when a panel_orientation_transform is active.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/927
Create the intermediate shadow framebuffer for use exclusively when a
shadowfb is required.
Keep the previous offscreen framebuffer is as an intermediate
framebuffer for transformations only.
This way, we can apply transformations between in-memory framebuffers
prior to blit the result to screen, and achieve acceptable performance
even with software rendering on discrete GPU.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/877
If we did a mode set, the gamma may have been changed by the kernel, and
if we didn't also update the gamma in the same transaction, we have no
way to predict the current gamma ramp state. In this case, read the
gamma state directly from KMS.
This should be relatively harmless regarding the race conditions the
state prediction was meant to solve, as the worst case is we get none or
out of date gamma ramps; and since this is for when gamma ramps are not
updated at mode setting time, we'd get intermediate gamma state to begin
with, so it's not worse than what we currently do anyway.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/851https://gitlab.gnome.org/GNOME/mutter/merge_requests/840
We can't just update the state of the connector and CRTC from KMS since
it might contain too new updates, e.g. from a from a future hot plug. In
order to not add ad-hoc hot plug detection everywhere, predict the state
changes by looking inside the MetaKmsUpdate object, and let the hot-plug
state changes happen after the actual hot-plug event.
This fixes issues where connectors were discovered as disconnected while
doing a mode-set, meaning assumptions about the connectedness of
monitors elsewhere were broken until the hot plug event was processed.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/782https://gitlab.gnome.org/GNOME/mutter/merge_requests/826
It was not the lack of forcing the shadow fb that caused slowness, but
rather due to the method the shadow fb content was copied onto the
scanout fb. With 'clutter: Use cogl_blit_framebuffer() for shadow FB'
we'll use a path that shouldn't be slow when copying onto the scanout
fb.
Also 437f6b3d59 accidentally enabled
shadow fb when using hw accelerated contexts, due to the cap being set
to 1 in majority of drivers. While the kernel documentation for the
related field says "hint to userspace to prefer shadow-fb rendering",
the name of the hint when exposed to userspace is
DRM_CAP_DUMB_PREFER_SHADOW, thus should only be taken into consideration
for dumb buffers, not rendering in general.
This reverts commit 437f6b3d59.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/818
The commit 'renderer/native: Use shadow fb on software GL if preferred'
attempted to force using a shadow fb when using llvmpipe in order to
speed up blending, but instead only did so when llvmpipe AND the drm
device explicityl asked for it.
Now instead always force it for llvmpipe and other software rendering
backends, and otherwise just query the drm device (i.e.
DRM_CAP_DUMB_PREFER_SHADOW).
https://gitlab.gnome.org/GNOME/mutter/merge_requests/807
When suspending, the devices are removed and the virtual device
associated with the corresponding core pointer is disposed.
Add the pointer accessibility virtual device to the core pointer
on resume to restore pointer accessibility on resume if enabled.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/761
The end goal is to have all clutter backend code in src/backends. Input
is the larger chunk of it, which is now part of our specific
MutterClutterBackendNative, this extends to device manager, input devices,
tools and keymap.
This was supposed to be nice and incremental, but there's no sane way
to cut this through. As a result of the refactor, a number of private
Clutter functions are now exported for external backends to be possible.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/672
Add meta-kms and meta-monitor-manager-kms listener for the udev
device-removed signal and on this signal update the device state /
re-enumerate the monitors, so that the monitors properly get updated
to disconnected state on GPU removal.
We really should also have meta-backend-native remove the GPU itself
from our list of GPU objects. But that is more involved, see:
https://gitlab.gnome.org/GNOME/mutter/issues/710
This commit at least gets us to a point where we properly update the
list of monitors when a GPU gets unplugged; and where we no longer
crash the first time the user changes the monitor configuration after
a GPU was unplugged.
Specifically before this commit we would hit the first g_error () in
meta_renderer_native_create_view () as soon as some monitor
(re)configuration is done after a GPU was unplugged.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/713
drmModeGetConnector may fail and return NULL, this may happen when
a connector is removed underneath us (which can happen with e.g.
DP MST or GPU hot unplug).
Deal with this by skipping the connector when enumerating and by
assuming it is disconnected when checking its connection state.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/713
drmModeGetCrtc may fail and return NULL. This will trigger when
meta_kms_crtc_update_state gets called from meta_kms_update_states_sync
after a GPU has been unplugged leading to a NULL pointer deref causing
a crash.
This commit fixes this by checking for NULL and clearing the current_state
when NULL is returned.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/713
Before this commit meta_kms_crtc_read_state was overwriting the
entire MetaKmsCrtcState struct stored in crtc->current_state including
the gamma (sub)struct.
This effectively zero-s the gamma struct each time before calling
read_gamma_state, setting the pointers where the previous gamma values
were stored to NULL without freeing the memory. Luckily this zero-ing
also sets gamma.size to 0, causing read_gamma_state to re-alloc the
arrays on each meta_kms_crtc_update_state call. But this does mean that
were leaking the old gamma arrays on each meta_kms_crtc_update_state call.
This commit fixes this by making meta_kms_crtc_read_state only overwrite
the other values in the MetaKmsCrtcState struct and leaving the gamma
sub-struct alone, this will make read_gamma_state correctly re-use the
gamma tables if the gamma table size is unchanged; or re-alloc them
(freeing the old ones) if the size has changed, fixing the memory leak.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/713
The "device-added" signal should use g_cclosure_marshal_VOID__OBJECT not
g_cclosure_marshal_VOID__VOID.
Instead of fixing this manually, simply replace the closure function for
both signals with NULL, glib will then automatically set the correct
va_marshaller.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/713
COPY_MODE_PRIMARY has two paths, automatically chosen. For debugging purposes,
e.g. why is my DisplayLink screen slowing down the whole desktop, it will be
useful to know which copy path is taken. Debug prints are added to both when
the primary GPU copy succeeds the first time and when it fails the first time.
This is not the full truth, because theoretically the success/failure could
change every frame, but we don't want to spam the logs (even in debug mode)
every frame. In practise, it should be rare for the success or failure to ever
change. Hence, saying what happened on the first time is enough. This does
indicate if it ever changes even once, too, so we know if that unexpected thing
happens.
The debug prints are per secondary GPU since there could be several.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
When the preferred path META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU cannot
be used, as is the case for e.g. DisplayLink devices which do not actually have
a GPU, try to use the primary GPU for the copying before falling back to
read-pixels which is a CPU copy.
When the primary GPU copy works, it should be a significant performance win
over the CPU copy by avoiding stalling libmutter for the duration.
This also renames META_SHARED_FRAMEBUFFER_COPY_MODE_* because the new names are
more accurate. While the secondary GPU copy is always a GPU copy, the primary
copy might be either a CPU or a GPU copy.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
This bit of code was more or less duplicated in meta-renderer-native-gles3.c
and meta-wayland-dma-buf.c. Start consolidating the two implementations by
moving the *-gles3.c function into meta-egl.c and generalizing it so it could
also accommodate the meta-wayland-dma-buf.c usage.
The workaround in the *-gles3.c implementation is moved to the caller. It is
the caller's responsibility to check for the existence of the appropriate EGL
extensions.
Commit 6f59e4858e worked around the lack of
EGL_EXT_image_dma_buf_import_modifiers with the assumption that if the modifier
is linear, there is no need to pass it into EGL. The problem is that not
passing a modifier explicitly to EGL invokes implementation-defined behaviour,
so we should not have that workaround in meta-egl.c.
This patch intends to be pure refactoring, no behavioral changes. The one
change is the addition of g_assert to catch overwriting arbitrary memory.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/615
We currently don't handle the lack of DRM_CLIENT_CAP_UNIVERSAL_PLANES
KMS capability. Fail constructing a device that can't handle this up
front, so later made assumptions, such as presence of a primary plane,
are actually valid.
If we want to support lack of said capability, the required planes need
to be emulated by a dummy MetaKmsPlane object.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/665
There were fallbacks in place in case IN_FORMATS didn't yield any usable
formats: the formats in the drmModePlane struct, and a hard coded array.
The lack of these fallbacks in place could result in a segfault as code
using the supported plane formats assumed there were at least something
in there.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/662
Simplify the call site a bit and make the native renderer know it should
queue mode reset itself when views have been rebuilt. This is done
partly due to more things needing to be dealt with after views have been
rebuilt.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/630
When building without EGL device support, the following compiler warning
is seen:
```
src/backends/native/meta-renderer-native.c:2637:20: warning: unused
variable ‘cogl_renderer_egl’ [-Wunused-variable]
```
Fix the warning by placing the relevant variable declarations within the
`#ifdef HAVE_EGL_DEVICE/#endif` statement.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/656
We used to have wayland-specific paths for this in src/wayland, now we
have ClutterKeymap that we can rely on in order to do state tracking,
and can do this all on src/backend domain.
This accomodates the feature in common code, so will work on both
Wayland and X11.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/590
This commit introduces, and makes use of, a transactional API used for
setting up KMS state, later to be applied, potentially atomically. From
an API point of view, so is always the case, but in the current
implementation, it still uses legacy drmMode* API to apply the state
non-atomically.
The API consists of various buliding blocks:
* MetaKmsUpdate - a set of configuration changes, the higher level
handle for handing over configuration to the impl backend. It's used to
set mode, assign framebuffers to planes, queue page flips and set
connector properties.
* MetaKmsPlaneAssignment - the assignment of a framebuffer to a plane.
Currently used to map a framebuffer to the primary plane of a CRTC. In
the legacy KMS implementation, the plane assignment is used to derive
the framebuffer used for mode setting and page flipping.
This also means various high level changes:
State, excluding configuring the cursor plane and creating/destroying
DRM framebuffer handles, are applied in the end of a clutter frame, in
one go. From an API point of view, this is done atomically, but as
mentioned, only the non-atomic implementation exists so far.
From MetaRendererNative's point of view, a page flip now initially
always succeeds; the handling of EBUSY errors are done asynchronously in
the MetaKmsImpl backend (still by retrying at refresh rate, but
postponing flip callbacks instead of manipulating the frame clock).
Handling of falling back to mode setting instead of page flipping is
notified after the fact by a more precise page flip feedback API.
EGLStream based page flipping relies on the impl backend not being
atomic, as the page flipping is done in the EGLStream backend (e.g.
nvidia driver). It uses a 'custom' page flip queueing method, keeping
the EGLStream logic inside meta-renderer-native.c.
Page flip handling is moved to meta-kms-impl-device.c from
meta-gpu-kms.c. It goes via an extra idle callback before reaching
meta-renderer-native.c to make sure callbacks are invoked outside of the
impl context.
While dummy power save page flipping is kept in meta-renderer-native.c, the
EBUSY handling is moved to meta-kms-impl-simple.c. Instead of freezing the
frame clock, actual page flip callbacks are postponed until all EBUSY retries
have either succeeded or failed due to some other error than EBUSY. This
effectively inhibits new frames to be drawn, meaning we won't stall waiting on
the file descriptor for pending page flips.
https://gitlab.gnome.org/GNOME/mutter/issues/548https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
The MetaKmsImpl implementation may need to add a GSource that should be
invoked in the right context; e.g. a idle callback, timeout etc. It
cannot just add it itself, since it's the responsibility of MetaKms to
determine what is the impl context and what is the main context, so add
API to MetaKms to ensure the callback is invoked correctly.
It's the responsibility of the caller to eventually remove and destroy
the GSource.
https://gitlab.gnome.org/GNOME/mutter/issues/548https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
As with CRTC state, variable connector state is now fetched via the
MetaKmsConnector. The existance of a connector state is equivalent of
the connector being connected. MetaOutputKms is changed to fetch
variable connector state via MetaKmsConnector intsead of KMS directly.
The drmModeConnector is still used for constructing the MetaOutputKms to
find properties used for applying configuration.
https://gitlab.gnome.org/GNOME/mutter/issues/548https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
Move reading state into a struct for MetaCrtcKms to use instead of
querying KMS itself. The state is fetched in the impl context, but
consists of only simple data types, so is made accessible publicly. As
of this, MetaCrtcKms construction does not involve any manual KMS
interaction outside of the MetaKms abstraction.
https://gitlab.gnome.org/GNOME/mutter/issues/548https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
Represents drmModeConnector; both connected and disconnected. Currently
only provides non-changing meta data. MetaOutputKms is changed to use
MetaKmsConnector to get basic metadata, but variable metadata, those
changing depending on what is connected (e.g. physical dimension, EDID,
etc), are still manually retrieved by MetaOutputKms.
https://gitlab.gnome.org/GNOME/mutter/issues/548https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
A plane is one of three possible: primary, overlay and cursor. Each
plane can have various properties, such as possible rotations, formats
etc. Each plane can also be used with a set of CRTCs.
A primary plane is the "backdrop" of a CRTC, i.e. the primary output for
the composited frame that covers the whole CRTC. In general, mutter
composites to a stage view frame onto a framebuffer that is then put on
the primary plane.
An overlay plane is a rectangular area that can be displayed on top of
the primary plane. Eventually it will be used to place non-fullscreen
surfaces, potentially avoiding stage redraws.
A cursor plane is a plane placed on top of all the other planes, usually
used to put the mouse cursor sprite.
Initially, we only fetch the rotation properties, and we so far
blacklist all rotations except ones that ends up with the same
dimensions as with no rotations. This is because non-180° rotations
doesn't work yet due to incorrect buffer modifiers. To make it possible
to use non-180° rotations, changes necessary include among other things
finding compatible modifiers using atomic modesetting. Until then,
simply blacklist the ones we know doesn't work.
https://gitlab.gnome.org/GNOME/mutter/issues/548https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
Add MetaKmsCrtc to represent a CRTC on the associated device. Change
MetaCrtcKms to use the ones discovered by the KMS abstraction. It still
reads the resources handed over by MetaGpuKms, but eventually it will
use only MetaKmsCrtc.
MetaKmsCrtc is a type of object that is usable both from an impl task
and from outside. All the API exposed via the non-private header is
expected to be accessible from outside of the meta-kms namespace.
https://gitlab.gnome.org/GNOME/mutter/issues/548https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
The intention with KMS abstraction is to hide away accessing the drm
functions behind an API that allows us to have different kind of KMS
implementations, including legacy non-atomic and atomic. The intention
is also that the code interacting with the drm device should be able to
be run in a different thread than the main thread. This means that we
need to make sure that all drm*() API usage must only occur from within
tasks that eventually can be run in the dedicated thread.
The idea here is that MetaKms provides a outward facing API other places
of mutter can use (e.g. MetaGpuKms and friends), while MetaKmsImpl is
an internal implementation that only gets interacted with via "tasks"
posted via the MetaKms object. These tasks will in the future
potentially be run on the dedicated KMS thread. Initially, we don't
create any new threads.
Likewise, MetaKmsDevice is a outward facing representation of a KMS
device, while MetaKmsImplDevice is the corresponding implementation,
which only runs from within the MetaKmsImpl tasks.
This commit only moves opening and closing the device to this new API,
while leaking the fd outside of the impl enclosure, effectively making
the isolation for drm*() calls pointless. This, however, is necessary to
allow gradual porting of drm interaction, and eventually the file
descriptor in MetaGpuKms will be removed. For now, it's harmless, since
everything still run in the main thread.
https://gitlab.gnome.org/GNOME/mutter/issues/548https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
Fix the following compiler warning:
../src/backends/native/meta-renderer-native.c: In function ‘meta_renderer_native_create_view’:
/usr/include/glib-2.0/glib/gmacros.h:523:17: warning: ‘formats’ may be used uninitialized in this function [-Wmaybe-uninitialized]
523 | { if (_ptr) (cleanup) ((ParentName *) _ptr); } \
| ^
../src/backends/native/meta-renderer-native.c:773:22: note: ‘formats’ was declared here
773 | g_autoptr (GArray) formats;
| ^~~~~~~
https://gitlab.gnome.org/GNOME/mutter/merge_requests/632
Make sure to destroy the EGL surface after releasing held buffers,
otherwise we'll get the following valgrind warnings:
==24016== Invalid read of size 8
==24016== at 0x1739943F: release_buffer (platform_drm.c:73)
==24016== by 0x49AC355: meta_drm_buffer_gbm_finalize (meta-drm-buffer-gbm.c:213)
==24016== by 0x4B75B61: g_object_unref (gobject.c:3346)
==24016== by 0x49B4B41: free_current_bo (meta-renderer-native.c:991)
==24016== by 0x49B816F: meta_renderer_native_release_onscreen (meta-renderer-native.c:2971)
==24016== by 0x5209441: _cogl_onscreen_free (cogl-onscreen.c:167)
==24016== by 0x5208D81: _cogl_object_onscreen_indirect_free (cogl-onscreen.c:51)
==24016== by 0x51C8066: _cogl_object_default_unref (cogl-object.c:103)
==24016== by 0x5207989: _cogl_framebuffer_unref (cogl-framebuffer.c:1814)
==24016== by 0x51C80B1: cogl_object_unref (cogl-object.c:115)
==24016== by 0x53673C7: clutter_stage_view_dispose (clutter-stage-view.c:304)
==24016== by 0x4B75AF2: g_object_unref (gobject.c:3309)
==24016== Address 0x18e742a8 is 536 bytes inside a block of size 784 free'd
==24016== at 0x4839A0C: free (vg_replace_malloc.c:540)
==24016== by 0x17399764: dri2_drm_destroy_surface (platform_drm.c:231)
==24016== by 0x1738550A: eglDestroySurface (eglapi.c:1145)
==24016== by 0x5440286: eglDestroySurface (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
==24016== by 0x49613A5: meta_egl_destroy_surface (meta-egl.c:432)
==24016== by 0x49B80F9: meta_renderer_native_release_onscreen (meta-renderer-native.c:2954)
==24016== by 0x5209441: _cogl_onscreen_free (cogl-onscreen.c:167)
==24016== by 0x5208D81: _cogl_object_onscreen_indirect_free (cogl-onscreen.c:51)
==24016== by 0x51C8066: _cogl_object_default_unref (cogl-object.c:103)
==24016== by 0x5207989: _cogl_framebuffer_unref (cogl-framebuffer.c:1814)
==24016== by 0x51C80B1: cogl_object_unref (cogl-object.c:115)
==24016== by 0x53673C7: clutter_stage_view_dispose (clutter-stage-view.c:304)
==24016== Block was alloc'd at
==24016== at 0x483AB1A: calloc (vg_replace_malloc.c:762)
==24016== by 0x173997AE: dri2_drm_create_window_surface (platform_drm.c:145)
==24016== by 0x17388906: _eglCreateWindowSurfaceCommon (eglapi.c:929)
==24016== by 0x5440197: eglCreateWindowSurface (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
==24016== by 0x49612FF: meta_egl_create_window_surface (meta-egl.c:396)
==24016== by 0x49B752E: meta_renderer_native_create_surface_gbm (meta-renderer-native.c:2538)
==24016== by 0x49B7E6C: meta_onscreen_native_allocate (meta-renderer-native.c:2870)
==24016== by 0x49B8BCF: meta_renderer_native_create_view (meta-renderer-native.c:3387)
==24016== by 0x48D274B: meta_renderer_create_view (meta-renderer.c:78)
==24016== by 0x48D27DE: meta_renderer_rebuild_views (meta-renderer.c:111)
==24016== by 0x49BB4FB: meta_stage_native_rebuild_views (meta-stage-native.c:142)
==24016== by 0x49A733C: meta_backend_native_update_screen_size (meta-backend-native.c:517)
https://gitlab.gnome.org/GNOME/mutter/merge_requests/622
When making a new surface/context pair current, mesa may want to flush
the old context. Make sure we don't try to flush any freed memory by
unmaking a surface/context pair current before freeing it.
Not doing this results in the following valgrind warnings:
==15986== Invalid read of size 8
==15986== at 0x69A6D80: dri_flush_front_buffer (gbm_dri.c:92)
==15986== by 0x1750D458: intel_flush_front (brw_context.c:251)
==15986== by 0x1750D4BB: intel_glFlush (brw_context.c:296)
==15986== by 0x1739D8DD: dri2_make_current (egl_dri2.c:1461)
==15986== by 0x17393A3A: eglMakeCurrent (eglapi.c:869)
==15986== by 0x54381FB: InternalMakeCurrentVendor (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
==15986== by 0x5438515: eglMakeCurrent (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
==15986== by 0x522A782: _cogl_winsys_egl_make_current (cogl-winsys-egl.c:303)
==15986== by 0x49B64C8: meta_renderer_native_create_view (meta-renderer-native.c:3076)
==15986== by 0x48D26E7: meta_renderer_create_view (meta-renderer.c:78)
==15986== by 0x48D277A: meta_renderer_rebuild_views (meta-renderer.c:111)
==15986== by 0x49BF46E: meta_stage_native_rebuild_views (meta-stage-native.c:142)
==15986== Address 0x1b076600 is 0 bytes inside a block of size 48 free'd
==15986== at 0x4839A0C: free (vg_replace_malloc.c:540)
==15986== by 0x49B59F3: meta_renderer_native_release_onscreen (meta-renderer-native.c:2651)
==15986== by 0x5211441: _cogl_onscreen_free (cogl-onscreen.c:167)
==15986== by 0x5210D81: _cogl_object_onscreen_indirect_free (cogl-onscreen.c:51)
==15986== by 0x51D0066: _cogl_object_default_unref (cogl-object.c:103)
==15986== by 0x520F989: _cogl_framebuffer_unref (cogl-framebuffer.c:1814)
==15986== by 0x51D00B1: cogl_object_unref (cogl-object.c:115)
==15986== by 0x536F3C7: clutter_stage_view_dispose (clutter-stage-view.c:304)
==15986== by 0x4B7DAF2: g_object_unref (gobject.c:3309)
==15986== by 0x4A9596C: g_list_foreach (glist.c:1013)
==15986== by 0x4A9599A: g_list_free_full (glist.c:223)
==15986== by 0x48D2737: meta_renderer_rebuild_views (meta-renderer.c:100)
==15986== Block was alloc'd at
==15986== at 0x483AB1A: calloc (vg_replace_malloc.c:762)
==15986== by 0x69A76B2: gbm_dri_surface_create (gbm_dri.c:1252)
==15986== by 0x69A6BFE: gbm_surface_create (gbm.c:600)
==15986== by 0x49B4E29: meta_renderer_native_create_surface_gbm (meta-renderer-native.c:2221)
==15986== by 0x49B57DB: meta_onscreen_native_allocate (meta-renderer-native.c:2569)
==15986== by 0x49B6423: meta_renderer_native_create_view (meta-renderer-native.c:3062)
==15986== by 0x48D26E7: meta_renderer_create_view (meta-renderer.c:78)
==15986== by 0x48D277A: meta_renderer_rebuild_views (meta-renderer.c:111)
==15986== by 0x49BF46E: meta_stage_native_rebuild_views (meta-stage-native.c:142)
==15986== by 0x49A75B5: meta_backend_native_update_screen_size (meta-backend-native.c:520)
==15986== by 0x48B01BB: meta_backend_sync_screen_size (meta-backend.c:224)
==15986== by 0x48B09B7: meta_backend_real_post_init (meta-backend.c:501)
https://gitlab.gnome.org/GNOME/mutter/merge_requests/622
Currently the EGLDevice code gets the display and calls eglInitialize.
As a follow-up it checks the required EGL extensions - technically it
could check the EGL device extensions earlier.
In either case, eglTerminate is missing. Thus the connection to the
display was still bound.
This was highlighted with Mesa commit d6edccee8da ("egl: add
EGL_platform_device support") + amdgpu.
In that case, since the eglTerminate is missing, we end up reusing the
underlying amdgpu_device due to some caching in libdrm_amdgpu. The
latter in itself being a good solution since it allows buffer sharing
across primary and render node of the same device.
Note: we should really get this in branches all the way back to 3.30.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/619
Fixes: 934184e23 ("MetaRendererNative: Add EGLDevice based rendering support")
Cc: Jonas Ådahl <jadahl@gmail.com>
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Extract the next buffer -logic into a new function. This allows to
simplify copy_shared_framebuffer_cpu () making it more readable.
This change is a pure refactoring, no functional changes.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/593
There is no reason why we should have an internal type enum when we have
all the infrastructure to just use multiple GObject types. Also there
was no code sharing between the old "types", the only common API was
getting the framebuffer ID, so lets make that a vfunc.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/584
Since "renderer/native: make EGL initialization failure not fatal" it is
possible, under specific failure conditions, to end up with a primary GPU whose
EGL initialization failed. That cannot work.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/521
The failure to initialize EGL does not necessarily mean the KMS device cannot
be used. The device could still be used as a "secondary GPU" with the CPU copy
mode.
If meta_renderer_native_create_renderer_gpu_data () fails,
meta_renderer_native_get_gpu_data () will return NULL, which may cause crashes.
This patch removes most of the failures, but does not fix the NULL dereferences
that will still happen if creating gpu data fails.
This patch reorders create_renderer_gpu_data_gbm () so that it fails hard only
if GBM device cannot be created, and otherwise always returns an initialized
gpu data structure. Users of the gpu data structure are responsible for
checking egl_display validity.
The GBM device creation failure is a hard failure because presumably GBM is
necessary for cursors.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/542https://gitlab.gnome.org/GNOME/mutter/merge_requests/521
We're currently always waiting for unfinished page flips before flipping
again. This is awkward when we are in an asynchronous retry-page-flip
loop, as we can synchronously wait for any KMS page flip event.
To avoid ending up with such situations, just freeze the frame clock
while we're retrying, then thaw it when we succeded.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
We rely on the frame clock to compress input events, thus if the frame
clock stops, input events are not dispatched. At the same time, there
is no reason to redraw at a full frame rate, as nothing will be
presented anyway, so slow down to 10Hz (compared to the most common
60Hz). Note that we'll only actually reach 10Hz if there is an active
animation being displayed, which won't happen e.g. if there is a screen
shield in the way.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
When we're in a page-flip retry loop due to the FIFO being full
(drmModePageFlip() failing with EBUSY), we should not continue to try
when starting to power save, as that means we're blocking new frames,
which itself blocks input events due to them being compressed using the
frame clock.
We'd also hit an assert assuming we only try to page flip when not power
saving.
Thus, fake we flipped if we ended up reaching a power saving state while
retrying.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/509https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
It tried to add a (implicitly casted) float to a uint64_t, and due to
floating point precision issues resulted in timestamps intended to be
in the future to actually be in the past. Fix this by first casting the
delay to an uint64_t, then add it to the time stamp.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
DPMS is configured from a bit all over the place: via D-Bus, via X11 and
when reading the current KMS state. Each of these places did it slightly
differently, directly poking at the field in MetaMonitorManager.
To make things a bit more managable, move the field into a new
MetaMonitorManagerPrivate, and add helpers to get and set the current
value. Prior to this, there were for example situations where the DPMS
setting was changed, but without signal listeners being notified about
it.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/506
The 'underscan' property is a drm connector property, not a CRTC
property, so we would never find it. We also didn't advertise support
for the feature, meaning even if it was on the CRTC, Settings wouldn't
know about it.
Fix this by moving the property to where it belongs: in MetaOutputKms,
and properly advertise support for it if the property is found.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/507
A clutter actor might be painted on a stage view with a view scale
other than 1. In this case, to show the content in full resolution, the
actor must use a higher resolution resource (e.g. texture), which will
be down scaled to the stage coordinate space, then scaled up again to
the stage view framebuffer scale.
Use a 'resource-scale' property to save information and notify when it
changes.
The resource scale is the ceiled value of the highest stage view scale a
actor is visible on. The value is ceiled because using a higher
resolution resource consistently results in better output quality. One
reason for this is that rendering is often not perfectly pixel aligned,
meaning even if we load a resource with a suitable size, due to us still
scaling ever so slightly, the quality is affected. Using a higher
resolution resource avoids this problem.
For situations inside clutter where the actual maximum view scale is
needed, a function _clutter_actor_get_real_resource_scale() is provided,
which returns the non-ceiled value.
Make sure we ignore resource scale computation requests during size
requests or allocation while ensure we've proper resource-scale on
pre-paint.
https://bugzilla.gnome.org/show_bug.cgi?id=765011https://gitlab.gnome.org/GNOME/mutter/merge_requests/3
We might fail to page flip a new buffer, often after resuming, due to
the FIFO being full. Prior to this commit, we handled this by switching
over to plain mode setting instead of page flipping. This is bad because
we won't be synchronized to the refresh rate anymore, but just the
clock.
Instead, deal with this by trying again until the FIFO is no longer
full. Do this on a v-sync based interval, until it works.
This also changes the error handling code for drivers not supporting
page flipping to rely on them returning -EINVAL. The handling is moved
from pretending a page flip working to explicit mode setting in
meta-renderer-native.c.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/460
A renderer view will, under the native backend, since long ago always
have a logical monitor associated with it, so remove the code handling
the legacy non-stage view case.
https://gitlab.gnome.org/GNOME/mutter/issues/460
When we freed the cursor GPU state including the gbm_bo objects attached
to it, we didn't unset the cursor renderer private of the CRTCs of the
associated GPU. This means that HW cursor invalidation could potentially
break if a new gbm_bo happened to be allocated at the same memory
address as the previous one.
To avoid this, iterate through the CRTCs of the GPU of which the cursor
data is freed, and unset the cursor renderer private if it was the one
destroyed.
https://gitlab.gnome.org/GNOME/mutter/issues/199
This means we need to make sure we don't accidentally free the provided
source GError (which automatically happens with `g_autoptr`), so use
`g_steal_pointer()`.
This fixes an issue where, when launched in a bubblewrap environment
(such as the one provided by Buildstream), mutter would give the
following warning message:
```
mutter-WARNING **: 8:31:35:069: Can't initialize KMS backend: (null)
```
... which isn't that useful when trying to debug the actual issue.
If the extension is missing, the GPU copy path would not work. The code sets
the error, but forgets to return a failure. Fix this.
While adding the necessary return FALSE, also destroy the EGL context we just
created. Code refactoring shares the destroying code.
Found by reading code.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/416
If the GPU copy path would use a software renderer, fall back to the CPU
copy path. The CPU copy path is possibly faster and avoids screen
corruption issues that were observed on an Intel Haswell desktop. The
corruption was likely due to texturing from an unfinished rendering or
memory caching issues.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/325
Print the pixel format chosen for an output on a secondary GPU for
debugging. Knowing the format can aid in debugging e.g. red/blue channel
swaps and CPU copy performance issues.
This adds a DRM format printing helper in meta-crtc-kms.h. This header
is included in most native backend files making it widely available,
while DRM formats are specific to the native backend. It could be shared
with Wayland bits, DRM format codes are used there too.
The helper makes the pixel format much more readable than a "%x".
https://gitlab.gnome.org/GNOME/mutter/merge_requests/341
When setting up an output on a secondary GPU with the CPU copy mode,
allocate the dumb buffers with a DRM format that is advertised supported
instead of hardcoding a format.
Particularly, DisplayLink devices do not quite yet support the hardcoded
DRM_FORMAT_XBGR8888. The proprietary driver stack actually ignores the
format assuming it is DRM_FORMAT_XRGB8888 which results the display
having red and blue channels swapped. This patch fixes the color swap
right now, while taking advantage if the driver adds support for XBGR
later.
The preferred_formats ordering is somewhat arbitrary. Here it is written
from glReadPixels point of view, based on my benchmarks on Intel Haswell
Desktop machine. This ordering prefers the format that was hardcoded
before.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/341
These functions allow inspecting which pixel formats a CRTC's primary
plane supports. Future patches will inspect the supported formats and
pick a framebuffer format accordingly instead of hardcoding a format.
The copy list function will be used to initialize a formats list, and
the supports format function will be used to intersect that list against
another CRTC's supported formats.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/341
This avoids having to hardcode the same fallbacks elsewhere multiple
times when determining what formats might be suitable for a set of
CRTCs. The formats_modifiers hash table is now guaranteed to be
populated with at least something, so future code will not need to
handle it being empty.
The hardcoded fallback formats are a minimal set probably supported by
most hardware. XRGB8888 is the format that, according to ancient lore,
all DRM devices should support, especially if they don't have the
capability to advertise otherwise. Mutter also hardcodes XRGB8888 as the
GBM surface format, so it is already required on primary GPUs.
XBGR8888 matches the most common OpenGL format, sans alpha channel since
scanout hardware has not traditionally supported alpha. XBGR8888 is here
also because Mutter hardcodes that format for secondary GPU outputs when
using the CPU copy path.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/341
If the IN_FORMATS property is not found, copy the formats from the DRM
plane instead. This is the fallback for getting a list of formats the
primary plane supports when DRM universal planes capability is enabled.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/341
Rather than picking just one format, parse and store all the formats and
their modifiers.
This gives us a list of supported formats (and modifiers) on a CRTC
primary plane. Later I will be using this list to choose a framebuffer
format instead of hardcoding it.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/341
Commit 25f416c13d added additional compilation warnings, including
-Werror=return-type. There are several places where this results
in build failures if `g_assert_not_reached()` is disabled at compile
time and the compiler misses a return value.
https://gitlab.gnome.org/GNOME/mutter/issues/447
As with the commits earlier, this also adds const qualifiers where
expected. However, the const variables are casted to non-const variants
so they can be passed to glib functions that take non-const variants but
expect const-like input.
There may be reasons to temporarly inhibit the HW cursor under certain
circumstances. Allow adding such inhibitations by adding API to the
cursor renderer to allow API users to add generic inhibitors with
whatever logic is deemed necessary.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/357
Mutter prefers platform devices over anything else as the primary GPU.
This will not work too well, when a platform device does not actually
have a rendering GPU but is a display-only device. An example of this
are DisplayLink devices with the proprietary driver stack, which exposes
a DRM KMS platform device but without any rendering driver.
Mutter cannot rely on EGL init failing on such devices either, because
nowadays Mesa supports software renderers on GBM, so the initialization
may well succeed.
The hardware rendering capability is recognized by matching the GL
renderer string to the known Mesa software renderers. At this time,
there is no better alternative to detecting this.
The secondary GPU data is abused for the GL renderer, as the Cogl
context may not have been created yet. Also, the Cogl context would
only be created on the primary GPU, but at this point the primary GPU
has not been chosen yet. Hence, GPU copy path GL context is used as a
proxy and predictor of what the Cogl context might be if it was created.
Mind, that even the GL flavour are not the same between Cogl and
secondary contexts, so this is stretch but it should be just enough.
The logic to choose the primary GPU is changed to always prefer hardware
rendering devices while also maintaining the old order of preferring
platform over boot_vga devices.
Co-authored by: Emilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk>
https://gitlab.gnome.org/GNOME/mutter/merge_requests/271
Moves the primary GPU choosing to after all secondary gpu data has been
created.
This makes it possible for a future patch to start looking at secondary
gpu data in choose_primary_gpu () to determine if it is using a hardware
driver or a software renderer.
Co-authored by: Pekka Paalanen <pekka.paalanen@collabora.com>
https://gitlab.gnome.org/GNOME/mutter/merge_requests/271
Initialize the secondary GPU data for all GPUs, even the primary one. By
not looking at the primary_gpu_kms member, a future patch is allowed to
postpone choosing the primary GPU.
A future patch will use the secondary GPU data to decide which GPU will
become the primary GPU.
Co-authored by: Pekka Paalanen <pekka.paalanen@collabora.com>
https://gitlab.gnome.org/GNOME/mutter/merge_requests/271
create_renderer_gpu_data_egl_device () relied on the primary GPU being
already chosen for the "EGLDevice currently only works with single GPU
systems" error message. A future patch will choose the primary GPU after
this, not before, so this check needs to be rewritten before the
initialization order is changed.
The new check is implemented exactly as the error message says: there
must be exactly one GPU, otherwise fail.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/271
Make the choosing and identity of the primary GPU an internal detail to
the native renderer. MonitorManagerKms did not need it for anything.
The primary GPU logic remains unchanged.
This allows follow-up patches to change how the renderer chooses the
primary GPU. It will be easier for the renderer to use private
information for choosing.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/271
This is a step towards moving the primary GPU logic into the native
renderer exclusively. In the future the renderer will have one more
criterion on choosing the primary GPU than MetaMonitorManagerKms should
know about: does a GPU offer hardware rendering.
The choosing of primary GPU is separated from the discovery of GPUs.
When GPUs are discovered and added to the list, the MetaGpuKmsFlag is
now populated correctly and used in choosing.
Choosing the primary GPU is done after all GPUs have been found and is
slightly different from before:
- Skipping devices that do not belong to our seat now works instead of
becoming the primary GPU.
- Fall back to any non-platform, non-boot_vga device if neither kind is
found.
The old preference of platform over boot_vga device is kept.
The hotplug path will continue creating a gpu_kms without flags, because
at that point the primary GPU has already been chosen and the flags are
irrelevant.
Co-authored by: Pekka Paalanen <pekka.paalanen@collabora.com>
https://gitlab.gnome.org/GNOME/mutter/merge_requests/271
Add a flags field to MetaGpuKms. In following commits, the flags defined
here will be set and used for choosing the primary GPU.
Co-authored by: Emilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk>
https://gitlab.gnome.org/GNOME/mutter/merge_requests/271
If a KMS device has the DRM_CAP_DUMB_PREFER_SHADOW and a software based
GL driver is used, always use a shadow fb. This will speed up read backs
in the llvmpipe OpenGL implementation, making blend operations faster.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/106
DRM_EVENT_CONTEXT_VERSION is the latest context version supported by
whatever version of libdrm is present. Mutter was blindly asserting it
supported whatever version that may be, even if it actually didn't.
With libdrm 2.4.78, setting a higher context version than 2 will attempt
to call the page_flip_handler2 vfunc if it was non-NULL, which being a
random chunk of stack memory, it might well have been.
Set the version as 2, which should be bumped only with the appropriate
version checks.
https://bugzilla.gnome.org/show_bug.cgi?id=781034
Which eliminates the 1px jitter that was visible when dragging windows,
and eliminates the flickering that was visible when pushing the cursor
against the right/bottom edges of the screen.
Since now we don't set the swap throttled value based
on sync-to-vblank, we can effectively remove it from
Cogl. Throttling swap buffers in Cogl is as much a
historical artifact as sync-to-vblank. Furthermore,
it doesn't make sense to disable it on a compositor,
which is the case with the embedded Cogl.
In addition to that, the winsys vfunc for updating
whenever swap throttling changes could also be removed,
since swap throttling is always enabled now.
Removing it means less code, less branches when running,
and one less config option to deal with.
This also removes the micro-perf test, since it doesn't
make sense for the case where Cogl is embedded into the
compositor.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/191
Externally setting the sync-to-vblank setting was a feature
added as a workaround to old Intel and ATI graphic cards, and
is not needed anymore. Furthermore, it doesn't make sense to
change it on a compositor whatsoever.
This commit removes all the ways to externally change this
setting, as well as the now unused API.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/191
We haven't supported disabling stage views in the native backend since
commit 70edc7dda4
Author: Jonas Ådahl <jadahl@gmail.com>
Date: Mon Jul 24 12:31:32 2017 +0800
backends/native: Stop supporting stage views being disabled
There were still some left over checks; lets remove them.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/343
Because it is implemented and always on. By advertising this fact
the master clock is able to sync to the native refresh rate instead
of always using the fallback of 60.00Hz.
https://bugzilla.gnome.org/show_bug.cgi?id=781296
Add support for getting hardware presentation times from KMS (Wayland
sessions). Also implement cogl_get_clock_time which is required to compare
and judge the age of presentation timestamps.
For single monitor systems this is straightforward. For multi-monitor
systems though we have to choose a display to sync to. The compositor
already partially solves this for us in the case of only one display
updating because it will only use the subset of monitors that are
changing. In the case of multiple monitors consuming the same frame
concurrently however, we choose the fastest one (in use at the time).
Note however that we also need !73 to land in order to fully realize
multiple monitors running at full speed.
Use cogl_framebuffer_read_pixels_into_bitmap () instead of
glReadPixels () for the CPU copy path in multi-GPU support.
The cogl function employs several tricks to make the read-pixels as fast
as possible and does the y-flip as necessary. This should make the copy
more performant over all kinds of hardware.
This is expected to be used on virtual outputs (e.g. DisplayLink USB
docks and monitors) foremost, where the dumb buffer memory is just
regular system memory. If the dumb buffer memory is somehow slow, like
residing in discrete VRAM or having an unexpected caching mode, it may
be possible for the cogl function perform worse because it might do the
y-flip in-place in the dumb buffer. Hopefully that does not happen in
any practical scenario.
Calling meta_renderer_native_gles3_read_pixels () here was conceptually
wrong to begin with because it was done with the Cogl GL context of the
primary GPU, not on the GL ES 3 context of a secondary GPU. However,
due eglBindAPI being a no-op in Mesa and the glReadPixels () arguments
being compatible, it worked.
This patch adds a pixel format conversion table between DRM and Cogl
formats. It contains more formats than absolutely necessary and the
texture components field which is currently unused for completeness. See
Mutter issue #323. Making the table more complete documents better how
the pixel formats actually map so that posterity should be less likely
to be confused. This table could be shared with
shm_buffer_get_cogl_pixel_format () as well, but not with
meta_wayland_dma_buf_buffer_attach ().
On HP ProBook 4520s laptop (Mesa DRI Intel(R) Ironlake Mobile, Mesa
18.0.5), without this patch copy_shared_framebuffer_cpu () for a
DisplayLink output takes 5 seconds with a 1080p frame. Obviously that
makes Mutter and gnome-shell completely unusable. With this patch, that
function takes 13-18 ms which makes it usable if not fluent.
On Intel i7-4790 (Mesa DRI Intel(R) Haswell Desktop) machine, this patch
makes no significant difference (the copy takes 4-5 ms).
The format will be needed in a following commit in the CPU copy path
which stops hardcoding another format and starts using the format the
dumb FB was created with.
Change the callers of init_dumb_fb () to use DRM format codes. DRM and
GBM format codes are identical, but since this is about dumb buffers,
DRM formats fit better.
The header /usr/include/gbm.h installed by Mesa says:
* The FourCC format codes are taken from the drm_fourcc.h definition, and
* re-namespaced. New GBM formats must not be added, unless they are
* identical ports from drm_fourcc.
That refers to the GBM_FORMAT_* codes.
We were using the connector_id for the winsys_id, but different
devices could have connectors with the same id. Since we use
winsys_id to uniquely identify outputs, use both the connector
id and the device id to avoid having outputs with the same id.
Python is not guaranteed to be installed in /usr/bin. This is especially
true for *BSD systems which don't consider Python as an integral part of
their systems.
The order and way include macros were structured was chaotic, with no
real common thread between files. Try to tidy up the mess with some
common scheme, to make things look less messy.
drmModePageFlip() is guaranteed to fail for the invalid FB id 0.
Therefore it never makes sense to call this function with such argument.
Disabling a CRTC must be done with SetCrtc instead, for example.
Trying to flip to FB 0 not only fails, but it also causes Mutter to
never try page flip on this output again, using drmModeSetCrtc()
instead.
There was a race in setting next_fb_id when a secondary GPU was using
the CPU copy path. Losing this race caused the attempt to
drmModePageFlip () to FB ID 0 which is invalid and always fails. Failing
to flip causes Mutter to fall back to drmModeSetCrtc () permanently.
In meta_onscreen_native_swap_buffers_with_damage ():
- update_secondary_gpu_state_pre_swap_buffers ()
- copy_shared_framebuffer_cpu () but only on the CPU copy path
- secondary_gpu_state->gbm.next_fb_id is set
- wait_for_pending_flips ()
- Waits for any remaining page flip events and executes and destroys
the related page flip closures.
- on_crtc_flipped ()
- meta_onscreen_native_swap_drm_fb ()
- swap_secondary_drm_fb ()
- secondary_gpu_state->gbm.next_fb_id = 0;
- meta_onscreen_native_flip_crtcs ()
- meta_onscreen_native_flip_crtc ()
- meta_gpu_kms_flip_crtc () gets called with fb_id = 0
This race was observed lost when running 'mutter --wayland' on a machine
with two outputs on Intel and one output on DisplayLink USB dock, and
wiggling around a weston-terminal window between the Intel and
DisplayLink outputs. It took from a second to a minute to trigger. For
testing with DisplayLink outputs Mutter also needed a patch to take the
DisplayLink output into use, as it would have otherwise been ignored
being a platform device rather than a PCI device.
Fix this race by first waiting for pending flips and only then
proceeding with the swap operations. This should be safe, because the
pending flips could have completed already before entering
meta_onscreen_native_swap_buffers_with_damage ().
meta_renderer_native_gles3_read_pixels() was assuming that the target
buffer stride == width * 4. This is not generally true. When a DRM
driver allocates a dumb buffer, it is free to choose a stride so that
the buffer can actually work on the hardware.
Record the driver chosen stride in MetaDumbBuffer, and use it in the CPU
copy path. This should fix any possible stride issues in
meta_renderer_native_gles3_read_pixels().
Track the allocated dumb buffer size in MetaDumbBuffer. Assert that the
size is as expected in copy_shared_framebuffer_cpu().
This is just to ensure that Cogl and the real size match. The size from
Cogl was used in the copy, so getting that wrong might have written
beyond the allocation.
This is a safety measure and has not been observed to happen yet.
If drmModeAddFB2() does not work, the fallback to drmModeAddFB() can
only handle a single specific format. Make sure the requested format is
that one format, and fail the operation otherwise.
This should at least makes the failure mode obvious on such old systems
where the kernel does not support AddFB2, rather than producing wrong
colors.
Previously, trackballs were detected based on the presence of the
substring "trackball" in the device name. This had the downside of
missing devices, such as the Kensington Expert Mouse, which don't have
"trackball" in their names.
Rather than depending on the device name, use the ID_INPUT_TRACKBALL
property from udev to determine whether or not to treat a device as a
trackball.
This adds a new function, `is_trackball_device`, to MetaInputEvents, and
eliminates the `meta_input_device_is_trackball` function.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/258
The "backends: Move MetaOutput::crtc field into private struct"
accidentally changed the view transform calculation code to assume that
"MetaCrtc::transform" corresponds to the transform of the CRTC; so is
not the case yet; one must calculate the transform from the logical
monitor, and check whether it is supported by the CRTC using
meta_monitor_manager_is_transform_handled(). This commit restores the
old behaviour that doesn't use MetaCrtc::transform when calculating the
view transform.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/216
We need a way for mutter to exit if no available GPUs are going to work.
For example if gdm starts gnome-shell and we're using a DRM driver that
doesn't work with KMS then we should exit so that GDM can try with Xorg,
rather than operating in headless mode.
Related: https://gitlab.gnome.org/GNOME/mutter/issues/223
Commit c0d9b08ef9 replaced the old GBM API calls
with the multi-plane GBM API. However, the call to gbm_bo_get_handle_for_plane
fails for some DRI drivers (in particular i915). Due to missing error checks,
the subsequent call to drmModeAddFB[2] fails and the screen output locks up.
This commit adds the missing error checks and falls back to the old GBM API
(non-planar) if necessary.
v5: test success of gbm_bo_get_handle_for_plane instead of errno
This commit adopts solution proposed by Daniel van Vugt to check the return
value of gbm_bo_get_handle_for_plane on plane 0 and fall back to old
non-planar method if the call fails. This removes the errno check (for
ENOSYS) that could abort if mesa ever sets a different value.
Related to: https://gitlab.gnome.org/GNOME/mutter/issues/127
The function is intentionally provided as macro to not require a
cast. Recently the macro was improved to check that the passed in
pointer matches the free function, so the cast to GDestroyNotify
is now even harmful.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/176
If drmModeSetCrtc() is called with no fb, mode or connectors for some
CRTC it may still fail, and we should handle that gracefully instead of
assuming it failed to set a non-disabled state.
Closes https://gitlab.gnome.org/GNOME/mutter/issues/70
Commit 712ec30cd9 added the logic to only
choose EGL configs that match the GBM_FORMAT_XRGB8888 pixel format.
However, there won't be any EGL config satisfying such criteria for
non-GBM backends, such as EGLDevice.
This change will let us choose the first EGL config for the EGLDevice
backend, while still forcing GBM_FORMAT_XRGB8888 configs for the GBM
one.
Related to: https://gitlab.gnome.org/GNOME/mutter/issues/2
Where to realize a hardware cursor depends on where on the screen it
will be displayed. For example it only needs buffers for the cursor
plane on a certain GPU if it overlaps with a monitor that is connected
said GPU.
Previously, we were too eager with uploading the cursor plane buffers,
which in effect resulted in the secondary GPU always being woken up
when changing the cursor, even though the cursor plane would actually
never be set unless the pointer cursor was moved to a monitor connected
to the secondary GPU. These wake-ups caused noticable stuttering; thus
by uploading the buffers more lazilly, the stuttering is avoided.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/77
When a cursor is hidden, the native backend will properly hide the HW
cursor sprite as well, but it would communicate this as if the cursor
was not handled by the backend, while in fact it still was. This caused
the generic cursor rendering layer to queue a redraw.
https://gitlab.gnome.org/GNOME/mutter/issues/77
When force-updating the HW state we might end up with a situation where
the HW cursor is no longer usable. If this would happen, we'd before
this commit not trigger the fallback paths using a GL texture.
https://gitlab.gnome.org/GNOME/mutter/issues/77
It is already handled by the monitor-updated-internal signal handler in
meta-cursor-renderer-native.c, which will always be called indirectly
by resuming the monitor manager.
While at it, remove a useless comment.
https://gitlab.gnome.org/GNOME/mutter/issues/77
It knows better when it's needed. For now, just do it just as before,
before drawing. Eventually, we can conditionalize where to realize
depending on the cursor sprite position.
https://gitlab.gnome.org/GNOME/mutter/issues/77
Use a common entry point into the cursor renderer implementations HW
cursor realization paths for all cursor sprite types. This is in
preparation for realizing at more strategic times.
https://gitlab.gnome.org/GNOME/mutter/issues/77
The end goal here is to being able to realize at any point in time
through a single API, so start by moving state into the cursor sprite
implementation.
https://gitlab.gnome.org/GNOME/mutter/issues/77
drmModeAddFB2 allows userspace to specify a real format enum on
non-ancient kernels, as an improvement over the legacy drmModeAddFB
which derives format from a fixed depth/bpp mapping.
As an optimisation, Weston used to decide at the first failure of
drmModeAddFB2 that the ioctl was unavailable: as non-existent DRM
ioctls return -EINVAL rather than -ENOSYS or similar, bad parameters are
not distinguishable from the ioctl not being present.
Mutter has also implemented the same optimisation for dumb framebuffers,
which potentially papers over errors for the gain of avoiding one ioctl
which will rapidly fail on ancient kernels. Remove the optimisation and
always use AddFB2 where possible.
Closes: #14
When using the EGLStream backend, the MetaRendererNative passed a
GClosure to KMS when using EGLStreams, but KMS flip callback event
handler in meta-gpu-kms.c expected a closure wrapped in a closure
container, meaning it'd instead crash when using EGLStreams. Make the
flip handler get what it expects also when using EGLStreams by wrapping
the flip closure in the container before handing it over to EGL.
https://bugzilla.gnome.org/show_bug.cgi?id=790316
While MetaStage, MetaWindowGroup and MetaDBusDisplayConfigSkeleton don't
appear explicitly in the public API, their gtypes are still exposed via
meta_get_stage_for_screen(), meta_get_*window_group_for_screen() and
MetaMonitorManager's parent type. Newer versions of gjs will warn about
undefined properties if it encounters a gtype without introspection
information, so expose those types to shut up the warnings.
https://bugzilla.gnome.org/show_bug.cgi?id=781471
Before we just set it to "none", but this was not enough since various
calls will depend on not just the context being active, but the main
rendering surface.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/21
This is a small mistake spotted while working on a solution
for #77. When a GPU fails to initialize, we're adding them
anyway, which might have pretty bad consequences when trying
to use these NULL GPUs.
Issue: #77
Make it re-enable:able by a hidden "experimental feature". To enable, add
"kms-modifiers" to the org.gnome.mutter.experimental-features GSettings entry.
And use the old "native" backend for both X11 and Wayland. This will
allow us to share fixes between implementations without having to delve
into the XSync X11 extension code.
https://bugzilla.gnome.org/show_bug.cgi?id=705942
If we attempt GBM surface allocation with a set of modifiers but the
allocation fails, fall back to non-modifier allocations. This fixes
startup on Pineview-based Atom systems, where KMS provides us a set of
modifiers but the GBM implementation doesn't support modifier use.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/84
Rotating an output would show duplicate cursors when the pointer is
located over an area which would be within the output if not rotated.
Make sure to swap the width/height of the output when rotated.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/85
Rendering the next frame (which mostly happens as part of the flush done
in swap buffers) is a task that the GPU can complete independently of
the CPU having to wait for previous page flips. So reverse their order
to get the GPU started earlier, with the aim of greater GPU-CPU
parallelism.
We just arbitrarily chose the first EGL config matching the passed
attributes, but we then assumed we always got GBM_FORMAT_XRGB8888. That
was not a correct assumption. Instead, make sure we always pick the
format we expect.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/2
When the buffer modifier is DRM_FORMAT_MOD_LINEAR, we can use the
old code path. That means not specifying any modifier parameter.
It was an issue when the primary GPU was creating a linear GBM surface
and that a secondary GPU (not supporting modifiers) was trying to
import it. It was failing because the driver could not use the
import_modifiers extension even though it could in theory easily
import the buffer.
https://gitlab.gnome.org/GNOME/mutter/issues/18
We were retrieving the supported KMS modifiers for all GPUs even
though what we really need to intersect between these sets of
modifiers:
1) KMS supported modifiers for primary GPU if the GPU is used for
scanout;
2) EGL supported modifiers for secondary GPUs (different than the
primary GPU used for rendering);
3) GBM supported modifiers when creating the surface (already
taken care of by gbm_surface_create_with_modifiers());
https://gitlab.gnome.org/GNOME/mutter/issues/18
There seems to be a kernel race when one disconnects an external
monitor connected to a DisplayPort via a USB-C adapter. The race
results in a connector being reported as connected, but without any
modes supported.
This had the side effect that we tried to set a preferred mode to
the first listed mode, but as no modes were available, we instead tried
to dereference the first element of a NULL array, causing a
segmentation fault.
Mitigate this by skipping adding output if no supported modes are
advertised and the output doesn't support scaling, while moving the
fallback path for calculating a preferred output mode to after possibly
adding the common modes, to avoid the unvolentary NULL dereference.
https://bugzilla.gnome.org/show_bug.cgi?id=789501
The tertiary-button-action (see bug 790028) is a place for g-c-c to store
the action which should be performed when a stylus' third button is pressed.
Pressing this button is signaled as a BTN_STYLUS3 event from the kernel or
X11 button 8.
https://bugzilla.gnome.org/show_bug.cgi?id=790033
Now that we have the list of supported modifiers from the monitor
manager (via the CRTCs to the primary planes), we can use this to inform
EGL it can use those modifiers to allocate the GBM surface with. Doing
so allows us to use tiling and compression for our scanout surfaces.
This requires the Mesa commit in:
Mesa 10.3 (08264e5dad4df448e7718e782ad9077902089a07) or
Mesa 10.2.7 (55d28925e6109a4afd61f109e845a8a51bd17652).
Otherwise Mesa closes the fd behind our back and re-importing will fail.
See FDO bug #76188 for details.
https://bugzilla.gnome.org/show_bug.cgi?id=785779
Newer versions of GBM support buffer modifiers, including multi-plane
buffers. Use this new API to explicitly pull the information from GBM,
and feed it to drmModeAddFB2WithModifiers.
https://bugzilla.gnome.org/show_bug.cgi?id=785779
The KMS IN_FORMATS blob property contains a structure defining which
format/modifier combinations are supported for each plane. Use this to
extract a list of acceptable modifiers to use for the primary plane for
XRGB8888, so we can ask EGL to allocate tiled/compressed buffers for
scanout when available.
https://bugzilla.gnome.org/show_bug.cgi?id=785779
Just like we swap the x and y resolution of the monitor modes when
the panel-orientation requires 90 or 270 degree rotation to compensate,
we should do the same for the width and height in mm of the monitor.
https://bugzilla.gnome.org/show_bug.cgi?id=782294
If a monitor's max resolution is a portrait resolution, then assume it is
a native portrait monitor and add portrait versions of the common modes.
https://bugzilla.gnome.org/show_bug.cgi?id=782294
Even if the logical_monitor config does not have an active transform,
we might still be doing a transform under the hood to compensate for
panel-orientation. Check for this and fall back to the sw cursor if this
is the case.
https://bugzilla.gnome.org/show_bug.cgi?id=782294
Some x86 clamshell design devices use portrait tablet LCD panels while
they should use a landscape panel, resoluting in a 90 degree rotated
picture.
Newer kernels detect this and rotate the fb console in software to
compensate. These kernels also export their knowledge of the LCD panel
orientation vs the casing in a "panel orientation" drm_connector property.
This commit adds support to mutter for reading the "panel orientation"
and transparently (from a mutter consumer's pov) fixing this by applying
a (hidden) rotation transform to compensate for the panel orientation.
Related: https://bugs.freedesktop.org/show_bug.cgi?id=94894https://bugzilla.gnome.org/show_bug.cgi?id=782294
Proprietary drivers such as ARM Mali export EGL_KHR_platform_gbm instead
of EGL_MESA_platform_gbm. As such, GBM platform check should be done for
both MESA and non-MESA drivers.
https://bugzilla.gnome.org/show_bug.cgi?id=780668
The DRM properties container must be destroyed with
drmModeFreeObjectProperties, and the connectors must be freed on every
caller. Also make it sure that gbm_device structs are destroyed with the
MetaRendererNativeGpuData that owns them.
https://bugzilla.gnome.org/show_bug.cgi?id=789984
On some architectures, including both GLES3/gl3.h GL/gl.h will cause
compilation issues due to incompatible type definitions. To avoid
running into that issue while building on other architectures, make
sure we haven't included GL/gl.h by accident.
https://bugzilla.gnome.org/show_bug.cgi?id=788695
The org.gnome.desktop.peripherals.trackball.scroll-wheel-emulation-button
setting contains buttons X11-style. Work out the BTN evcode that applies
to it when applying the setting on the libinput device.
https://bugzilla.gnome.org/show_bug.cgi?id=787804
Adding an internal signal and use it to update the internal state before
emitting "monitors-changed" which will be repeated by the screen to the world.
https://bugzilla.gnome.org/show_bug.cgi?id=788860
On hybrid GPU systems, hardware cursors needs to be realized on all the
GPUs, as scanout cursor planes cannot be shared. Do this by moving gbm
buffer and drm buffer ID management to a per GPU struct, realizing a
cursor on each GPU when previously only realized on the primary GPU.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
A hybrid GPU system is a system where more than one GPU is connected to
connectors. A common configuration is having a integrated GPU (iGPU)
connected to a laptop panel, and a dedicated GPU (dGPU) connected to
one or more external connector (such as HDMI).
This commit adds support for rendering the compositor stage using the
iGPU, then copying the framebuffer content onto a secondary framebuffer
that will be page flipped on the CRTC of the dGPU.
This can work in two different ways: GPU accelerated using Open GL ES
3, or CPU unaccelerated.
When supported, GPU accelerated copying works by exporting the iGPU
onscreen framebuffer as a DMA-BUF, importing it as a texture on a
separate dGPU EGL context, then using glBlitFramebuffer(), blitting it
onto a framebuffer on the dGPU that can then be page flipped on the dGPU
CRTC.
When GPU acceleration is not available, copying works by creating two
dumb buffers, and each frame glReadPixels() from the iGPU EGL render
context directly into the dumb buffer. The dumb buffer is then page
flipped on the dGPU CRTC.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
First find the primary GPU and open it. Then go through all other
discovered GPUs with connectors and add those too. MetaRendererNative
still fails to initialize when multiple added GPUs and
MetaCursorRendererNative still always falls back on OpenGL based cursor
rendering when there are multiple GPUs.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
When creating a renderer with a custom winsys (which is always how
mutter uses cogl) make it possible to pass a user data with the winsys.
Still unused.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Make dumb buffer creation/destruction reusable by introducing a
MetaDumbBuffer type (private to meta-renderer-native.c). This will
later be used for software based fallback paths for copying render GPU
buffers onto secondary GPUs.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
On a CRTC that doesn't report any transforms at all, setting the normal
transform will fail. Avoid failing by checking if any transforms are
supported before applying it, and early out if no transforms are
supported.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Get rid of some technical dept by removing the support in the native
backend for drawing the the whole stage to one large framebuffer.
Previously the only way to disable stage views was to set the
MUTTER_STAGE_VIEWS environment variable to 0; doing that now will cause
the native backend to fail to initialize.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Don't permanently fall back to OpenGL based cursor rendering when
setting the HW cursor fails with EACCES as that may happen on VT
switching and other things temporarily revoking fd access.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
When drmHandleEvent() returns an error and errno is set to EAGAIN,
instead of ending up in a busy loop, poll() the fd until there is
anything to read.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
The prefix, if any, of a variable name often contains information about
the namespace (such as clutter_backend is the ClutterBackend, while
backend is a MetaBackend). Clean up some more inconsistencies in
meta-renderer-native.c where various variable names were egl_ prefixed
but in fact was Cogl types.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
In order to eventually support multilpe GPUs with their own connectors,
split out related meta data management (i.e. outputs, CRTCs and CRTC
modes) into a new MetaGpu GObject.
The Xrandr backend always assumes there is always only a single "GPU" as
the GPU is abstracted by the X server; only the native backend (aside
from the test backend) will eventually see more than one GPU.
The Xrandr backend still moves some management to MetaGpuXrandr, in
order to behave more similarly to the KMS counterparts.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Pass the backend to a new factory function, and keep a pointer to the
monitor manager, which is accessed elsewhere in the same file instead of
fetching the singleton. The HW cursor initialization part is also made
more obvious, without depending on seemingly irrelevant clutter
features.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Move finding, opening and managment of the KMS file descriptor to
MetaMonitorManagerKms. This means that the monitor manager creation can
now fail, both if more than one GPU with connectors is discovered, or
if finding or opening the primary GPU fails.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
The monitor manager instance was created and setup in one step; at
construction. This is problematic if, in the future, the monitor manager
creation can fail, as the monitor manager is created quite late.
To make it possible to in the future fail creating a monitor manager,
create the instance very early when initiating the backend, then on
post init backend setup, "setup" the monitor manager state, i.e. read
the current state and setup the stage.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
The error was printed, then dropped, eventually resulting in another
generic error being printed. Lets just propogate the error all the way
up instead.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Move code dealing with MetaCrtcKms and related functionality to its
own file. Eventually, MetaCrtcKms should become a GObject based on
MetaCrtc, and this commit is in preparation for that.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Instead of passing it around or fetching the singleton, keep a pointer
to the monitor manager that owns the CRTC. This will eventually be
replaced with a per GPU/graphics card object.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Move code dealing with MetaOutputKms and related functionality to its
own file. Eventually, MetaOutputKms should become a GObject based on
MetaOutput, and this commit is in preparation for that.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Instead of passing it around or fetching the singleton, keep a pointer
to the monitor manager that owns the output. This will eventually be
replaced with a per GPU/graphics card object.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Convert MetaCrtcMode from a plain struct to a GObject. This changes the
storage format, and also the API, as the API was dependent on the
storage format.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
Turn MetaCrtc into a GObject and move it to a separate file. This
changes the storage format, resulting in changing the API for accessing
MetaCrtcs from using an array, to using a GList.
https://bugzilla.gnome.org/show_bug.cgi?id=785381