[mutter] clutter: Add API to get the resource scale of an actor



commit ad5555bf4286ece9844d919d62f8368dce90edf1
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Apr 7 14:06:36 2017 +0200

    clutter: Add API to get the resource scale of an actor
    
    A clutter actor might be painted on a stage view with a view scale
    other than 1. In this case, to show the content in full resolution, the
    actor must use a higher resolution resource (e.g. texture), which will
    be down scaled to the stage coordinate space, then scaled up again to
    the stage view framebuffer scale.
    
    Use a 'resource-scale' property to save information and notify when it
    changes.
    
    The resource scale is the ceiled value of the highest stage view scale a
    actor is visible on. The value is ceiled because using a higher
    resolution resource consistently results in better output quality. One
    reason for this is that rendering is often not perfectly pixel aligned,
    meaning even if we load a resource with a suitable size, due to us still
    scaling ever so slightly, the quality is affected. Using a higher
    resolution resource avoids this problem.
    
    For situations inside clutter where the actual maximum view scale is
    needed, a function _clutter_actor_get_real_resource_scale() is provided,
    which returns the non-ceiled value.
    
    Make sure we ignore resource scale computation requests during size
    requests or allocation while ensure we've proper resource-scale on
    pre-paint.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=765011
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/3

 clutter/clutter/clutter-actor-private.h           |   3 +
 clutter/clutter/clutter-actor.c                   | 251 +++++++++++++++++++++-
 clutter/clutter/clutter-actor.h                   |   5 +
 clutter/clutter/clutter-mutter.h                  |   3 +
 clutter/clutter/clutter-private.h                 |  11 +-
 clutter/clutter/clutter-stage-private.h           |   2 +
 clutter/clutter/clutter-stage.c                   |  14 ++
 src/backends/native/meta-stage-native.c           |   2 +
 src/backends/x11/nested/meta-backend-x11-nested.c |   5 +-
 9 files changed, 287 insertions(+), 9 deletions(-)
---
diff --git a/clutter/clutter/clutter-actor-private.h b/clutter/clutter/clutter-actor-private.h
index 7806894bc..c44f6342f 100644
--- a/clutter/clutter/clutter-actor-private.h
+++ b/clutter/clutter/clutter-actor-private.h
@@ -315,8 +315,11 @@ void                            _clutter_actor_detach_clone
 void                            _clutter_actor_queue_redraw_on_clones                   (ClutterActor 
*actor);
 void                            _clutter_actor_queue_relayout_on_clones                 (ClutterActor 
*actor);
 void                            _clutter_actor_queue_only_relayout                      (ClutterActor 
*actor);
+void                            _clutter_actor_queue_update_resource_scale_recursive    (ClutterActor 
*actor);
 
 CoglFramebuffer *               _clutter_actor_get_active_framebuffer                   (ClutterActor 
*actor);
+gboolean                        _clutter_actor_get_real_resource_scale                  (ClutterActor *actor,
+                                                                                         float        
*resource_scale);
 
 ClutterPaintNode *              clutter_actor_create_texture_paint_node                 (ClutterActor *self,
                                                                                          CoglTexture  
*texture);
diff --git a/clutter/clutter/clutter-actor.c b/clutter/clutter/clutter-actor.c
index 43d58cd14..d0f7434ef 100644
--- a/clutter/clutter/clutter-actor.c
+++ b/clutter/clutter/clutter-actor.c
@@ -699,6 +699,8 @@ struct _ClutterActorPrivate
   /* the cached transformation matrix; see apply_transform() */
   CoglMatrix transform;
 
+  float resource_scale;
+
   guint8 opacity;
   gint opacity_override;
 
@@ -844,6 +846,7 @@ struct _ClutterActorPrivate
   guint needs_y_expand              : 1;
   guint needs_paint_volume_update   : 1;
   guint had_effects_on_last_paint_volume_update : 1;
+  guint needs_compute_resource_scale : 1;
 };
 
 enum
@@ -916,6 +919,7 @@ enum
   PROP_SCALE_CENTER_X, /* XXX:2.0 remove */
   PROP_SCALE_CENTER_Y, /* XXX:2.0 remove */
   PROP_SCALE_GRAVITY, /* XXX:2.0 remove */
+  PROP_RESOURCE_SCALE,
 
   PROP_ROTATION_ANGLE_X, /* XXX:2.0 rename to rotation-x */
   PROP_ROTATION_ANGLE_Y, /* XXX:2.0 rename to rotation-y */
@@ -1095,6 +1099,8 @@ static void clutter_actor_set_child_transform_internal (ClutterActor        *sel
 
 static void     clutter_actor_realize_internal          (ClutterActor *self);
 static void     clutter_actor_unrealize_internal        (ClutterActor *self);
+static gboolean clutter_actor_update_resource_scale     (ClutterActor *self);
+static void     clutter_actor_ensure_resource_scale     (ClutterActor *self);
 
 static void clutter_actor_push_in_cloned_branch (ClutterActor *self,
                                                  gulong        count);
@@ -1521,6 +1527,8 @@ clutter_actor_real_map (ClutterActor *self)
                 priv->pick_id,
                 _clutter_actor_get_debug_name (self));
 
+  clutter_actor_ensure_resource_scale (self);
+
   /* notify on parent mapped before potentially mapping
    * children, so apps see a top-down notification.
    */
@@ -2778,6 +2786,16 @@ clutter_actor_real_queue_redraw (ClutterActor       *self,
   return FALSE;
 }
 
+static inline gboolean
+clutter_actor_needs_relayout (ClutterActor *self)
+{
+  ClutterActorPrivate *priv = self->priv;
+
+  return (priv->needs_width_request ||
+          priv->needs_height_request ||
+          priv->needs_allocation);
+}
+
 static void
 clutter_actor_real_queue_relayout (ClutterActor *self)
 {
@@ -3837,6 +3855,8 @@ clutter_actor_paint (ClutterActor *self)
   if (!CLUTTER_ACTOR_IS_MAPPED (self))
     return;
 
+  clutter_actor_ensure_resource_scale (self);
+
   stage = (ClutterStage *) _clutter_actor_get_stage_internal (self);
 
   /* mark that we are in the paint process */
@@ -4339,7 +4359,10 @@ clutter_actor_remove_child_internal (ClutterActor                 *self,
 
   /* clutter_actor_reparent() will emit ::parent-set for us */
   if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child))
-    g_signal_emit (child, actor_signals[PARENT_SET], 0, self);
+    {
+      child->priv->needs_compute_resource_scale = TRUE;
+      g_signal_emit (child, actor_signals[PARENT_SET], 0, self);
+    }
 
   /* if the child was mapped then we need to relayout ourselves to account
    * for the removed child
@@ -5664,6 +5687,16 @@ clutter_actor_get_property (GObject    *object,
       g_value_set_enum (value, clutter_actor_get_scale_gravity (actor));
       break;
 
+    case PROP_RESOURCE_SCALE:
+      if (priv->needs_compute_resource_scale)
+        {
+          if (!clutter_actor_update_resource_scale (actor))
+            g_warning ("Getting invalid resource scale property");
+        }
+
+      g_value_set_float (value, priv->resource_scale);
+      break;
+
     case PROP_REACTIVE:
       g_value_set_boolean (value, clutter_actor_get_reactive (actor));
       break;
@@ -7117,6 +7150,19 @@ clutter_actor_class_init (ClutterActorClass *klass)
                        G_PARAM_STATIC_STRINGS |
                        G_PARAM_DEPRECATED);
 
+  /**
+   * ClutterActor:resource-scale:
+   *
+   * The resource-scale of the #ClutterActor if any or -1 if not available
+   */
+  obj_props[PROP_RESOURCE_SCALE] =
+    g_param_spec_float ("resource-scale",
+                        P_("Resource Scale"),
+                        P_("The Scaling factor for resources painting"),
+                        -1.0f, G_MAXFLOAT,
+                        1.0f,
+                        CLUTTER_PARAM_READABLE);
+
   /**
    * ClutterActor:rotation-angle-x:
    *
@@ -8556,11 +8602,13 @@ clutter_actor_init (ClutterActor *self)
 
   priv->opacity = 0xff;
   priv->show_on_set_parent = TRUE;
+  priv->resource_scale = -1.0f;
 
   priv->needs_width_request = TRUE;
   priv->needs_height_request = TRUE;
   priv->needs_allocation = TRUE;
   priv->needs_paint_volume_update = TRUE;
+  priv->needs_compute_resource_scale = TRUE;
 
   priv->cached_width_age = 1;
   priv->cached_height_age = 1;
@@ -9520,6 +9568,8 @@ clutter_actor_get_preferred_width (ClutterActor *self,
       return;
     }
 
+  CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_WIDTH);
+
   /* the remaining cases are:
    *
    *   - either min_width or natural_width have been set
@@ -9611,6 +9661,8 @@ clutter_actor_get_preferred_width (ClutterActor *self,
 
   if (natural_width_p)
     *natural_width_p = request_natural_width;
+
+  CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_WIDTH);
 }
 
 /**
@@ -9664,6 +9716,8 @@ clutter_actor_get_preferred_height (ClutterActor *self,
       return;
     }
 
+  CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_HEIGHT);
+
   /* the remaining cases are:
    *
    *   - either min_height or natural_height have been set
@@ -9754,6 +9808,8 @@ clutter_actor_get_preferred_height (ClutterActor *self,
 
   if (natural_height_p)
     *natural_height_p = request_natural_height;
+
+  CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_PREF_HEIGHT);
 }
 
 /**
@@ -10096,6 +10152,9 @@ clutter_actor_allocate (ClutterActor           *self,
   if (CLUTTER_ACTOR_IS_MAPPED (self))
     self->priv->needs_paint_volume_update = TRUE;
 
+  if (stage_allocation_changed)
+    priv->needs_compute_resource_scale = TRUE;
+
   if (!stage_allocation_changed)
     {
       /* If the actor didn't move but needs_allocation is set, we just
@@ -12944,7 +13003,10 @@ clutter_actor_add_child_internal (ClutterActor              *self,
 
   /* clutter_actor_reparent() will emit ::parent-set for us */
   if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child))
-    g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL);
+    {
+      child->priv->needs_compute_resource_scale = TRUE;
+      g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL);
+    }
 
   if (check_state)
     {
@@ -12977,9 +13039,7 @@ clutter_actor_add_child_internal (ClutterActor              *self,
   /* maintain the invariant that if an actor needs layout,
    * its parents do as well
    */
-  if (child->priv->needs_width_request ||
-      child->priv->needs_height_request ||
-      child->priv->needs_allocation)
+  if (clutter_actor_needs_relayout (child))
     {
       /* we work around the short-circuiting we do
        * in clutter_actor_queue_relayout() since we
@@ -13548,6 +13608,8 @@ clutter_actor_reparent (ClutterActor *self,
                                           insert_child_at_depth,
                                           NULL);
 
+      priv->needs_compute_resource_scale = TRUE;
+
       /* we emit the ::parent-set signal once */
       g_signal_emit (self, actor_signals[PARENT_SET], 0, old_parent);
 
@@ -17717,6 +17779,185 @@ clutter_actor_get_paint_box (ClutterActor    *self,
   return TRUE;
 }
 
+static gboolean
+_clutter_actor_get_resource_scale_for_rect (ClutterActor *self,
+                                            ClutterRect  *bounding_rect,
+                                            float        *resource_scale)
+{
+  ClutterActor *stage;
+  GList *views;
+  GList *l;
+  float max_scale = 0;
+
+  stage = _clutter_actor_get_stage_internal (self);
+  if (!stage)
+    return FALSE;
+
+  views = _clutter_stage_peek_stage_views (CLUTTER_STAGE (stage));
+  for (l = views; l; l = l->next)
+    {
+      ClutterStageView *view = l->data;
+      cairo_rectangle_int_t view_layout;
+      ClutterRect view_rect;
+
+      clutter_stage_view_get_layout (view, &view_layout);
+      _clutter_util_rect_from_rectangle (&view_layout, &view_rect);
+
+      if (clutter_rect_intersection (&view_rect, bounding_rect, NULL))
+        max_scale = MAX (clutter_stage_view_get_scale (view), max_scale);
+    }
+
+  if (max_scale == 0)
+    return FALSE;
+
+  *resource_scale = max_scale;
+
+  return TRUE;
+}
+
+static gboolean
+_clutter_actor_compute_resource_scale (ClutterActor *self,
+                                       float        *resource_scale)
+{
+  ClutterRect bounding_rect;
+  ClutterActorPrivate *priv = self->priv;
+
+  if (CLUTTER_ACTOR_IN_DESTRUCTION (self) ||
+      CLUTTER_ACTOR_IN_PREF_SIZE (self) ||
+      !clutter_actor_is_mapped (self))
+    {
+      return FALSE;
+    }
+
+  clutter_actor_get_transformed_position (self,
+                                          &bounding_rect.origin.x,
+                                          &bounding_rect.origin.y);
+  clutter_actor_get_transformed_size (self,
+                                      &bounding_rect.size.width,
+                                      &bounding_rect.size.height);
+
+  if (bounding_rect.size.width == 0.0 ||
+      bounding_rect.size.height == 0.0 ||
+      !_clutter_actor_get_resource_scale_for_rect (self,
+                                                   &bounding_rect,
+                                                   resource_scale))
+    {
+      if (priv->parent)
+        return _clutter_actor_compute_resource_scale (priv->parent,
+                                                      resource_scale);
+      else
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
+static ClutterActorTraverseVisitFlags
+queue_update_resource_scale_cb (ClutterActor *actor,
+                                int           depth,
+                                void         *user_data)
+{
+  actor->priv->needs_compute_resource_scale = TRUE;
+  return CLUTTER_ACTOR_TRAVERSE_VISIT_CONTINUE;
+}
+
+void
+_clutter_actor_queue_update_resource_scale_recursive (ClutterActor *self)
+{
+  _clutter_actor_traverse (self,
+                           CLUTTER_ACTOR_TRAVERSE_DEPTH_FIRST,
+                           queue_update_resource_scale_cb,
+                           NULL,
+                           NULL);
+}
+
+static gboolean
+clutter_actor_update_resource_scale (ClutterActor *self)
+{
+  ClutterActorPrivate *priv;
+  float resource_scale;
+  float old_resource_scale;
+  priv = self->priv;
+
+  g_return_val_if_fail (priv->needs_compute_resource_scale, FALSE);
+
+  old_resource_scale = priv->resource_scale;
+  priv->resource_scale = -1.0f;
+
+  if (_clutter_actor_compute_resource_scale (self, &resource_scale))
+    {
+      priv->resource_scale = resource_scale;
+      priv->needs_compute_resource_scale = FALSE;
+
+      return fabsf (old_resource_scale - resource_scale) > FLT_EPSILON;
+    }
+
+  return FALSE;
+}
+
+static void
+clutter_actor_ensure_resource_scale (ClutterActor *self)
+{
+  ClutterActorPrivate *priv = self->priv;
+
+  if (!priv->needs_compute_resource_scale)
+    return;
+
+  if (clutter_actor_update_resource_scale (self))
+    g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_RESOURCE_SCALE]);
+}
+
+gboolean
+_clutter_actor_get_real_resource_scale (ClutterActor *self,
+                                        gfloat       *resource_scale)
+{
+  ClutterActorPrivate *priv = self->priv;
+
+  clutter_actor_ensure_resource_scale (self);
+
+  if (!priv->needs_compute_resource_scale)
+    {
+      *resource_scale = priv->resource_scale;
+      return TRUE;
+    }
+
+  *resource_scale = -1.0f;
+  return FALSE;
+}
+
+/**
+ * clutter_actor_get_resource_scale:
+ * @self: A #ClutterActor
+ * @resource_scale: (out): return location for the resource scale
+ *
+ * Retrieves the resource scale for this actor, if available.
+ *
+ * The resource scale refers to the scale the actor should use for its resources.
+ * For example if an actor draws a a picture of size 100 x 100 in the stage
+ * coordinate space, it should use a texture of twice the size (i.e. 200 x 200)
+ * if the resource scale is 2.
+ *
+ * The resource scale is determined by calculating the highest #ClutterStageView
+ * scale the actor will get painted on.
+ *
+ * Returns: TRUE if resource scale is set for the actor, otherwise FALSE
+ */
+gboolean
+clutter_actor_get_resource_scale (ClutterActor *self,
+                                  gfloat       *resource_scale)
+{
+  g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
+  g_return_val_if_fail (resource_scale != NULL, FALSE);
+
+  if (_clutter_actor_get_real_resource_scale (self, resource_scale))
+    {
+      *resource_scale = ceilf (*resource_scale);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
 /**
  * clutter_actor_has_overlaps:
  * @self: A #ClutterActor
diff --git a/clutter/clutter/clutter-actor.h b/clutter/clutter/clutter-actor.h
index ade912485..7d2168af1 100644
--- a/clutter/clutter/clutter-actor.h
+++ b/clutter/clutter/clutter-actor.h
@@ -584,6 +584,11 @@ gboolean                        clutter_actor_is_in_clone_paint
 CLUTTER_EXPORT
 gboolean                        clutter_actor_get_paint_box                     (ClutterActor               
*self,
                                                                                  ClutterActorBox            
*box);
+
+CLUTTER_EXPORT
+gboolean                        clutter_actor_get_resource_scale                (ClutterActor *self,
+                                                                                 gfloat       
*resource_scale);
+
 CLUTTER_EXPORT
 gboolean                        clutter_actor_has_overlaps                      (ClutterActor               
*self);
 
diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h
index 788757140..a53080457 100644
--- a/clutter/clutter/clutter-mutter.h
+++ b/clutter/clutter/clutter-mutter.h
@@ -49,6 +49,9 @@ void clutter_stage_freeze_updates (ClutterStage *stage);
 CLUTTER_EXPORT
 void clutter_stage_thaw_updates (ClutterStage *stage);
 
+CLUTTER_EXPORT
+void clutter_stage_update_resource_scales (ClutterStage *stage);
+
 CLUTTER_EXPORT
 gboolean clutter_actor_has_damage (ClutterActor *actor);
 
diff --git a/clutter/clutter/clutter-private.h b/clutter/clutter/clutter-private.h
index 891a5612b..cbfaaa7f0 100644
--- a/clutter/clutter/clutter-private.h
+++ b/clutter/clutter/clutter-private.h
@@ -69,6 +69,9 @@ typedef struct _ClutterVertex4          ClutterVertex4;
 #define CLUTTER_ACTOR_IN_REPARENT(a)            ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_REPARENT) != FALSE)
 #define CLUTTER_ACTOR_IN_PAINT(a)               ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PAINT) != FALSE)
 #define CLUTTER_ACTOR_IN_RELAYOUT(a)            ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_RELAYOUT) != FALSE)
+#define CLUTTER_ACTOR_IN_PREF_WIDTH(a)          ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_WIDTH) != 
FALSE)
+#define CLUTTER_ACTOR_IN_PREF_HEIGHT(a)         ((CLUTTER_PRIVATE_FLAGS (a) & CLUTTER_IN_PREF_HEIGHT) != 
FALSE)
+#define CLUTTER_ACTOR_IN_PREF_SIZE(a)           ((CLUTTER_PRIVATE_FLAGS (a) & 
(CLUTTER_IN_PREF_HEIGHT|CLUTTER_IN_PREF_WIDTH)) != FALSE)
 
 #define CLUTTER_PARAM_READABLE  (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)
 #define CLUTTER_PARAM_WRITABLE  (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)
@@ -98,15 +101,17 @@ typedef enum
   CLUTTER_IN_DESTRUCTION = 1 << 0,
   CLUTTER_IS_TOPLEVEL    = 1 << 1,
   CLUTTER_IN_REPARENT    = 1 << 2,
+  CLUTTER_IN_PREF_WIDTH  = 1 << 3,
+  CLUTTER_IN_PREF_HEIGHT = 1 << 4,
 
   /* Used to avoid recursion */
-  CLUTTER_IN_PAINT       = 1 << 3,
+  CLUTTER_IN_PAINT       = 1 << 5,
 
   /* Used to avoid recursion */
-  CLUTTER_IN_RELAYOUT    = 1 << 4,
+  CLUTTER_IN_RELAYOUT    = 1 << 6,
 
   /* a flag for internal children of Containers (DEPRECATED) */
-  CLUTTER_INTERNAL_CHILD = 1 << 5
+  CLUTTER_INTERNAL_CHILD = 1 << 7
 } ClutterPrivateFlags;
 
 /*
diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h
index dde8d4e21..688768bac 100644
--- a/clutter/clutter/clutter-stage-private.h
+++ b/clutter/clutter/clutter-stage-private.h
@@ -129,6 +129,8 @@ void            _clutter_stage_presented                (ClutterStage      *stag
                                                          CoglFrameEvent     frame_event,
                                                          ClutterFrameInfo  *frame_info);
 
+GList *         _clutter_stage_peek_stage_views         (ClutterStage *stage);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_STAGE_PRIVATE_H__ */
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index a10069eb1..67992d816 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -5003,3 +5003,17 @@ clutter_stage_thaw_updates (ClutterStage *stage)
       _clutter_master_clock_set_paused (master_clock, FALSE);
     }
 }
+
+GList *
+_clutter_stage_peek_stage_views (ClutterStage *stage)
+{
+  ClutterStagePrivate *priv = stage->priv;
+
+  return _clutter_stage_window_get_views (priv->impl);
+}
+
+void
+clutter_stage_update_resource_scales (ClutterStage *stage)
+{
+  _clutter_actor_queue_update_resource_scale_recursive (CLUTTER_ACTOR (stage));
+}
diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c
index c8afa752c..add3e81fd 100644
--- a/src/backends/native/meta-stage-native.c
+++ b/src/backends/native/meta-stage-native.c
@@ -137,9 +137,11 @@ meta_stage_native_rebuild_views (MetaStageNative *stage_native)
 {
   MetaBackend *backend = meta_get_backend ();
   MetaRenderer *renderer = meta_backend_get_renderer (backend);
+  ClutterActor *stage = meta_backend_get_stage (backend);
 
   meta_renderer_rebuild_views (renderer);
   meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer));
+  clutter_stage_update_resource_scales (CLUTTER_STAGE (stage));
   ensure_frame_callbacks (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 81a95bae8..172c4d9ac 100644
--- a/src/backends/x11/nested/meta-backend-x11-nested.c
+++ b/src/backends/x11/nested/meta-backend-x11-nested.c
@@ -68,7 +68,10 @@ meta_backend_x11_nested_update_screen_size (MetaBackend *backend,
   MetaRenderer *renderer = meta_backend_get_renderer (backend);
 
   if (meta_is_stage_views_enabled ())
-    meta_renderer_rebuild_views (renderer);
+    {
+      meta_renderer_rebuild_views (renderer);
+      clutter_stage_update_resource_scales (CLUTTER_STAGE (stage));
+    }
   clutter_actor_set_size (stage, width, height);
 }
 


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