Merge lp:~thumper/unity/regional-damage-sru into lp:unity/5.0

Proposed by Tim Penhey on 2012-07-26
Status: Merged
Approved by: Łukasz Zemczak on 2012-08-02
Approved revision: 2399
Merged at revision: 2394
Proposed branch: lp:~thumper/unity/regional-damage-sru
Merge into: lp:unity/5.0
Diff against target: 784 lines (+353/-117)
12 files modified
manual-tests/Dash.txt (+15/-0)
manual-tests/Launcher.txt (+15/-0)
manual-tests/Panel.txt (+17/-0)
manual-tests/WindowManagement.txt (+20/-0)
plugins/unityshell/src/AbstractLauncherIcon.h (+1/-0)
plugins/unityshell/src/Launcher.cpp (+11/-0)
plugins/unityshell/src/Launcher.h (+4/-0)
plugins/unityshell/src/LauncherIcon.cpp (+3/-0)
plugins/unityshell/src/PanelController.cpp (+15/-0)
plugins/unityshell/src/PanelController.h (+1/-0)
plugins/unityshell/src/unityshell.cpp (+239/-110)
plugins/unityshell/src/unityshell.h (+12/-7)
To merge this branch: bzr merge lp:~thumper/unity/regional-damage-sru
Reviewer Review Type Date Requested Status
Łukasz Zemczak Approve on 2012-08-02
Marco Trevisan (Treviño) 2012-07-26 Approve on 2012-08-01
Daniel van Vugt 2012-07-26 Approve on 2012-07-27
Review via email: mp+116796@code.launchpad.net

Commit message

Backport the fixes for regional damage, and the regressions that were introduced by it.
Fixes lots of bugs.

Description of the change

This branch backports the fixes for regional damage, and the regression that were introduced by it.

Fixes lots of bugs.

To post a comment you must log in.
Daniel van Vugt (vanvugt) wrote :

Please note: This proposal has two external prerequisite fixes:
  bug 1012956 (already fixed in lp:compiz-core/0.9.7)
  bug 1014610 (already fixed in lp:nux/2.0)

It appears neither of these fixes have hit ubuntu yet.

Daniel van Vugt (vanvugt) wrote :

Looks OK but keeps crashing when I run it on nvidia-295.49. The crash does not happen with lp:unity/5.0 !?

(gdb) bt
#0 0x00007fb402b65e1e in ?? () from /usr/lib/nvidia-current-updates/libnvidia-glcore.so.295.49
#1 0x00007fb402c09da1 in ?? () from /usr/lib/nvidia-current-updates/libnvidia-glcore.so.295.49
#2 0x00007fb402e0ada1 in ?? () from /usr/lib/nvidia-current-updates/libnvidia-glcore.so.295.49
#3 0x00007fb402e081f3 in ?? () from /usr/lib/nvidia-current-updates/libnvidia-glcore.so.295.49
#4 0x00007fb3ff4df22a in nux::GraphicsEngine::QRP_GLSL_1Tex(int, int, int, int, nux::ObjectPtr<nux::IOpenGLBaseTexture>, nux::TexCoordXForm&, nux::color::Color const&) ()
   from /usr/lib/libnux-graphics-2.0.so.0
#5 0x00007fb3ff4c98e9 in nux::GraphicsEngine::QRP_1Tex(int, int, int, int, nux::ObjectPtr<nux::IOpenGLBaseTexture>, nux::TexCoordXForm&, nux::color::Color const&) ()
   from /usr/lib/libnux-graphics-2.0.so.0
#6 0x00007fb3ff822891 in nux::WindowCompositor::PresentBufferToScreen(nux::ObjectPtr<nux::IOpenGLBaseTexture>, int, int, bool, bool, float, bool) () from /usr/lib/libnux-2.0.so.0
#7 0x00007fb3ff825990 in nux::WindowCompositor::RenderTopViews(bool, std::list<nux::ObjectWeakPtr<nux::BaseWindow>, std::allocator<nux::ObjectWeakPtr<nux::BaseWindow> > >&, bool) ()
   from /usr/lib/libnux-2.0.so.0
#8 0x00007fb3ff825cca in nux::WindowCompositor::Draw(bool, bool) () from /usr/lib/libnux-2.0.so.0
#9 0x00007fb3ff82ccb1 in nux::WindowThread::RenderInterfaceFromForeignCmd(nux::Rect*) () from /usr/lib/libnux-2.0.so.0
#10 0x00007fb4003e8cc4 in unity::UnityScreen::paintDisplay (this=0x1f07220, region=..., transform=..., mask=65536) at /home/dan/bzr/unity/tim/plugins/unityshell/src/unityshell.cpp:829

review: Needs Fixing
Daniel van Vugt (vanvugt) wrote :

And yes I did try compiling the latest lp:nux/2.0 as well. But when I use it, I get NO readable stacktrace of the crash.

Daniel van Vugt (vanvugt) wrote :

Uninstalled nvidia-295.49 and tested with nouveau. Now it works well.

Can anyone else confirm the nvidia crash?

review: Needs Information
Daniel van Vugt (vanvugt) wrote :

Verified; works on intel too. Why is only nvidia broken?!

Brenton Hall (brent-hall-27) wrote :

Compiled it. Running fine on ATI, using the open drivers.

Brenton Hall (brent-hall-27) wrote :

Been through the new manual tests for this branch. They all passed for ATI.

Daniel van Vugt (vanvugt) wrote :

Tested Unit 6.0 and Nux 3.0 again. They now crash in the same way on nvidia. So it's nothing to do with this branch.

I also upgraded nvidia 295.40 to 295.49 but no difference (other than the stack traces are now completely unreadable).

I suspect the nvidia problem could be related to bug 982485 or bug 980298. When run under valgrind, I get a rubbish stack, but it happens immediately after bug 988880, which might be relevant.

Anyway, this branch seems good but I can't test it on nvidia-current/nvidia-current-updates.

review: Approve
Daniel van Vugt (vanvugt) wrote :

Actually, bug 982626 seems to describe the exact crash I'm getting now. Let's make that a separate discussion to this.

Marco Trevisan (Treviño) (3v1n0) wrote :

I can confirm the crash on a Nvidia GeForce GT 650M, the first time I launched this unity branch it worked and it also seemed to fix the bug #915265, however it hanged and after reloading compiz (one or two times), I can't run it anymore.

Gdb complains issues related to the nvidia bloab, so... It's not helpful at all.

The same happens with trunk with this change enabled.

Łukasz Zemczak (sil2100) wrote :

I would probably like to have this fixed before releasing this as an SRU. I know we have the same bug in trunk and quantal, but Precise is a LTS, so we probably shouldn't release anything that has any known ill side-effects. So fixing bug #982626 becomes rather a priority here.

Marco Trevisan (Treviño) (3v1n0) wrote :

FYI this is the stacktrace of the crash that I'm getting http://paste.ubuntu.com/1121725/

Marco Trevisan (Treviño) (3v1n0) wrote :

A weird thing about this crash is that if I replace an unity sesssion, from unity it will always crash.
If I replace it after a tty switch, then there's no crash...

Marco Trevisan (Treviño) (3v1n0) wrote :

Using a bad workaround like this, seems to bypass the crash... http://paste.ubuntu.com/1122495/
Checking something better.

Marco Trevisan (Treviño) (3v1n0) wrote :

Ok, thanks to the Sam's tip, I got the proper fix for the crash that was affecting the nvidia cards (using the nvidia driver).

I've made a branch that fixes this, and that uses this one as prerequisite: lp:~3v1n0/unity/fix-nvidia-glDrawArrays-crash-5.0/+merge/117553

So, at this point I can approve this branch too.

review: Approve
Łukasz Zemczak (sil2100) wrote :

Since I already tested the branch, along with Alan and the Nice guys, I think it's safe to apply as the nvidia bug is getting handled as well.

review: Approve
Unity Merger (unity-merger) wrote :

No commit message specified.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'manual-tests/Dash.txt'
2--- manual-tests/Dash.txt 2012-06-21 16:10:54 +0000
3+++ manual-tests/Dash.txt 2012-07-26 05:12:23 +0000
4@@ -203,6 +203,21 @@
5 Outcome:
6 The Dash should close and the music file should open up in Firefox.
7
8+
9+DnD stacking
10+------------
11+
12+Setup:
13+#. Open the Dash (Super).
14+
15+Action:
16+#. Drag any icon from the dash and wave it over the dash and launcher area.
17+
18+Outcome:
19+ The icon being dragged is drawn on top of the dash and launcher. Never
20+ below it.
21+
22+
23 Lens Tests
24 ============
25
26
27=== modified file 'manual-tests/Launcher.txt'
28--- manual-tests/Launcher.txt 2012-07-13 15:19:42 +0000
29+++ manual-tests/Launcher.txt 2012-07-26 05:12:23 +0000
30@@ -40,6 +40,21 @@
31 in the last used workspace.
32
33
34+Test Alt+F1 KeyNavMode Rendering
35+--------------------------------
36+This test shows that the launcher is redrawing correctly during Alt+F1
37+KeyNav mode.
38+
39+Action:
40+#. Press Alt+F1 to enter keynav mode.
41+#. Keep pressing the down arrow key until the highlighted launcher icon is the
42+ bottom one (usually Trash).
43+
44+Outcome:
45+ For every Down keypress, the next launcher icon down should be highlighted.
46+ Verify each icon gets highlighted from top to bottom.
47+
48+
49 Test Alt+F1 KeyNavMode Mouse Works
50 -------------------------------
51 This test shows that the mouse still works normally while keynav mode is active.
52
53=== modified file 'manual-tests/Panel.txt'
54--- manual-tests/Panel.txt 2012-04-05 22:21:55 +0000
55+++ manual-tests/Panel.txt 2012-07-26 05:12:23 +0000
56@@ -69,3 +69,20 @@
57 Expected Result:
58 The panel should stay translucent
59
60+
61+Panel (and Launcher) blinking/flickering
62+-----------------------------------------
63+Setup:
64+#. Optionally install "emacs23"
65+
66+Actions:
67+#. Open LibreOffice Impress.
68+#. Click on "Click to add title" and "Click to add text" a few times.
69+#. Optionally: Run emacs23
70+#. Optionally: Open a large file in emacs23.
71+#. Optionally: Scroll to the bottom of the file using Page Down.
72+
73+Outcome:
74+ At no point during the actions should the panel (or launcher) blink or
75+ flicker out of existence.
76+
77
78=== modified file 'manual-tests/WindowManagement.txt'
79--- manual-tests/WindowManagement.txt 2012-03-23 15:14:42 +0000
80+++ manual-tests/WindowManagement.txt 2012-07-26 05:12:23 +0000
81@@ -49,3 +49,23 @@
82
83 Outcome:
84 The window should be in the maximized state.
85+
86+
87+Fullscreen windows
88+--------------------
89+Tests rendering of fullscreen windows.
90+
91+Action:
92+#. Set a window to full screen. e.g. F11 in a web browser.
93+#. Verify you can scroll the window.
94+#. Tap the Super key.
95+#. Verify you can still scroll the window.
96+
97+Outcome:
98+ The fullscreen window should never look corrupt and always be scrollable.
99+
100+Recovery (in case of failure):
101+#. Tap the Super key again.
102+#. Tap F11 to leave full screen.
103+#. Press Super+S twice to force a full screen redraw.
104+
105
106=== modified file 'plugins/unityshell/src/AbstractLauncherIcon.h'
107--- plugins/unityshell/src/AbstractLauncherIcon.h 2012-07-16 11:03:18 +0000
108+++ plugins/unityshell/src/AbstractLauncherIcon.h 2012-07-26 05:12:23 +0000
109@@ -218,6 +218,7 @@
110
111 sigc::signal<void, AbstractLauncherIcon::Ptr> needs_redraw;
112 sigc::signal<void, AbstractLauncherIcon::Ptr> remove;
113+ sigc::signal<void, nux::ObjectPtr<nux::View>> tooltip_visible;
114 sigc::signal<void> visibility_changed;
115
116 sigc::connection needs_redraw_connection;
117
118=== modified file 'plugins/unityshell/src/Launcher.cpp'
119--- plugins/unityshell/src/Launcher.cpp 2012-07-17 16:20:53 +0000
120+++ plugins/unityshell/src/Launcher.cpp 2012-07-26 05:12:23 +0000
121@@ -1655,6 +1655,11 @@
122 }
123 }
124
125+nux::ObjectPtr<nux::View> Launcher::GetActiveTooltip() const
126+{
127+ return _active_tooltip;
128+}
129+
130 void
131 Launcher::SetActionState(LauncherActionState actionstate)
132 {
133@@ -1815,6 +1820,7 @@
134 EnsureAnimation();
135
136 icon->needs_redraw.connect(sigc::mem_fun(this, &Launcher::OnIconNeedsRedraw));
137+ icon->tooltip_visible.connect(sigc::mem_fun(this, &Launcher::OnTooltipVisible));
138 }
139
140 void Launcher::OnIconRemoved(AbstractLauncherIcon::Ptr icon)
141@@ -1891,6 +1897,11 @@
142 EnsureAnimation();
143 }
144
145+void Launcher::OnTooltipVisible(nux::ObjectPtr<nux::View> view)
146+{
147+ _active_tooltip = view;
148+}
149+
150 void Launcher::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
151 {
152
153
154=== modified file 'plugins/unityshell/src/Launcher.h'
155--- plugins/unityshell/src/Launcher.h 2012-04-17 05:29:12 +0000
156+++ plugins/unityshell/src/Launcher.h 2012-07-26 05:12:23 +0000
157@@ -99,6 +99,8 @@
158 return _parent;
159 };
160
161+ nux::ObjectPtr<nux::View> GetActiveTooltip() const; // nullptr = no tooltip
162+
163 virtual void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags);
164 virtual void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
165 virtual void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
166@@ -276,6 +278,7 @@
167 void OnOrderChanged();
168
169 void OnIconNeedsRedraw(AbstractLauncherIcon::Ptr icon);
170+ void OnTooltipVisible(nux::ObjectPtr<nux::View> view);
171
172 void OnOverlayHidden(GVariant* data);
173 void OnOverlayShown(GVariant* data);
174@@ -314,6 +317,7 @@
175
176 void DndReset();
177 void DndHoveredIconReset();
178+ nux::ObjectPtr<nux::View> _active_tooltip;
179
180 nux::HLayout* m_Layout;
181
182
183=== modified file 'plugins/unityshell/src/LauncherIcon.cpp'
184--- plugins/unityshell/src/LauncherIcon.cpp 2012-07-16 11:03:18 +0000
185+++ plugins/unityshell/src/LauncherIcon.cpp 2012-07-26 05:12:23 +0000
186@@ -524,6 +524,7 @@
187 LoadTooltip();
188 _tooltip->ShowTooltipWithTipAt(tip_x, tip_y);
189 _tooltip->ShowWindow(!tooltip_text().empty());
190+ tooltip_visible.emit(_tooltip);
191 }
192
193 void
194@@ -545,6 +546,7 @@
195
196 if (_tooltip)
197 _tooltip->ShowWindow(false);
198+ tooltip_visible.emit(nux::ObjectPtr<nux::View>(nullptr));
199 }
200
201 bool LauncherIcon::OpenQuicklist(bool select_first_item, int monitor)
202@@ -663,6 +665,7 @@
203 {
204 if (_tooltip)
205 _tooltip->ShowWindow(false);
206+ tooltip_visible.emit(nux::ObjectPtr<nux::View>(nullptr));
207 }
208
209 gboolean
210
211=== modified file 'plugins/unityshell/src/PanelController.cpp'
212--- plugins/unityshell/src/PanelController.cpp 2012-04-04 20:21:45 +0000
213+++ plugins/unityshell/src/PanelController.cpp 2012-07-26 05:12:23 +0000
214@@ -48,6 +48,7 @@
215 void QueueRedraw();
216
217 std::vector<Window> GetTrayXids() const;
218+ std::vector<nux::View*> GetPanelViews() const;
219 std::vector<nux::Geometry> GetGeometries() const;
220
221 // NOTE: nux::Property maybe?
222@@ -111,6 +112,15 @@
223 return xids;
224 }
225
226+std::vector<nux::View*> Controller::Impl::GetPanelViews() const
227+{
228+ std::vector<nux::View*> views;
229+ views.reserve(windows_.size());
230+ for (auto window: windows_)
231+ views.push_back(ViewForWindow(window));
232+ return views;
233+}
234+
235 std::vector<nux::Geometry> Controller::Impl::GetGeometries() const
236 {
237 std::vector<nux::Geometry> geometries;
238@@ -337,6 +347,11 @@
239 return pimpl->GetTrayXids();
240 }
241
242+std::vector<nux::View*> Controller::GetPanelViews() const
243+{
244+ return pimpl->GetPanelViews();
245+}
246+
247 std::vector<nux::Geometry> Controller::GetGeometries() const
248 {
249 return pimpl->GetGeometries();
250
251=== modified file 'plugins/unityshell/src/PanelController.h'
252--- plugins/unityshell/src/PanelController.h 2012-04-02 14:02:29 +0000
253+++ plugins/unityshell/src/PanelController.h 2012-07-26 05:12:23 +0000
254@@ -41,6 +41,7 @@
255 void QueueRedraw();
256
257 std::vector<Window> GetTrayXids() const;
258+ std::vector<nux::View*> GetPanelViews() const;
259 std::vector<nux::Geometry> GetGeometries() const;
260
261 // NOTE: nux::Property maybe?
262
263=== modified file 'plugins/unityshell/src/unityshell.cpp'
264--- plugins/unityshell/src/unityshell.cpp 2012-07-13 17:56:23 +0000
265+++ plugins/unityshell/src/unityshell.cpp 2012-07-26 05:12:23 +0000
266@@ -115,8 +115,8 @@
267 , _redraw_handle(0)
268 , newFocusedWindow(nullptr)
269 , doShellRepaint(false)
270+ , didShellRepaint(false)
271 , allowWindowPaint(false)
272- , damaged(false)
273 , _key_nav_mode_requested(false)
274 , _last_output(nullptr)
275 #ifndef USE_GLES
276@@ -911,13 +911,14 @@
277 }
278
279 doShellRepaint = false;
280- damaged = false;
281+ didShellRepaint = true;
282 }
283
284 bool UnityScreen::forcePaintOnTop ()
285 {
286 return !allowWindowPaint ||
287- ((switcher_controller_->Visible() || launcher_controller_->IsOverlayOpen())
288+ ((switcher_controller_->Visible() ||
289+ PluginAdapter::Default()->IsExpoActive())
290 && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
291 }
292
293@@ -1204,6 +1205,42 @@
294 }
295 }
296
297+bool UnityScreen::shellCouldBeHidden(CompOutput const& output)
298+{
299+ std::vector<Window> const& nuxwins(nux::XInputWindow::NativeHandleList());
300+
301+ // Loop through windows from front to back
302+ CompWindowList const& wins = screen->windows();
303+ for ( CompWindowList::const_reverse_iterator r = wins.rbegin()
304+ ; r != wins.rend()
305+ ; r++
306+ )
307+ {
308+ CompWindow* w = *r;
309+
310+ /*
311+ * The shell is hidden if there exists any window that fully covers
312+ * the output and is in front of all Nux windows on that output.
313+ */
314+ if (w->isMapped() &&
315+ !(w->state () & CompWindowStateHiddenMask) &&
316+ w->geometry().contains(output))
317+ {
318+ return true;
319+ }
320+ else
321+ {
322+ for (Window n : nuxwins)
323+ {
324+ if (w->id() == n && output.intersects(w->geometry()))
325+ return false;
326+ }
327+ }
328+ }
329+
330+ return false;
331+}
332+
333 /* called whenever we need to repaint parts of the screen */
334 bool UnityScreen::glPaintOutput(const GLScreenPaintAttrib& attrib,
335 const GLMatrix& transform,
336@@ -1213,7 +1250,20 @@
337 {
338 bool ret;
339
340- doShellRepaint = true;
341+ /*
342+ * Very important!
343+ * Don't waste GPU and CPU rendering the shell on every frame if you don't
344+ * need to. Doing so on every frame causes Nux to hog the GPU and slow down
345+ * ALL rendering. (LP: #988079)
346+ */
347+ bool force = forcePaintOnTop();
348+ doShellRepaint = force ||
349+ ( !region.isEmpty() &&
350+ ( !wt->GetDrawList().empty() ||
351+ (mask & PAINT_SCREEN_FULL_MASK)
352+ )
353+ );
354+
355 allowWindowPaint = true;
356 _last_output = output;
357 paint_panel_ = false;
358@@ -1228,14 +1278,27 @@
359 * once an fbo is bound any further
360 * attempts to bind it will only increment
361 * its bind reference so make sure that
362- * you always unbind as much as you bind */
363- _fbo->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
364+ * you always unbind as much as you bind
365+ *
366+ * But NOTE: It is only safe to bind the FBO if !shellCouldBeHidden.
367+ * Otherwise it's possible painting won't occur and that would
368+ * confuse the state of the FBO.
369+ */
370+ if (doShellRepaint && !shellCouldBeHidden(*output))
371+ _fbo->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
372 #endif
373
374+ // CompRegion has no clear() method. So this is the fastest alternative.
375+ fullscreenRegion = CompRegion();
376+ nuxRegion = CompRegion();
377+
378 /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
379 ret = gScreen->glPaintOutput(attrib, transform, region, output, mask);
380
381 #ifndef USE_GLES
382+ if (doShellRepaint && !force && fullscreenRegion.contains(*output))
383+ doShellRepaint = false;
384+
385 if (doShellRepaint)
386 paintDisplay(region, transform, mask);
387 #endif
388@@ -1288,16 +1351,26 @@
389 for (ShowdesktopHandlerWindowInterface *wi : ShowdesktopHandler::animating_windows)
390 wi->HandleAnimations (ms);
391
392- if (damaged)
393- {
394- damaged = false;
395- damageNuxRegions();
396- }
397+ compizDamageNux(cScreen->currentDamage());
398
399+ didShellRepaint = false;
400+ firstWindowAboveShell = NULL;
401 }
402
403 void UnityScreen::donePaint()
404 {
405+ /*
406+ * It's only safe to clear the draw list if drawing actually occurred
407+ * (i.e. the shell was not obscured behind a fullscreen window).
408+ * If you clear the draw list and drawing has not occured then you'd be
409+ * left with all your views thinking they're queued for drawing still and
410+ * would refuse to redraw when you return from fullscreen.
411+ * I think this is a Nux bug. ClearDrawList should ideally also mark all
412+ * the queued views as draw_cmd_queued_=false.
413+ */
414+ if (didShellRepaint)
415+ wt->ClearDrawList();
416+
417 std::list <ShowdesktopHandlerWindowInterface *> remove_windows;
418
419 for (ShowdesktopHandlerWindowInterface *wi : ShowdesktopHandler::animating_windows)
420@@ -1318,35 +1391,116 @@
421 cScreen->donePaint ();
422 }
423
424+void UnityScreen::compizDamageNux(CompRegion const& damage)
425+{
426+ if (!launcher_controller_)
427+ return;
428+
429+ /*
430+ * Prioritise user interaction over active blur updates. So the general
431+ * slowness of the active blur doesn't affect the UI interaction performance.
432+ *
433+ * Also, BackgroundEffectHelper::ProcessDamage() is causing a feedback loop
434+ * while the dash is open. Calling it results in the NEXT frame (and the
435+ * current one?) to get some damage. This GetDrawList().empty() check avoids
436+ * that feedback loop and allows us to idle correctly.
437+ */
438+ if (wt->GetDrawList().empty())
439+ {
440+ CompRect::vector const& rects(damage.rects());
441+ for (CompRect const& r : rects)
442+ {
443+ nux::Geometry geo(r.x(), r.y(), r.width(), r.height());
444+ BackgroundEffectHelper::ProcessDamage(geo);
445+ }
446+ }
447+
448+ auto launchers = launcher_controller_->launchers();
449+ for (auto launcher : launchers)
450+ {
451+ if (!launcher->Hidden())
452+ {
453+ nux::Geometry geo = launcher->GetAbsoluteGeometry();
454+ CompRegion launcher_region(geo.x, geo.y, geo.width, geo.height);
455+ if (damage.intersects(launcher_region))
456+ launcher->QueueDraw();
457+ nux::ObjectPtr<nux::View> tooltip = launcher->GetActiveTooltip();
458+ if (!tooltip.IsNull())
459+ {
460+ nux::Geometry tip = tooltip->GetAbsoluteGeometry();
461+ CompRegion tip_region(tip.x, tip.y, tip.width, tip.height);
462+ if (damage.intersects(tip_region))
463+ tooltip->QueueDraw();
464+ }
465+ }
466+ }
467+
468+ std::vector<nux::View*> const& panels(panel_controller_->GetPanelViews());
469+ for (nux::View* view : panels)
470+ {
471+ nux::Geometry geo = view->GetAbsoluteGeometry();
472+ CompRegion panel_region(geo.x, geo.y, geo.width, geo.height);
473+ if (damage.intersects(panel_region))
474+ view->QueueDraw();
475+ }
476+
477+ QuicklistManager* qm = QuicklistManager::Default();
478+ if (qm)
479+ {
480+ QuicklistView* view = qm->Current();
481+ if (view)
482+ {
483+ nux::Geometry geo = view->GetAbsoluteGeometry();
484+ CompRegion quicklist_region(geo.x, geo.y, geo.width, geo.height);
485+ if (damage.intersects(quicklist_region))
486+ view->QueueDraw();
487+ }
488+ }
489+}
490+
491 /* Grab changed nux regions and add damage rects for them */
492-void UnityScreen::damageNuxRegions()
493+void UnityScreen::nuxDamageCompiz()
494 {
495+ /*
496+ * WARNING: Nux bug LP: #1014610 (unbounded DrawList growth) will cause
497+ * this code to be called far too often in some cases and
498+ * Unity will appear to freeze for a while. Please ensure you
499+ * have Nux 3.0+ with the fix for LP: #1014610.
500+ */
501+
502+ if (!launcher_controller_ || !dash_controller_)
503+ return;
504+
505 CompRegion nux_damage;
506
507- if (damaged)
508- return;
509-
510- std::vector<nux::Geometry> dirty = wt->GetDrawList();
511- damaged = true;
512-
513- for (std::vector<nux::Geometry>::iterator it = dirty.begin(), end = dirty.end();
514- it != end; ++it)
515- {
516- nux::Geometry const& geo = *it;
517- nux_damage += CompRegion(geo.x, geo.y, geo.width, geo.height);
518- }
519-
520- nux::Geometry geo = wt->GetWindowCompositor().GetTooltipMainWindowGeometry();
521- nux_damage += CompRegion(geo.x, geo.y, geo.width, geo.height);
522-
523- geo = lastTooltipArea;
524- nux_damage += CompRegion(lastTooltipArea.x, lastTooltipArea.y,
525- lastTooltipArea.width, lastTooltipArea.height);
526+ std::vector<nux::Geometry> const& dirty = wt->GetDrawList();
527+ for (auto geo : dirty)
528+ nux_damage += CompRegion(geo.x, geo.y, geo.width, geo.height);
529+
530+ if (launcher_controller_->IsOverlayOpen())
531+ {
532+ nux::BaseWindow* dash_window = dash_controller_->window();
533+ nux::Geometry const& geo = dash_window->GetAbsoluteGeometry();
534+ nux_damage += CompRegion(geo.x, geo.y, geo.width, geo.height);
535+ }
536+
537+ auto launchers = launcher_controller_->launchers();
538+ for (auto launcher : launchers)
539+ {
540+ if (!launcher->Hidden())
541+ {
542+ nux::ObjectPtr<nux::View> tooltip = launcher->GetActiveTooltip();
543+ if (!tooltip.IsNull())
544+ {
545+ nux::Geometry const& g = tooltip->GetAbsoluteGeometry();
546+ nux_damage += CompRegion(g.x, g.y, g.width, g.height);
547+ }
548+ }
549+ }
550+
551+ cScreen->damageRegionSetEnabled(this, false);
552 cScreen->damageRegion(nux_damage);
553-
554- wt->ClearDrawList();
555-
556- lastTooltipArea = geo;
557+ cScreen->damageRegionSetEnabled(this, true);
558 }
559
560 /* handle X Events */
561@@ -1502,44 +1656,12 @@
562 {
563 wt->ProcessForeignEvent(event, NULL);
564 }
565-
566- if (event->type == cScreen->damageEvent() + XDamageNotify)
567- {
568- XDamageNotifyEvent *de = (XDamageNotifyEvent *) event;
569- CompWindow* w = screen->findWindow (de->drawable);
570- std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
571- CompWindow* lastNWindow = screen->findWindow (xwns.back ());
572- bool processDamage = true;
573-
574- if (w)
575- {
576- if (!w->overrideRedirect () &&
577- w->isViewable () &&
578- !w->invisible ())
579- {
580-
581- for (; lastNWindow != NULL; lastNWindow = lastNWindow->next)
582- {
583- if (lastNWindow == w)
584- {
585- processDamage = false;
586- break;
587- }
588- }
589-
590- if (processDamage)
591- {
592- nux::Geometry damage (de->area.x, de->area.y, de->area.width, de->area.height);
593-
594- const CompWindow::Geometry &geom = w->geometry ();
595- damage.x += geom.x () + geom.border ();
596- damage.y += geom.y () + geom.border ();
597-
598- BackgroundEffectHelper::ProcessDamage(damage);
599- }
600- }
601- }
602- }
603+}
604+
605+void UnityScreen::damageRegion(const CompRegion &region)
606+{
607+ compizDamageNux(region);
608+ cScreen->damageRegion(region);
609 }
610
611 void UnityScreen::handleCompizEvent(const char* plugin,
612@@ -2195,14 +2317,6 @@
613 return false;
614 }
615
616-const CompWindowList& UnityScreen::getWindowPaintList()
617-{
618- CompWindowList& pl = _withRemovedNuxWindows = cScreen->getWindowPaintList();
619- pl.remove_if(isNuxWindow);
620-
621- return pl;
622-}
623-
624 void UnityScreen::RaiseInputWindows()
625 {
626 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
627@@ -2227,6 +2341,42 @@
628 const CompRegion& region,
629 unsigned int mask)
630 {
631+ /*
632+ * The occlusion pass tests windows from TOP to BOTTOM. That's opposite to
633+ * the actual painting loop.
634+ *
635+ * Detect uScreen->fullscreenRegion here. That represents the region which
636+ * fully covers the shell on its output. It does not include regular windows
637+ * stacked above the shell like DnD icons or Onboard etc.
638+ */
639+ if (isNuxWindow(window))
640+ {
641+ if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
642+ {
643+ uScreen->nuxRegion += window->geometry();
644+ uScreen->nuxRegion -= uScreen->fullscreenRegion;
645+ }
646+ return false; // Ensure nux windows are never painted by compiz
647+ }
648+ else if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
649+ {
650+ static const unsigned int nonOcclusionBits =
651+ PAINT_WINDOW_TRANSLUCENT_MASK |
652+ PAINT_WINDOW_TRANSFORMED_MASK |
653+ PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
654+ if (!(mask & nonOcclusionBits) &&
655+ (window->state() & CompWindowStateFullscreenMask))
656+ // And I've been advised to test other things, but they don't work:
657+ // && (attrib.opacity == OPAQUE)) <-- Doesn't work; Only set in glDraw
658+ // && !window->alpha() <-- Doesn't work; Opaque windows often have alpha
659+ {
660+ uScreen->fullscreenRegion += window->geometry();
661+ uScreen->fullscreenRegion -= uScreen->nuxRegion;
662+ }
663+ if (uScreen->nuxRegion.isEmpty())
664+ uScreen->firstWindowAboveShell = window;
665+ }
666+
667 GLWindowPaintAttrib wAttrib = attrib;
668
669 if (mMinimizeHandler)
670@@ -2285,28 +2435,17 @@
671 }
672 }
673
674- if (uScreen->doShellRepaint && !uScreen->forcePaintOnTop ())
675+ if (uScreen->doShellRepaint &&
676+ !uScreen->forcePaintOnTop () &&
677+ window == uScreen->firstWindowAboveShell &&
678+ !uScreen->fullscreenRegion.contains(window->geometry())
679+ )
680 {
681- std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
682- unsigned int size = xwns.size();
683-
684- for (CompWindow* w = window; w && uScreen->doShellRepaint; w = w->prev)
685- {
686- auto id = w->id();
687-
688- for (unsigned int i = 0; i < size; ++i)
689- {
690- if (xwns[i] == id)
691- {
692 #ifdef USE_GLES
693- uScreen->paintDisplay();
694+ uScreen->paintDisplay();
695 #else
696- uScreen->paintDisplay(region, matrix, mask);
697+ uScreen->paintDisplay(region, matrix, mask);
698 #endif
699- break;
700- }
701- }
702- }
703 }
704
705 if (window->type() == CompWindowTypeDesktopMask)
706@@ -2611,17 +2750,7 @@
707
708 void UnityScreen::onRedrawRequested()
709 {
710- // disable blur updates so we dont waste perf. This can stall the blur during animations
711- // but ensures a smooth animation.
712- if (_in_paint)
713- {
714- if (!_redraw_handle)
715- _redraw_handle = g_idle_add_full (G_PRIORITY_DEFAULT, &UnityScreen::OnRedrawTimeout, this, NULL);
716- }
717- else
718- {
719- damageNuxRegions();
720- }
721+ nuxDamageCompiz();
722 }
723
724 /* Handle option changes and plug that into nux windows */
725
726=== modified file 'plugins/unityshell/src/unityshell.h'
727--- plugins/unityshell/src/unityshell.h 2012-06-27 01:19:32 +0000
728+++ plugins/unityshell/src/unityshell.h 2012-07-26 05:12:23 +0000
729@@ -111,6 +111,9 @@
730 const char *eventName,
731 CompOption::Vector &o);
732
733+ void damageRegion(const CompRegion &region);
734+
735+ bool shellCouldBeHidden(CompOutput const& output);
736
737 /* paint on top of all windows if we could not find a window
738 * to paint underneath */
739@@ -132,9 +135,6 @@
740 CompOutput*,
741 unsigned int);
742
743- /* Pop our InputOutput windows from the paint list */
744- const CompWindowList& getWindowPaintList();
745-
746 /* handle X11 events */
747 void handleEvent(XEvent*);
748
749@@ -211,7 +211,10 @@
750
751 static gboolean initPluginActions(gpointer data);
752 void initLauncher();
753- void damageNuxRegions();
754+
755+ void compizDamageNux(CompRegion const& region);
756+ void nuxDamageCompiz();
757+
758 void onRedrawRequested();
759 void Relayout();
760
761@@ -261,7 +264,6 @@
762 bool enable_shortcut_overlay_;
763
764 std::unique_ptr<GestureEngine> gesture_engine_;
765- nux::Geometry lastTooltipArea;
766 bool needsRelayout;
767 bool _in_paint;
768 guint32 relayoutSourceId;
769@@ -280,11 +282,14 @@
770
771 /* handle paint order */
772 bool doShellRepaint;
773+ bool didShellRepaint;
774 bool allowWindowPaint;
775- bool damaged;
776 bool _key_nav_mode_requested;
777 CompOutput* _last_output;
778- CompWindowList _withRemovedNuxWindows;
779+
780+ CompRegion nuxRegion;
781+ CompRegion fullscreenRegion;
782+ CompWindow* firstWindowAboveShell;
783
784 nux::Property<nux::Geometry> primary_monitor_;
785

Subscribers

People subscribed via source and target branches

to all changes: