Backport fix for software cursors artifacts
Resolves: RHEL-58079 Resolves: RHEL-81897
This commit is contained in:
parent
7d87e29721
commit
efbeeeb09a
178
0001-backends-Update-stage-views-and-stage-dimension-from.patch
Normal file
178
0001-backends-Update-stage-views-and-stage-dimension-from.patch
Normal file
@ -0,0 +1,178 @@
|
||||
From cedeee4eb0c252d2450b7174b35f47ff5c27fc8e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Wed, 12 Mar 2025 11:35:17 +0800
|
||||
Subject: [PATCH 1/2] backends: Update stage views and stage dimension from
|
||||
MetaStage
|
||||
|
||||
This reduces the amount of code duplication between the native and
|
||||
nested backend.
|
||||
---
|
||||
src/backends/meta-stage-impl-private.h | 2 ++
|
||||
src/backends/meta-stage-impl.c | 12 ++++++++++++
|
||||
src/backends/meta-stage-private.h | 2 ++
|
||||
src/backends/meta-stage.c | 16 ++++++++++++++++
|
||||
src/backends/native/meta-backend-native.c | 5 +----
|
||||
src/backends/native/meta-stage-native.c | 12 ------------
|
||||
src/backends/native/meta-stage-native.h | 2 --
|
||||
.../x11/nested/meta-backend-x11-nested.c | 11 ++---------
|
||||
8 files changed, 35 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/src/backends/meta-stage-impl-private.h b/src/backends/meta-stage-impl-private.h
|
||||
index 766c283488..93b8bbad2f 100644
|
||||
--- a/src/backends/meta-stage-impl-private.h
|
||||
+++ b/src/backends/meta-stage-impl-private.h
|
||||
@@ -64,4 +64,6 @@ MetaBackend * meta_stage_impl_get_backend (MetaStageImpl *stage_impl);
|
||||
void meta_stage_impl_add_onscreen_frame_info (MetaStageImpl *stage_impl,
|
||||
ClutterStageView *view);
|
||||
|
||||
+void meta_stage_impl_rebuild_views (MetaStageImpl *stage_impl);
|
||||
+
|
||||
G_END_DECLS
|
||||
diff --git a/src/backends/meta-stage-impl.c b/src/backends/meta-stage-impl.c
|
||||
index 945e95ff2b..804d77f25d 100644
|
||||
--- a/src/backends/meta-stage-impl.c
|
||||
+++ b/src/backends/meta-stage-impl.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
+#include "backends/meta-renderer.h"
|
||||
#include "backends/meta-stage-view-private.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
#include "cogl/cogl.h"
|
||||
@@ -907,3 +908,14 @@ meta_stage_impl_get_backend (MetaStageImpl *stage_impl)
|
||||
|
||||
return priv->backend;
|
||||
}
|
||||
+
|
||||
+void
|
||||
+meta_stage_impl_rebuild_views (MetaStageImpl *stage_impl)
|
||||
+{
|
||||
+ MetaBackend *backend = meta_stage_impl_get_backend (stage_impl);
|
||||
+ MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
+ ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
+
|
||||
+ meta_renderer_rebuild_views (renderer);
|
||||
+ clutter_stage_clear_stage_views (CLUTTER_STAGE (stage));
|
||||
+}
|
||||
diff --git a/src/backends/meta-stage-private.h b/src/backends/meta-stage-private.h
|
||||
index 5546cc8ccf..e59ea35c6c 100644
|
||||
--- a/src/backends/meta-stage-private.h
|
||||
+++ b/src/backends/meta-stage-private.h
|
||||
@@ -68,4 +68,6 @@ META_EXPORT_TEST
|
||||
void meta_stage_remove_watch (MetaStage *stage,
|
||||
MetaStageWatch *watch);
|
||||
|
||||
+void meta_stage_rebuild_views (MetaStage *stage);
|
||||
+
|
||||
G_END_DECLS
|
||||
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
|
||||
index 96224a03b5..32f681c8c5 100644
|
||||
--- a/src/backends/meta-stage.c
|
||||
+++ b/src/backends/meta-stage.c
|
||||
@@ -494,3 +494,19 @@ meta_stage_remove_watch (MetaStage *stage,
|
||||
|
||||
g_assert (removed);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+meta_stage_rebuild_views (MetaStage *stage)
|
||||
+{
|
||||
+ ClutterStageWindow *stage_window =
|
||||
+ _clutter_stage_get_window (CLUTTER_STAGE (stage));
|
||||
+ MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_window);
|
||||
+ MetaMonitorManager *monitor_manager =
|
||||
+ meta_backend_get_monitor_manager (stage->backend);
|
||||
+ int width, height;
|
||||
+
|
||||
+ meta_stage_impl_rebuild_views (stage_impl);
|
||||
+
|
||||
+ meta_monitor_manager_get_screen_size (monitor_manager, &width, &height);
|
||||
+ clutter_actor_set_size (CLUTTER_ACTOR (stage), width, height);
|
||||
+}
|
||||
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
|
||||
index ee02b2783a..85bfeb7810 100644
|
||||
--- a/src/backends/native/meta-backend-native.c
|
||||
+++ b/src/backends/native/meta-backend-native.c
|
||||
@@ -399,14 +399,11 @@ static void
|
||||
meta_backend_native_update_stage (MetaBackend *backend)
|
||||
{
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
- ClutterStageWindow *stage_window =
|
||||
- _clutter_stage_get_window (CLUTTER_STAGE (stage));
|
||||
- MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
int width, height;
|
||||
|
||||
- meta_stage_native_rebuild_views (stage_native);
|
||||
+ meta_stage_rebuild_views (META_STAGE (stage));
|
||||
|
||||
meta_monitor_manager_get_screen_size (monitor_manager, &width, &height);
|
||||
clutter_actor_set_size (stage, width, height);
|
||||
diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c
|
||||
index 80d869b920..34849e5b9c 100644
|
||||
--- a/src/backends/native/meta-stage-native.c
|
||||
+++ b/src/backends/native/meta-stage-native.c
|
||||
@@ -54,18 +54,6 @@ G_DEFINE_TYPE_WITH_CODE (MetaStageNative, meta_stage_native,
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW,
|
||||
clutter_stage_window_iface_init))
|
||||
|
||||
-void
|
||||
-meta_stage_native_rebuild_views (MetaStageNative *stage_native)
|
||||
-{
|
||||
- MetaStageImpl *stage_impl = META_STAGE_IMPL (stage_native);
|
||||
- MetaBackend *backend = meta_stage_impl_get_backend (stage_impl);
|
||||
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
- ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
-
|
||||
- meta_renderer_rebuild_views (renderer);
|
||||
- clutter_stage_clear_stage_views (CLUTTER_STAGE (stage));
|
||||
-}
|
||||
-
|
||||
static gboolean
|
||||
meta_stage_native_can_clip_redraws (ClutterStageWindow *stage_window)
|
||||
{
|
||||
diff --git a/src/backends/native/meta-stage-native.h b/src/backends/native/meta-stage-native.h
|
||||
index 18ce3b14bb..cf081a32ea 100644
|
||||
--- a/src/backends/native/meta-stage-native.h
|
||||
+++ b/src/backends/native/meta-stage-native.h
|
||||
@@ -28,5 +28,3 @@
|
||||
#define META_TYPE_STAGE_NATIVE (meta_stage_native_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaStageNative, meta_stage_native,
|
||||
META, STAGE_NATIVE, MetaStageImpl)
|
||||
-
|
||||
-void meta_stage_native_rebuild_views (MetaStageNative *stage_native);
|
||||
diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c b/src/backends/x11/nested/meta-backend-x11-nested.c
|
||||
index ec82f1d1a9..09d2a91cb6 100644
|
||||
--- a/src/backends/x11/nested/meta-backend-x11-nested.c
|
||||
+++ b/src/backends/x11/nested/meta-backend-x11-nested.c
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "backends/meta-input-settings-dummy.h"
|
||||
#include "backends/meta-monitor-manager-dummy.h"
|
||||
+#include "backends/meta-stage-private.h"
|
||||
#include "backends/x11/nested/meta-backend-x11-nested.h"
|
||||
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
|
||||
#include "backends/x11/nested/meta-renderer-x11-nested.h"
|
||||
@@ -107,16 +108,8 @@ static void
|
||||
meta_backend_x11_nested_update_stage (MetaBackend *backend)
|
||||
{
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
- MetaMonitorManager *monitor_manager =
|
||||
- meta_backend_get_monitor_manager (backend);
|
||||
- int width, height;
|
||||
|
||||
- meta_renderer_rebuild_views (renderer);
|
||||
- clutter_stage_clear_stage_views (CLUTTER_STAGE (stage));
|
||||
-
|
||||
- meta_monitor_manager_get_screen_size (monitor_manager, &width, &height);
|
||||
- clutter_actor_set_size (stage, width, height);
|
||||
+ meta_stage_rebuild_views (META_STAGE (stage));
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
2.44.0.501.g19981daefd.dirty
|
||||
|
266
0002-stage-Track-overlay-damage-per-view.patch
Normal file
266
0002-stage-Track-overlay-damage-per-view.patch
Normal file
@ -0,0 +1,266 @@
|
||||
From 3e09a7f1717d8c4b0a815fd9673471a52d6328b9 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Wed, 12 Mar 2025 11:56:46 +0800
|
||||
Subject: [PATCH 2/2] stage: Track overlay damage per view
|
||||
|
||||
The previously painted rectangle of an overlay is not a global state,
|
||||
but depends on what view it was painted on. There was also an issue
|
||||
where an overlay being updated but not changing position, e.g. due to a
|
||||
0,0 pointer movement or an absolute pointer movement with the position
|
||||
not changing, not properly triggering damage of the old position when it
|
||||
eventually actually moved.
|
||||
|
||||
Fix this by tracking damage per view, while also fixing the state
|
||||
tracking to handle unchanged positions.
|
||||
---
|
||||
src/backends/meta-stage.c | 163 +++++++++++++++++++++++++-------------
|
||||
1 file changed, 107 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/src/backends/meta-stage.c b/src/backends/meta-stage.c
|
||||
index 32f681c8c5..58f15bbb33 100644
|
||||
--- a/src/backends/meta-stage.c
|
||||
+++ b/src/backends/meta-stage.c
|
||||
@@ -38,6 +38,12 @@ struct _MetaStageWatch
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
+typedef struct _MetaOverlayViewState
|
||||
+{
|
||||
+ graphene_rect_t painted_rect;
|
||||
+ gboolean has_painted_rect;
|
||||
+} MetaOverlayViewState;
|
||||
+
|
||||
struct _MetaOverlay
|
||||
{
|
||||
MetaStage *stage;
|
||||
@@ -49,8 +55,8 @@ struct _MetaOverlay
|
||||
|
||||
graphene_matrix_t transform;
|
||||
graphene_rect_t current_rect;
|
||||
- graphene_rect_t previous_rect;
|
||||
- gboolean previous_is_valid;
|
||||
+
|
||||
+ GHashTable *view_states;
|
||||
};
|
||||
|
||||
struct _MetaStage
|
||||
@@ -77,6 +83,7 @@ meta_overlay_new (MetaStage *stage)
|
||||
overlay = g_new0 (MetaOverlay, 1);
|
||||
overlay->stage = stage;
|
||||
overlay->pipeline = cogl_pipeline_new (ctx);
|
||||
+ overlay->view_states = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
return overlay;
|
||||
}
|
||||
@@ -86,6 +93,7 @@ meta_overlay_free (MetaOverlay *overlay)
|
||||
{
|
||||
if (overlay->pipeline)
|
||||
g_object_unref (overlay->pipeline);
|
||||
+ g_hash_table_unref (overlay->view_states);
|
||||
|
||||
g_free (overlay);
|
||||
}
|
||||
@@ -115,19 +123,57 @@ meta_overlay_set (MetaOverlay *overlay,
|
||||
overlay->current_rect = *dst_rect;
|
||||
}
|
||||
|
||||
+static MetaOverlayViewState *
|
||||
+get_view_state (MetaOverlay *overlay,
|
||||
+ ClutterStageView *view)
|
||||
+{
|
||||
+ return g_hash_table_lookup (overlay->view_states, view);
|
||||
+}
|
||||
+
|
||||
+static MetaOverlayViewState *
|
||||
+ensure_view_state (MetaOverlay *overlay,
|
||||
+ ClutterStageView *view)
|
||||
+{
|
||||
+ MetaOverlayViewState *view_state;
|
||||
+
|
||||
+ view_state = get_view_state (overlay, view);
|
||||
+
|
||||
+ if (!view_state)
|
||||
+ {
|
||||
+ view_state = g_new0 (MetaOverlayViewState, 1);
|
||||
+ g_hash_table_insert (overlay->view_states, view, view_state);
|
||||
+ }
|
||||
+
|
||||
+ return view_state;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+meta_overlay_invalidate_views (MetaOverlay *overlay)
|
||||
+{
|
||||
+ g_hash_table_remove_all (overlay->view_states);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
meta_overlay_paint (MetaOverlay *overlay,
|
||||
ClutterPaintContext *paint_context)
|
||||
{
|
||||
+ ClutterStageView *view;
|
||||
+ MetaOverlayViewState *view_state = NULL;
|
||||
CoglFramebuffer *framebuffer;
|
||||
|
||||
- if (!overlay->texture)
|
||||
- return;
|
||||
+ view = clutter_paint_context_get_stage_view (paint_context);
|
||||
+ if (view)
|
||||
+ view_state = ensure_view_state (overlay, view);
|
||||
|
||||
- if (!overlay->is_visible &&
|
||||
+ if ((!overlay->texture ||
|
||||
+ !overlay->is_visible) &&
|
||||
!(clutter_paint_context_get_paint_flags (paint_context) &
|
||||
CLUTTER_PAINT_FLAG_FORCE_CURSORS))
|
||||
- return;
|
||||
+ {
|
||||
+ if (view_state)
|
||||
+ view_state->has_painted_rect = FALSE;
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
|
||||
cogl_framebuffer_draw_rectangle (framebuffer,
|
||||
@@ -139,10 +185,10 @@ meta_overlay_paint (MetaOverlay *overlay,
|
||||
(overlay->current_rect.origin.y +
|
||||
overlay->current_rect.size.height));
|
||||
|
||||
- if (!graphene_rect_equal (&overlay->previous_rect, &overlay->current_rect))
|
||||
+ if (view_state)
|
||||
{
|
||||
- overlay->previous_rect = overlay->current_rect;
|
||||
- overlay->previous_is_valid = TRUE;
|
||||
+ view_state->painted_rect = overlay->current_rect;
|
||||
+ view_state->has_painted_rect = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,67 +389,68 @@ meta_stage_new (MetaBackend *backend)
|
||||
}
|
||||
|
||||
static void
|
||||
-queue_cursor_overlay_redraw_clutter_rect (MetaStage *stage,
|
||||
- MetaOverlay *overlay,
|
||||
- graphene_rect_t *rect)
|
||||
+intersect_and_queue_redraw (ClutterStageView *view,
|
||||
+ const MtkRectangle *clip)
|
||||
{
|
||||
- MtkRectangle clip = {
|
||||
- .x = (int) floorf (rect->origin.x),
|
||||
- .y = (int) floorf (rect->origin.y),
|
||||
- .width = (int) ceilf (rect->size.width),
|
||||
- .height = (int) ceilf (rect->size.height)
|
||||
- };
|
||||
- GList *l;
|
||||
+ MtkRectangle view_layout;
|
||||
+ MtkRectangle view_clip;
|
||||
|
||||
- /* Since we're flooring the coordinates, we need to enlarge the clip by the
|
||||
- * difference between the actual coordinate and the floored value */
|
||||
- clip.width += (int) ceilf (rect->origin.x - clip.x) * 2;
|
||||
- clip.height += (int) ceilf (rect->origin.y - clip.y) * 2;
|
||||
+ clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
- for (l = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
|
||||
- l;
|
||||
- l = l->next)
|
||||
+ if (mtk_rectangle_intersect (clip, &view_layout, &view_clip))
|
||||
{
|
||||
- ClutterStageView *view = l->data;
|
||||
- MtkRectangle view_layout;
|
||||
- MtkRectangle view_clip;
|
||||
-
|
||||
- if (clutter_stage_view_get_default_paint_flags (view) &
|
||||
- CLUTTER_PAINT_FLAG_NO_CURSORS)
|
||||
- continue;
|
||||
-
|
||||
- if (meta_stage_view_is_cursor_overlay_inhibited (META_STAGE_VIEW (view)))
|
||||
- return;
|
||||
+ clutter_stage_view_add_redraw_clip (view, &view_clip);
|
||||
+ clutter_stage_view_schedule_update (view);
|
||||
+ }
|
||||
+}
|
||||
|
||||
- clutter_stage_view_get_layout (view, &view_layout);
|
||||
+static void
|
||||
+cursor_rect_to_clip (const graphene_rect_t *cursor_rect,
|
||||
+ MtkRectangle *clip_rect)
|
||||
+{
|
||||
+ mtk_rectangle_from_graphene_rect (cursor_rect,
|
||||
+ MTK_ROUNDING_STRATEGY_GROW,
|
||||
+ clip_rect);
|
||||
|
||||
- if (mtk_rectangle_intersect (&clip, &view_layout, &view_clip))
|
||||
- {
|
||||
- clutter_stage_view_add_redraw_clip (view, &view_clip);
|
||||
- clutter_stage_view_schedule_update (view);
|
||||
- }
|
||||
- }
|
||||
+ /* Since we're flooring the coordinates, we need to enlarge the clip by the
|
||||
+ * difference between the actual coordinate and the floored value */
|
||||
+ clip_rect->width += (int) ceilf (cursor_rect->origin.x - clip_rect->x) * 2;
|
||||
+ clip_rect->height += (int) ceilf (cursor_rect->origin.y - clip_rect->y) * 2;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_redraw_for_cursor_overlay (MetaStage *stage,
|
||||
MetaOverlay *overlay)
|
||||
{
|
||||
- /* Clear the location the overlay was at before, if we need to. */
|
||||
- if (overlay->previous_is_valid)
|
||||
- {
|
||||
- queue_cursor_overlay_redraw_clutter_rect (stage,
|
||||
- overlay,
|
||||
- &overlay->previous_rect);
|
||||
- overlay->previous_is_valid = FALSE;
|
||||
- }
|
||||
+ GList *l;
|
||||
|
||||
- /* Draw the overlay at the new position */
|
||||
- if (overlay->is_visible && overlay->texture)
|
||||
+ for (l = clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
|
||||
+ l;
|
||||
+ l = l->next)
|
||||
{
|
||||
- queue_cursor_overlay_redraw_clutter_rect (stage,
|
||||
- overlay,
|
||||
- &overlay->current_rect);
|
||||
+ ClutterStageView *view = CLUTTER_STAGE_VIEW (l->data);
|
||||
+ MetaOverlayViewState *view_state;
|
||||
+
|
||||
+ view_state = ensure_view_state (overlay, view);
|
||||
+ if (view_state->has_painted_rect)
|
||||
+ {
|
||||
+ MtkRectangle clip;
|
||||
+
|
||||
+ cursor_rect_to_clip (&view_state->painted_rect, &clip);
|
||||
+ intersect_and_queue_redraw (view, &clip);
|
||||
+ }
|
||||
+
|
||||
+ if (overlay->is_visible &&
|
||||
+ overlay->texture &&
|
||||
+ !(clutter_stage_view_get_default_paint_flags (view) &
|
||||
+ CLUTTER_PAINT_FLAG_NO_CURSORS) &&
|
||||
+ !meta_stage_view_is_cursor_overlay_inhibited (META_STAGE_VIEW (view)))
|
||||
+ {
|
||||
+ MtkRectangle clip;
|
||||
+
|
||||
+ cursor_rect_to_clip (&overlay->current_rect, &clip);
|
||||
+ intersect_and_queue_redraw (view, &clip);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,4 +556,8 @@ meta_stage_rebuild_views (MetaStage *stage)
|
||||
|
||||
meta_monitor_manager_get_screen_size (monitor_manager, &width, &height);
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (stage), width, height);
|
||||
+
|
||||
+ g_list_foreach (stage->overlays,
|
||||
+ (GFunc) meta_overlay_invalidate_views,
|
||||
+ NULL);
|
||||
}
|
||||
--
|
||||
2.44.0.501.g19981daefd.dirty
|
||||
|
@ -65,6 +65,10 @@ Patch: 0003-monitor-manager-Configure-for-lease-monitors-in-Appl.patch
|
||||
Patch: 0001-wayland-Fix-refresh-interval-reporting-in-presentati.patch
|
||||
Patch: 0002-input-capture-session-Disconnect-on_keymap_changed-o.patch
|
||||
|
||||
# Overlay cursor damage fix: RHEL-58079, RHEL-81897
|
||||
Patch: 0001-backends-Update-stage-views-and-stage-dimension-from.patch
|
||||
Patch: 0002-stage-Track-overlay-damage-per-view.patch
|
||||
|
||||
BuildRequires: pkgconfig(gobject-introspection-1.0) >= 1.41.0
|
||||
BuildRequires: pkgconfig(sm)
|
||||
BuildRequires: pkgconfig(libwacom)
|
||||
|
Loading…
Reference in New Issue
Block a user