[mutter] cursor-renderer: Align OpenGL cursor rect to physical pixel grid



commit 178b975d6a9c687fd42c722a0ad840a259c5bd15
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon May 6 15:25:16 2019 +0200

    cursor-renderer: Align OpenGL cursor rect to physical pixel grid
    
    When stage views are scaled with fractional scales, the cursor rectangle
    won't be aligned with the physical pixel grid, making it potentially
    blurry when positioned in between physical pixels. This can be avoided
    by aligning the drawn rectangle to the physical pixel grid of the stage
    view the cursor is located on.
    
    Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/413
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/610

 src/backends/meta-cursor-renderer.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)
---
diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c
index 96211a4bd..dae40b3d3 100644
--- a/src/backends/meta-cursor-renderer.c
+++ b/src/backends/meta-cursor-renderer.c
@@ -30,6 +30,7 @@
 
 #include "backends/meta-stage-private.h"
 #include "clutter/clutter.h"
+#include "clutter/clutter-mutter.h"
 #include "cogl/cogl.h"
 #include "meta/meta-backend.h"
 #include "meta/util.h"
@@ -82,6 +83,33 @@ meta_cursor_renderer_emit_painted (MetaCursorRenderer *renderer,
   g_signal_emit (renderer, signals[CURSOR_PAINTED], 0, cursor_sprite);
 }
 
+static void
+align_cursor_position (MetaCursorRenderer *renderer,
+                       ClutterRect        *rect)
+{
+  MetaCursorRendererPrivate *priv =
+    meta_cursor_renderer_get_instance_private (renderer);
+  MetaBackend *backend = meta_get_backend ();
+  ClutterActor *stage = meta_backend_get_stage (backend);
+  ClutterStageView *view;
+  cairo_rectangle_int_t view_layout;
+  float view_scale;
+
+  view = clutter_stage_get_view_at (CLUTTER_STAGE (stage),
+                                    priv->current_x,
+                                    priv->current_y);
+  if (!view)
+    return;
+
+  clutter_stage_view_get_layout (view, &view_layout);
+  view_scale = clutter_stage_view_get_scale (view);
+
+  clutter_rect_offset (rect, -view_layout.x, -view_layout.y);
+  rect->origin.x = floorf (rect->origin.x * view_scale) / view_scale;
+  rect->origin.y = floorf (rect->origin.y * view_scale) / view_scale;
+  clutter_rect_offset (rect, view_layout.x, view_layout.y);
+}
+
 static void
 queue_redraw (MetaCursorRenderer *renderer,
               MetaCursorSprite   *cursor_sprite)
@@ -92,13 +120,16 @@ queue_redraw (MetaCursorRenderer *renderer,
   CoglTexture *texture;
   ClutterRect rect = CLUTTER_RECT_INIT_ZERO;
 
-  if (cursor_sprite)
-    rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
-
   /* During early initialization, we can have no stage */
   if (!stage)
     return;
 
+  if (cursor_sprite)
+    {
+      rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
+      align_cursor_position (renderer, &rect);
+    }
+
   if (!priv->stage_overlay)
     priv->stage_overlay = meta_stage_create_cursor_overlay (META_STAGE (stage));
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]