Merge lp:~vanvugt/unity/regionalDamage into lp:unity

Proposed by Daniel van Vugt
Status: Superseded
Proposed branch: lp:~vanvugt/unity/regionalDamage
Merge into: lp:unity
Diff against target: 493 lines (+203/-61)
8 files modified
launcher/AbstractLauncherIcon.h (+1/-0)
launcher/Launcher.cpp (+11/-0)
launcher/Launcher.h (+4/-0)
launcher/LauncherIcon.cpp (+3/-0)
panel/PanelController.cpp (+15/-0)
panel/PanelController.h (+1/-0)
plugins/unityshell/src/unityshell.cpp (+161/-59)
plugins/unityshell/src/unityshell.h (+7/-2)
To merge this branch: bzr merge lp:~vanvugt/unity/regionalDamage
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Fixing
Unity Team Pending
Review via email: mp+110989@code.launchpad.net

This proposal has been superseded by a proposal from 2012-06-22.

Commit message

Stop Unity from redrawing the shell on every frame (ie. when it doesn't need
to). It had a severe impact on graphics performance. (LP: #988079)

This especially improves OpenGL application performance and multi-monitor
desktop performance. Because unity was previously slowing down compiz
rendering by 20-40% for each monitor added to the system. This slowdown no
longer occurs as only damaged areas of the unity shell are repainted. Now
unity will not have any impact on compiz rendering performance for most
frames.

Coincidentally, this also fixes LP: #967112 and LP: #992516. Maybe more...

Description of the change

For me, this branch eliminates the 25-30% slowdown (compared to regular compiz) when unity is running with a single monitor. With 2 monitors, this branch eliminates the 75%(!) slowdown experienced when unity is running. Extrapolate and hypothesize as you like.

WARNING: This fix can only work if no window is redrawing _under_ a panel or launcher. If you have something drawing under the panel, launcher, tooltip or quicklist, then the shell will need to redraw and you won't get any performance benefit. Fixing that is a much bigger job and should be considered separate.

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

227 + /*
228 + * The shell is hidden if there exists any window that fully covers
229 + * the output and is in front of all Nux windows on that output.
230 + * We could also check CompositeWindow::opacity() but that would be slower
231 + * and almost always pointless.
232 + */
233 + if (w->isMapped() &&
234 + w->isViewable() &&
235 + !w->inShowDesktopMode() && // Why must this != isViewable?
236 + w->geometry().contains(output))

What might be faster here is using the occlusion detection passes from core. That will take into account whether or not the window is truly occluded. Usually you can get this by checking gw->clip () in GLWindow.

This code won't work for windows that are semitransparent or have an alpha channel, which will work a little weird.

Revision history for this message
Andrea Azzarone (azzar1) wrote :

Does it fix bug 977984 too?

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

I guess you can even remove this now

const std::string REDRAW_IDLE = "redraw-idle";

in: if (launcher_controller_.get()) no need for .get().

Overall looks good...

PS: pay attention to style, i.e.:
 bool UnityScreen::shellIsHidden(const CompOutput &output) -> bool UnityScreen::ShellIsHidden(CompOutput const& output)
 const std::vector<Window> &nuxwins(nux::XInputWindow::NativeHandleList()); -> std::vector<Window> const& nuxwins(nux::XInputWindow::NativeHandleList());

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

Marco, I think your style is wrong :)
In C and C++, & and * are part of the variable, not part of the type:
    A b, *c, d, &e(b);
That is why they usually go next to the variable and not the type.

Also, the Google C++ style guide that Unity is meant to use agrees:
    http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments
but then it allows both styles :)
    http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Pointer_and_Reference_Expressions

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

Andrea, no I don't think this will fix bug 977984.

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

Sam, gw->priv->clip only seems to get updated after glPaintOutputs which looks too late. How does one use clip() normally?

shellIsHidden is designed to be fast. And it is AFAIK. Yes, I did already add a comment about transparent windows. But we're only talking about fullscreen windows here. And I don't think the case of transparent or alpha fullscreen windows is one that we should need to waste time handling. If you make a fullscreen window transparent then you won't see the shell behind it. Does that matter?

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

Actually, it does matter. The whole point of this proposal is to avoid rendering the shell because it hogs so much GPU. So I think we should not be rendering the shell if it is stacked below a transparent fullscreen window.

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

Just noticed a bug with NVIDIA:
Un-fullscreening a window does not damage the screen (!?) so the shell doesn't repaint until something changes or you use it. Not sure about the most elegant fix. It looks like a compiz bug, but I haven't yet proven it.

Revision history for this message
Daniel van Vugt (vanvugt) :
review: Needs Fixing
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

> Marco, I think your style is wrong :)
> In C and C++, & and * are part of the variable, not part of the type:
> A b, *c, d, &e(b);
> That is why they usually go next to the variable and not the type.

I know, and that's how I used to do before, but the Unity style guide is different, see:
http://bazaar.launchpad.net/~unity-team/unity/trunk/view/head:/guides/cppguide.xml
(recently updated by Tim) http://bazaar.launchpad.net/~unity-team/unity/trunk/revision/2378

So here we use:
PointerType* ptr;
Object const& obj = ...;

Revision history for this message
Sam Spilsbury (smspillaz) wrote :
Download full text (4.2 KiB)

> Sam, gw->priv->clip only seems to get updated after glPaintOutputs which looks
> too late. How does one use clip() normally?

The clip region is updated after the occlusion pass. You are right, this happens within paintOutputRegion and not paintOutputs like I thought.

I feel like there are two options here:

1. Framebuffer object rebinds are not condition on whether or not the shell is repainting, but just as it is now with BackgroundEffectHelper::HasDirtyHelpers (). That leaves the problem of windows on top of the shell. At the moment, the damage collection code examines all damage events, but we don't care about stuff underneath the shell. As such, you could probably ignore any damage events coming in between PaintDisplay and glPaintOutput (damageRegionSetEnabled (false)). I don't think this will handle the case of fullscreen windows on top of the shell very well however. In compiz at least, we'd need a concept of layered damage, which is not trivial as it requires all damage to be tied to a particular object.

At this point, you can determine whether or not to paint the shell when you actually hit a nux window. This again, depends on being able to see nux windows in the paint stack (see lp:~smspillaz/unity/unity.less-paint-insanity). I guess at the moment, you could use the heuristic, and then Window -> CompWindow the nux window and check the clip region there to see if it is empty.

2. Second option is a bit trickier, but might also work. You'll need to effectively make unity do the occlusion pass. What you would do here is loop all the windows and do something like:

class UnityWindow :
....
{
....
private:

    CompRegion clip_;
};

void DetectOcclusionsOnUnityWindows (const GLMatrix &matrix,
                                     CompOutput *output)
{
GLWindowPaintAttrib a;
CompRegion tmpRegion (*output);

/* Top to bottom */
for (CompWindow *w : screen->reverseWindows ())
{
    UnityWindow *uw = UnityWindow::get (w);

    /* We only care about windows we actually clipped */
    clip = infiniteRegion;

    if (window->alpha ())
        continue;

    if (!window->isViewable ())
        continue;

    /* GLWindow::glPaint will return true if this window should be regarded
     * as occluding other windows. PAINT_WINDOW_OCCLUSION_DETECTION_MASK will
     * not actually paint the window, but will allow plugins to modify the state
     * of the window as if it was being painted, so we will know whether it should
     * occlude other windows */
    if (gw->glPaint (a, matrix, tmpRegion, PAINT_WINDOW_OCCLUSION_DETECTION_MASK))
        tmpRegion -= w->region (); // Not inputRect () or outputRect (): Decorations are ARGB windows

    uw->clip_ = tmpRegion;
}
}

Now, you can loop the list of nux windows (probably safe to store that internally, a nux window is a nux window for life, just detect it on the UnityWindow ctor) and see if they all have empty clip regions. If so, don't paint the shell.

You can also use the region detection to determine what parts of the shell to "damage" as well.

iirc, this is something similar to what the blur plugin does. Have a look at that for other ideas. This will also fix problems to do with ...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/AbstractLauncherIcon.h'
2--- launcher/AbstractLauncherIcon.h 2012-06-06 15:40:19 +0000
3+++ launcher/AbstractLauncherIcon.h 2012-06-22 06:31:22 +0000
4@@ -218,6 +218,7 @@
5
6 sigc::signal<void, AbstractLauncherIcon::Ptr> needs_redraw;
7 sigc::signal<void, AbstractLauncherIcon::Ptr> remove;
8+ sigc::signal<void, nux::ObjectPtr<nux::View>> tooltip_visible;
9 sigc::signal<void> visibility_changed;
10
11 sigc::connection needs_redraw_connection;
12
13=== modified file 'launcher/Launcher.cpp'
14--- launcher/Launcher.cpp 2012-06-20 18:51:16 +0000
15+++ launcher/Launcher.cpp 2012-06-22 06:31:22 +0000
16@@ -1520,6 +1520,11 @@
17 }
18 }
19
20+nux::ObjectPtr<nux::View> Launcher::GetActiveTooltip() const
21+{
22+ return _active_tooltip;
23+}
24+
25 void Launcher::SetActionState(LauncherActionState actionstate)
26 {
27 if (_launcher_action_state == actionstate)
28@@ -1681,6 +1686,7 @@
29 EnsureAnimation();
30
31 icon->needs_redraw.connect(sigc::mem_fun(this, &Launcher::OnIconNeedsRedraw));
32+ icon->tooltip_visible.connect(sigc::mem_fun(this, &Launcher::OnTooltipVisible));
33 }
34
35 void Launcher::OnIconRemoved(AbstractLauncherIcon::Ptr icon)
36@@ -1757,6 +1763,11 @@
37 EnsureAnimation();
38 }
39
40+void Launcher::OnTooltipVisible(nux::ObjectPtr<nux::View> view)
41+{
42+ _active_tooltip = view;
43+}
44+
45 void Launcher::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
46 {
47
48
49=== modified file 'launcher/Launcher.h'
50--- launcher/Launcher.h 2012-06-15 02:03:31 +0000
51+++ launcher/Launcher.h 2012-06-22 06:31:22 +0000
52@@ -96,6 +96,8 @@
53 return _parent;
54 };
55
56+ nux::ObjectPtr<nux::View> GetActiveTooltip() const; // nullptr = no tooltip
57+
58 virtual void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags);
59 virtual void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags);
60 virtual void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
61@@ -269,6 +271,7 @@
62 void OnOrderChanged();
63
64 void OnIconNeedsRedraw(AbstractLauncherIcon::Ptr icon);
65+ void OnTooltipVisible(nux::ObjectPtr<nux::View> view);
66
67 void OnOverlayHidden(GVariant* data);
68 void OnOverlayShown(GVariant* data);
69@@ -311,6 +314,7 @@
70
71 LauncherModel::Ptr _model;
72 nux::BaseWindow* _parent;
73+ nux::ObjectPtr<nux::View> _active_tooltip;
74 QuicklistView* _active_quicklist;
75
76 nux::HLayout* m_Layout;
77
78=== modified file 'launcher/LauncherIcon.cpp'
79--- launcher/LauncherIcon.cpp 2012-06-19 01:00:36 +0000
80+++ launcher/LauncherIcon.cpp 2012-06-22 06:31:22 +0000
81@@ -513,6 +513,7 @@
82 LoadTooltip();
83 _tooltip->ShowTooltipWithTipAt(tip_x, tip_y);
84 _tooltip->ShowWindow(!tooltip_text().empty());
85+ tooltip_visible.emit(_tooltip);
86 }
87
88 void
89@@ -534,6 +535,7 @@
90
91 if (_tooltip)
92 _tooltip->ShowWindow(false);
93+ tooltip_visible.emit(nux::ObjectPtr<nux::View>(nullptr));
94 }
95
96 bool LauncherIcon::OpenQuicklist(bool select_first_item, int monitor)
97@@ -653,6 +655,7 @@
98 {
99 if (_tooltip)
100 _tooltip->ShowWindow(false);
101+ tooltip_visible.emit(nux::ObjectPtr<nux::View>(nullptr));
102 }
103
104 bool
105
106=== modified file 'panel/PanelController.cpp'
107--- panel/PanelController.cpp 2012-06-15 02:03:31 +0000
108+++ panel/PanelController.cpp 2012-06-22 06:31:22 +0000
109@@ -49,6 +49,7 @@
110 void QueueRedraw();
111
112 std::vector<Window> GetTrayXids() const;
113+ std::vector<nux::View*> GetPanelViews() const;
114 std::vector<nux::Geometry> GetGeometries() const;
115
116 // NOTE: nux::Property maybe?
117@@ -106,6 +107,15 @@
118 return xids;
119 }
120
121+std::vector<nux::View*> Controller::Impl::GetPanelViews() const
122+{
123+ std::vector<nux::View*> views;
124+ views.reserve(windows_.size());
125+ for (auto window: windows_)
126+ views.push_back(ViewForWindow(window));
127+ return views;
128+}
129+
130 std::vector<nux::Geometry> Controller::Impl::GetGeometries() const
131 {
132 std::vector<nux::Geometry> geometries;
133@@ -325,6 +335,11 @@
134 return pimpl->GetTrayXids();
135 }
136
137+std::vector<nux::View*> Controller::GetPanelViews() const
138+{
139+ return pimpl->GetPanelViews();
140+}
141+
142 std::vector<nux::Geometry> Controller::GetGeometries() const
143 {
144 return pimpl->GetGeometries();
145
146=== modified file 'panel/PanelController.h'
147--- panel/PanelController.h 2012-05-06 23:48:38 +0000
148+++ panel/PanelController.h 2012-06-22 06:31:22 +0000
149@@ -41,6 +41,7 @@
150 void QueueRedraw();
151
152 std::vector<Window> GetTrayXids() const;
153+ std::vector<nux::View*> GetPanelViews() const;
154 std::vector<nux::Geometry> GetGeometries() const;
155
156 // NOTE: nux::Property maybe?
157
158=== modified file 'plugins/unityshell/src/unityshell.cpp'
159--- plugins/unityshell/src/unityshell.cpp 2012-06-15 02:03:31 +0000
160+++ plugins/unityshell/src/unityshell.cpp 2012-06-22 06:31:22 +0000
161@@ -100,7 +100,6 @@
162 const unsigned int SCROLL_UP_BUTTON = 7;
163
164 const std::string RELAYOUT_TIMEOUT = "relayout-timeout";
165-const std::string REDRAW_IDLE = "redraw-idle";
166 } // namespace local
167 } // anon namespace
168
169@@ -118,6 +117,7 @@
170 , super_keypressed_(false)
171 , newFocusedWindow(nullptr)
172 , doShellRepaint(false)
173+ , didShellRepaint(false)
174 , allowWindowPaint(false)
175 , damaged(false)
176 , _key_nav_mode_requested(false)
177@@ -902,6 +902,7 @@
178 }
179
180 doShellRepaint = false;
181+ didShellRepaint = true;
182 damaged = false;
183 }
184
185@@ -1204,7 +1205,20 @@
186 {
187 bool ret;
188
189- doShellRepaint = true;
190+ /*
191+ * Very important!
192+ * Don't waste GPU and CPU rendering the shell on every frame if you don't
193+ * need to. Doing so on every frame causes Nux to hog the GPU and slow down
194+ * all other OpenGL apps (LP: #988079)
195+ */
196+ if (forcePaintOnTop() || PluginAdapter::Default()->IsExpoActive())
197+ doShellRepaint = true;
198+ else if (region.isEmpty() || shellIsHidden(*output))
199+ doShellRepaint = false;
200+ else
201+ doShellRepaint = wt->GetDrawList().size() > 0 ||
202+ BackgroundEffectHelper::HasDirtyHelpers();
203+
204 allowWindowPaint = true;
205 _last_output = output;
206 paint_panel_ = false;
207@@ -1220,7 +1234,8 @@
208 * attempts to bind it will only increment
209 * its bind reference so make sure that
210 * you always unbind as much as you bind */
211- _fbo->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
212+ if (doShellRepaint)
213+ _fbo->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
214 #endif
215
216 /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
217@@ -1279,16 +1294,32 @@
218 for (ShowdesktopHandlerWindowInterface *wi : ShowdesktopHandler::animating_windows)
219 wi->HandleAnimations (ms);
220
221+ // Workaround Nux bug LP: #1014610:
222 if (damaged)
223 {
224 damaged = false;
225- damageNuxRegions();
226+ nuxDamageCompiz();
227 }
228
229+ compizDamageNux(cScreen->currentDamage());
230+
231+ didShellRepaint = false;
232 }
233
234 void UnityScreen::donePaint()
235 {
236+ /*
237+ * It's only safe to clear the draw list if drawing actually occurred
238+ * (i.e. the shell was not obscured behind a fullscreen window).
239+ * If you clear the draw list and drawing has not occured then you'd be
240+ * left with all your views thinking they're queued for drawing still and
241+ * would refuse to redraw when you return from fullscreen.
242+ * I think this is a Nux bug. ClearDrawList should ideally also mark all
243+ * the queued views as draw_cmd_queued_=false.
244+ */
245+ if (didShellRepaint)
246+ wt->ClearDrawList();
247+
248 std::list <ShowdesktopHandlerWindowInterface *> remove_windows;
249
250 for (ShowdesktopHandlerWindowInterface *wi : ShowdesktopHandler::animating_windows)
251@@ -1309,42 +1340,137 @@
252 cScreen->donePaint ();
253 }
254
255+bool UnityScreen::shellIsHidden(CompOutput const& output)
256+{
257+ bool hidden = false;
258+ std::vector<Window> const& nuxwins(nux::XInputWindow::NativeHandleList());
259+
260+ // Loop through windows from back to front
261+ for (CompWindow* w : screen->windows ())
262+ {
263+ /*
264+ * The shell is hidden if there exists any window that fully covers
265+ * the output and is in front of all Nux windows on that output.
266+ * We could also check CompositeWindow::opacity() but that would be slower
267+ * and almost always pointless.
268+ */
269+ if (w->isMapped() &&
270+ w->isViewable() &&
271+ !w->inShowDesktopMode() && // Why must this != isViewable?
272+ w->geometry().contains(output))
273+ {
274+ hidden = true;
275+ }
276+ else if (hidden)
277+ {
278+ for (Window n : nuxwins)
279+ {
280+ if (w->id() == n && output.intersects(w->geometry()))
281+ {
282+ hidden = false;
283+ break;
284+ }
285+ }
286+ }
287+ }
288+
289+ return hidden;
290+}
291+
292+void UnityScreen::compizDamageNux(CompRegion const& damage)
293+{
294+ if (!launcher_controller_)
295+ return;
296+
297+ CompRect::vector const& rects(damage.rects());
298+ for (const CompRect &r : rects)
299+ {
300+ nux::Geometry geo(r.x(), r.y(), r.width(), r.height());
301+ BackgroundEffectHelper::ProcessDamage(geo);
302+ }
303+
304+ auto launchers = launcher_controller_->launchers();
305+ for (auto launcher : launchers)
306+ {
307+ if (!launcher->Hidden())
308+ {
309+ nux::Geometry geo = launcher->GetAbsoluteGeometry();
310+ CompRegion launcher_region(geo.x, geo.y, geo.width, geo.height);
311+ if (damage.intersects(launcher_region))
312+ launcher->QueueDraw();
313+ nux::ObjectPtr<nux::View> tooltip = launcher->GetActiveTooltip();
314+ if (!tooltip.IsNull())
315+ {
316+ nux::Geometry tip = tooltip->GetAbsoluteGeometry();
317+ CompRegion tip_region(tip.x, tip.y, tip.width, tip.height);
318+ if (damage.intersects(tip_region))
319+ tooltip->QueueDraw();
320+ }
321+ }
322+ }
323+
324+ std::vector<nux::View*> const& panels(panel_controller_->GetPanelViews());
325+ for (nux::View* view : panels)
326+ {
327+ nux::Geometry geo = view->GetAbsoluteGeometry();
328+ CompRegion panel_region(geo.x, geo.y, geo.width, geo.height);
329+ if (damage.intersects(panel_region))
330+ view->QueueDraw();
331+ }
332+
333+ QuicklistManager* qm = QuicklistManager::Default();
334+ if (qm)
335+ {
336+ QuicklistView* view = qm->Current();
337+ if (view)
338+ {
339+ nux::Geometry geo = view->GetAbsoluteGeometry();
340+ CompRegion quicklist_region(geo.x, geo.y, geo.width, geo.height);
341+ if (damage.intersects(quicklist_region))
342+ view->QueueDraw();
343+ }
344+ }
345+}
346+
347 /* Grab changed nux regions and add damage rects for them */
348-void UnityScreen::damageNuxRegions()
349+void UnityScreen::nuxDamageCompiz()
350 {
351+ // Workaround Nux bug LP: #1014610 (unbounded DrawList growth)
352+ // Also, ensure we don't dereference null *controller_ on startup.
353+ if (damaged || !launcher_controller_ || !dash_controller_)
354+ return;
355+ damaged = true;
356+
357 CompRegion nux_damage;
358
359- if (damaged)
360- return;
361-
362- std::vector<nux::Geometry> dirty = wt->GetDrawList();
363- damaged = true;
364-
365- for (std::vector<nux::Geometry>::iterator it = dirty.begin(), end = dirty.end();
366- it != end; ++it)
367- {
368- nux::Geometry const& geo = *it;
369- nux_damage += CompRegion(geo.x, geo.y, geo.width, geo.height);
370- }
371-
372- nux::Geometry geo = wt->GetWindowCompositor().GetTooltipMainWindowGeometry();
373- nux_damage += CompRegion(geo.x, geo.y, geo.width, geo.height);
374-
375- geo = lastTooltipArea;
376- nux_damage += CompRegion(lastTooltipArea.x, lastTooltipArea.y,
377- lastTooltipArea.width, lastTooltipArea.height);
378-
379- /*
380- * Avoid Nux damaging Nux as recommended by smspillaz. Though I don't
381- * believe it would be harmful or significantly expensive right now.
382- */
383+ std::vector<nux::Geometry> const& dirty = wt->GetDrawList();
384+ for (auto geo : dirty)
385+ nux_damage += CompRegion(geo.x, geo.y, geo.width, geo.height);
386+
387+ if (launcher_controller_->IsOverlayOpen())
388+ {
389+ nux::BaseWindow* dash_window = dash_controller_->window();
390+ nux::Geometry const& geo = dash_window->GetAbsoluteGeometry();
391+ nux_damage += CompRegion(geo.x, geo.y, geo.width, geo.height);
392+ }
393+
394+ auto launchers = launcher_controller_->launchers();
395+ for (auto launcher : launchers)
396+ {
397+ if (!launcher->Hidden())
398+ {
399+ nux::ObjectPtr<nux::View> tooltip = launcher->GetActiveTooltip();
400+ if (!tooltip.IsNull())
401+ {
402+ nux::Geometry const& g = tooltip->GetAbsoluteGeometry();
403+ nux_damage += CompRegion(g.x, g.y, g.width, g.height);
404+ }
405+ }
406+ }
407+
408 cScreen->damageRegionSetEnabled(this, false);
409 cScreen->damageRegion(nux_damage);
410 cScreen->damageRegionSetEnabled(this, true);
411-
412- wt->ClearDrawList();
413-
414- lastTooltipArea = geo;
415 }
416
417 /* handle X Events */
418@@ -1504,13 +1630,7 @@
419
420 void UnityScreen::damageRegion(const CompRegion &region)
421 {
422- const CompRect::vector &rects(region.rects());
423- for (const CompRect &r : rects)
424- {
425- nux::Geometry geo(r.x(), r.y(), r.width(), r.height());
426- BackgroundEffectHelper::ProcessDamage(geo);
427- }
428-
429+ compizDamageNux(region);
430 cScreen->damageRegion(region);
431 }
432
433@@ -2527,25 +2647,7 @@
434
435 void UnityScreen::onRedrawRequested()
436 {
437- // disable blur updates so we dont waste perf. This can stall the blur during animations
438- // but ensures a smooth animation.
439- if (_in_paint)
440- {
441- if (!sources_.GetSource(local::REDRAW_IDLE))
442- {
443- auto redraw_idle(std::make_shared<glib::Idle>(glib::Source::Priority::DEFAULT));
444- sources_.Add(redraw_idle, local::REDRAW_IDLE);
445-
446- redraw_idle->Run([&]() {
447- onRedrawRequested();
448- return false;
449- });
450- }
451- }
452- else
453- {
454- damageNuxRegions();
455- }
456+ nuxDamageCompiz();
457 }
458
459 /* Handle option changes and plug that into nux windows */
460
461=== modified file 'plugins/unityshell/src/unityshell.h'
462--- plugins/unityshell/src/unityshell.h 2012-06-15 02:03:31 +0000
463+++ plugins/unityshell/src/unityshell.h 2012-06-22 06:31:22 +0000
464@@ -212,7 +212,12 @@
465
466 bool initPluginActions();
467 void initLauncher();
468- void damageNuxRegions();
469+
470+ void compizDamageNux(CompRegion const& region);
471+ void nuxDamageCompiz();
472+
473+ bool shellIsHidden(CompOutput const& output);
474+
475 void onRedrawRequested();
476 void Relayout();
477
478@@ -255,7 +260,6 @@
479 bool enable_shortcut_overlay_;
480
481 GestureEngine gesture_engine_;
482- nux::Geometry lastTooltipArea;
483 bool needsRelayout;
484 bool _in_paint;
485 bool super_keypressed_;
486@@ -272,6 +276,7 @@
487
488 /* handle paint order */
489 bool doShellRepaint;
490+ bool didShellRepaint;
491 bool allowWindowPaint;
492 bool damaged;
493 bool _key_nav_mode_requested;