kms: Only emit resources-changed signal if we recorded a change

Since we cache already all the KMS parameters we care about let's check at
each device update if anything has really changed and only in such case
emit a resources-changed signal.

In this way we can also filter out the DRM parameters that when changed
don't require a full monitors rebuild.

Examples are the gamma settings or the privacy screen parameters, that
emits an udev "hotplug" event when changed, but we want to register those
only when we handle the changed property.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1964>
This commit is contained in:
Marco Trevisan (Treviño) 2020-07-31 21:37:17 +02:00 committed by Marge Bot
parent d2eec866ed
commit a8d11161b6
16 changed files with 364 additions and 93 deletions

View File

@ -463,3 +463,37 @@ meta_output_class_init (MetaOutputClass *klass)
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, obj_props);
}
gboolean
meta_tile_info_equal (MetaTileInfo *a,
MetaTileInfo *b)
{
if (a == b)
return TRUE;
if (a->group_id != b->group_id)
return FALSE;
if (a->flags != b->flags)
return FALSE;
if (a->max_h_tiles != b->max_h_tiles)
return FALSE;
if (a->max_v_tiles != b->max_v_tiles)
return FALSE;
if (a->loc_h_tile != b->loc_h_tile)
return FALSE;
if (a->loc_v_tile != b->loc_v_tile)
return FALSE;
if (a->tile_w != b->tile_w)
return FALSE;
if (a->tile_h != b->tile_h)
return FALSE;
return TRUE;
}

View File

@ -106,6 +106,10 @@ typedef struct _MetaOutputInfo
MetaTileInfo tile_info;
} MetaOutputInfo;
gboolean
meta_tile_info_equal (MetaTileInfo *a,
MetaTileInfo *b);
#define META_TYPE_OUTPUT_INFO (meta_output_info_get_type ())
META_EXPORT_TEST
GType meta_output_info_get_type (void);

View File

@ -62,9 +62,6 @@ void meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms,
MetaCrtcMode * meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms,
MetaKmsMode *kms_mode);
gboolean meta_drm_mode_equal (const drmModeModeInfo *one,
const drmModeModeInfo *two);
MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms,
MetaCrtc *crtc,
GClosure *flip_closure);

View File

@ -38,8 +38,8 @@ uint32_t meta_kms_connector_get_prop_id (MetaKmsConnector *connector,
const char * meta_kms_connector_get_prop_name (MetaKmsConnector *connector,
MetaKmsConnectorProp prop);
void meta_kms_connector_update_state (MetaKmsConnector *connector,
drmModeRes *drm_resources);
MetaKmsUpdateChanges meta_kms_connector_update_state (MetaKmsConnector *connector,
drmModeRes *drm_resources);
void meta_kms_connector_predict_state (MetaKmsConnector *connector,
MetaKmsUpdate *update);

View File

@ -46,6 +46,7 @@ struct _MetaKmsConnector
uint32_t type_id;
char *name;
drmModeConnection connection;
MetaKmsConnectorState *current_state;
MetaKmsConnectorPropTable prop_table;
@ -467,18 +468,116 @@ meta_kms_connector_state_free (MetaKmsConnectorState *state)
g_free (state);
}
static void
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsConnectorState,
meta_kms_connector_state_free);
static gboolean
kms_modes_equal (GList *modes,
GList *other_modes)
{
GList *l;
if (g_list_length (modes) != g_list_length (other_modes))
return FALSE;
for (l = modes; l; l = l->next)
{
GList *k;
MetaKmsMode *mode = l->data;
for (k = other_modes; k; k = k->next)
{
MetaKmsMode *other_mode = k->data;
if (!meta_kms_mode_equal (mode, other_mode))
return FALSE;
}
}
return TRUE;
}
static MetaKmsUpdateChanges
meta_kms_connector_state_changes (MetaKmsConnectorState *state,
MetaKmsConnectorState *new_state)
{
if (state->current_crtc_id != new_state->current_crtc_id)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->common_possible_crtcs != new_state->common_possible_crtcs)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->common_possible_clones != new_state->common_possible_clones)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->encoder_device_idxs != new_state->encoder_device_idxs)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->width_mm != new_state->width_mm)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->height_mm != new_state->height_mm)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->has_scaling != new_state->has_scaling)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->non_desktop != new_state->non_desktop)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->subpixel_order != new_state->subpixel_order)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->suggested_x != new_state->suggested_x)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->suggested_y != new_state->suggested_y)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->hotplug_mode_update != new_state->hotplug_mode_update)
return META_KMS_UPDATE_CHANGE_FULL;
if (state->panel_orientation_transform !=
new_state->panel_orientation_transform)
return META_KMS_UPDATE_CHANGE_FULL;
if (!meta_tile_info_equal (&state->tile_info, &new_state->tile_info))
return META_KMS_UPDATE_CHANGE_FULL;
if ((state->edid_data && !new_state->edid_data) || !state->edid_data ||
!g_bytes_equal (state->edid_data, new_state->edid_data))
return META_KMS_UPDATE_CHANGE_FULL;
if (!kms_modes_equal (state->modes, new_state->modes))
return META_KMS_UPDATE_CHANGE_FULL;
return META_KMS_UPDATE_CHANGE_NONE;
}
static MetaKmsUpdateChanges
meta_kms_connector_read_state (MetaKmsConnector *connector,
MetaKmsImplDevice *impl_device,
drmModeConnector *drm_connector,
drmModeRes *drm_resources)
{
MetaKmsConnectorState *state;
g_autoptr (MetaKmsConnectorState) state = NULL;
g_autoptr (MetaKmsConnectorState) current_state = NULL;
MetaKmsUpdateChanges connector_changes;
MetaKmsUpdateChanges changes;
g_clear_pointer (&connector->current_state, meta_kms_connector_state_free);
current_state = g_steal_pointer (&connector->current_state);
changes = META_KMS_UPDATE_CHANGE_NONE;
if (!drm_connector || drm_connector->connection != DRM_MODE_CONNECTED)
return;
if (drm_connector->connection != DRM_MODE_CONNECTED)
{
if (drm_connector->connection != connector->connection)
{
connector->connection = drm_connector->connection;
changes |= META_KMS_UPDATE_CHANGE_FULL;
}
return changes;
}
state = meta_kms_connector_state_new ();
@ -495,26 +594,54 @@ meta_kms_connector_read_state (MetaKmsConnector *connector,
state_set_crtc_state (state, drm_connector, impl_device, drm_resources);
connector->current_state = state;
if (drm_connector->connection != connector->connection)
{
connector->connection = drm_connector->connection;
changes |= META_KMS_UPDATE_CHANGE_FULL;
}
sync_fd_held (connector, impl_device);
if (!current_state)
connector_changes = META_KMS_UPDATE_CHANGE_FULL;
else
connector_changes = meta_kms_connector_state_changes (current_state, state);
if (connector_changes == META_KMS_UPDATE_CHANGE_NONE)
{
connector->current_state = g_steal_pointer (&current_state);
}
else
{
connector->current_state = g_steal_pointer (&state);
changes |= connector_changes;
}
if (changes != META_KMS_UPDATE_CHANGE_NONE)
sync_fd_held (connector, impl_device);
return changes;
}
void
MetaKmsUpdateChanges
meta_kms_connector_update_state (MetaKmsConnector *connector,
drmModeRes *drm_resources)
{
MetaKmsImplDevice *impl_device;
drmModeConnector *drm_connector;
MetaKmsUpdateChanges changes;
impl_device = meta_kms_device_get_impl_device (connector->device);
drm_connector = drmModeGetConnector (meta_kms_impl_device_get_fd (impl_device),
connector->id);
meta_kms_connector_read_state (connector, impl_device,
drm_connector,
drm_resources);
if (drm_connector)
drmModeFreeConnector (drm_connector);
if (!drm_connector)
return META_KMS_UPDATE_CHANGE_FULL;
changes = meta_kms_connector_read_state (connector, impl_device,
drm_connector,
drm_resources);
drmModeFreeConnector (drm_connector);
return changes;
}
void
@ -651,6 +778,7 @@ meta_kms_connector_new (MetaKmsImplDevice *impl_device,
{
MetaKmsConnector *connector;
g_assert (drm_connector);
connector = g_object_new (META_TYPE_KMS_CONNECTOR, NULL);
connector->device = meta_kms_impl_device_get_device (impl_device);
connector->id = drm_connector->connector_id;

View File

@ -23,6 +23,7 @@
#include <xf86drmMode.h>
#include "backends/native/meta-kms-crtc.h"
#include "backends/native/meta-kms-update-private.h"
typedef enum _MetaKmsCrtcProp
{
@ -37,7 +38,7 @@ MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
int idx,
GError **error);
void meta_kms_crtc_update_state (MetaKmsCrtc *crtc);
MetaKmsUpdateChanges meta_kms_crtc_update_state (MetaKmsCrtc *crtc);
void meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
MetaKmsUpdate *update);

View File

@ -94,32 +94,62 @@ meta_kms_crtc_is_active (MetaKmsCrtc *crtc)
static void
read_gamma_state (MetaKmsCrtc *crtc,
MetaKmsCrtcState *crtc_state,
MetaKmsImplDevice *impl_device,
drmModeCrtc *drm_crtc)
{
MetaKmsCrtcState *current_state = &crtc->current_state;
if (current_state->gamma.size != drm_crtc->gamma_size)
if (crtc_state->gamma.size != drm_crtc->gamma_size)
{
current_state->gamma.size = drm_crtc->gamma_size;
crtc_state->gamma.size = drm_crtc->gamma_size;
current_state->gamma.red = g_realloc_n (current_state->gamma.red,
drm_crtc->gamma_size,
sizeof (uint16_t));
current_state->gamma.green = g_realloc_n (current_state->gamma.green,
drm_crtc->gamma_size,
sizeof (uint16_t));
current_state->gamma.blue = g_realloc_n (current_state->gamma.blue,
drm_crtc->gamma_size,
sizeof (uint16_t));
crtc_state->gamma.red = g_realloc_n (crtc_state->gamma.red,
drm_crtc->gamma_size,
sizeof (uint16_t));
crtc_state->gamma.green = g_realloc_n (crtc_state->gamma.green,
drm_crtc->gamma_size,
sizeof (uint16_t));
crtc_state->gamma.blue = g_realloc_n (crtc_state->gamma.blue,
drm_crtc->gamma_size,
sizeof (uint16_t));
}
drmModeCrtcGetGamma (meta_kms_impl_device_get_fd (impl_device),
crtc->id,
current_state->gamma.size,
current_state->gamma.red,
current_state->gamma.green,
current_state->gamma.blue);
crtc_state->gamma.size,
crtc_state->gamma.red,
crtc_state->gamma.green,
crtc_state->gamma.blue);
}
static MetaKmsUpdateChanges
meta_kms_crtc_state_changes (MetaKmsCrtcState *state,
MetaKmsCrtcState *other_state)
{
if (!meta_rectangle_equal (&state->rect, &other_state->rect))
return META_KMS_UPDATE_CHANGE_FULL;
if (state->is_drm_mode_valid != other_state->is_drm_mode_valid)
return META_KMS_UPDATE_CHANGE_FULL;
if (!meta_drm_mode_equal (&state->drm_mode, &other_state->drm_mode))
return META_KMS_UPDATE_CHANGE_FULL;
if (state->gamma.size != other_state->gamma.size)
return META_KMS_UPDATE_CHANGE_GAMMA;
if (memcmp (state->gamma.blue, other_state->gamma.blue,
state->gamma.size * sizeof (uint16_t)) != 0)
return META_KMS_UPDATE_CHANGE_GAMMA;
if (memcmp (state->gamma.green, other_state->gamma.green,
state->gamma.size * sizeof (uint16_t)) != 0)
return META_KMS_UPDATE_CHANGE_GAMMA;
if (memcmp (state->gamma.red, other_state->gamma.red,
state->gamma.size * sizeof (uint16_t)) != 0)
return META_KMS_UPDATE_CHANGE_GAMMA;
return META_KMS_UPDATE_CHANGE_NONE;
}
static int
@ -141,23 +171,35 @@ find_prop_idx (MetaKmsProp *prop,
}
static void
clear_gamma_state (MetaKmsCrtcState *crtc_state)
{
crtc_state->gamma.size = 0;
g_clear_pointer (&crtc_state->gamma.red, g_free);
g_clear_pointer (&crtc_state->gamma.green, g_free);
g_clear_pointer (&crtc_state->gamma.blue, g_free);
}
static MetaKmsUpdateChanges
meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
MetaKmsImplDevice *impl_device,
drmModeCrtc *drm_crtc,
drmModeObjectProperties *drm_props)
{
MetaKmsCrtcState crtc_state = {0};
MetaKmsUpdateChanges changes = META_KMS_UPDATE_CHANGE_NONE;
MetaKmsProp *active_prop;
int active_idx;
crtc->current_state.rect = (MetaRectangle) {
crtc_state.rect = (MetaRectangle) {
.x = drm_crtc->x,
.y = drm_crtc->y,
.width = drm_crtc->width,
.height = drm_crtc->height,
};
crtc->current_state.is_drm_mode_valid = drm_crtc->mode_valid;
crtc->current_state.drm_mode = drm_crtc->mode;
crtc_state.is_drm_mode_valid = drm_crtc->mode_valid;
crtc_state.drm_mode = drm_crtc->mode;
crtc_state.gamma.size = 0;
active_prop = &crtc->prop_table.props[META_KMS_CRTC_PROP_ACTIVE];
if (active_prop->prop_id)
@ -165,13 +207,36 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
active_idx = find_prop_idx (active_prop,
drm_props->props,
drm_props->count_props);
crtc->current_state.is_active = !!drm_props->prop_values[active_idx];
crtc_state.is_active = !!drm_props->prop_values[active_idx];
}
else
{
crtc->current_state.is_active = drm_crtc->mode_valid;
crtc_state.is_active = drm_crtc->mode_valid;
}
if (crtc_state.is_active != crtc->current_state.is_active)
{
changes |= META_KMS_UPDATE_CHANGE_FULL;
}
else if (!crtc_state.is_active)
{
clear_gamma_state (&crtc_state);
return changes;
}
read_gamma_state (crtc, &crtc_state, impl_device, drm_crtc);
changes |= meta_kms_crtc_state_changes (&crtc->current_state, &crtc_state);
if (changes == META_KMS_UPDATE_CHANGE_NONE)
{
clear_gamma_state (&crtc_state);
return changes;
}
clear_gamma_state (&crtc->current_state);
crtc->current_state = crtc_state;
meta_topic (META_DEBUG_KMS,
"Read CRTC %u state: active: %d, mode: %s",
crtc->id, crtc->current_state.is_active,
@ -179,13 +244,14 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
? crtc->current_state.drm_mode.name
: "(nil)");
read_gamma_state (crtc, impl_device, drm_crtc);
return changes;
}
void
MetaKmsUpdateChanges
meta_kms_crtc_update_state (MetaKmsCrtc *crtc)
{
MetaKmsImplDevice *impl_device;
MetaKmsUpdateChanges changes;
int fd;
drmModeCrtc *drm_crtc;
drmModeObjectProperties *drm_props;
@ -201,23 +267,17 @@ meta_kms_crtc_update_state (MetaKmsCrtc *crtc)
crtc->current_state.is_active = FALSE;
crtc->current_state.rect = (MetaRectangle) { };
crtc->current_state.is_drm_mode_valid = FALSE;
changes = META_KMS_UPDATE_CHANGE_FULL;
goto out;
}
meta_kms_crtc_read_state (crtc, impl_device, drm_crtc, drm_props);
changes = meta_kms_crtc_read_state (crtc, impl_device, drm_crtc, drm_props);
out:
g_clear_pointer (&drm_props, drmModeFreeObjectProperties);
g_clear_pointer (&drm_crtc, drmModeFreeCrtc);
}
static void
clear_gamma_state (MetaKmsCrtc *crtc)
{
crtc->current_state.gamma.size = 0;
g_clear_pointer (&crtc->current_state.gamma.red, g_free);
g_clear_pointer (&crtc->current_state.gamma.green, g_free);
g_clear_pointer (&crtc->current_state.gamma.blue, g_free);
return changes;
}
void
@ -270,7 +330,7 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
if (gamma->crtc != crtc)
continue;
clear_gamma_state (crtc);
clear_gamma_state (&crtc->current_state);
crtc->current_state.gamma.size = gamma->size;
crtc->current_state.gamma.red =
g_memdup2 (gamma->red, gamma->size * sizeof (uint16_t));
@ -380,7 +440,7 @@ meta_kms_crtc_finalize (GObject *object)
{
MetaKmsCrtc *crtc = META_KMS_CRTC (object);
clear_gamma_state (crtc);
clear_gamma_state (&crtc->current_state);
G_OBJECT_CLASS (meta_kms_crtc_parent_class)->finalize (object);
}
@ -388,6 +448,7 @@ meta_kms_crtc_finalize (GObject *object)
static void
meta_kms_crtc_init (MetaKmsCrtc *crtc)
{
crtc->current_state.gamma.size = 0;
}
static void

View File

@ -21,10 +21,11 @@
#define META_KMS_DEVICE_PRIVATE_H
#include "backends/native/meta-kms-types.h"
#include "backends/native/meta-kms-update-private.h"
MetaKmsImplDevice * meta_kms_device_get_impl_device (MetaKmsDevice *device);
void meta_kms_device_update_states_in_impl (MetaKmsDevice *device);
MetaKmsUpdateChanges meta_kms_device_update_states_in_impl (MetaKmsDevice *device);
void meta_kms_device_predict_states_in_impl (MetaKmsDevice *device,
MetaKmsUpdate *update);

View File

@ -186,15 +186,19 @@ meta_kms_device_get_fallback_modes (MetaKmsDevice *device)
return device->fallback_modes;
}
void
MetaKmsUpdateChanges
meta_kms_device_update_states_in_impl (MetaKmsDevice *device)
{
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
MetaKmsUpdateChanges changes;
meta_assert_in_kms_impl (device->kms);
meta_assert_is_waiting_for_kms_impl_task (device->kms);
meta_kms_impl_device_update_states (impl_device);
changes = meta_kms_impl_device_update_states (impl_device);
if (changes == META_KMS_UPDATE_CHANGE_NONE)
return changes;
g_list_free (device->crtcs);
device->crtcs = meta_kms_impl_device_copy_crtcs (impl_device);
@ -204,6 +208,8 @@ meta_kms_device_update_states_in_impl (MetaKmsDevice *device)
g_list_free (device->planes);
device->planes = meta_kms_impl_device_copy_planes (impl_device);
return changes;
}
void

View File

@ -36,7 +36,6 @@
#include "backends/native/meta-kms-plane-private.h"
#include "backends/native/meta-kms-plane.h"
#include "backends/native/meta-kms-private.h"
#include "backends/native/meta-kms-update-private.h"
#include "meta-default-modes.h"
#include "meta-private-enum-types.h"
@ -390,13 +389,14 @@ find_existing_connector (MetaKmsImplDevice *impl_device,
return NULL;
}
static void
static MetaKmsUpdateChanges
update_connectors (MetaKmsImplDevice *impl_device,
drmModeRes *drm_resources)
{
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
GList *connectors = NULL;
g_autolist (MetaKmsConnector) connectors = NULL;
gboolean needs_full_change = FALSE;
unsigned int i;
int fd;
@ -413,17 +413,28 @@ update_connectors (MetaKmsImplDevice *impl_device,
connector = find_existing_connector (impl_device, drm_connector);
if (connector)
connector = g_object_ref (connector);
{
connector = g_object_ref (connector);
}
else
connector = meta_kms_connector_new (impl_device, drm_connector,
drm_resources);
{
connector = meta_kms_connector_new (impl_device, drm_connector,
drm_resources);
needs_full_change = TRUE;
}
drmModeFreeConnector (drm_connector);
connectors = g_list_prepend (connectors, connector);
}
if (!needs_full_change)
return META_KMS_UPDATE_CHANGE_NONE;
g_list_free_full (priv->connectors, g_object_unref);
priv->connectors = g_list_reverse (connectors);
priv->connectors = g_list_reverse (g_steal_pointer (&connectors));
return META_KMS_UPDATE_CHANGE_FULL;
}
static MetaKmsPlaneType
@ -690,7 +701,7 @@ clear_latched_fd_hold (MetaKmsImplDevice *impl_device)
}
}
void
MetaKmsUpdateChanges
meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDevicePrivate *priv =
@ -698,6 +709,8 @@ meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
g_autoptr (GError) error = NULL;
int fd;
drmModeRes *drm_resources;
MetaKmsUpdateChanges changes;
GList *l;
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
@ -720,20 +733,25 @@ meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
goto err;
}
update_connectors (impl_device, drm_resources);
changes = update_connectors (impl_device, drm_resources);
for (l = priv->crtcs; l; l = l->next)
changes |= meta_kms_crtc_update_state (META_KMS_CRTC (l->data));
for (l = priv->connectors; l; l = l->next)
changes |= meta_kms_connector_update_state (META_KMS_CONNECTOR (l->data),
drm_resources);
g_list_foreach (priv->crtcs, (GFunc) meta_kms_crtc_update_state,
NULL);
g_list_foreach (priv->connectors, (GFunc) meta_kms_connector_update_state,
drm_resources);
drmModeFreeResources (drm_resources);
return;
return changes;
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);
return META_KMS_UPDATE_CHANGE_FULL;
}
void

View File

@ -135,7 +135,7 @@ 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);
MetaKmsUpdateChanges meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device);
void meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update);

View File

@ -73,7 +73,7 @@ meta_kms_mode_get_drm_mode (MetaKmsMode *mode)
return &mode->drm_mode;
}
static gboolean
gboolean
meta_drm_mode_equal (const drmModeModeInfo *one,
const drmModeModeInfo *two)
{

View File

@ -42,6 +42,9 @@ const drmModeModeInfo * meta_kms_mode_get_drm_mode (MetaKmsMode *mode);
gboolean meta_kms_mode_equal (MetaKmsMode *mode,
MetaKmsMode *other_mode);
gboolean meta_drm_mode_equal (const drmModeModeInfo *one,
const drmModeModeInfo *two);
unsigned int meta_kms_mode_hash (MetaKmsMode *mode);
#endif /* META_KMS_MODE_H */

View File

@ -64,6 +64,13 @@ typedef enum _MetaKmsDeviceFlag
META_KMS_DEVICE_FLAG_NO_MODE_SETTING = 1 << 4,
} MetaKmsDeviceFlag;
typedef enum _MetaKmsUpdateChanges
{
META_KMS_UPDATE_CHANGE_NONE = 0,
META_KMS_UPDATE_CHANGE_GAMMA = 1 << 0,
META_KMS_UPDATE_CHANGE_FULL = -1,
} MetaKmsUpdateChanges;
typedef enum _MetaKmsPlaneType MetaKmsPlaneType;
typedef enum _MetaKmsPropType

View File

@ -29,6 +29,8 @@
#include "backends/native/meta-udev.h"
#include "cogl/cogl.h"
#include "meta-private-enum-types.h"
/**
* SECTION:kms
* @short description: KMS abstraction
@ -563,17 +565,25 @@ meta_kms_is_waiting_for_impl_task (MetaKms *kms)
return kms->waiting_for_impl_task;
}
static void
meta_kms_update_states_in_impl (MetaKms *kms)
static MetaKmsUpdateChanges
meta_kms_update_states_in_impl (MetaKms *kms)
{
MetaKmsUpdateChanges changes = META_KMS_UPDATE_CHANGE_NONE;
GList *l;
COGL_TRACE_BEGIN_SCOPED (MetaKmsUpdateStates,
"KMS (update states)");
meta_assert_in_kms_impl (kms);
g_list_foreach (kms->devices,
(GFunc) meta_kms_device_update_states_in_impl,
NULL);
for (l = kms->devices; l; l = l->next)
{
MetaKmsDevice *kms_device = META_KMS_DEVICE (l->data);
changes |= meta_kms_device_update_states_in_impl (kms_device);
}
return changes;
}
static gpointer
@ -583,30 +593,27 @@ update_states_in_impl (MetaKmsImpl *impl,
{
MetaKms *kms = meta_kms_impl_get_kms (impl);
meta_kms_update_states_in_impl (kms);
return GINT_TO_POINTER (TRUE);
return GUINT_TO_POINTER (meta_kms_update_states_in_impl (kms));
}
static gboolean
meta_kms_update_states_sync (MetaKms *kms,
GError **error)
static MetaKmsUpdateChanges
meta_kms_update_states_sync (MetaKms *kms)
{
gpointer ret;
ret = meta_kms_run_impl_task_sync (kms, update_states_in_impl, NULL, error);
return GPOINTER_TO_INT (ret);
ret = meta_kms_run_impl_task_sync (kms, update_states_in_impl, NULL, NULL);
return GPOINTER_TO_UINT (ret);
}
static void
handle_hotplug_event (MetaKms *kms)
{
g_autoptr (GError) error = NULL;
MetaKmsUpdateChanges changes;
if (!meta_kms_update_states_sync (kms, &error))
g_warning ("Updating KMS state failed: %s", error->message);
changes = meta_kms_update_states_sync (kms);
g_signal_emit (kms, signals[RESOURCES_CHANGED], 0);
if (changes != META_KMS_UPDATE_CHANGE_NONE)
g_signal_emit (kms, signals[RESOURCES_CHANGED], 0, changes);
}
void
@ -750,5 +757,6 @@ meta_kms_class_init (MetaKmsClass *klass)
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
G_TYPE_NONE, 1,
META_TYPE_KMS_UPDATE_CHANGES);
}

View File

@ -508,9 +508,12 @@ handle_hotplug_event (MetaMonitorManager *manager)
}
static void
on_kms_resources_changed (MetaKms *kms,
MetaMonitorManager *manager)
on_kms_resources_changed (MetaKms *kms,
MetaKmsUpdateChanges changes,
MetaMonitorManager *manager)
{
g_assert (changes != META_KMS_UPDATE_CHANGE_NONE);
handle_hotplug_event (manager);
}