Merge lp:~vanvugt/unity/fix-917210-trunk into lp:unity

Proposed by Daniel van Vugt
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 2146
Proposed branch: lp:~vanvugt/unity/fix-917210-trunk
Merge into: lp:unity
Diff against target: 125 lines (+51/-10)
3 files modified
manual-tests/Wakeups.txt (+23/-0)
plugins/unityshell/src/Launcher.cpp (+26/-8)
plugins/unityshell/src/Launcher.h (+2/-2)
To merge this branch: bzr merge lp:~vanvugt/unity/fix-917210-trunk
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
Tim Penhey Pending
Review via email: mp+97348@code.launchpad.net

This proposal supersedes a proposal from 2012-01-24.

Commit message

Fix the autoscroll timer waking up 50 times per sec when no scrolling needs to be done (LP: #917210)

Description of the change

Fix the autoscroll timer waking up 50 times per sec when no scrolling needs to be done (LP: #917210)

Also removed some unused variables.

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

Hi Daniel,

How do we test that this has been fixed?

review: Needs Information
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Sorry for the delay, it's a public holiday...

To test the fix use "powertop" or "eventstat" to display the number of kernel wakeups per second each process is causing. As discussed in bug 917210. Though, you will also need the compiz fix installed (fix-880707.2 available in ppa:vanvugt/compiz) to avoid the constant wakeups caused by the old composite code.

A well-behaving "idle" compiz shouldn't be waking up more than about 10 times per second, maximum. Ideally less.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

You may also need to hover the mouse over either end of the launcher to make the autoscroll timer start. Then when you move the mouse off the launcher, it keeps spinning. That's the bug.

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

Hi Daniel,

I've been trying to test this. I installed powertop and made my launcher icons large so they fold.

On an idle system, I have between 15 and 20 events / second from compiz.

Holding the mouse pointer over the launcher at the bottom makes compiz go from 25 to 38 events / second.

However leaving it and going idle again, it drops back to 15 to 20 events / second.

Do you have the launcher always out?

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Yes, my launcher is always visible. Maybe that's the difference?

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

On Tue 14 Feb 2012 16:11:19 NZDT, Daniel van Vugt wrote:
> Yes, my launcher is always visible. Maybe that's the difference?
>

I'll try that

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

If it looks too much, I remember there was an ultra-simplified version of this fix that was possible. However the simplified version could not detect when the mouse "happens to be left idle over one of the autoscroll hotspots on the launcher".

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

On Tue 14 Feb 2012 16:21:18 NZDT, Daniel van Vugt wrote:
> If it looks too much, I remember there was an ultra-simplified version of this fix that was possible. However the simplified version could not detect when the mouse "happens to be left idle over one of the autoscroll hotspots on the launcher".

Can you still reproduce this behaviour with trunk? I'm compiling and
testing here.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Sorry, that was developed on oneiric and then ported to trunk by hand. I haven't tested unity trunk yet.

If you can't reproduce the problem then maybe demote the bug to Medium and defer it till I (or someone) can revisit it?

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

It seems that this has since been fixed.

I can't get compiz to keep the high number of wakeups after moving the mouse off the launcher.

Do you think we should say the bug is fixed? or just demote and comment?

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I think just demote and comment. Leave it up to Colin King or myself to retest later.

The primary problem when the mouse is not over the launcher may have been fixed already. Thought given the original issue was obvious upon simple code review I can't imagine how it might have been fixed if there are no conflicts caused by this branch.

Also, your comment "Holding the mouse pointer over the launcher at the bottom makes compiz go from 25 to 38 events / second." shows that you are still able to reproduce part of the bug.

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

So this reduces the number of wake-ups only while the cursor is in the auto-scroll position?

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

No, it definitely does both.

From memory my test scenario was:
1. Have the launcher always visible.
2. Hover over the top or bottom of the launcher to start the timer.
3. Move the pointer back to the regular desktop.
4. The timer keeps spinning at full speed even though I'm not hovering over any part of the launcher any more.

The primary cause of unwanted wakeups was the timer callback returning TRUE when it should have been FALSE (to cancel the timer). This appears to be a very simple and obvious logic error. The important changes are lines 49-->52 and 62-->75. The important parts are to return FALSE (and set _autoscroll_handle = 0) to stop the timer as soon as it is no longer required.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote : Posted in a previous version of this proposal

The logic I see here seems right. There's no reason to keep the timer running, if it's not needed.

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

My concern here now is that the logic has changed:

Before:
  if (self->_keynav_activated || self->_key_switcher_activated || !self->_hovered ||
      self->GetActionState() == ACTION_DRAG_LAUNCHER)
    return TRUE

Now:
  all the above, + self->_scroll_limit_reached
  -> effectively return FALSE;

This feels wrong. If I'm wrong, can you explain it?

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Tim, you have spotted the primary cause of bug 917210. It should return FALSE there to cancel the timer. As I mentioned in my previous comment.

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

OK, I understand now.

I'd like to make sure we have some test coverage of it though.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Fixed conflicts. Added test case. Re-tested against unity_5.6.0-0ubuntu3. Works!

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Looks good to me.

Would be possible to add some introspection data and test with Autopilot when the timeout is running and when not?
(to check that is there only when it should).

review: Needs Information
Revision history for this message
Alex Launi (alexlauni) wrote :

Could you investigate automating this? It should be very simple once you figure out how to get wake ups.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Let's approve it for now... We'll automate the test ASAP. With didrock's approval ;)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'manual-tests/Wakeups.txt'
2--- manual-tests/Wakeups.txt 1970-01-01 00:00:00 +0000
3+++ manual-tests/Wakeups.txt 2012-03-14 07:38:39 +0000
4@@ -0,0 +1,23 @@
5+Launcher autoscroll wake-ups
6+----------------------------
7+This test makes sure that the timer controlling autoscroll animations does
8+not keep running (at 50Hz) when it's not required to animate anything. This
9+is LP: #917210.
10+
11+#. Ensure the screen is idle, with very little changing.
12+#. Open a terminal and start a tool that can measure process wakeups per
13+ second. You can choose one of:
14+ - gnome-power-statistics (click on Processor)
15+ - powertop
16+ - eventstat
17+#. Hover the mouse pointer over the top end of the Launcher. That's just above
18+ the Ubuntu icon.
19+#. Hover the mouse pointer over the bottom end of the Launcher. That's over
20+ the bottom of the trash icon.
21+#. Move the mouse pointer back to the centre of the screen and leave it there.
22+#. Wait 30-60 seconds, leaving the screen idle before verifying the Outcome.
23+
24+Outcome
25+ The number of wakeups per second (events per second) reported for the
26+ compiz process should be much lower than 50.
27+
28
29=== modified file 'plugins/unityshell/src/Launcher.cpp'
30--- plugins/unityshell/src/Launcher.cpp 2012-03-13 17:20:30 +0000
31+++ plugins/unityshell/src/Launcher.cpp 2012-03-14 07:38:39 +0000
32@@ -201,8 +201,7 @@
33 _folded_angle = 1.0f;
34 _neg_folded_angle = -1.0f;
35 _space_between_icons = 5;
36- _launcher_top_y = 0;
37- _launcher_bottom_y = 0;
38+ _last_delta_y = 0.0f;
39 _folded_z_distance = 10.0f;
40 _launcher_action_state = ACTION_NONE;
41 _icon_under_mouse = NULL;
42@@ -227,6 +226,7 @@
43 _shortcuts_shown = false;
44 _hovered = false;
45 _hidden = false;
46+ _scroll_limit_reached = false;
47 _render_drag_window = false;
48 _drag_edge_touching = false;
49 _steal_drag = false;
50@@ -1203,6 +1203,9 @@
51 delta_y *= hover_progress;
52 center.y += delta_y;
53 folding_threshold += delta_y;
54+
55+ _scroll_limit_reached = (delta_y == _last_delta_y);
56+ _last_delta_y = delta_y;
57 }
58 else
59 {
60@@ -1669,12 +1672,18 @@
61 {
62 Launcher* self = (Launcher*) data;
63 nux::Geometry geo = self->GetGeometry();
64+ gboolean anim = TRUE;
65
66+ //
67+ // Always check _scroll_limit_reached to ensure we don't keep spinning
68+ // this timer if the mouse happens to be left idle over one of the autoscroll
69+ // hotspots on the launcher.
70+ //
71 if (self->IsInKeyNavMode() || !self->_hovered ||
72+ self->_scroll_limit_reached ||
73 self->GetActionState() == ACTION_DRAG_LAUNCHER)
74- return TRUE;
75-
76- if (self->MouseOverTopScrollArea())
77+ anim = FALSE;
78+ else if (self->MouseOverTopScrollArea())
79 {
80 if (self->MouseOverTopScrollExtrema())
81 self->_launcher_drag_delta += 6;
82@@ -1688,9 +1697,18 @@
83 else
84 self->_launcher_drag_delta -= 3;
85 }
86-
87- self->EnsureAnimation();
88- return TRUE;
89+ else
90+ anim = FALSE;
91+
92+ if (anim)
93+ self->EnsureAnimation();
94+ else
95+ {
96+ self->_autoscroll_handle = 0;
97+ self->_scroll_limit_reached = false;
98+ }
99+
100+ return anim;
101 }
102
103 void Launcher::EnsureScrollTimer()
104
105=== modified file 'plugins/unityshell/src/Launcher.h'
106--- plugins/unityshell/src/Launcher.h 2012-03-13 02:07:54 +0000
107+++ plugins/unityshell/src/Launcher.h 2012-03-14 07:38:39 +0000
108@@ -315,6 +315,7 @@
109
110 bool _hovered;
111 bool _hidden;
112+ bool _scroll_limit_reached;
113 bool _render_drag_window;
114
115 bool _shortcuts_shown;
116@@ -324,8 +325,7 @@
117 float _folded_angle;
118 float _neg_folded_angle;
119 float _folded_z_distance;
120- float _launcher_top_y;
121- float _launcher_bottom_y;
122+ float _last_delta_y;
123 float _edge_overcome_pressure;
124
125 LauncherActionState _launcher_action_state;