[mutter] clutter/stage-cogl: Use buffer age when view monitor is rotated



commit 9d3e4fd40224b946ddb9f40a6a250231e52b297f
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Tue May 5 19:05:36 2020 +0200

    clutter/stage-cogl: Use buffer age when view monitor is rotated
    
    We failed to use the buffer age when monitors were rotated, as when they
    are, we first composite to an offscreen framebuffer, then later again to
    the onscreen. The buffer age checking happened on the offscreen, and an
    offscreen being single buffered, they can't possible support buffer
    ages.
    
    Instead, move the buffer age check to check the actual onscreen
    framebuffer. The offscreen to onscreen painting is still always full
    frame, but that will be fixed in a later commit.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1237

 clutter/clutter/clutter-stage-view-private.h |  6 ++++
 clutter/clutter/clutter-stage-view.c         | 29 ++++++++++--------
 clutter/clutter/clutter-stage-view.h         | 11 ++++---
 clutter/clutter/cogl/clutter-stage-cogl.c    | 46 +++++++++-------------------
 src/backends/meta-renderer-view.c            | 22 +++++++++++++
 5 files changed, 64 insertions(+), 50 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage-view-private.h b/clutter/clutter/clutter-stage-view-private.h
index 2855211ebe..b5b65a4df8 100644
--- a/clutter/clutter/clutter-stage-view-private.h
+++ b/clutter/clutter/clutter-stage-view-private.h
@@ -52,4 +52,10 @@ cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view);
 
 CoglScanout * clutter_stage_view_take_scanout (ClutterStageView *view);
 
+void clutter_stage_view_transform_rect_to_onscreen (ClutterStageView            *view,
+                                                    const cairo_rectangle_int_t *src_rect,
+                                                    int                          dst_width,
+                                                    int                          dst_height,
+                                                    cairo_rectangle_int_t       *dst_rect);
+
 #endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index b7a3d67162..97aadcc9c8 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -166,6 +166,22 @@ clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view)
   g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
 }
 
+void
+clutter_stage_view_transform_rect_to_onscreen (ClutterStageView            *view,
+                                               const cairo_rectangle_int_t *src_rect,
+                                               int                          dst_width,
+                                               int                          dst_height,
+                                               cairo_rectangle_int_t       *dst_rect)
+{
+  ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view);
+
+  return view_class->transform_rect_to_onscreen (view,
+                                                 src_rect,
+                                                 dst_width,
+                                                 dst_height,
+                                                 dst_rect);
+}
+
 static void
 paint_transformed_framebuffer (ClutterStageView *view,
                                CoglPipeline     *pipeline,
@@ -471,19 +487,6 @@ clutter_stage_view_take_redraw_clip (ClutterStageView *view)
   return g_steal_pointer (&priv->redraw_clip);
 }
 
-void
-clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
-                                          gfloat           *x,
-                                          gfloat           *y)
-{
-  gfloat z = 0, w = 1;
-  CoglMatrix matrix;
-
-  clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
-  cogl_matrix_get_inverse (&matrix, &matrix);
-  cogl_matrix_transform_point (&matrix, x, y, &z, &w);
-}
-
 static void
 clutter_stage_default_get_offscreen_transformation_matrix (ClutterStageView *view,
                                                            CoglMatrix       *matrix)
diff --git a/clutter/clutter/clutter-stage-view.h b/clutter/clutter/clutter-stage-view.h
index 26bf10e798..eb0184e9ab 100644
--- a/clutter/clutter/clutter-stage-view.h
+++ b/clutter/clutter/clutter-stage-view.h
@@ -43,6 +43,12 @@ struct _ClutterStageViewClass
 
   void (* get_offscreen_transformation_matrix) (ClutterStageView *view,
                                                 CoglMatrix       *matrix);
+
+  void (* transform_rect_to_onscreen) (ClutterStageView            *view,
+                                       const cairo_rectangle_int_t *src_rect,
+                                       int                          dst_width,
+                                       int                          dst_height,
+                                       cairo_rectangle_int_t       *dst_rect);
 };
 
 CLUTTER_EXPORT
@@ -56,11 +62,6 @@ CoglFramebuffer *clutter_stage_view_get_onscreen (ClutterStageView *view);
 CLUTTER_EXPORT
 void             clutter_stage_view_invalidate_offscreen_blit_pipeline (ClutterStageView *view);
 
-CLUTTER_EXPORT
-void             clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
-                                                           gfloat           *x,
-                                                           gfloat           *y);
-
 CLUTTER_EXPORT
 float clutter_stage_view_get_scale (ClutterStageView *view);
 
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 4a7eee7355..fa9d655d31 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -536,44 +536,25 @@ static cairo_region_t *
 transform_swap_region_to_onscreen (ClutterStageView *view,
                                    cairo_region_t   *swap_region)
 {
-  CoglFramebuffer *framebuffer;
-  cairo_rectangle_int_t layout;
-  gint width, height;
+  CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (view);
   int n_rects, i;
   cairo_rectangle_int_t *rects;
   cairo_region_t *transformed_region;
+  int width, height;
 
-  framebuffer = clutter_stage_view_get_onscreen (view);
-  clutter_stage_view_get_layout (view, &layout);
-
-  width = cogl_framebuffer_get_width (framebuffer);
-  height = cogl_framebuffer_get_height (framebuffer);
+  width = cogl_framebuffer_get_width (onscreen);
+  height = cogl_framebuffer_get_height (onscreen);
 
   n_rects = cairo_region_num_rectangles (swap_region);
   rects = g_newa (cairo_rectangle_int_t, n_rects);
   for (i = 0; i < n_rects; i++)
     {
-      gfloat x1, y1, x2, y2;
-
       cairo_region_get_rectangle (swap_region, i, &rects[i]);
-
-      x1 = (float) rects[i].x / layout.width;
-      y1 = (float) rects[i].y / layout.height;
-      x2 = (float) (rects[i].x + rects[i].width) / layout.width;
-      y2 = (float) (rects[i].y + rects[i].height) / layout.height;
-
-      clutter_stage_view_transform_to_onscreen (view, &x1, &y1);
-      clutter_stage_view_transform_to_onscreen (view, &x2, &y2);
-
-      x1 = floor (x1 * width);
-      y1 = floor (height - (y1 * height));
-      x2 = ceil (x2 * width);
-      y2 = ceil (height - (y2 * height));
-
-      rects[i].x = x1;
-      rects[i].y = y1;
-      rects[i].width = x2 - x1;
-      rects[i].height = y2 - y1;
+      clutter_stage_view_transform_rect_to_onscreen (view,
+                                                     &rects[i],
+                                                     width,
+                                                     height,
+                                                     &rects[i]);
     }
   transformed_region = cairo_region_create_rectangles (rects, n_rects);
 
@@ -598,6 +579,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
   ClutterStageViewCoglPrivate *view_priv =
     clutter_stage_view_cogl_get_instance_private (view_cogl);
   CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
+  CoglFramebuffer *onscreen = clutter_stage_view_get_onscreen (view);
   cairo_rectangle_int_t view_rect;
   gboolean is_full_redraw;
   gboolean use_clipped_redraw;
@@ -619,10 +601,10 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
   fb_height = cogl_framebuffer_get_height (fb);
 
   can_blit_sub_buffer =
-    cogl_is_onscreen (fb) &&
+    cogl_is_onscreen (onscreen) &&
     cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION);
 
-  has_buffer_age = cogl_is_onscreen (fb) && is_buffer_age_enabled ();
+  has_buffer_age = cogl_is_onscreen (onscreen) && is_buffer_age_enabled ();
 
   redraw_clip = clutter_stage_view_take_redraw_clip (view);
   if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
@@ -636,7 +618,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
 
   if (has_buffer_age)
     {
-      buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
+      buffer_age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (onscreen));
       if (!valid_buffer_age (view_cogl, buffer_age))
         {
           CLUTTER_NOTE (CLIPPING,
@@ -654,7 +636,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
     !is_full_redraw &&
     /* some drivers struggle to get going and produce some junk
      * frames when starting up... */
-    cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3;
+    cogl_onscreen_get_frame_counter (COGL_ONSCREEN (onscreen)) > 3;
 
   if (use_clipped_redraw)
     {
diff --git a/src/backends/meta-renderer-view.c b/src/backends/meta-renderer-view.c
index ae771f2de8..785b29cd7b 100644
--- a/src/backends/meta-renderer-view.c
+++ b/src/backends/meta-renderer-view.c
@@ -34,6 +34,7 @@
 
 #include "backends/meta-renderer.h"
 #include "clutter/clutter-mutter.h"
+#include "compositor/region-utils.h"
 
 enum
 {
@@ -117,6 +118,25 @@ meta_renderer_view_setup_offscreen_blit_pipeline (ClutterStageView *view,
   cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
 }
 
+static void
+meta_renderer_view_transform_rect_to_onscreen (ClutterStageView            *view,
+                                               const cairo_rectangle_int_t *src_rect,
+                                               int                          dst_width,
+                                               int                          dst_height,
+                                               cairo_rectangle_int_t       *dst_rect)
+{
+  MetaRendererView *renderer_view = META_RENDERER_VIEW (view);
+  MetaMonitorTransform inverted_transform;
+
+  inverted_transform =
+    meta_monitor_transform_invert (renderer_view->transform);
+  return meta_rectangle_transform (src_rect,
+                                   inverted_transform,
+                                   dst_width,
+                                   dst_height,
+                                   dst_rect);
+}
+
 static void
 meta_renderer_view_set_transform (MetaRendererView     *view,
                                   MetaMonitorTransform  transform)
@@ -181,6 +201,8 @@ meta_renderer_view_class_init (MetaRendererViewClass *klass)
     meta_renderer_view_setup_offscreen_blit_pipeline;
   view_class->get_offscreen_transformation_matrix =
     meta_renderer_view_get_offscreen_transformation_matrix;
+  view_class->transform_rect_to_onscreen =
+    meta_renderer_view_transform_rect_to_onscreen;
 
   object_class->get_property = meta_renderer_view_get_property;
   object_class->set_property = meta_renderer_view_set_property;


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