kms/impl-device: Add meta_kms_impl_device_get_signaled_sync_file helper

It returns a file descriptor which references a signaled sync_file.

v2:
* Change function name and add Doxygen comment to hopefully make its
  purpose a bit clearer (Ivan Molodetskikh)
v3: (Jonas Ådahl)
* Create sync_file from scratch via a syncobj, no buffer needed anymore
* Initialize priv->sync_file = 1 and use g_clear_fd in finalize

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3389>
This commit is contained in:
Michel Dänzer 2023-11-12 15:59:51 +01:00 committed by Marge Bot
parent 3ad32ee0bc
commit 281ff86b4b
2 changed files with 65 additions and 0 deletions

View File

@ -21,6 +21,8 @@
#include <errno.h>
#include <glib/gstdio.h>
#include <linux/dma-buf.h>
#include <sys/ioctl.h>
#include <sys/timerfd.h>
#include <xf86drm.h>
@ -99,6 +101,9 @@ typedef struct _MetaKmsImplDevicePrivate
GHashTable *crtc_frames;
gboolean deadline_timer_inhibited;
gboolean sync_file_retrieved;
int sync_file;
} MetaKmsImplDevicePrivate;
static void
@ -1026,6 +1031,60 @@ meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
return meta_device_file_get_fd (priv->device_file);
}
/**
* meta_kms_impl_device_get_signaled_sync_file:
* @impl_device: a #MetaKmsImplDevice object
*
* Returns a file descriptor which references a sync_file. The file descriptor
* must not be closed by the caller.
*
* Always returns the same file descriptor for the same impl_device. The
* referenced sync_file will always be considered signaled.
*
* Returns a negative value if a sync_file fd couldn't be retrieved.
*/
int
meta_kms_impl_device_get_signaled_sync_file (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
if (!priv->sync_file_retrieved)
{
uint32_t syncobj_handle;
int drm_fd, ret;
priv->sync_file = -1;
priv->sync_file_retrieved = TRUE;
drm_fd = meta_kms_impl_device_get_fd (impl_device);
ret = drmSyncobjCreate (drm_fd,
DRM_SYNCOBJ_CREATE_SIGNALED,
&syncobj_handle);
if (ret < 0)
{
meta_topic (META_DEBUG_KMS,
"drmSyncobjCreate failed: %s",
g_strerror (errno));
return -1;
}
ret = drmSyncobjExportSyncFile (drm_fd, syncobj_handle, &priv->sync_file);
if (ret < 0)
{
meta_topic (META_DEBUG_KMS,
"drmSyncobjExportSyncFile failed: %s",
g_strerror (errno));
}
drmSyncobjDestroy (drm_fd, syncobj_handle);
}
return priv->sync_file;
}
static void
disarm_crtc_frame_deadline_timer (CrtcFrame *crtc_frame)
{
@ -1825,6 +1884,8 @@ meta_kms_impl_device_finalize (GObject *object)
g_free (priv->driver_description);
g_free (priv->path);
g_clear_fd (&priv->sync_file, NULL);
G_OBJECT_CLASS (meta_kms_impl_device_parent_class)->finalize (object);
}
@ -1947,6 +2008,8 @@ meta_kms_impl_device_initable_init (GInitable *initable,
g_hash_table_new_full (NULL, NULL,
NULL, (GDestroyNotify) crtc_frame_free);
priv->sync_file = -1;
return TRUE;
}

View File

@ -145,6 +145,8 @@ void meta_kms_impl_device_hold_fd (MetaKmsImplDevice *impl_device);
void meta_kms_impl_device_unhold_fd (MetaKmsImplDevice *impl_device);
int meta_kms_impl_device_get_signaled_sync_file (MetaKmsImplDevice *impl_device);
MetaKmsResourceChanges meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device,
uint32_t crtc_id,
uint32_t connector_id);