mirror of
https://github.com/brl/mutter.git
synced 2024-11-12 17:27:03 -05:00
kms: Add atomic MetaKmsImplDevice backend
This adds a MetaKmsImplDevice backend using atomic drmMode* API in constrast to non-atomic legacy drmMode* API used in MetaKmsImplDeviceSimple. This has various behavioral differences worth noting, compared to the simple backend: * We can only commit once per CRTC per page flip. This means that we can only update the cursor plane once. If a primary plane composition missed a dead line, we cannot commit only a cursor update that would be presented earlier. * Partial success is not possible with the atomic backend. Cursor planes may fail with the simple backend. This is not the case with the atomic backend. This will instead later be handled using API specific to the atomic backend, that will effectively translate into TEST_ONLY commits. For testing and debugging purposes, the environment variable MUTTER_DEBUG_ENABLE_ATOMIC_KMS can be set to either 1 or 0 to force-enable or force-disable atomic mode setting. Setting it to some other value will cause mutter to abort(). Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/548 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
parent
8e235768da
commit
fb38c451b5
@ -26,6 +26,7 @@
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-kms-impl-device-atomic.h"
|
||||
#include "backends/native/meta-kms-impl-device-simple.h"
|
||||
#include "backends/native/meta-kms-impl-device.h"
|
||||
#include "backends/native/meta-kms-impl.h"
|
||||
@ -237,6 +238,20 @@ typedef struct _CreateImplDeviceData
|
||||
char *out_driver_description;
|
||||
} CreateImplDeviceData;
|
||||
|
||||
static gboolean
|
||||
is_atomic_allowed (const char *driver_name)
|
||||
{
|
||||
const char *atomic_driver_deny_list[] = {
|
||||
"qxl",
|
||||
"vmwgfx",
|
||||
"vboxvideo",
|
||||
"nvidia-drm",
|
||||
NULL,
|
||||
};
|
||||
|
||||
return !g_strv_contains (atomic_driver_deny_list, driver_name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_driver_info (int fd,
|
||||
char **name,
|
||||
@ -264,9 +279,12 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
|
||||
const char *path,
|
||||
GError **error)
|
||||
{
|
||||
GType impl_device_type;
|
||||
gboolean supports_atomic_mode_setting;
|
||||
int ret;
|
||||
g_autofree char *driver_name = NULL;
|
||||
g_autofree char *driver_description = NULL;
|
||||
const char *atomic_kms_enable_env;
|
||||
|
||||
meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl));
|
||||
|
||||
@ -285,10 +303,64 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
|
||||
driver_description = g_strdup ("Unknown");
|
||||
}
|
||||
|
||||
g_message ("Adding device '%s' (%s) using non-atomic mode setting.",
|
||||
path, driver_name);
|
||||
atomic_kms_enable_env = getenv ("MUTTER_DEBUG_ENABLE_ATOMIC_KMS");
|
||||
if (atomic_kms_enable_env)
|
||||
{
|
||||
if (g_strcmp0 (atomic_kms_enable_env, "1") == 0)
|
||||
{
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_ATOMIC;
|
||||
if (drmSetClientCap (fd, DRM_CLIENT_CAP_ATOMIC, 1) != 0)
|
||||
{
|
||||
g_error ("Failed to force atomic mode setting on '%s' (%s).",
|
||||
path, driver_name);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (atomic_kms_enable_env, "0") == 0)
|
||||
{
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_SIMPLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_error ("Invalid value '%s' for MUTTER_DEBUG_ENABLE_ATOMIC_KMS, "
|
||||
"bailing.",
|
||||
atomic_kms_enable_env);
|
||||
}
|
||||
|
||||
return g_initable_new (META_TYPE_KMS_IMPL_DEVICE_SIMPLE, NULL, error,
|
||||
g_message ("Mode setting implementation for '%s' (%s) forced (%s).",
|
||||
path, driver_name,
|
||||
impl_device_type == META_TYPE_KMS_IMPL_DEVICE_ATOMIC ?
|
||||
"atomic" : "non-atomic");
|
||||
}
|
||||
else if (!is_atomic_allowed (driver_name))
|
||||
{
|
||||
g_message ("Adding device '%s' (%s) using non-atomic mode setting"
|
||||
" (using atomic mode setting not allowed).",
|
||||
path, driver_name);
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_SIMPLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = drmSetClientCap (fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||
if (ret == 0)
|
||||
supports_atomic_mode_setting = TRUE;
|
||||
else
|
||||
supports_atomic_mode_setting = FALSE;
|
||||
|
||||
if (supports_atomic_mode_setting)
|
||||
{
|
||||
g_message ("Adding device '%s' (%s) using atomic mode setting.",
|
||||
path, driver_name);
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_ATOMIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message ("Adding device '%s' (%s) using non-atomic mode setting.",
|
||||
path, driver_name);
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_SIMPLE;
|
||||
}
|
||||
}
|
||||
|
||||
return g_initable_new (impl_device_type, NULL, error,
|
||||
"device", device,
|
||||
"impl", impl,
|
||||
"fd", fd,
|
||||
|
1035
src/backends/native/meta-kms-impl-device-atomic.c
Normal file
1035
src/backends/native/meta-kms-impl-device-atomic.c
Normal file
File diff suppressed because it is too large
Load Diff
29
src/backends/native/meta-kms-impl-device-atomic.h
Normal file
29
src/backends/native/meta-kms-impl-device-atomic.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KMS_IMPL_DEVICE_ATOMIC_H
|
||||
#define META_KMS_IMPL_DEVICE_ATOMIC_H
|
||||
|
||||
#include "backends/native/meta-kms-impl-device.h"
|
||||
|
||||
#define META_TYPE_KMS_IMPL_DEVICE_ATOMIC (meta_kms_impl_device_atomic_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaKmsImplDeviceAtomic, meta_kms_impl_device_atomic,
|
||||
META, KMS_IMPL_DEVICE_ATOMIC, MetaKmsImplDevice)
|
||||
|
||||
#endif /* META_KMS_IMPL_DEVICE_ATOMIC_H */
|
@ -129,6 +129,24 @@ meta_kms_impl_device_peek_connectors (MetaKmsImplDevice *impl_device)
|
||||
return priv->connectors;
|
||||
}
|
||||
|
||||
GList *
|
||||
meta_kms_impl_device_peek_crtcs (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
|
||||
return priv->crtcs;
|
||||
}
|
||||
|
||||
GList *
|
||||
meta_kms_impl_device_peek_planes (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
|
||||
return priv->planes;
|
||||
}
|
||||
|
||||
const MetaKmsDeviceCaps *
|
||||
meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
|
@ -80,6 +80,10 @@ GList * meta_kms_impl_device_copy_planes (MetaKmsImplDevice *impl_device);
|
||||
|
||||
GList * meta_kms_impl_device_peek_connectors (MetaKmsImplDevice *impl_device);
|
||||
|
||||
GList * meta_kms_impl_device_peek_crtcs (MetaKmsImplDevice *impl_device);
|
||||
|
||||
GList * meta_kms_impl_device_peek_planes (MetaKmsImplDevice *impl_device);
|
||||
|
||||
const MetaKmsDeviceCaps * meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device);
|
||||
|
||||
GList * meta_kms_impl_device_copy_fallback_modes (MetaKmsImplDevice *impl_device);
|
||||
|
@ -3330,6 +3330,7 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native,
|
||||
CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
|
||||
break;
|
||||
case META_KMS_FEEDBACK_FAILED:
|
||||
add_onscreen_frame_info (crtc);
|
||||
clutter_frame_set_result (frame,
|
||||
CLUTTER_FRAME_RESULT_PENDING_PRESENTED);
|
||||
|
||||
|
@ -679,6 +679,8 @@ if have_native_backend
|
||||
'backends/native/meta-kms-device-private.h',
|
||||
'backends/native/meta-kms-device.c',
|
||||
'backends/native/meta-kms-device.h',
|
||||
'backends/native/meta-kms-impl-device-atomic.c',
|
||||
'backends/native/meta-kms-impl-device-atomic.h',
|
||||
'backends/native/meta-kms-impl-device-simple.c',
|
||||
'backends/native/meta-kms-impl-device-simple.h',
|
||||
'backends/native/meta-kms-impl-device.c',
|
||||
|
Loading…
Reference in New Issue
Block a user