After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 670636 - avoid unnecessary redraws of uiGroup
avoid unnecessary redraws of uiGroup
Status: RESOLVED OBSOLETE
Product: gnome-shell
Classification: Core
Component: general
3.3.x
Other Linux
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
: 673673 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2012-02-22 20:05 UTC by Stefano Facchini
Modified: 2021-07-05 14:17 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
main: don't use a BindConstraint for uiGroup (1.67 KB, patch)
2012-02-22 20:07 UTC, Stefano Facchini
committed Details | Review
main: don't use a BindConstraint for uiGroup (2.34 KB, patch)
2012-04-07 20:30 UTC, Stefano Facchini
rejected Details | Review

Description Stefano Facchini 2012-02-22 20:05:47 UTC
The BindConstraint on uiGroup introduced in commit 	0c2037875a9368134ae3c7b7b97e67033b8801d1 has the side-effect of forcing full redraws of the stage for every motion-event during a drag, making the UI sometimes laggy.

The simplest fix is to remove the constraint and use get_preferred_{width,height}. As discussed on IRC, this can be sub-optimal but it can be used as fallback if nothing better comes out.
Comment 1 Stefano Facchini 2012-02-22 20:07:17 UTC
Created attachment 208217 [details] [review]
main: don't use a BindConstraint for uiGroup

A BindConstraint on the size of uiGroup forces full redraws of the scene.
Instead, implement and use get_preferred_width and get_preferred_height.
Comment 2 drago01 2012-02-23 10:58:04 UTC
Review of attachment 208217 [details] [review]:

<ebassi> drago01: the constraint will update the allocation, but not the preferred size; there may be something asking for the size of the uiGroup prior to the allocation, thus getting the preferred size? no idea
<drago01> ebassi: the lightbox uses a constraint on the uiGroup to sync it's size / position ... wouldn't that cause the allocation of uiGroup to be updated?
<ebassi> yes, that's how constraints work: we query them during clutter_actor_allocate()

Marking as needs-work based on that.
Comment 3 drago01 2012-02-28 13:38:43 UTC
Can you retest whether this is till needed with the new paint_volume handling that landed in master?
Comment 4 Alex Hultman 2012-04-07 16:02:39 UTC
See also Bug 673673
Comment 5 drago01 2012-04-07 16:12:31 UTC
Review of attachment 208217 [details] [review]:

We should probably just go with that (it fixes a real issue after all) but add a comment in the code explaining why we can't use a constraint here.
Comment 6 drago01 2012-04-07 16:13:06 UTC
*** Bug 673673 has been marked as a duplicate of this bug. ***
Comment 7 Jasper St. Pierre (not reading bugmail) 2012-04-07 16:19:25 UTC
drago01, I remember this being fixed with some of the patches with the new St... is that not the case? Also, this is a Clutter bug, is it not?
Comment 8 drago01 2012-04-07 16:21:11 UTC
(In reply to comment #7)
> drago01, I remember this being fixed with some of the patches with the new
> St... is that not the case?

Apparently not Stefano could still reproduce it and it seems it happens for Alex too.

>  Also, this is a Clutter bug, is it not?

Ebassi thinks it isn't.
Comment 9 Stefano Facchini 2012-04-07 16:36:21 UTC
To add some more weirdness, replacing the signal handlers with this (as drago01 suggested IIRC):

const UiGroup = new Lang.Class({
    Name: 'UiGroup',
    Extends: Shell.GenericContainer,

    vfunc_allocate: function (box, flags) {
        let children = this.get_children();
        for (let i = 0; i < children.length; i++)
            children[i].allocate_preferred_size(flags);
    },

    vfunc_get_preferred_width: function(forHeight) {
        let width = global.stage.width;
        return [width, width];
    },

    vfunc_get_preferred_height: function(forWidth) {
        let height = global.stage.height;
        return [height, height];
    }
});

[...]

uiGroup = new UiGroup();

[...]


also fails to work.
Comment 10 Jasper St. Pierre (not reading bugmail) 2012-04-07 16:40:55 UTC
I'm quite sure this is Clutter's fault. CCing ebassi.
Comment 11 Emmanuele Bassi (:ebassi) 2012-04-07 18:03:51 UTC
(In reply to comment #9)

> also fails to work.

define "fails to work": the paint volume is not respected?

the default get_paint_volume() implementation will only return a valid paint volume *iff* the function pointers for paint() and get_paint_volume() are the ones installed by ClutterActor - to avoid breaking backward compatibility. if any of those two pointers are different, then the default implementation will return FALSE.

just to rule out any default behaviour, override get_paint_volume() with something like:

  vfunc_get_paint_volume : function(paintVolume) {
      let defaultPaintVolume = this.get_default_paint_volume();

      if (defaultPaintVolume) {
          paintVolume.set_origin(defaultPaintVolume.get_origin());
          paintVolume.set_width(defaultPaintVolume.get_width());
          paintVolume.set_height(defaultPaintVolume.get_height());
          paintVolume.set_depth(defaultPaintVolume.get_depth());
          return true;
      }
      else {
          return false;
      }
  },

and see if the clipped redraws work.
Comment 12 Stefano Facchini 2012-04-07 19:06:49 UTC
(In reply to comment #11)
> (In reply to comment #9)
> 
> define "fails to work"

1. $ CLUTTER_PAINT=redraws gnome-shell --replace
2. Go to overview and drag a window around
=> every actor has a green border

This happens both when using the bind constraint and when overriding the vfuncs (event with vfunc_get_paint_volume). OTOH, connecting the signal handlers as in the patch I see a blue border around most actors, except the dragged one (green border + slightly bigger red border).
Comment 13 Jasper St. Pierre (not reading bugmail) 2012-04-07 19:12:59 UTC
(In reply to comment #9)
> To add some more weirdness, replacing the signal handlers with this (as drago01
> suggested IIRC):
> 
> const UiGroup = new Lang.Class({
>     Name: 'UiGroup',
>     Extends: Shell.GenericContainer,
>     ...
> });

Why are you subclassing Shell.GenericContainer? Just subclass ClutterActor.
Comment 14 Stefano Facchini 2012-04-07 20:30:24 UTC
(In reply to comment #13)
> (In reply to comment #9)
> > To add some more weirdness, replacing the signal handlers with this (as drago01
> > suggested IIRC):
> > 
> > const UiGroup = new Lang.Class({
> >     Name: 'UiGroup',
> >     Extends: Shell.GenericContainer,
> >     ...
> > });
> 
> Why are you subclassing Shell.GenericContainer? Just subclass ClutterActor.

Because layout.js makes use of the set_skip_paint method and I was lazy to check if this could be avoided somehow.

But actually the subclassing approach works, too, I just forgot to call set_allocation() in vfunc_allocate.
Comment 15 Stefano Facchini 2012-04-07 20:30:58 UTC
Created attachment 211552 [details] [review]
main: don't use a BindConstraint for uiGroup

A BindConstraint on the size of uiGroup forces full redraws of the scene.
Instead, implement and use get_preferred_width and get_preferred_height.
Comment 16 Jasper St. Pierre (not reading bugmail) 2012-04-07 20:47:47 UTC
Unless I"m missing something, set_skip_paint should be the same as show/hide, no?
Comment 17 Stefano Facchini 2012-04-07 21:04:24 UTC
(In reply to comment #16)
> Unless I"m missing something, set_skip_paint should be the same as show/hide,
> no?

It is used as an override to hide "visible" actors without fiddling with their state, IIRC (useful for example when there is a fullscreen window). So, when in layout.js we have actor.set_skip_paint(false) it doesn't mean that the actor will be painted.

I tried once a naive replacement with show/hide, it broke dash tooltips and something on the message tray (a boxpointer?)
Comment 18 Jasper St. Pierre (not reading bugmail) 2012-04-12 18:47:11 UTC
So, after a good two or three hours of tracking this down, I finally realized this was:

http://git.gnome.org/browse/clutter/tree/clutter/clutter-bind-constraint.c#n149

The stage is layed out every frame, which means that the uiGroup gets a relayout every frame as well. We need to track the source's allocation. Unfortunately, naively swapping the "queue-relayout" signal with "allocation-changed" causes "clutter_actor_queue_relayout() called while in allocation cycle" warnings.
Comment 19 Jasper St. Pierre (not reading bugmail) 2012-04-12 18:49:40 UTC
Review of attachment 208217 [details] [review]:

Let's go with this for now, until Emmanuele looks into and solves this for real.
Comment 20 Jasper St. Pierre (not reading bugmail) 2012-04-12 18:50:14 UTC
Review of attachment 211552 [details] [review]:

I'm not comfortable using the new JS GObject inheritance in a .1 release.
Comment 21 Stefano Facchini 2012-04-13 13:20:32 UTC
Comment on attachment 208217 [details] [review]
main: don't use a BindConstraint for uiGroup

Attachment 208217 [details] pushed as 8c94a5a - main: don't use a BindConstraint for uiGroup
Comment 22 GNOME Infrastructure Team 2021-07-05 14:17:21 UTC
GNOME is going to shut down bugzilla.gnome.org in favor of  gitlab.gnome.org.
As part of that, we are mass-closing older open tickets in bugzilla.gnome.org
which have not seen updates for a longer time (resources are unfortunately
quite limited so not every ticket can get handled).

If you can still reproduce the situation described in this ticket in a recent
and supported software version, then please follow
  https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines
and create a new ticket at
  https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/

Thank you for your understanding and your help.