native: Release output device files that are unused
In order to make it possible to e.g. unload an unused DRM device, we need to make sure that we don't keep the file descriptor open if we don't need it; otherwise we block anyone from unloading the corresponding module. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1828>
This commit is contained in:
parent
3c47661b78
commit
ce5a5789bb
@ -32,6 +32,8 @@ typedef enum _MetaDeviceFileFlags
|
|||||||
|
|
||||||
typedef enum _MetaDeviceFileTags
|
typedef enum _MetaDeviceFileTags
|
||||||
{
|
{
|
||||||
|
META_DEVICE_FILE_TAG_KMS,
|
||||||
|
|
||||||
META_DEVICE_FILE_N_TAGS,
|
META_DEVICE_FILE_N_TAGS,
|
||||||
} MetaDeviceFileTags;
|
} MetaDeviceFileTags;
|
||||||
|
|
||||||
|
@ -52,6 +52,8 @@ struct _MetaKmsConnector
|
|||||||
|
|
||||||
uint32_t edid_blob_id;
|
uint32_t edid_blob_id;
|
||||||
uint32_t tile_blob_id;
|
uint32_t tile_blob_id;
|
||||||
|
|
||||||
|
gboolean fd_held;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaKmsConnector, meta_kms_connector, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (MetaKmsConnector, meta_kms_connector, G_TYPE_OBJECT)
|
||||||
@ -128,6 +130,25 @@ meta_kms_connector_is_underscanning_supported (MetaKmsConnector *connector)
|
|||||||
return underscan_prop_id != 0;
|
return underscan_prop_id != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sync_fd_held (MetaKmsConnector *connector,
|
||||||
|
MetaKmsImplDevice *impl_device)
|
||||||
|
{
|
||||||
|
gboolean should_hold_fd;
|
||||||
|
|
||||||
|
should_hold_fd = connector->current_state->current_crtc_id != 0;
|
||||||
|
|
||||||
|
if (connector->fd_held == should_hold_fd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (should_hold_fd)
|
||||||
|
meta_kms_impl_device_hold_fd (impl_device);
|
||||||
|
else
|
||||||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||||||
|
|
||||||
|
connector->fd_held = should_hold_fd;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_panel_orientation (MetaKmsConnectorState *state,
|
set_panel_orientation (MetaKmsConnectorState *state,
|
||||||
drmModePropertyPtr prop,
|
drmModePropertyPtr prop,
|
||||||
@ -475,6 +496,8 @@ meta_kms_connector_read_state (MetaKmsConnector *connector,
|
|||||||
state_set_crtc_state (state, drm_connector, impl_device, drm_resources);
|
state_set_crtc_state (state, drm_connector, impl_device, drm_resources);
|
||||||
|
|
||||||
connector->current_state = state;
|
connector->current_state = state;
|
||||||
|
|
||||||
|
sync_fd_held (connector, impl_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -498,6 +521,7 @@ void
|
|||||||
meta_kms_connector_predict_state (MetaKmsConnector *connector,
|
meta_kms_connector_predict_state (MetaKmsConnector *connector,
|
||||||
MetaKmsUpdate *update)
|
MetaKmsUpdate *update)
|
||||||
{
|
{
|
||||||
|
MetaKmsImplDevice *impl_device;
|
||||||
MetaKmsConnectorState *current_state;
|
MetaKmsConnectorState *current_state;
|
||||||
GList *mode_sets;
|
GList *mode_sets;
|
||||||
GList *l;
|
GList *l;
|
||||||
@ -527,6 +551,9 @@ meta_kms_connector_predict_state (MetaKmsConnector *connector,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_device = meta_kms_device_get_impl_device (connector->device);
|
||||||
|
sync_fd_held (connector, impl_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -645,6 +672,14 @@ meta_kms_connector_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
MetaKmsConnector *connector = META_KMS_CONNECTOR (object);
|
MetaKmsConnector *connector = META_KMS_CONNECTOR (object);
|
||||||
|
|
||||||
|
if (connector->fd_held)
|
||||||
|
{
|
||||||
|
MetaKmsImplDevice *impl_device;
|
||||||
|
|
||||||
|
impl_device = meta_kms_device_get_impl_device (connector->device);
|
||||||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||||||
|
}
|
||||||
|
|
||||||
g_clear_pointer (&connector->current_state, meta_kms_connector_state_free);
|
g_clear_pointer (&connector->current_state, meta_kms_connector_state_free);
|
||||||
g_free (connector->name);
|
g_free (connector->name);
|
||||||
|
|
||||||
|
@ -602,6 +602,8 @@ process_page_flip_listener (MetaKmsImplDevice *impl_device,
|
|||||||
GUINT_TO_POINTER (crtc_id),
|
GUINT_TO_POINTER (crtc_id),
|
||||||
page_flip_data);
|
page_flip_data);
|
||||||
|
|
||||||
|
meta_kms_impl_device_hold_fd (impl_device);
|
||||||
|
|
||||||
meta_topic (META_DEBUG_KMS,
|
meta_topic (META_DEBUG_KMS,
|
||||||
"[atomic] Adding page flip data for (%u, %s): %p",
|
"[atomic] Adding page flip data for (%u, %s): %p",
|
||||||
crtc_id,
|
crtc_id,
|
||||||
@ -709,6 +711,8 @@ atomic_page_flip_handler (int fd,
|
|||||||
if (!page_flip_data)
|
if (!page_flip_data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||||||
|
|
||||||
meta_kms_page_flip_data_set_timings_in_impl (page_flip_data,
|
meta_kms_page_flip_data_set_timings_in_impl (page_flip_data,
|
||||||
sequence, tv_sec, tv_usec);
|
sequence, tv_sec, tv_usec);
|
||||||
meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
|
meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
|
||||||
@ -1014,8 +1018,10 @@ dispose_page_flip_data (gpointer key,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaKmsPageFlipData *page_flip_data = value;
|
MetaKmsPageFlipData *page_flip_data = value;
|
||||||
|
MetaKmsImplDevice *impl_device = user_data;
|
||||||
|
|
||||||
meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL);
|
meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL);
|
||||||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1028,7 +1034,7 @@ meta_kms_impl_device_atomic_prepare_shutdown (MetaKmsImplDevice *impl_device)
|
|||||||
|
|
||||||
g_hash_table_foreach_remove (impl_device_atomic->page_flip_datas,
|
g_hash_table_foreach_remove (impl_device_atomic->page_flip_datas,
|
||||||
dispose_page_flip_data,
|
dispose_page_flip_data,
|
||||||
NULL);
|
impl_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1055,7 +1061,6 @@ meta_kms_impl_device_atomic_open_device_file (MetaKmsImplDevice *impl_device,
|
|||||||
MetaDevicePool *device_pool =
|
MetaDevicePool *device_pool =
|
||||||
meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
|
meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
|
||||||
g_autoptr (MetaDeviceFile) device_file = NULL;
|
g_autoptr (MetaDeviceFile) device_file = NULL;
|
||||||
int fd;
|
|
||||||
|
|
||||||
device_file = meta_device_pool_open (device_pool, path,
|
device_file = meta_device_pool_open (device_pool, path,
|
||||||
META_DEVICE_FILE_FLAG_TAKE_CONTROL,
|
META_DEVICE_FILE_FLAG_TAKE_CONTROL,
|
||||||
@ -1063,7 +1068,15 @@ meta_kms_impl_device_atomic_open_device_file (MetaKmsImplDevice *impl_device,
|
|||||||
if (!device_file)
|
if (!device_file)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fd = meta_device_file_get_fd (device_file);
|
if (!meta_device_file_has_tag (device_file,
|
||||||
|
META_DEVICE_FILE_TAG_KMS,
|
||||||
|
META_KMS_DEVICE_FILE_TAG_ATOMIC))
|
||||||
|
{
|
||||||
|
int fd = meta_device_file_get_fd (device_file);
|
||||||
|
|
||||||
|
g_warn_if_fail (!meta_device_file_has_tag (device_file,
|
||||||
|
META_DEVICE_FILE_TAG_KMS,
|
||||||
|
META_KMS_DEVICE_FILE_TAG_SIMPLE));
|
||||||
|
|
||||||
if (drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
|
if (drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
|
||||||
{
|
{
|
||||||
@ -1079,6 +1092,11 @@ meta_kms_impl_device_atomic_open_device_file (MetaKmsImplDevice *impl_device,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta_device_file_tag (device_file,
|
||||||
|
META_DEVICE_FILE_TAG_KMS,
|
||||||
|
META_KMS_DEVICE_FILE_TAG_ATOMIC);
|
||||||
|
}
|
||||||
|
|
||||||
return g_steal_pointer (&device_file);
|
return g_steal_pointer (&device_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,6 +655,7 @@ retry_page_flips (gpointer user_data)
|
|||||||
g_critical ("Failed to page flip: %s", error->message);
|
g_critical ("Failed to page flip: %s", error->message);
|
||||||
|
|
||||||
meta_kms_page_flip_data_discard_in_impl (page_flip_data, error);
|
meta_kms_page_flip_data_discard_in_impl (page_flip_data, error);
|
||||||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -977,6 +978,7 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device,
|
|||||||
fb_id = 0;
|
fb_id = 0;
|
||||||
drm_mode = cached_mode_set->drm_mode;
|
drm_mode = cached_mode_set->drm_mode;
|
||||||
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
|
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
|
||||||
|
meta_kms_impl_device_hold_fd (impl_device);
|
||||||
schedule_retry_page_flip (impl_device_simple,
|
schedule_retry_page_flip (impl_device_simple,
|
||||||
crtc,
|
crtc,
|
||||||
fb_id,
|
fb_id,
|
||||||
@ -1016,6 +1018,8 @@ dispatch_page_flip (MetaKmsImplDevice *impl_device,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
meta_kms_impl_device_hold_fd (impl_device);
|
||||||
|
|
||||||
impl_device_simple->posted_page_flip_datas =
|
impl_device_simple->posted_page_flip_datas =
|
||||||
g_list_prepend (impl_device_simple->posted_page_flip_datas,
|
g_list_prepend (impl_device_simple->posted_page_flip_datas,
|
||||||
page_flip_data);
|
page_flip_data);
|
||||||
@ -1367,6 +1371,8 @@ page_flip_handler (int fd,
|
|||||||
page_flip_data,
|
page_flip_data,
|
||||||
meta_kms_crtc_get_id (crtc));
|
meta_kms_crtc_get_id (crtc));
|
||||||
|
|
||||||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||||||
|
|
||||||
meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
|
meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
|
||||||
impl_device_simple->posted_page_flip_datas =
|
impl_device_simple->posted_page_flip_datas =
|
||||||
g_list_remove (impl_device_simple->posted_page_flip_datas,
|
g_list_remove (impl_device_simple->posted_page_flip_datas,
|
||||||
@ -1465,6 +1471,14 @@ meta_kms_impl_device_simple_handle_page_flip_callback (MetaKmsImplDevice *impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dispose_page_flip_data (MetaKmsPageFlipData *page_flip_data,
|
||||||
|
MetaKmsImplDevice *impl_device)
|
||||||
|
{
|
||||||
|
meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL);
|
||||||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_kms_impl_device_simple_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
|
meta_kms_impl_device_simple_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
|
||||||
{
|
{
|
||||||
@ -1489,7 +1503,7 @@ meta_kms_impl_device_simple_discard_pending_page_flips (MetaKmsImplDevice *impl_
|
|||||||
meta_kms_impl_device_get_path (
|
meta_kms_impl_device_get_path (
|
||||||
meta_kms_page_flip_data_get_impl_device (page_flip_data)));
|
meta_kms_page_flip_data_get_impl_device (page_flip_data)));
|
||||||
|
|
||||||
meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL);
|
dispose_page_flip_data (page_flip_data, impl_device);
|
||||||
retry_page_flip_data_free (retry_page_flip_data);
|
retry_page_flip_data_free (retry_page_flip_data);
|
||||||
}
|
}
|
||||||
g_clear_pointer (&impl_device_simple->pending_page_flip_retries, g_list_free);
|
g_clear_pointer (&impl_device_simple->pending_page_flip_retries, g_list_free);
|
||||||
@ -1505,8 +1519,8 @@ meta_kms_impl_device_simple_prepare_shutdown (MetaKmsImplDevice *impl_device)
|
|||||||
META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
|
META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
|
||||||
|
|
||||||
g_list_foreach (impl_device_simple->posted_page_flip_datas,
|
g_list_foreach (impl_device_simple->posted_page_flip_datas,
|
||||||
(GFunc) meta_kms_page_flip_data_discard_in_impl,
|
(GFunc) dispose_page_flip_data,
|
||||||
NULL);
|
impl_device);
|
||||||
g_clear_list (&impl_device_simple->posted_page_flip_datas, NULL);
|
g_clear_list (&impl_device_simple->posted_page_flip_datas, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1515,18 +1529,16 @@ meta_kms_impl_device_simple_finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
MetaKmsImplDeviceSimple *impl_device_simple =
|
MetaKmsImplDeviceSimple *impl_device_simple =
|
||||||
META_KMS_IMPL_DEVICE_SIMPLE (object);
|
META_KMS_IMPL_DEVICE_SIMPLE (object);
|
||||||
|
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
|
||||||
|
|
||||||
g_list_free_full (impl_device_simple->pending_page_flip_retries,
|
g_list_free_full (impl_device_simple->pending_page_flip_retries,
|
||||||
(GDestroyNotify) retry_page_flip_data_free);
|
(GDestroyNotify) retry_page_flip_data_free);
|
||||||
dispatch_page_flip_datas (&impl_device_simple->posted_page_flip_datas,
|
|
||||||
(GFunc) meta_kms_page_flip_data_discard_in_impl,
|
|
||||||
NULL);
|
|
||||||
dispatch_page_flip_datas (&impl_device_simple->postponed_page_flip_datas,
|
dispatch_page_flip_datas (&impl_device_simple->postponed_page_flip_datas,
|
||||||
(GFunc) meta_kms_page_flip_data_discard_in_impl,
|
(GFunc) dispose_page_flip_data,
|
||||||
NULL);
|
impl_device);
|
||||||
dispatch_page_flip_datas (&impl_device_simple->postponed_mode_set_fallback_datas,
|
dispatch_page_flip_datas (&impl_device_simple->postponed_mode_set_fallback_datas,
|
||||||
(GFunc) meta_kms_page_flip_data_discard_in_impl,
|
(GFunc) dispose_page_flip_data,
|
||||||
NULL);
|
impl_device);
|
||||||
|
|
||||||
g_assert (!impl_device_simple->posted_page_flip_datas);
|
g_assert (!impl_device_simple->posted_page_flip_datas);
|
||||||
|
|
||||||
@ -1548,7 +1560,6 @@ meta_kms_impl_device_simple_open_device_file (MetaKmsImplDevice *impl_device,
|
|||||||
MetaDevicePool *device_pool =
|
MetaDevicePool *device_pool =
|
||||||
meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
|
meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
|
||||||
g_autoptr (MetaDeviceFile) device_file = NULL;
|
g_autoptr (MetaDeviceFile) device_file = NULL;
|
||||||
int fd;
|
|
||||||
|
|
||||||
device_file = meta_device_pool_open (device_pool, path,
|
device_file = meta_device_pool_open (device_pool, path,
|
||||||
META_DEVICE_FILE_FLAG_TAKE_CONTROL,
|
META_DEVICE_FILE_FLAG_TAKE_CONTROL,
|
||||||
@ -1556,7 +1567,15 @@ meta_kms_impl_device_simple_open_device_file (MetaKmsImplDevice *impl_device,
|
|||||||
if (!device_file)
|
if (!device_file)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fd = meta_device_file_get_fd (device_file);
|
if (!meta_device_file_has_tag (device_file,
|
||||||
|
META_DEVICE_FILE_TAG_KMS,
|
||||||
|
META_KMS_DEVICE_FILE_TAG_SIMPLE))
|
||||||
|
{
|
||||||
|
int fd = meta_device_file_get_fd (device_file);
|
||||||
|
|
||||||
|
g_warn_if_fail (!meta_device_file_has_tag (device_file,
|
||||||
|
META_DEVICE_FILE_TAG_KMS,
|
||||||
|
META_KMS_DEVICE_FILE_TAG_ATOMIC));
|
||||||
|
|
||||||
if (drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
|
if (drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0)
|
||||||
{
|
{
|
||||||
@ -1565,6 +1584,11 @@ meta_kms_impl_device_simple_open_device_file (MetaKmsImplDevice *impl_device,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta_device_file_tag (device_file,
|
||||||
|
META_DEVICE_FILE_TAG_KMS,
|
||||||
|
META_KMS_DEVICE_FILE_TAG_SIMPLE);
|
||||||
|
}
|
||||||
|
|
||||||
return g_steal_pointer (&device_file);
|
return g_steal_pointer (&device_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
#include "backends/native/meta-kms-plane-private.h"
|
#include "backends/native/meta-kms-plane-private.h"
|
||||||
#include "backends/native/meta-kms-plane.h"
|
#include "backends/native/meta-kms-plane.h"
|
||||||
#include "backends/native/meta-kms-private.h"
|
#include "backends/native/meta-kms-private.h"
|
||||||
#include "backends/native/meta-kms-update.h"
|
#include "backends/native/meta-kms-update-private.h"
|
||||||
|
|
||||||
#include "meta-default-modes.h"
|
#include "meta-default-modes.h"
|
||||||
#include "meta-private-enum-types.h"
|
#include "meta-private-enum-types.h"
|
||||||
@ -60,10 +60,12 @@ typedef struct _MetaKmsImplDevicePrivate
|
|||||||
MetaKmsDevice *device;
|
MetaKmsDevice *device;
|
||||||
MetaKmsImpl *impl;
|
MetaKmsImpl *impl;
|
||||||
|
|
||||||
|
int fd_hold_count;
|
||||||
MetaDeviceFile *device_file;
|
MetaDeviceFile *device_file;
|
||||||
GSource *fd_source;
|
GSource *fd_source;
|
||||||
char *path;
|
char *path;
|
||||||
MetaKmsDeviceFlag flags;
|
MetaKmsDeviceFlag flags;
|
||||||
|
gboolean has_latched_fd_hold;
|
||||||
|
|
||||||
char *driver_name;
|
char *driver_name;
|
||||||
char *driver_description;
|
char *driver_description;
|
||||||
@ -619,11 +621,81 @@ init_fallback_modes (MetaKmsImplDevice *impl_device)
|
|||||||
priv->fallback_modes = g_list_reverse (modes);
|
priv->fallback_modes = g_list_reverse (modes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaDeviceFile *
|
||||||
|
meta_kms_impl_device_open_device_file (MetaKmsImplDevice *impl_device,
|
||||||
|
const char *path,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
MetaKmsImplDevicePrivate *priv =
|
||||||
|
meta_kms_impl_device_get_instance_private (impl_device);
|
||||||
|
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
|
||||||
|
|
||||||
|
return klass->open_device_file (impl_device, priv->path, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
ensure_device_file (MetaKmsImplDevice *impl_device,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
MetaKmsImplDevicePrivate *priv =
|
||||||
|
meta_kms_impl_device_get_instance_private (impl_device);
|
||||||
|
MetaDeviceFile *device_file;
|
||||||
|
|
||||||
|
if (priv->device_file)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
device_file = meta_kms_impl_device_open_device_file (impl_device,
|
||||||
|
priv->path,
|
||||||
|
error);
|
||||||
|
if (!device_file)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
priv->device_file = device_file;
|
||||||
|
|
||||||
|
if (!(priv->flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING))
|
||||||
|
{
|
||||||
|
priv->fd_source =
|
||||||
|
meta_kms_register_fd_in_impl (meta_kms_impl_get_kms (priv->impl),
|
||||||
|
meta_device_file_get_fd (device_file),
|
||||||
|
kms_event_dispatch_in_impl,
|
||||||
|
impl_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ensure_latched_fd_hold (MetaKmsImplDevice *impl_device)
|
||||||
|
{
|
||||||
|
MetaKmsImplDevicePrivate *priv =
|
||||||
|
meta_kms_impl_device_get_instance_private (impl_device);
|
||||||
|
|
||||||
|
if (!priv->has_latched_fd_hold)
|
||||||
|
{
|
||||||
|
meta_kms_impl_device_hold_fd (impl_device);
|
||||||
|
priv->has_latched_fd_hold = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_latched_fd_hold (MetaKmsImplDevice *impl_device)
|
||||||
|
{
|
||||||
|
MetaKmsImplDevicePrivate *priv =
|
||||||
|
meta_kms_impl_device_get_instance_private (impl_device);
|
||||||
|
|
||||||
|
if (priv->has_latched_fd_hold)
|
||||||
|
{
|
||||||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||||||
|
priv->has_latched_fd_hold = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
|
meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
|
||||||
{
|
{
|
||||||
MetaKmsImplDevicePrivate *priv =
|
MetaKmsImplDevicePrivate *priv =
|
||||||
meta_kms_impl_device_get_instance_private (impl_device);
|
meta_kms_impl_device_get_instance_private (impl_device);
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
int fd;
|
int fd;
|
||||||
drmModeRes *drm_resources;
|
drmModeRes *drm_resources;
|
||||||
|
|
||||||
@ -631,17 +703,21 @@ meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
|
|||||||
|
|
||||||
meta_topic (META_DEBUG_KMS, "Updating device state for %s", priv->path);
|
meta_topic (META_DEBUG_KMS, "Updating device state for %s", priv->path);
|
||||||
|
|
||||||
|
if (!ensure_device_file (impl_device, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to reopen '%s': %s", priv->path, error->message);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_latched_fd_hold (impl_device);
|
||||||
|
|
||||||
fd = meta_device_file_get_fd (priv->device_file);
|
fd = meta_device_file_get_fd (priv->device_file);
|
||||||
drm_resources = drmModeGetResources (fd);
|
drm_resources = drmModeGetResources (fd);
|
||||||
if (!drm_resources)
|
if (!drm_resources)
|
||||||
{
|
{
|
||||||
g_list_free_full (priv->planes, g_object_unref);
|
meta_topic (META_DEBUG_KMS, "Device '%s' didn't return any resources",
|
||||||
g_list_free_full (priv->crtcs, g_object_unref);
|
priv->path);
|
||||||
g_list_free_full (priv->connectors, g_object_unref);
|
goto err;
|
||||||
priv->planes = NULL;
|
|
||||||
priv->crtcs = NULL;
|
|
||||||
priv->connectors = NULL;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update_connectors (impl_device, drm_resources);
|
update_connectors (impl_device, drm_resources);
|
||||||
@ -651,6 +727,13 @@ meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
|
|||||||
g_list_foreach (priv->connectors, (GFunc) meta_kms_connector_update_state,
|
g_list_foreach (priv->connectors, (GFunc) meta_kms_connector_update_state,
|
||||||
drm_resources);
|
drm_resources);
|
||||||
drmModeFreeResources (drm_resources);
|
drmModeFreeResources (drm_resources);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
err:
|
||||||
|
g_clear_list (&priv->planes, g_object_unref);
|
||||||
|
g_clear_list (&priv->crtcs, g_object_unref);
|
||||||
|
g_clear_list (&priv->connectors, g_object_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -666,6 +749,12 @@ meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device,
|
|||||||
update);
|
update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_kms_impl_device_notify_modes_set (MetaKmsImplDevice *impl_device)
|
||||||
|
{
|
||||||
|
clear_latched_fd_hold (impl_device);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
|
meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
|
||||||
{
|
{
|
||||||
@ -683,8 +772,17 @@ meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
|
|||||||
MetaKmsUpdateFlag flags)
|
MetaKmsUpdateFlag flags)
|
||||||
{
|
{
|
||||||
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
|
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
|
||||||
|
MetaKmsFeedback *feedback;
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
|
||||||
return klass->process_update (impl_device, update, flags);
|
if (!ensure_device_file (impl_device, &error))
|
||||||
|
return meta_kms_feedback_new_failed (NULL, g_steal_pointer (&error));
|
||||||
|
|
||||||
|
meta_kms_impl_device_hold_fd (impl_device);
|
||||||
|
feedback = klass->process_update (impl_device, update, flags);
|
||||||
|
meta_kms_impl_device_unhold_fd (impl_device);
|
||||||
|
|
||||||
|
return feedback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -704,6 +802,44 @@ meta_kms_impl_device_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
|
|||||||
klass->discard_pending_page_flips (impl_device);
|
klass->discard_pending_page_flips (impl_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_kms_impl_device_hold_fd (MetaKmsImplDevice *impl_device)
|
||||||
|
{
|
||||||
|
MetaKmsImplDevicePrivate *priv =
|
||||||
|
meta_kms_impl_device_get_instance_private (impl_device);
|
||||||
|
MetaKms *kms = meta_kms_device_get_kms (priv->device);
|
||||||
|
|
||||||
|
meta_assert_in_kms_impl (kms);
|
||||||
|
|
||||||
|
g_assert (priv->device_file);
|
||||||
|
|
||||||
|
priv->fd_hold_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_kms_impl_device_unhold_fd (MetaKmsImplDevice *impl_device)
|
||||||
|
{
|
||||||
|
MetaKmsImplDevicePrivate *priv =
|
||||||
|
meta_kms_impl_device_get_instance_private (impl_device);
|
||||||
|
MetaKms *kms = meta_kms_device_get_kms (priv->device);
|
||||||
|
|
||||||
|
meta_assert_in_kms_impl (kms);
|
||||||
|
|
||||||
|
g_return_if_fail (priv->fd_hold_count > 0);
|
||||||
|
|
||||||
|
priv->fd_hold_count--;
|
||||||
|
if (priv->fd_hold_count == 0)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&priv->device_file, meta_device_file_release);
|
||||||
|
|
||||||
|
if (priv->fd_source)
|
||||||
|
{
|
||||||
|
g_source_destroy (priv->fd_source);
|
||||||
|
g_clear_pointer (&priv->fd_source, g_source_unref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_kms_impl_device_get_property (GObject *object,
|
meta_kms_impl_device_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -776,7 +912,8 @@ meta_kms_impl_device_finalize (GObject *object)
|
|||||||
g_list_free_full (priv->fallback_modes,
|
g_list_free_full (priv->fallback_modes,
|
||||||
(GDestroyNotify) meta_kms_mode_free);
|
(GDestroyNotify) meta_kms_mode_free);
|
||||||
|
|
||||||
g_clear_pointer (&priv->device_file, meta_device_file_release);
|
clear_latched_fd_hold (impl_device);
|
||||||
|
g_warn_if_fail (!priv->device_file);
|
||||||
|
|
||||||
g_free (priv->driver_name);
|
g_free (priv->driver_name);
|
||||||
g_free (priv->driver_description);
|
g_free (priv->driver_description);
|
||||||
@ -816,12 +953,6 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
|
|||||||
|
|
||||||
drmModeFreeResources (drm_resources);
|
drmModeFreeResources (drm_resources);
|
||||||
|
|
||||||
priv->fd_source =
|
|
||||||
meta_kms_register_fd_in_impl (meta_kms_impl_get_kms (priv->impl),
|
|
||||||
fd,
|
|
||||||
kms_event_dispatch_in_impl,
|
|
||||||
impl_device);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -862,13 +993,13 @@ meta_kms_impl_device_initable_init (GInitable *initable,
|
|||||||
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
|
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
|
||||||
MetaKmsImplDevicePrivate *priv =
|
MetaKmsImplDevicePrivate *priv =
|
||||||
meta_kms_impl_device_get_instance_private (impl_device);
|
meta_kms_impl_device_get_instance_private (impl_device);
|
||||||
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
priv->device_file = klass->open_device_file (impl_device, priv->path, error);
|
if (!ensure_device_file (impl_device, error))
|
||||||
if (!priv->device_file)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
ensure_latched_fd_hold (impl_device);
|
||||||
|
|
||||||
g_clear_pointer (&priv->path, g_free);
|
g_clear_pointer (&priv->path, g_free);
|
||||||
priv->path = g_strdup (meta_device_file_get_path (priv->device_file));
|
priv->path = g_strdup (meta_device_file_get_path (priv->device_file));
|
||||||
|
|
||||||
|
@ -87,6 +87,12 @@ enum
|
|||||||
META_KMS_ERROR_NOT_SUPPORTED,
|
META_KMS_ERROR_NOT_SUPPORTED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
META_KMS_DEVICE_FILE_TAG_ATOMIC = 1 << 0,
|
||||||
|
META_KMS_DEVICE_FILE_TAG_SIMPLE = 1 << 1,
|
||||||
|
};
|
||||||
|
|
||||||
#define META_KMS_ERROR meta_kms_error_quark ()
|
#define META_KMS_ERROR meta_kms_error_quark ()
|
||||||
GQuark meta_kms_error_quark (void);
|
GQuark meta_kms_error_quark (void);
|
||||||
|
|
||||||
@ -124,11 +130,17 @@ drmModePropertyPtr meta_kms_impl_device_find_property (MetaKmsImplDevice *
|
|||||||
|
|
||||||
int meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device);
|
int meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device);
|
||||||
|
|
||||||
|
void meta_kms_impl_device_hold_fd (MetaKmsImplDevice *impl_device);
|
||||||
|
|
||||||
|
void meta_kms_impl_device_unhold_fd (MetaKmsImplDevice *impl_device);
|
||||||
|
|
||||||
void meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device);
|
void meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device);
|
||||||
|
|
||||||
void meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device,
|
void meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device,
|
||||||
MetaKmsUpdate *update);
|
MetaKmsUpdate *update);
|
||||||
|
|
||||||
|
void meta_kms_impl_device_notify_modes_set (MetaKmsImplDevice *impl_device);
|
||||||
|
|
||||||
MetaKmsPlane * meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device,
|
MetaKmsPlane * meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device,
|
||||||
MetaKmsPlaneType plane_type,
|
MetaKmsPlaneType plane_type,
|
||||||
MetaKmsCrtc *crtc);
|
MetaKmsCrtc *crtc);
|
||||||
|
@ -119,6 +119,16 @@ meta_kms_impl_prepare_shutdown (MetaKmsImpl *impl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_kms_impl_notify_modes_set (MetaKmsImpl *impl)
|
||||||
|
{
|
||||||
|
MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
|
||||||
|
|
||||||
|
g_list_foreach (priv->impl_devices,
|
||||||
|
(GFunc) meta_kms_impl_device_notify_modes_set,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
MetaKmsImpl *
|
MetaKmsImpl *
|
||||||
meta_kms_impl_new (MetaKms *kms)
|
meta_kms_impl_new (MetaKms *kms)
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,8 @@ void meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl);
|
|||||||
|
|
||||||
void meta_kms_impl_prepare_shutdown (MetaKmsImpl *impl);
|
void meta_kms_impl_prepare_shutdown (MetaKmsImpl *impl);
|
||||||
|
|
||||||
|
void meta_kms_impl_notify_modes_set (MetaKmsImpl *impl);
|
||||||
|
|
||||||
MetaKmsImpl * meta_kms_impl_new (MetaKms *kms);
|
MetaKmsImpl * meta_kms_impl_new (MetaKms *kms);
|
||||||
|
|
||||||
#endif /* META_KMS_IMPL_H */
|
#endif /* META_KMS_IMPL_H */
|
||||||
|
@ -345,6 +345,24 @@ meta_kms_discard_pending_page_flips (MetaKms *kms)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
meta_kms_notify_modes_set_in_impl (MetaKmsImpl *impl,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
meta_kms_impl_notify_modes_set (impl);
|
||||||
|
return GINT_TO_POINTER (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_kms_notify_modes_set (MetaKms *kms)
|
||||||
|
{
|
||||||
|
meta_kms_run_impl_task_sync (kms,
|
||||||
|
meta_kms_notify_modes_set_in_impl,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_kms_callback_data_free (MetaKmsCallbackData *callback_data)
|
meta_kms_callback_data_free (MetaKmsCallbackData *callback_data)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +52,8 @@ MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms,
|
|||||||
|
|
||||||
void meta_kms_discard_pending_page_flips (MetaKms *kms);
|
void meta_kms_discard_pending_page_flips (MetaKms *kms);
|
||||||
|
|
||||||
|
void meta_kms_notify_modes_set (MetaKms *kms);
|
||||||
|
|
||||||
MetaBackend * meta_kms_get_backend (MetaKms *kms);
|
MetaBackend * meta_kms_get_backend (MetaKms *kms);
|
||||||
|
|
||||||
GList * meta_kms_get_devices (MetaKms *kms);
|
GList * meta_kms_get_devices (MetaKms *kms);
|
||||||
|
@ -102,6 +102,11 @@ G_DEFINE_TYPE_WITH_CODE (MetaRendererNative,
|
|||||||
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
|
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
|
||||||
static const CoglWinsysVtable *parent_vtable;
|
static const CoglWinsysVtable *parent_vtable;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_renderer_native_ensure_gpu_data (MetaRendererNative *renderer_native,
|
||||||
|
MetaGpuKms *gpu_kms,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native);
|
meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native);
|
||||||
|
|
||||||
@ -625,6 +630,44 @@ clear_kept_alive_onscreens (MetaRendererNative *renderer_native)
|
|||||||
g_object_unref);
|
g_object_unref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_gpu_unused (gpointer key,
|
||||||
|
gpointer value,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GHashTable *used_gpus = user_data;
|
||||||
|
|
||||||
|
return !g_hash_table_contains (used_gpus, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_unused_gpu_datas (MetaRendererNative *renderer_native)
|
||||||
|
{
|
||||||
|
MetaRenderer *renderer = META_RENDERER (renderer_native);
|
||||||
|
g_autoptr (GHashTable) used_gpus = NULL;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
used_gpus = g_hash_table_new (NULL, NULL);
|
||||||
|
g_hash_table_add (used_gpus, renderer_native->primary_gpu_kms);
|
||||||
|
|
||||||
|
for (l = meta_renderer_get_views (renderer); l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaRendererView *view = l->data;
|
||||||
|
MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
|
||||||
|
MetaGpu *gpu;
|
||||||
|
|
||||||
|
gpu = meta_crtc_get_gpu (crtc);
|
||||||
|
if (!gpu)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
g_hash_table_add (used_gpus, gpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_foreach_remove (renderer_native->gpu_datas,
|
||||||
|
is_gpu_unused,
|
||||||
|
used_gpus);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native)
|
meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native)
|
||||||
{
|
{
|
||||||
@ -665,6 +708,10 @@ meta_renderer_native_post_mode_set_updates (MetaRendererNative *renderer_native)
|
|||||||
}
|
}
|
||||||
|
|
||||||
clear_kept_alive_onscreens (renderer_native);
|
clear_kept_alive_onscreens (renderer_native);
|
||||||
|
|
||||||
|
meta_kms_notify_modes_set (kms);
|
||||||
|
|
||||||
|
free_unused_gpu_datas (renderer_native);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1061,9 +1108,24 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
|||||||
if (META_IS_CRTC_KMS (crtc))
|
if (META_IS_CRTC_KMS (crtc))
|
||||||
{
|
{
|
||||||
MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
|
MetaGpuKms *gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
|
||||||
MetaGpuKms *primary_gpu_kms = renderer_native->primary_gpu_kms;
|
|
||||||
MetaOnscreenNative *onscreen_native;
|
MetaOnscreenNative *onscreen_native;
|
||||||
|
|
||||||
|
if (!meta_renderer_native_ensure_gpu_data (renderer_native,
|
||||||
|
gpu_kms,
|
||||||
|
&error))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to create secondary GPU data for %s",
|
||||||
|
meta_gpu_kms_get_file_path (gpu_kms));
|
||||||
|
use_shadowfb = FALSE;
|
||||||
|
framebuffer = create_fallback_offscreen (renderer_native,
|
||||||
|
cogl_context,
|
||||||
|
onscreen_width,
|
||||||
|
onscreen_height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MetaGpuKms *primary_gpu_kms = renderer_native->primary_gpu_kms;
|
||||||
|
|
||||||
onscreen_native = meta_onscreen_native_new (renderer_native,
|
onscreen_native = meta_onscreen_native_new (renderer_native,
|
||||||
primary_gpu_kms,
|
primary_gpu_kms,
|
||||||
output,
|
output,
|
||||||
@ -1076,6 +1138,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
|||||||
{
|
{
|
||||||
g_warning ("Failed to allocate onscreen framebuffer for %s",
|
g_warning ("Failed to allocate onscreen framebuffer for %s",
|
||||||
meta_gpu_kms_get_file_path (gpu_kms));
|
meta_gpu_kms_get_file_path (gpu_kms));
|
||||||
|
use_shadowfb = FALSE;
|
||||||
framebuffer = create_fallback_offscreen (renderer_native,
|
framebuffer = create_fallback_offscreen (renderer_native,
|
||||||
cogl_context,
|
cogl_context,
|
||||||
onscreen_width,
|
onscreen_width,
|
||||||
@ -1088,6 +1151,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
|||||||
framebuffer = COGL_FRAMEBUFFER (onscreen_native);
|
framebuffer = COGL_FRAMEBUFFER (onscreen_native);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CoglOffscreen *virtual_onscreen;
|
CoglOffscreen *virtual_onscreen;
|
||||||
@ -1331,6 +1395,22 @@ meta_renderer_native_ensure_gles3 (MetaRendererNative *renderer_native)
|
|||||||
renderer_native->gles3 = meta_gles3_new (egl);
|
renderer_native->gles3 = meta_gles3_new (egl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
maybe_restore_cogl_egl_api (MetaRendererNative *renderer_native)
|
||||||
|
{
|
||||||
|
CoglContext *cogl_context;
|
||||||
|
CoglDisplay *cogl_display;
|
||||||
|
CoglRenderer *cogl_renderer;
|
||||||
|
|
||||||
|
cogl_context = cogl_context_from_renderer_native (renderer_native);
|
||||||
|
if (!cogl_context)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cogl_display = cogl_context_get_display (cogl_context);
|
||||||
|
cogl_renderer = cogl_display_get_renderer (cogl_display);
|
||||||
|
cogl_renderer_bind_api (cogl_renderer);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
|
init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -1343,13 +1423,15 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
|
|||||||
const char **missing_gl_extensions;
|
const char **missing_gl_extensions;
|
||||||
const char *renderer_str;
|
const char *renderer_str;
|
||||||
|
|
||||||
|
meta_egl_bind_api (egl, EGL_OPENGL_ES_API, NULL);
|
||||||
|
|
||||||
if (!create_secondary_egl_config (egl, renderer_gpu_data->mode, egl_display,
|
if (!create_secondary_egl_config (egl, renderer_gpu_data->mode, egl_display,
|
||||||
&egl_config, error))
|
&egl_config, error))
|
||||||
return FALSE;
|
goto err;
|
||||||
|
|
||||||
egl_context = create_secondary_egl_context (egl, egl_display, egl_config, error);
|
egl_context = create_secondary_egl_context (egl, egl_display, egl_config, error);
|
||||||
if (egl_context == EGL_NO_CONTEXT)
|
if (egl_context == EGL_NO_CONTEXT)
|
||||||
return FALSE;
|
goto err;
|
||||||
|
|
||||||
meta_renderer_native_ensure_gles3 (renderer_native);
|
meta_renderer_native_ensure_gles3 (renderer_native);
|
||||||
|
|
||||||
@ -1361,7 +1443,7 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
|
|||||||
error))
|
error))
|
||||||
{
|
{
|
||||||
meta_egl_destroy_context (egl, egl_display, egl_context, NULL);
|
meta_egl_destroy_context (egl, egl_display, egl_context, NULL);
|
||||||
return FALSE;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer_str = (const char *) glGetString (GL_RENDERER);
|
renderer_str = (const char *) glGetString (GL_RENDERER);
|
||||||
@ -1372,7 +1454,7 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
|
|||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
"Do not want to use software renderer (%s), falling back to CPU copy path",
|
"Do not want to use software renderer (%s), falling back to CPU copy path",
|
||||||
renderer_str);
|
renderer_str);
|
||||||
goto out_fail_with_context;
|
goto err_fail_with_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!meta_gles3_has_extensions (renderer_native->gles3,
|
if (!meta_gles3_has_extensions (renderer_native->gles3,
|
||||||
@ -1390,7 +1472,7 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
|
|||||||
g_free (missing_gl_extensions_str);
|
g_free (missing_gl_extensions_str);
|
||||||
g_free (missing_gl_extensions);
|
g_free (missing_gl_extensions);
|
||||||
|
|
||||||
goto out_fail_with_context;
|
goto err_fail_with_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer_gpu_data->secondary.is_hardware_rendering = TRUE;
|
renderer_gpu_data->secondary.is_hardware_rendering = TRUE;
|
||||||
@ -1403,9 +1485,11 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data,
|
|||||||
"EGL_EXT_image_dma_buf_import_modifiers",
|
"EGL_EXT_image_dma_buf_import_modifiers",
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
maybe_restore_cogl_egl_api (renderer_native);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
out_fail_with_context:
|
err_fail_with_context:
|
||||||
meta_egl_make_current (egl,
|
meta_egl_make_current (egl,
|
||||||
egl_display,
|
egl_display,
|
||||||
EGL_NO_SURFACE,
|
EGL_NO_SURFACE,
|
||||||
@ -1414,6 +1498,9 @@ out_fail_with_context:
|
|||||||
NULL);
|
NULL);
|
||||||
meta_egl_destroy_context (egl, egl_display, egl_context, NULL);
|
meta_egl_destroy_context (egl, egl_display, egl_context, NULL);
|
||||||
|
|
||||||
|
err:
|
||||||
|
maybe_restore_cogl_egl_api (renderer_native);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1874,6 +1961,20 @@ create_renderer_gpu_data (MetaRendererNative *renderer_native,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_renderer_native_ensure_gpu_data (MetaRendererNative *renderer_native,
|
||||||
|
MetaGpuKms *gpu_kms,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||||
|
|
||||||
|
renderer_gpu_data = g_hash_table_lookup (renderer_native->gpu_datas, gpu_kms);
|
||||||
|
if (renderer_gpu_data)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return create_renderer_gpu_data (renderer_native, gpu_kms, error);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_gpu_added (MetaBackendNative *backend_native,
|
on_gpu_added (MetaBackendNative *backend_native,
|
||||||
MetaGpuKms *gpu_kms,
|
MetaGpuKms *gpu_kms,
|
||||||
|
Loading…
Reference in New Issue
Block a user