mirror of
https://github.com/brl/mutter.git
synced 2025-02-16 13:24:09 +00:00
wayland/output: Track protocol state for computing changed properties
This makes sure that xdg-output.logical_size and xdg-output.logical_position are only sent when they actually changed. There should be no behavior change in wl_output_transform_from_transform but it now uses the same technique of tracking the protocol state and comparing it to the current state to compute which properties have changed. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3622>
This commit is contained in:
parent
f94e32037c
commit
5690bd3eaa
@ -51,16 +51,17 @@ struct _MetaWaylandOutput
|
|||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
uint32_t mode_flags;
|
|
||||||
float refresh_rate;
|
|
||||||
int scale;
|
|
||||||
MetaMonitorTransform transform;
|
|
||||||
int mode_width;
|
|
||||||
int mode_height;
|
|
||||||
|
|
||||||
GList *resources;
|
GList *resources;
|
||||||
GList *xdg_output_resources;
|
GList *xdg_output_resources;
|
||||||
|
|
||||||
|
/* Protocol state */
|
||||||
|
MtkRectangle layout;
|
||||||
|
CoglSubpixelOrder subpixel_order;
|
||||||
|
MetaMonitorTransform transform;
|
||||||
|
MetaMonitorMode *mode;
|
||||||
|
MetaMonitorMode *preferred_mode;
|
||||||
|
float scale;
|
||||||
|
|
||||||
MetaMonitor *monitor;
|
MetaMonitor *monitor;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -131,17 +132,6 @@ cogl_subpixel_order_to_wl_output_subpixel (CoglSubpixelOrder subpixel_order)
|
|||||||
return WL_OUTPUT_SUBPIXEL_UNKNOWN;
|
return WL_OUTPUT_SUBPIXEL_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
calculate_wayland_output_scale (MetaMonitor *monitor)
|
|
||||||
{
|
|
||||||
MetaLogicalMonitor *logical_monitor;
|
|
||||||
float scale;
|
|
||||||
|
|
||||||
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
|
||||||
scale = meta_logical_monitor_get_scale (logical_monitor);
|
|
||||||
return ceilf (scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum wl_output_transform
|
static enum wl_output_transform
|
||||||
wl_output_transform_from_transform (MetaMonitorTransform transform)
|
wl_output_transform_from_transform (MetaMonitorTransform transform)
|
||||||
{
|
{
|
||||||
@ -174,100 +164,113 @@ send_output_events (struct wl_resource *resource,
|
|||||||
gboolean need_all_events,
|
gboolean need_all_events,
|
||||||
gboolean *pending_done_event)
|
gboolean *pending_done_event)
|
||||||
{
|
{
|
||||||
|
MetaLogicalMonitor *logical_monitor =
|
||||||
|
meta_monitor_get_logical_monitor (monitor);
|
||||||
int version = wl_resource_get_version (resource);
|
int version = wl_resource_get_version (resource);
|
||||||
MetaMonitorMode *current_mode;
|
MtkRectangle layout;
|
||||||
MetaMonitorMode *preferred_mode;
|
MtkRectangle old_layout;
|
||||||
guint mode_flags = WL_OUTPUT_MODE_CURRENT;
|
|
||||||
MetaLogicalMonitor *logical_monitor;
|
|
||||||
MetaLogicalMonitor *old_logical_monitor;
|
|
||||||
guint old_mode_flags;
|
|
||||||
gint old_scale;
|
|
||||||
float old_refresh_rate;
|
|
||||||
float refresh_rate;
|
|
||||||
MetaMonitorTransform old_transform;
|
|
||||||
MetaMonitorTransform transform;
|
MetaMonitorTransform transform;
|
||||||
int new_width, new_height;
|
MetaMonitorTransform old_transform;
|
||||||
|
MetaMonitorMode *mode;
|
||||||
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
MetaMonitorMode *old_mode;
|
||||||
old_logical_monitor =
|
MetaMonitorMode *preferred_mode;
|
||||||
meta_monitor_get_logical_monitor (wayland_output->monitor);
|
MetaMonitorMode *old_preferred_mode;
|
||||||
old_mode_flags = wayland_output->mode_flags;
|
guint mode_flags;
|
||||||
old_scale = wayland_output->scale;
|
guint old_mode_flags;
|
||||||
old_transform = wayland_output->transform;
|
int32_t refresh_rate_khz;
|
||||||
old_refresh_rate = wayland_output->refresh_rate;
|
int32_t old_refresh_rate_khz;
|
||||||
|
int scale_int;
|
||||||
current_mode = meta_monitor_get_current_mode (monitor);
|
int old_scale_int;
|
||||||
refresh_rate = meta_monitor_mode_get_refresh_rate (current_mode);
|
int mode_width, mode_height;
|
||||||
transform = meta_logical_monitor_get_transform (logical_monitor);
|
int old_mode_width, old_mode_height;
|
||||||
|
|
||||||
gboolean need_done = FALSE;
|
gboolean need_done = FALSE;
|
||||||
|
|
||||||
|
layout = meta_logical_monitor_get_layout (logical_monitor);
|
||||||
|
old_layout = wayland_output->layout;
|
||||||
|
|
||||||
|
transform = meta_logical_monitor_get_transform (logical_monitor);
|
||||||
|
old_transform = wayland_output->transform;
|
||||||
|
|
||||||
|
mode = meta_monitor_get_current_mode (monitor);
|
||||||
|
old_mode = wayland_output->mode;
|
||||||
|
|
||||||
|
preferred_mode = meta_monitor_get_preferred_mode (monitor);
|
||||||
|
old_preferred_mode = wayland_output->preferred_mode;
|
||||||
|
|
||||||
|
mode_flags = WL_OUTPUT_MODE_CURRENT;
|
||||||
|
if (mode == preferred_mode)
|
||||||
|
mode_flags |= WL_OUTPUT_MODE_PREFERRED;
|
||||||
|
|
||||||
|
old_mode_flags = WL_OUTPUT_MODE_CURRENT;
|
||||||
|
if (old_mode == old_preferred_mode)
|
||||||
|
old_mode_flags |= WL_OUTPUT_MODE_PREFERRED;
|
||||||
|
|
||||||
|
refresh_rate_khz = meta_monitor_mode_get_refresh_rate (mode) * 1000;
|
||||||
|
old_refresh_rate_khz = meta_monitor_mode_get_refresh_rate (old_mode) * 1000;
|
||||||
|
|
||||||
|
scale_int = ceilf (meta_logical_monitor_get_scale (logical_monitor));
|
||||||
|
old_scale_int = ceilf (wayland_output->scale);
|
||||||
|
|
||||||
|
meta_monitor_mode_get_resolution (mode, &mode_width, &mode_height);
|
||||||
|
meta_monitor_mode_get_resolution (old_mode,
|
||||||
|
&old_mode_width, &old_mode_height);
|
||||||
|
|
||||||
if (need_all_events ||
|
if (need_all_events ||
|
||||||
old_logical_monitor->rect.x != logical_monitor->rect.x ||
|
old_layout.x != layout.x || old_layout.y != layout.y ||
|
||||||
old_logical_monitor->rect.y != logical_monitor->rect.y ||
|
|
||||||
old_transform != transform)
|
old_transform != transform)
|
||||||
{
|
{
|
||||||
int width_mm, height_mm;
|
|
||||||
const char *vendor;
|
const char *vendor;
|
||||||
const char *product;
|
const char *product;
|
||||||
|
int physical_width_mm;
|
||||||
|
int physical_height_mm;
|
||||||
|
CoglSubpixelOrder subpixel_order;
|
||||||
|
enum wl_output_subpixel wl_subpixel_order;
|
||||||
uint32_t wl_transform;
|
uint32_t wl_transform;
|
||||||
CoglSubpixelOrder cogl_subpixel_order;
|
|
||||||
enum wl_output_subpixel subpixel_order;
|
|
||||||
|
|
||||||
meta_monitor_get_physical_dimensions (monitor, &width_mm, &height_mm);
|
|
||||||
vendor = meta_monitor_get_vendor (monitor);
|
vendor = meta_monitor_get_vendor (monitor);
|
||||||
product = meta_monitor_get_product (monitor);
|
product = meta_monitor_get_product (monitor);
|
||||||
|
|
||||||
cogl_subpixel_order = meta_monitor_get_subpixel_order (monitor);
|
meta_monitor_get_physical_dimensions (monitor,
|
||||||
subpixel_order =
|
&physical_width_mm,
|
||||||
cogl_subpixel_order_to_wl_output_subpixel (cogl_subpixel_order);
|
&physical_height_mm);
|
||||||
|
|
||||||
|
subpixel_order = meta_monitor_get_subpixel_order (monitor);
|
||||||
|
wl_subpixel_order =
|
||||||
|
cogl_subpixel_order_to_wl_output_subpixel (subpixel_order);
|
||||||
|
|
||||||
wl_transform = wl_output_transform_from_transform (transform);
|
wl_transform = wl_output_transform_from_transform (transform);
|
||||||
|
|
||||||
wl_output_send_geometry (resource,
|
wl_output_send_geometry (resource,
|
||||||
logical_monitor->rect.x,
|
layout.x,
|
||||||
logical_monitor->rect.y,
|
layout.y,
|
||||||
width_mm,
|
physical_width_mm,
|
||||||
height_mm,
|
physical_height_mm,
|
||||||
subpixel_order,
|
wl_subpixel_order,
|
||||||
vendor ? vendor : "unknown",
|
vendor ? vendor : "unknown",
|
||||||
product ? product : "unknown",
|
product ? product : "unknown",
|
||||||
wl_transform);
|
wl_transform);
|
||||||
need_done = TRUE;
|
need_done = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
preferred_mode = meta_monitor_get_preferred_mode (monitor);
|
|
||||||
if (current_mode == preferred_mode)
|
|
||||||
mode_flags |= WL_OUTPUT_MODE_PREFERRED;
|
|
||||||
|
|
||||||
meta_monitor_mode_get_resolution (current_mode,
|
|
||||||
&new_width,
|
|
||||||
&new_height);
|
|
||||||
if (need_all_events ||
|
if (need_all_events ||
|
||||||
wayland_output->mode_width != new_width ||
|
old_mode_width != mode_width ||
|
||||||
wayland_output->mode_height != new_height ||
|
old_mode_height != mode_height ||
|
||||||
old_refresh_rate != refresh_rate ||
|
old_refresh_rate_khz != refresh_rate_khz ||
|
||||||
old_mode_flags != mode_flags)
|
old_mode_flags != mode_flags)
|
||||||
{
|
{
|
||||||
wl_output_send_mode (resource,
|
wl_output_send_mode (resource,
|
||||||
mode_flags,
|
mode_flags,
|
||||||
new_width,
|
mode_width,
|
||||||
new_height,
|
mode_height,
|
||||||
(int32_t) (refresh_rate * 1000));
|
refresh_rate_khz);
|
||||||
need_done = TRUE;
|
need_done = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION &&
|
||||||
|
(need_all_events || old_scale_int != scale_int))
|
||||||
{
|
{
|
||||||
int scale;
|
wl_output_send_scale (resource, scale_int);
|
||||||
|
need_done = TRUE;
|
||||||
scale = calculate_wayland_output_scale (monitor);
|
|
||||||
if (need_all_events ||
|
|
||||||
old_scale != scale)
|
|
||||||
{
|
|
||||||
wl_output_send_scale (resource, scale);
|
|
||||||
need_done = TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_all_events && version >= WL_OUTPUT_NAME_SINCE_VERSION)
|
if (need_all_events && version >= WL_OUTPUT_NAME_SINCE_VERSION)
|
||||||
@ -309,6 +312,7 @@ bind_output (struct wl_client *client,
|
|||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
#ifdef WITH_VERBOSE_MODE
|
#ifdef WITH_VERBOSE_MODE
|
||||||
MetaLogicalMonitor *logical_monitor;
|
MetaLogicalMonitor *logical_monitor;
|
||||||
|
int mode_width, mode_height;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
resource = wl_resource_create (client, &wl_output_interface, version, id);
|
resource = wl_resource_create (client, &wl_output_interface, version, id);
|
||||||
@ -331,13 +335,14 @@ bind_output (struct wl_client *client,
|
|||||||
|
|
||||||
#ifdef WITH_VERBOSE_MODE
|
#ifdef WITH_VERBOSE_MODE
|
||||||
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
||||||
|
meta_monitor_mode_get_resolution (wayland_output->mode, &mode_width, &mode_height);
|
||||||
|
|
||||||
meta_verbose ("Binding monitor %p/%s (%u, %u, %u, %u) x %f",
|
meta_verbose ("Binding monitor %p/%s (%u, %u, %u, %u) x %f",
|
||||||
logical_monitor,
|
logical_monitor,
|
||||||
meta_monitor_get_product (monitor),
|
meta_monitor_get_product (monitor),
|
||||||
logical_monitor->rect.x, logical_monitor->rect.y,
|
wayland_output->layout.x, wayland_output->layout.y,
|
||||||
wayland_output->mode_width,
|
mode_width, mode_height,
|
||||||
wayland_output->mode_height,
|
meta_monitor_mode_get_refresh_rate (wayland_output->mode));
|
||||||
wayland_output->refresh_rate);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
send_output_events (resource, wayland_output, monitor, TRUE, NULL);
|
send_output_events (resource, wayland_output, monitor, TRUE, NULL);
|
||||||
@ -349,28 +354,18 @@ static void
|
|||||||
meta_wayland_output_set_monitor (MetaWaylandOutput *wayland_output,
|
meta_wayland_output_set_monitor (MetaWaylandOutput *wayland_output,
|
||||||
MetaMonitor *monitor)
|
MetaMonitor *monitor)
|
||||||
{
|
{
|
||||||
MetaMonitorMode *current_mode;
|
|
||||||
MetaMonitorMode *preferred_mode;
|
|
||||||
MetaLogicalMonitor *logical_monitor;
|
MetaLogicalMonitor *logical_monitor;
|
||||||
|
|
||||||
wayland_output->monitor = monitor;
|
wayland_output->monitor = monitor;
|
||||||
wayland_output->mode_flags = WL_OUTPUT_MODE_CURRENT;
|
|
||||||
|
|
||||||
current_mode = meta_monitor_get_current_mode (monitor);
|
|
||||||
preferred_mode = meta_monitor_get_preferred_mode (monitor);
|
|
||||||
|
|
||||||
if (current_mode == preferred_mode)
|
|
||||||
wayland_output->mode_flags |= WL_OUTPUT_MODE_PREFERRED;
|
|
||||||
wayland_output->scale = calculate_wayland_output_scale (monitor);
|
|
||||||
wayland_output->refresh_rate = meta_monitor_mode_get_refresh_rate (current_mode);
|
|
||||||
|
|
||||||
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
||||||
|
wayland_output->layout = meta_logical_monitor_get_layout (logical_monitor);
|
||||||
|
wayland_output->subpixel_order = meta_monitor_get_subpixel_order (monitor);
|
||||||
wayland_output->transform =
|
wayland_output->transform =
|
||||||
meta_logical_monitor_get_transform (logical_monitor);
|
meta_logical_monitor_get_transform (logical_monitor);
|
||||||
|
wayland_output->mode = meta_monitor_get_current_mode (monitor);
|
||||||
meta_monitor_mode_get_resolution (current_mode,
|
wayland_output->preferred_mode = meta_monitor_get_preferred_mode (monitor);
|
||||||
&wayland_output->mode_width,
|
wayland_output->scale = meta_logical_monitor_get_scale (logical_monitor);
|
||||||
&wayland_output->mode_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -608,17 +603,29 @@ send_xdg_output_events (struct wl_resource *resource,
|
|||||||
gboolean need_all_events,
|
gboolean need_all_events,
|
||||||
gboolean *pending_done_event)
|
gboolean *pending_done_event)
|
||||||
{
|
{
|
||||||
|
MetaLogicalMonitor *logical_monitor =
|
||||||
|
meta_monitor_get_logical_monitor (monitor);
|
||||||
|
int version = wl_resource_get_version (resource);
|
||||||
MtkRectangle layout;
|
MtkRectangle layout;
|
||||||
MetaLogicalMonitor *logical_monitor;
|
MtkRectangle old_layout;
|
||||||
int version;
|
gboolean need_done = FALSE;
|
||||||
|
|
||||||
logical_monitor = meta_monitor_get_logical_monitor (monitor);
|
|
||||||
layout = meta_logical_monitor_get_layout (logical_monitor);
|
layout = meta_logical_monitor_get_layout (logical_monitor);
|
||||||
|
old_layout = wayland_output->layout;
|
||||||
|
|
||||||
zxdg_output_v1_send_logical_position (resource, layout.x, layout.y);
|
if (need_all_events ||
|
||||||
zxdg_output_v1_send_logical_size (resource, layout.width, layout.height);
|
old_layout.x != layout.x || old_layout.y != layout.y)
|
||||||
|
{
|
||||||
|
zxdg_output_v1_send_logical_position (resource, layout.x, layout.y);
|
||||||
|
need_done = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
version = wl_resource_get_version (resource);
|
if (need_all_events ||
|
||||||
|
old_layout.width != layout.width || old_layout.height != layout.height)
|
||||||
|
{
|
||||||
|
zxdg_output_v1_send_logical_size (resource, layout.width, layout.height);
|
||||||
|
need_done = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (need_all_events && version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
|
if (need_all_events && version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
|
||||||
{
|
{
|
||||||
@ -626,6 +633,7 @@ send_xdg_output_events (struct wl_resource *resource,
|
|||||||
|
|
||||||
name = meta_monitor_get_connector (monitor);
|
name = meta_monitor_get_connector (monitor);
|
||||||
zxdg_output_v1_send_name (resource, name);
|
zxdg_output_v1_send_name (resource, name);
|
||||||
|
need_done = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_all_events && version >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION)
|
if (need_all_events && version >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION)
|
||||||
@ -634,9 +642,10 @@ send_xdg_output_events (struct wl_resource *resource,
|
|||||||
|
|
||||||
description = meta_monitor_get_display_name (monitor);
|
description = meta_monitor_get_display_name (monitor);
|
||||||
zxdg_output_v1_send_description (resource, description);
|
zxdg_output_v1_send_description (resource, description);
|
||||||
|
need_done = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pending_done_event)
|
if (pending_done_event && need_done)
|
||||||
*pending_done_event = TRUE;
|
*pending_done_event = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user