libweston: Fix crash with mirror-of

Since c4eb15d453 we keep a copy of
native mode parameters, however we forgot to initialize the
native mode parameters in some situations, which breaks the
output mirroring code when it sees uninitialized data.

Fixes c4eb15d453
Fixes #949

Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
This commit is contained in:
Derek Foreman 2024-08-30 07:46:06 -05:00
parent f81c0358c5
commit 50d92f9d6f
6 changed files with 45 additions and 13 deletions

View File

@ -2540,6 +2540,9 @@ wet_output_compute_output_from_mirror(struct weston_output *output,
struct weston_mode *mode, struct weston_mode *mode,
int *scale) int *scale)
{ {
assert(output->native_mode_copy.width);
assert(output->native_mode_copy.height);
mode->width = output->native_mode_copy.width / mode->width = output->native_mode_copy.width /
mirror->current_scale; mirror->current_scale;

View File

@ -912,7 +912,7 @@ drm_output_set_mode(struct weston_output *base,
output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT; output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
/* Set native_ fields, so weston_output_mode_switch_to_native() works */ /* Set native_ fields, so weston_output_mode_switch_to_native() works */
output->base.native_mode = output->base.current_mode; weston_output_copy_native_mode(&output->base, output->base.current_mode);
output->base.native_scale = output->base.current_scale; output->base.native_scale = output->base.current_scale;
return 0; return 0;

View File

@ -1129,7 +1129,8 @@ pipewire_switch_mode(struct weston_output *base, struct weston_mode *target_mode
base->current_mode->flags &= ~WL_OUTPUT_MODE_CURRENT; base->current_mode->flags &= ~WL_OUTPUT_MODE_CURRENT;
base->current_mode = base->native_mode = local_mode; base->current_mode = local_mode;
weston_output_copy_native_mode(base, local_mode);
base->current_mode->flags |= WL_OUTPUT_MODE_CURRENT; base->current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
fb_size.width = target_mode->width; fb_size.width = target_mode->width;
@ -1172,8 +1173,8 @@ pipewire_output_set_size(struct weston_output *base, int width, int height)
current_mode = pipewire_ensure_matching_mode(&output->base, &init_mode); current_mode = pipewire_ensure_matching_mode(&output->base, &init_mode);
current_mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED; current_mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
output->base.current_mode = output->base.native_mode = current_mode; output->base.current_mode = current_mode;
weston_output_copy_native_mode(base, current_mode);
output->base.start_repaint_loop = pipewire_output_start_repaint_loop; output->base.start_repaint_loop = pipewire_output_start_repaint_loop;
output->base.repaint = pipewire_output_repaint; output->base.repaint = pipewire_output_repaint;
output->base.assign_planes = NULL; output->base.assign_planes = NULL;

View File

@ -1182,7 +1182,7 @@ x11_output_set_size(struct weston_output *base, int width, int height)
wl_list_insert(&output->base.mode_list, &output->mode.link); wl_list_insert(&output->base.mode_list, &output->mode.link);
output->base.current_mode = &output->mode; output->base.current_mode = &output->mode;
output->base.native_mode = &output->native; weston_output_copy_native_mode(&output->base, &output->mode);
output->base.native_scale = output->base.current_scale; output->base.native_scale = output->base.current_scale;
return 0; return 0;

View File

@ -525,6 +525,36 @@ static void
weston_compositor_reflow_outputs(struct weston_compositor *compositor, weston_compositor_reflow_outputs(struct weston_compositor *compositor,
struct weston_output *resized_output, int delta_width); struct weston_output *resized_output, int delta_width);
/** Set up the native mode for an output
*
* \param output The weston_output object
* \param mode The new native mode
*
* Our mode setting code does some ugly tricks, and will
* sometimes save pointers to ephemeral structures for
* comparison later.
*
* To work around this fragility, we copy the contents of
* the native mode at set time.
*
* This function will be removed when we fix the mode set
* code.
*
* \ingroup output
* \internal
*/
WL_EXPORT void
weston_output_copy_native_mode(struct weston_output *output,
struct weston_mode *mode)
{
output->native_mode = mode;
output->native_mode_copy.width = mode->width;
output->native_mode_copy.height = mode->height;
output->native_mode_copy.flags = mode->flags;
output->native_mode_copy.aspect_ratio = mode->aspect_ratio;
output->native_mode_copy.refresh = mode->refresh;
}
/** /**
* \ingroup output * \ingroup output
*/ */
@ -552,15 +582,9 @@ weston_output_mode_set_native(struct weston_output *output,
} }
old_width = output->width; old_width = output->width;
output->native_mode = mode; weston_output_copy_native_mode(output, mode);
output->native_scale = scale; output->native_scale = scale;
output->native_mode_copy.width = mode->width;
output->native_mode_copy.height = mode->height;
output->native_mode_copy.flags = mode->flags;
output->native_mode_copy.aspect_ratio = mode->aspect_ratio;
output->native_mode_copy.refresh = mode->refresh;
weston_mode_switch_finish(output, mode_changed, scale_changed); weston_mode_switch_finish(output, mode_changed, scale_changed);
if (mode_changed || scale_changed) { if (mode_changed || scale_changed) {
@ -8053,7 +8077,7 @@ weston_output_set_single_mode(struct weston_output *output,
wl_list_insert(&output->mode_list, &mode->link); wl_list_insert(&output->mode_list, &mode->link);
out: out:
output->current_mode = mode; output->current_mode = mode;
output->native_mode = mode; weston_output_copy_native_mode(output, mode);
if (local) { if (local) {
wl_list_remove(&local->link); wl_list_remove(&local->link);

View File

@ -656,4 +656,8 @@ convert_size_by_transform_scale(int32_t *width_out, int32_t *height_out,
bool bool
weston_authenticate_user(const char *username, const char *password); weston_authenticate_user(const char *username, const char *password);
void
weston_output_copy_native_mode(struct weston_output *output,
struct weston_mode *mode);
#endif #endif