Merge lp:~smspillaz/unity/unity.less-paint-insanity into lp:unity

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~smspillaz/unity/unity.less-paint-insanity
Merge into: lp:unity
Diff against target: 1221 lines (+724/-134)
9 files modified
plugins/unityshell/src/ScreenEffectFramebufferObject.cpp (+10/-1)
plugins/unityshell/src/ScreenEffectFramebufferObject.h (+6/-0)
plugins/unityshell/src/unityshell.cpp (+187/-119)
plugins/unityshell/src/unityshell.h (+39/-14)
tests/CMakeLists.txt (+2/-0)
tests/test_shell_paint_schedule.cpp (+284/-0)
unity-shared/CMakeLists.txt (+1/-0)
unity-shared/ShellPaintSchedule.cpp (+91/-0)
unity-shared/ShellPaintSchedule.h (+104/-0)
To merge this branch: bzr merge lp:~smspillaz/unity/unity.less-paint-insanity
Reviewer Review Type Date Requested Status
Sam Spilsbury (community) Needs Fixing
Daniel van Vugt Approve
Jason Smith Pending
Marco Trevisan (Treviño) Pending
Review via email: mp+109757@code.launchpad.net

This proposal supersedes a proposal from 2012-06-07.

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

Description of the change

Removes the whole scanning of the list thing in getWindowPaintList and the whole "trying to figure out where the window was because we don't actually know" in glDraw by scanning the paint list again and again.

There's a much better way of doing this - just hook glPaint, skip the wrap chain to core (eg every single plugin skipped) and tell core not to do anything with the window.

I have no idea why there is a bunch of logic about whether or not to paint the panel in glDraw (that was moved to glPaint). Someone enlighten me?

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

Bump?

I'd like to see this go in, because it should reduce lots of list copying within unity and also lots of unecessary list traversal, which should represent a nice speed boost. In addition, its far simpler in its implementation and far less bug prone.

I'm sure testing is probably an issue. I'll have another quick look at the code and see if I can think of a way to get it under test.

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

Works for me. Though there are some indentation/tab mismatches around line 107. Looks like your tabs are not 8 characters wide like they should be?

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

indentation fixed ... will add tests when I have time.

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

Manual testing -> Works well.

This branch also appears to solve the problem of my missing panel shadow when running dev builds of Unity. But that's just a bonus.

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

Whoops. It turns out this branch is tricking the decor plugin into painting (proper) shadows for the panel and launcher. It looks awesome so I hope we can keep it. But it's probably a mistake.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

> Whoops. It turns out this branch is tricking the decor plugin into painting
> (proper) shadows for the panel and launcher. It looks awesome so I hope we can
> keep it. But it's probably a mistake.

It probably is, thanks for catching that.

review: Needs Fixing
2374. By Sam Spilsbury

Merge lp:unity

2375. By Sam Spilsbury

Merge lp:~vanvugt/unity/fix-1010348

2376. By Sam Spilsbury

Make the code slightly more sane, use some interfaces to demonstrate
what is happening and break dependencies a little

2377. By Sam Spilsbury

Ensure that we always paint on top of the topmost nux window

2378. By Sam Spilsbury

Also return false if someone tries to paint us with PAINT_WINDOW_NO_CORE_INSTANCE_MASK

2379. By Sam Spilsbury

Implement top window detection in terms of paint requestor

2380. By Sam Spilsbury

Merge lp:unity

2381. By Sam Spilsbury

Move paint requestor enforcement to UnityPaintDispatch

2382. By Sam Spilsbury

Move paint mask prohibition into UnityPaintDispatch through strategy

2383. By Sam Spilsbury

Ensure that the backing fbo is painted too

2384. By Sam Spilsbury

Work correctly with USE_MODERN_COMPIZ_GL too

2385. By Sam Spilsbury

Move UnityPaintDispatch to separate file

2386. By Sam Spilsbury

Use UnityPaintDispatch by composition

2387. By Sam Spilsbury

Rename variable

2388. By Sam Spilsbury

UnityPaint* -> ShellPaint*

2389. By Sam Spilsbury

mv UnityPaintSchedule -> ShellPaintSchedule

2390. By Sam Spilsbury

Initial tests for ShellPaintSchedule

2391. By Sam Spilsbury

Basic paint tests

2392. By Sam Spilsbury

Basic prohibition test

2393. By Sam Spilsbury

Inverse prohibition test case

2394. By Sam Spilsbury

Basic top requestor tests

2395. By Sam Spilsbury

Test suprvening requestor behaviour

2396. By Sam Spilsbury

Tests for RepaintPending value

2397. By Sam Spilsbury

Test prohibited paint requestor retreival

2398. By Sam Spilsbury

Merge lp:unity

2399. By Sam Spilsbury

Merge lp:unity

2400. By Sam Spilsbury

Change namespace to unity::compiz

2401. By Sam Spilsbury

unsigned int -> enum && move namespace compiz {} to namespace unity::compiz

2402. By Sam Spilsbury

Nuke FBOBindingQueryInterface

2403. By Sam Spilsbury

Basic documentation, not really a substitute for better code ...

2404. By Sam Spilsbury

Merge lp:unity

2405. By Sam Spilsbury

Remove unused method and rename methods to make more sense

Unmerged revisions

2405. By Sam Spilsbury

Remove unused method and rename methods to make more sense

2404. By Sam Spilsbury

Merge lp:unity

2403. By Sam Spilsbury

Basic documentation, not really a substitute for better code ...

2402. By Sam Spilsbury

Nuke FBOBindingQueryInterface

2401. By Sam Spilsbury

unsigned int -> enum && move namespace compiz {} to namespace unity::compiz

2400. By Sam Spilsbury

Change namespace to unity::compiz

2399. By Sam Spilsbury

Merge lp:unity

2398. By Sam Spilsbury

Merge lp:unity

2397. By Sam Spilsbury

Test prohibited paint requestor retreival

2396. By Sam Spilsbury

Tests for RepaintPending value

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/ScreenEffectFramebufferObject.cpp'
2--- plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-05-28 03:19:35 +0000
3+++ plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-06-14 09:04:28 +0000
4@@ -76,7 +76,6 @@
5 mScreenSize = screenSize;
6 }
7
8-
9 void unity::ScreenEffectFramebufferObject::unbind ()
10 {
11 if (!mBoundCnt)
12@@ -92,6 +91,8 @@
13 /* Matches the viewport set we did in ::bind () */
14 glPopAttrib ();
15
16+ successful_bind_ = true;
17+
18 }
19
20 bool unity::ScreenEffectFramebufferObject::status ()
21@@ -106,6 +107,8 @@
22 * Because binding has a severe impact on graphics performance and we
23 * can't afford to do it every frame. (LP: #861061) (LP: #987304)
24 */
25+ successful_bind_ = false;
26+
27 if (!BackgroundEffectHelper::HasDirtyHelpers())
28 return;
29
30@@ -212,6 +215,11 @@
31 mBoundCnt++;
32 }
33
34+bool
35+unity::ScreenEffectFramebufferObject::NewContentsValid ()
36+{
37+ return successful_bind_;
38+}
39
40 unity::ScreenEffectFramebufferObject::ScreenEffectFramebufferObject (GLXGetProcAddressProc p, const nux::Geometry &geom)
41 : getProcAddressGLX (p)
42@@ -220,6 +228,7 @@
43 , mGeometry (geom)
44 , mBoundCnt (0)
45 , mScreenSize (geom)
46+ , successful_bind_ (false)
47 {
48 activeTexture = (GLActiveTextureProc) (*getProcAddressGLX) ((GLubyte *) "glActiveTexture");
49 genFramebuffers = (GLGenFramebuffersProc) (*getProcAddressGLX) ((GLubyte *)"glGenFramebuffersEXT");
50
51=== modified file 'plugins/unityshell/src/ScreenEffectFramebufferObject.h'
52--- plugins/unityshell/src/ScreenEffectFramebufferObject.h 2012-04-06 10:23:49 +0000
53+++ plugins/unityshell/src/ScreenEffectFramebufferObject.h 2012-06-14 09:04:28 +0000
54@@ -49,6 +49,10 @@
55
56 void onScreenSizeChanged (const nux::Geometry &screenSize);
57
58+ /* Returns true if the fbo was bound, painted into and unbound
59+ * successfully */
60+ bool NewContentsValid ();
61+
62 private:
63
64 FuncPtr getProcAddr (const std::string &);
65@@ -82,6 +86,8 @@
66 unsigned int mBoundCnt;
67
68 nux::Geometry mScreenSize;
69+
70+ bool successful_bind_;
71 };
72 } // namespace unity
73
74
75=== modified file 'plugins/unityshell/src/unityshell.cpp'
76--- plugins/unityshell/src/unityshell.cpp 2012-06-13 03:54:37 +0000
77+++ plugins/unityshell/src/unityshell.cpp 2012-06-14 09:04:28 +0000
78@@ -110,6 +110,8 @@
79 , screen(screen)
80 , cScreen(CompositeScreen::get(screen))
81 , gScreen(GLScreen::get(screen))
82+ , paint_dispatch_ (this,
83+ boost::bind (&UnityScreen::GetProhibitedPaintMasks, this))
84 , debugger_(this)
85 , enable_shortcut_overlay_(true)
86 , gesture_engine_(screen)
87@@ -117,8 +119,6 @@
88 , _in_paint(false)
89 , super_keypressed_(false)
90 , newFocusedWindow(nullptr)
91- , doShellRepaint(false)
92- , allowWindowPaint(false)
93 , damaged(false)
94 , _key_nav_mode_requested(false)
95 , _last_output(nullptr)
96@@ -263,8 +263,8 @@
97 if (GL::fbo)
98 {
99 nux::Geometry geometry (0, 0, screen->width (), screen->height ());
100- uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
101- uScreen->_fbo->onScreenSizeChanged (geometry);
102+ uScreen->fbo_ = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
103+ uScreen->fbo_->onScreenSizeChanged (geometry);
104 }
105 #endif
106
107@@ -734,16 +734,52 @@
108 panel_texture_has_changed_ = true;
109 }
110
111-#ifdef USE_MODERN_COMPIZ_GL
112-void UnityScreen::paintDisplay()
113+bool
114+UnityScreen::WasBound ()
115+{
116+#ifndef USE_MODERN_COMPIZ_GL
117+ return fbo_->NewContentsValid ();
118 #else
119-void UnityScreen::paintDisplay(const CompRegion& region, const GLMatrix& transform, unsigned int mask)
120-#endif
121+ return true;
122+#endif
123+}
124+
125+unsigned int
126+UnityScreen::GetPaintRequestorType ()
127+{
128+ return ShellPaintRequestorInterface::ScreenPaintRequestor;
129+}
130+
131+bool UnityScreen::PaintBackingFBO (CompOutput *output)
132+{
133+#ifndef USE_MODERN_COMPIZ_GL
134+ fbo_->unbind ();
135+ if (fbo_->NewContentsValid ())
136+ {
137+ GLMatrix sTransform;
138+ sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
139+ glPushMatrix ();
140+ glLoadMatrixf (sTransform.getMatrix ());
141+ fbo_->paint (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
142+ glPopMatrix ();
143+
144+ return true;
145+ }
146+#endif
147+ return false;
148+}
149+
150+void UnityScreen::PaintDisplay (FBOBindingQueryInterface *fbo_query)
151 {
152 CompOutput *output = _last_output;
153
154+ PaintBackingFBO (output);
155+
156 #ifndef USE_MODERN_COMPIZ_GL
157- bool was_bound = _fbo->bound ();
158+ bool was_bound = fbo_query->WasBound ();
159+#else
160+ bool was_bound = true;
161+#endif
162
163 if (nux::GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath())
164 {
165@@ -779,28 +815,18 @@
166 }
167 }
168
169- _fbo->unbind ();
170-
171 /* Draw the bit of the relevant framebuffer for each output */
172
173- if (was_bound)
174- {
175- GLMatrix sTransform;
176- sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
177- glPushMatrix ();
178- glLoadMatrixf (sTransform.getMatrix ());
179- _fbo->paint (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
180- glPopMatrix ();
181- }
182+ GLuint fbo_texture_name = 0;
183+#ifndef USE_MODERN_COMPIZ_GL
184+ fbo_texture_name = fbo_->texture();
185+#else
186+ fbo_texture_name = gScreen->fbo ()->tex ()->name ();
187+#endif
188
189 nux::ObjectPtr<nux::IOpenGLBaseTexture> device_texture =
190- nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(_fbo->texture(),
191+ nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(fbo_texture_name,
192 screen->width (), screen->height(), 1, nux::BITFMT_R8G8B8A8);
193-#else
194- nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture =
195- nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(gScreen->fbo ()->tex ()->name (),
196- output->width(), output->height(), 1, nux::BITFMT_R8G8B8A8);
197-#endif
198
199 nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture;
200
201@@ -823,7 +849,7 @@
202
203 for (Window tray_xid : panel_controller_->GetTrayXids())
204 {
205- if (tray_xid && !allowWindowPaint)
206+ if (tray_xid && (no_paint_allowed_mask_ & ShellPaintRequestorInterface::WindowPaintRequestor))
207 {
208 CompWindow *tray = screen->findWindow (tray_xid);
209
210@@ -901,15 +927,54 @@
211 }
212 }
213
214- doShellRepaint = false;
215 damaged = false;
216 }
217
218-bool UnityScreen::forcePaintOnTop ()
219-{
220- return !allowWindowPaint ||
221- ((switcher_controller_->Visible() || launcher_controller_->IsOverlayOpen())
222- && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
223+unsigned int UnityScreen::GetProhibitedPaintMasks ()
224+{
225+ bool unity_force_overlay = switcher_controller_->Visible() || launcher_controller_->IsOverlayOpen();
226+ bool no_screen_grabs = !(screen->grabbed () && !screen->otherGrabExist (NULL));
227+ bool fullscreen_windows = !fullscreen_windows_.empty ();
228+
229+ unsigned int pmask = no_paint_allowed_mask_;
230+
231+ if (unity_force_overlay &&
232+ fullscreen_windows &&
233+ no_screen_grabs)
234+ pmask |= ShellPaintRequestorInterface::WindowPaintRequestor;
235+
236+ return pmask;
237+}
238+
239+bool UnityScreen::Paint (ShellPaintRequestorInterface *r,
240+ FBOBindingQueryInterface *q)
241+{
242+ return paint_dispatch_.Paint (r, q);
243+}
244+
245+bool UnityScreen::EnforceRequestor (ShellPaintRequestorInterface *r)
246+{
247+ return paint_dispatch_.EnforceRequestor (r);
248+}
249+
250+void UnityScreen::ClearRequestorEnforcement ()
251+{
252+ paint_dispatch_.ClearRequestorEnforcement ();
253+}
254+
255+unsigned int UnityScreen::ProhibitedPaintRequestors ()
256+{
257+ return paint_dispatch_.ProhibitedPaintRequestors ();
258+}
259+
260+void UnityScreen::RequireShellRepaint ()
261+{
262+ paint_dispatch_.RequireShellRepaint ();
263+}
264+
265+bool UnityScreen::RepaintPending ()
266+{
267+ return paint_dispatch_.RepaintPending ();
268 }
269
270 void UnityWindow::paintThumbnail (nux::Geometry const& bounding, float alpha)
271@@ -1204,8 +1269,9 @@
272 {
273 bool ret;
274
275- doShellRepaint = true;
276- allowWindowPaint = true;
277+ ClearRequestorEnforcement ();
278+ RequireShellRepaint ();
279+ no_paint_allowed_mask_ = 0;
280 _last_output = output;
281 paint_panel_ = false;
282
283@@ -1220,16 +1286,13 @@
284 * attempts to bind it will only increment
285 * its bind reference so make sure that
286 * you always unbind as much as you bind */
287- _fbo->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
288+ fbo_->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
289 #endif
290
291 /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
292 ret = gScreen->glPaintOutput(attrib, transform, region, output, mask);
293
294-#ifndef USE_MODERN_COMPIZ_GL
295- if (doShellRepaint)
296- paintDisplay(region, transform, mask);
297-#endif
298+ Paint (this, this);
299
300 return ret;
301 }
302@@ -1241,7 +1304,7 @@
303 {
304 bool useFbo = false;
305
306- if (doShellRepaint)
307+ if (RepaintPending ())
308 {
309 oldFbo = fbo->bind ();
310 useFbo = fbo->checkStatus () && fbo->tex ();
311@@ -1250,7 +1313,7 @@
312 ::GLFramebufferObject::rebind (oldFbo);
313 return;
314 }
315- paintDisplay();
316+ Paint (this, this);
317 ::GLFramebufferObject::rebind (oldFbo);
318 }
319
320@@ -1267,7 +1330,7 @@
321 CompOutput* output,
322 unsigned int mask)
323 {
324- allowWindowPaint = false;
325+ no_paint_allowed_mask_ = ShellPaintRequestorInterface::WindowPaintRequestor;
326 gScreen->glPaintTransformedOutput(attrib, transform, region, output, mask);
327
328 }
329@@ -2124,31 +2187,6 @@
330 return "Unity";
331 }
332
333-bool isNuxWindow (CompWindow* value)
334-{
335- std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
336- auto id = value->id();
337-
338- // iterate loop by hand rather than use std::find as this is considerably faster
339- // we care about performance here becuase of the high frequency in which this function is
340- // called (nearly every frame)
341- unsigned int size = xwns.size();
342- for (unsigned int i = 0; i < size; ++i)
343- {
344- if (xwns[i] == id)
345- return true;
346- }
347- return false;
348-}
349-
350-const CompWindowList& UnityScreen::getWindowPaintList()
351-{
352- CompWindowList& pl = _withRemovedNuxWindows = cScreen->getWindowPaintList();
353- pl.remove_if(isNuxWindow);
354-
355- return pl;
356-}
357-
358 void UnityScreen::RaiseInputWindows()
359 {
360 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
361@@ -2161,13 +2199,11 @@
362 }
363 }
364
365-/* detect occlusions
366- *
367- * core passes down the PAINT_WINDOW_OCCLUSION_DETECTION
368- * mask when it is doing occlusion detection, so use that
369- * order to fill our occlusion buffer which we'll flip
370- * to nux later
371- */
372+/* we want to paint underneath other windows here,
373+ * so we need to find if this window is actually
374+ * stacked on top of one of the nux input windows
375+ * and if so paint nux and stop us from painting
376+ * other windows or on top of the whole screen */
377 bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib,
378 const GLMatrix& matrix,
379 const CompRegion& region,
380@@ -2187,7 +2223,7 @@
381
382 std::vector<Window> const& tray_xids = uScreen->panel_controller_->GetTrayXids();
383 if (std::find(tray_xids.begin(), tray_xids.end(), window->id()) != tray_xids.end() &&
384- !uScreen->allowWindowPaint)
385+ (uScreen->ProhibitedPaintRequestors () & ShellPaintRequestorInterface::WindowPaintRequestor))
386 {
387 if (!uScreen->painting_tray_)
388 {
389@@ -2196,26 +2232,7 @@
390 }
391 }
392
393- return gWindow->glPaint(wAttrib, matrix, region, mask);
394-}
395-
396-/* handle window painting in an opengl context
397- *
398- * we want to paint underneath other windows here,
399- * so we need to find if this window is actually
400- * stacked on top of one of the nux input windows
401- * and if so paint nux and stop us from painting
402- * other windows or on top of the whole screen */
403-bool UnityWindow::glDraw(const GLMatrix& matrix,
404-#ifndef USE_MODERN_COMPIZ_GL
405- GLFragment::Attrib& attrib,
406-#else
407- const GLWindowPaintAttrib& attrib,
408-#endif
409- const CompRegion& region,
410- unsigned int mask)
411-{
412- if (uScreen->doShellRepaint && !uScreen->paint_panel_ && window->type() == CompWindowTypeNormalMask)
413+ if (uScreen->RepaintPending () && !uScreen->paint_panel_ && window->type() == CompWindowTypeNormalMask)
414 {
415 guint32 id = window->id();
416 bool maximized = WindowManager::Default()->IsWindowMaximized(id);
417@@ -2231,29 +2248,63 @@
418 }
419 }
420
421- if (uScreen->doShellRepaint && !uScreen->forcePaintOnTop ())
422+ if (IsNuxWindow ())
423 {
424- std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
425- unsigned int size = xwns.size();
426-
427- for (CompWindow* w = window; w && uScreen->doShellRepaint; w = w->prev)
428- {
429- auto id = w->id();
430-
431- for (unsigned int i = 0; i < size; ++i)
432- {
433- if (xwns[i] == id)
434- {
435-#ifdef USE_MODERN_COMPIZ_GL
436- uScreen->paintDisplay();
437+ /* Windows are painted in top-to-bottom order
438+ * with occlusion detection on, so we can
439+ * find out the top most nux window and paint
440+ * there */
441+ if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
442+ {
443+ GLWindowPaintAttrib noAlphaAttrib;
444+
445+ noAlphaAttrib.opacity = OPAQUE;
446+ noAlphaAttrib.brightness = BRIGHT;
447+ noAlphaAttrib.saturation = COLOR;
448+
449+ bool status = gWindow->glPaint (noAlphaAttrib,
450+ matrix,
451+ region,
452+ PAINT_WINDOW_OCCLUSION_DETECTION_MASK);
453+
454+ if (status)
455+ uScreen->EnforceRequestor (this);
456+
457+ /* We don't want core to take this window
458+ * into account when doing occlusion detection
459+ * however */
460+ return false;
461+ }
462+ /* Don't care about "fake" paints */
463+ else if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
464+ {
465+ return false;
466+ }
467+ else
468+ {
469+ uScreen->Paint (this, uScreen);
470+
471+ /* Don't paint nux windows on the real paint pass */
472+ return false;
473+ }
474+ }
475+
476+ return gWindow->glPaint(wAttrib, matrix, region, mask);
477+}
478+
479+/* handle window painting in an opengl context
480+ */
481+bool UnityWindow::glDraw(const GLMatrix& matrix,
482+#ifndef USE_MODERN_COMPIZ_GL
483+ GLFragment::Attrib& attrib,
484 #else
485- uScreen->paintDisplay(region, matrix, mask);
486+ const GLWindowPaintAttrib& attrib,
487 #endif
488- break;
489- }
490- }
491- }
492- }
493+ const CompRegion& region,
494+ unsigned int mask)
495+{
496+ if (IsNuxWindow ())
497+ return false;
498
499 if (window->type() == CompWindowTypeDesktopMask)
500 uScreen->setPanelShadowMatrix(matrix);
501@@ -2272,7 +2323,6 @@
502 uScreen->paintPanelShadow(matrix);
503 }
504
505-
506 return ret;
507 }
508
509@@ -2747,8 +2797,8 @@
510 #ifndef USE_MODERN_COMPIZ_GL
511 if (GL::fbo)
512 {
513- uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
514- uScreen->_fbo->onScreenSizeChanged (geometry);
515+ uScreen->fbo_ = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
516+ uScreen->fbo_->onScreenSizeChanged (geometry);
517 }
518 #endif
519
520@@ -2914,6 +2964,18 @@
521 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" Drag"), _("Resize window."), shortcut::COMPIZ_MOUSE_OPTION, "resize", "initiate_button"));
522 }
523
524+bool
525+UnityWindow::IsNuxWindow ()
526+{
527+ return is_nux_window_;
528+}
529+
530+unsigned int
531+UnityWindow::GetPaintRequestorType ()
532+{
533+ return ShellPaintRequestorInterface::WindowPaintRequestor;
534+}
535+
536 /* Window init */
537 UnityWindow::UnityWindow(CompWindow* window)
538 : BaseSwitchWindow (dynamic_cast<BaseSwitchScreen *> (UnityScreen::get (screen)), window)
539@@ -2922,10 +2984,16 @@
540 , gWindow(GLWindow::get(window))
541 , mMinimizeHandler()
542 , mShowdesktopHandler(nullptr)
543+ , is_nux_window_ (false)
544 {
545 WindowInterface::setHandler(window);
546 GLWindowInterface::setHandler(gWindow);
547
548+ std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
549+ for (unsigned int i = 0; i < xwns.size(); i++)
550+ if (xwns[i] == window->id ())
551+ is_nux_window_ = true;
552+
553 if (UnityScreen::get (screen)->optionGetShowMinimizedWindows () &&
554 window->mapNum ())
555 {
556
557=== modified file 'plugins/unityshell/src/unityshell.h'
558--- plugins/unityshell/src/unityshell.h 2012-05-30 18:43:17 +0000
559+++ plugins/unityshell/src/unityshell.h 2012-06-14 09:04:28 +0000
560@@ -52,6 +52,7 @@
561 #include "UBusWrapper.h"
562 #include "UnityshellPrivate.h"
563 #include "UnityShowdesktopHandler.h"
564+#include "ShellPaintSchedule.h"
565 #ifndef USE_MODERN_COMPIZ_GL
566 #include "ScreenEffectFramebufferObject.h"
567 #endif
568@@ -68,6 +69,10 @@
569
570 /* base screen class */
571 class UnityScreen :
572+ public FBOBindingQueryInterface,
573+ public ShellPaintDispatchInterface,
574+ public ShellPaintRequestorInterface,
575+ public ShellPaintInterface,
576 public unity::debug::Introspectable,
577 public sigc::trackable,
578 public ScreenInterface,
579@@ -92,11 +97,8 @@
580 void nuxEpilogue();
581
582 /* nux draw wrapper */
583-#ifdef USE_MODERN_COMPIZ_GL
584- void paintDisplay();
585-#else
586- void paintDisplay(const CompRegion& region, const GLMatrix& transform, unsigned int mask);
587-#endif
588+ bool PaintBackingFBO (CompOutput *output);
589+ void PaintDisplay (FBOBindingQueryInterface *);
590 void paintPanelShadow(const GLMatrix& matrix);
591 void setPanelShadowMatrix(const GLMatrix& matrix);
592
593@@ -132,9 +134,6 @@
594 CompOutput*,
595 unsigned int);
596
597- /* Pop our InputOutput windows from the paint list */
598- const CompWindowList& getWindowPaintList();
599-
600 /* handle X11 events */
601 void handleEvent(XEvent*);
602
603@@ -188,8 +187,6 @@
604 void NeedsRelayout();
605 void ScheduleRelayout(guint timeout);
606
607- bool forcePaintOnTop ();
608-
609 protected:
610 std::string GetName() const;
611 void AddProperties(GVariantBuilder* builder);
612@@ -231,6 +228,20 @@
613
614 void OnPanelStyleChanged();
615
616+ bool WasBound ();
617+ unsigned int GetPaintRequestorType ();
618+ unsigned int GetProhibitedPaintMasks ();
619+
620+ bool Paint (ShellPaintRequestorInterface *,
621+ FBOBindingQueryInterface *);
622+ bool EnforceRequestor (ShellPaintRequestorInterface *);
623+ void ClearRequestorEnforcement ();
624+ unsigned int ProhibitedPaintRequestors ();
625+ void RequireShellRepaint ();
626+ bool RepaintPending ();
627+
628+ ShellPaintDispatch paint_dispatch_;
629+
630 Settings dash_settings_;
631 dash::Style dash_style_;
632 panel::Style panel_style_;
633@@ -270,12 +281,9 @@
634 GLTexture::List _shadow_texture;
635
636 /* handle paint order */
637- bool doShellRepaint;
638- bool allowWindowPaint;
639 bool damaged;
640 bool _key_nav_mode_requested;
641 CompOutput* _last_output;
642- CompWindowList _withRemovedNuxWindows;
643
644 nux::Property<nux::Geometry> primary_monitor_;
645
646@@ -284,7 +292,7 @@
647 #ifdef USE_MODERN_COMPIZ_GL
648 ::GLFramebufferObject *oldFbo;
649 #else
650- ScreenEffectFramebufferObject::Ptr _fbo;
651+ ScreenEffectFramebufferObject::Ptr fbo_;
652 GLuint _active_fbo;
653 #endif
654
655@@ -311,15 +319,27 @@
656
657 UBusManager ubus_manager_;
658 glib::SourceManager sources_;
659+ unsigned int no_paint_allowed_mask_;
660
661 friend class UnityWindow;
662 };
663
664+class NuxBridgeWindowInterface
665+{
666+public:
667+
668+ virtual ~NuxBridgeWindowInterface () {};
669+
670+ virtual bool IsNuxWindow () = 0;
671+};
672+
673 class UnityWindow :
674 public WindowInterface,
675 public GLWindowInterface,
676 public ShowdesktopHandlerWindowInterface,
677 public compiz::WindowInputRemoverLockAcquireInterface,
678+ public NuxBridgeWindowInterface,
679+ public ShellPaintRequestorInterface,
680 public BaseSwitchWindow,
681 public PluginClassHandler <UnityWindow, CompWindow>
682 {
683@@ -417,7 +437,12 @@
684
685 compiz::WindowInputRemoverLock::Ptr GetInputRemover ();
686
687+ bool IsNuxWindow ();
688+ unsigned int GetPaintRequestorType ();
689+
690 compiz::WindowInputRemoverLock::Weak input_remover_;
691+
692+ bool is_nux_window_;
693 glib::Source::UniquePtr focus_desktop_timeout_;
694 };
695
696
697=== modified file 'tests/CMakeLists.txt'
698--- tests/CMakeLists.txt 2012-06-12 08:23:23 +0000
699+++ tests/CMakeLists.txt 2012-06-14 09:04:28 +0000
700@@ -150,6 +150,7 @@
701 test_unityshell_private.cpp
702 test_showdesktop_handler.cpp
703 test_hud_private.cpp
704+ test_shell_paint_schedule.cpp
705 ${CMAKE_SOURCE_DIR}/launcher/AbstractLauncherIcon.cpp
706 ${CMAKE_SOURCE_DIR}/unity-shared/Animator.cpp
707 ${UNITY_SRC}/DebugDBusInterface.cpp
708@@ -162,6 +163,7 @@
709 ${CMAKE_SOURCE_DIR}/launcher/FavoriteStorePrivate.cpp
710 ${CMAKE_SOURCE_DIR}/shortcuts/ShortcutModel.cpp
711 ${CMAKE_SOURCE_DIR}/shortcuts/ShortcutHintPrivate.cpp
712+ ${CMAKE_SOURCE_DIR}/unity-shared/ShellPaintSchedule.cpp
713 ${CMAKE_SOURCE_DIR}/unity-shared/Introspectable.cpp
714 ${CMAKE_SOURCE_DIR}/unity-shared/TextureCache.cpp
715 ${CMAKE_SOURCE_DIR}/unity-shared/Timer.cpp
716
717=== added file 'tests/test_shell_paint_schedule.cpp'
718--- tests/test_shell_paint_schedule.cpp 1970-01-01 00:00:00 +0000
719+++ tests/test_shell_paint_schedule.cpp 2012-06-14 09:04:28 +0000
720@@ -0,0 +1,284 @@
721+/*
722+ * Copyright 2012 Canonical Ltd.
723+ *
724+ * This program is free software: you can redistribute it and/or modify it
725+ * under the terms of the GNU General Public License version 3, as published
726+ * by the Free Software Foundation.
727+ *
728+ * This program is distributed in the hope that it will be useful, but
729+ * WITHOUT ANY WARRANTY; without even the implied warranties of
730+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
731+ * PURPOSE. See the GNU General Public License for more details.
732+ *
733+ * You should have received a copy of the GNU General Public License
734+ * version 3 along with this program. If not, see
735+ * <http://www.gnu.org/licenses/>
736+ *
737+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
738+ *
739+ */
740+
741+#include <gtest/gtest.h>
742+#include <gmock/gmock.h>
743+
744+using ::testing::StrictMock;
745+using ::testing::_;
746+using ::testing::AtLeast;
747+using ::testing::Return;
748+
749+#include "ShellPaintSchedule.h"
750+
751+using namespace unity;
752+
753+class MockShellPaintRequestor :
754+ public ShellPaintRequestorInterface
755+{
756+public:
757+
758+ MOCK_METHOD0 (GetPaintRequestorType, unsigned int ());
759+
760+};
761+
762+class MockFBOBindingQuery :
763+ public FBOBindingQueryInterface
764+{
765+public:
766+
767+ MOCK_METHOD0 (WasBound, bool ());
768+};
769+
770+class MockShellPaint :
771+ public ShellPaintInterface
772+{
773+public:
774+
775+ MOCK_METHOD1 (PaintDisplay, void (FBOBindingQueryInterface *));
776+};
777+
778+class MockShellPaintDispatch
779+{
780+public:
781+
782+ MOCK_METHOD2 (Paint, bool (ShellPaintRequestorInterface *, FBOBindingQueryInterface *));
783+ MOCK_METHOD1 (EnforceRequestor, void (ShellPaintRequestorInterface *));
784+ MOCK_METHOD0 (ClearRequestorEnforcement, void ());
785+ MOCK_METHOD0 (ProhibitedPaintRequestors, unsigned int ());
786+ MOCK_METHOD0 (RequireShellRepaint, void ());
787+ MOCK_METHOD0 (RepaintPending, bool ());
788+};
789+
790+class TestShellPaintSchedule :
791+ public ::testing::Test
792+{
793+};
794+
795+TEST(TestShellPaintSchedule, NoPaintWhereNotRequired)
796+{
797+ StrictMock <MockShellPaint> p;
798+ MockShellPaintRequestor r;
799+ MockFBOBindingQuery q;
800+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> unsigned int { return 0; } );
801+
802+ ShellPaintDispatch dispatch (&p, f);
803+
804+ dispatch.Paint (&r, &q);
805+}
806+
807+TEST(TestShellPaintSchedule, PaintWhereRequired)
808+{
809+ StrictMock <MockShellPaint> p;
810+ MockShellPaintRequestor r;
811+ MockFBOBindingQuery q;
812+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> unsigned int { return 0; } );
813+
814+ ShellPaintDispatch dispatch (&p, f);
815+
816+ dispatch.RequireShellRepaint ();
817+
818+ EXPECT_CALL (r, GetPaintRequestorType ());
819+ EXPECT_CALL (p, PaintDisplay (&q));
820+
821+ dispatch.Paint (&r, &q);
822+}
823+
824+TEST(TestShellPaintSchedule, NoPaintTwice)
825+{
826+ StrictMock <MockShellPaint> p;
827+ MockShellPaintRequestor r;
828+ MockFBOBindingQuery q;
829+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> unsigned int { return 0; } );
830+
831+ ShellPaintDispatch dispatch (&p, f);
832+
833+ dispatch.RequireShellRepaint ();
834+
835+ EXPECT_CALL (r, GetPaintRequestorType ());
836+ EXPECT_CALL (p, PaintDisplay (&q));
837+
838+ dispatch.Paint (&r, &q);
839+ dispatch.Paint (&r, &q);
840+}
841+
842+TEST(TestShellPaintSchedule, NoWindowPaintButScreenPaint)
843+{
844+ StrictMock <MockShellPaint> p;
845+ MockShellPaintRequestor r;
846+ MockFBOBindingQuery q;
847+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> unsigned int { return ShellPaintRequestorInterface::WindowPaintRequestor; } );
848+
849+ ShellPaintDispatch dispatch (&p, f);
850+
851+ dispatch.RequireShellRepaint ();
852+
853+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
854+
855+ dispatch.Paint (&r, &q);
856+
857+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::ScreenPaintRequestor));
858+ EXPECT_CALL (p, PaintDisplay (&q));
859+
860+ dispatch.Paint (&r, &q);
861+}
862+
863+TEST(TestShellPaintSchedule, NoScreenPaintButWindowPaint)
864+{
865+ StrictMock <MockShellPaint> p;
866+ MockShellPaintRequestor r;
867+ MockFBOBindingQuery q;
868+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> unsigned int { return ShellPaintRequestorInterface::ScreenPaintRequestor; } );
869+
870+ ShellPaintDispatch dispatch (&p, f);
871+
872+ dispatch.RequireShellRepaint ();
873+
874+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::ScreenPaintRequestor));
875+
876+ dispatch.Paint (&r, &q);
877+
878+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
879+ EXPECT_CALL (p, PaintDisplay (&q));
880+
881+ dispatch.Paint (&r, &q);
882+}
883+
884+TEST(TestShellPaintSchedule, TopRequestorOnlyPaints)
885+{
886+ StrictMock <MockShellPaint> p;
887+ MockShellPaintRequestor r_w1, r_w2;
888+ MockFBOBindingQuery q;
889+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> unsigned int { return 0; } );
890+
891+ ShellPaintDispatch dispatch (&p, f);
892+
893+ dispatch.RequireShellRepaint ();
894+
895+ dispatch.ClearRequestorEnforcement ();
896+ dispatch.EnforceRequestor (&r_w2);
897+
898+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
899+ EXPECT_CALL (r_w1, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
900+
901+ dispatch.Paint (&r_w1, &q);
902+
903+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
904+ EXPECT_CALL (p, PaintDisplay (&q));
905+
906+ dispatch.Paint (&r_w2, &q);
907+}
908+
909+TEST(TestShellPaintSchedule, SuperveningRequestorOfOtherTypePaints)
910+{
911+ StrictMock <MockShellPaint> p;
912+ MockShellPaintRequestor r_w1, r_w2, r_s1;
913+ MockFBOBindingQuery q;
914+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> unsigned int { return 0; } );
915+
916+ ShellPaintDispatch dispatch (&p, f);
917+
918+ dispatch.RequireShellRepaint ();
919+
920+ dispatch.ClearRequestorEnforcement ();
921+ dispatch.EnforceRequestor (&r_w2);
922+
923+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
924+ EXPECT_CALL (r_w1, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
925+
926+ dispatch.Paint (&r_w1, &q);
927+
928+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
929+ EXPECT_CALL (r_s1, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::ScreenPaintRequestor));
930+
931+ EXPECT_CALL (p, PaintDisplay (&q));
932+
933+ dispatch.Paint (&r_s1, &q);
934+
935+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
936+
937+ dispatch.Paint (&r_w2, &q);
938+}
939+
940+TEST(TestShellPaintSchedule, DoubleEnforcementHasNoEffect)
941+{
942+ StrictMock <MockShellPaint> p;
943+ MockShellPaintRequestor r_w1, r_w2;
944+ MockFBOBindingQuery q;
945+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> unsigned int { return 0; } );
946+
947+ ShellPaintDispatch dispatch (&p, f);
948+
949+ dispatch.RequireShellRepaint ();
950+
951+ dispatch.ClearRequestorEnforcement ();
952+ dispatch.EnforceRequestor (&r_w2);
953+ dispatch.EnforceRequestor (&r_w1);
954+
955+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
956+ EXPECT_CALL (r_w1, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
957+
958+ dispatch.Paint (&r_w1, &q);
959+
960+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
961+ EXPECT_CALL (p, PaintDisplay (&q));
962+
963+ dispatch.Paint (&r_w2, &q);
964+}
965+
966+TEST(TestShellPaintSchedule, GetPendingRepaint)
967+{
968+ StrictMock <MockShellPaint> p;
969+ MockShellPaintRequestor r;
970+ MockFBOBindingQuery q;
971+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> unsigned int { return 0; } );
972+
973+ ShellPaintDispatch dispatch (&p, f);
974+
975+ EXPECT_FALSE (dispatch.RepaintPending ());
976+
977+ dispatch.RequireShellRepaint ();
978+
979+ EXPECT_TRUE (dispatch.RepaintPending ());
980+
981+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::WindowPaintRequestor));
982+ EXPECT_CALL (p, PaintDisplay (&q));
983+
984+ dispatch.Paint (&r, &q);
985+
986+ EXPECT_FALSE (dispatch.RepaintPending ());
987+}
988+
989+TEST(TestShellPaintSchedule, GetProhibitedPaintMasks)
990+{
991+ StrictMock <MockShellPaint> p;
992+ MockShellPaintRequestor r;
993+ MockFBOBindingQuery q;
994+ unsigned int prohibited_paint_mask = 0;
995+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([&]() -> unsigned int { return prohibited_paint_mask; } );
996+
997+ ShellPaintDispatch dispatch (&p, f);
998+
999+ EXPECT_EQ (prohibited_paint_mask, dispatch.ProhibitedPaintRequestors ());
1000+ prohibited_paint_mask = ShellPaintRequestorInterface::WindowPaintRequestor;
1001+ EXPECT_EQ (prohibited_paint_mask, dispatch.ProhibitedPaintRequestors ());
1002+ prohibited_paint_mask = ShellPaintRequestorInterface::ScreenPaintRequestor;
1003+ EXPECT_EQ (prohibited_paint_mask, dispatch.ProhibitedPaintRequestors ());
1004+}
1005
1006=== modified file 'unity-shared/CMakeLists.txt'
1007--- unity-shared/CMakeLists.txt 2012-05-22 10:15:47 +0000
1008+++ unity-shared/CMakeLists.txt 2012-06-14 09:04:28 +0000
1009@@ -47,6 +47,7 @@
1010 PanelStyle.cpp
1011 SearchBar.cpp
1012 SearchBarSpinner.cpp
1013+ ShellPaintSchedule.cpp
1014 StaticCairoText.cpp
1015 TextureCache.cpp
1016 Timer.cpp
1017
1018=== added file 'unity-shared/ShellPaintSchedule.cpp'
1019--- unity-shared/ShellPaintSchedule.cpp 1970-01-01 00:00:00 +0000
1020+++ unity-shared/ShellPaintSchedule.cpp 2012-06-14 09:04:28 +0000
1021@@ -0,0 +1,91 @@
1022+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1023+/*
1024+ * Copyright (C) 2012 Canonical Ltd
1025+ *
1026+ * This program is free software: you can redistribute it and/or modify
1027+ * it under the terms of the GNU General Public License version 3 as
1028+ * published by the Free Software Foundation.
1029+ *
1030+ * This program is distributed in the hope that it will be useful,
1031+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1032+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1033+ * GNU General Public License for more details.
1034+ *
1035+ * You should have received a copy of the GNU General Public License
1036+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1037+ *
1038+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1039+ */
1040+
1041+#include "ShellPaintSchedule.h"
1042+
1043+namespace unity
1044+{
1045+
1046+ShellPaintDispatch::ShellPaintDispatch (ShellPaintInterface *paint_interface,
1047+ const GetProhibitedPaintMasksFunc &prohibited_func) :
1048+ shell_repaint_required_ (false),
1049+ top_requestor_ (nullptr),
1050+ prohibited_paint_masks_func_ (prohibited_func),
1051+ paint_interface_ (paint_interface)
1052+{
1053+}
1054+
1055+bool
1056+ShellPaintDispatch::Paint (ShellPaintRequestorInterface *requestor,
1057+ FBOBindingQueryInterface *fbo_query)
1058+{
1059+ if (!shell_repaint_required_)
1060+ return false;
1061+
1062+ if (prohibited_paint_masks_func_ () & requestor->GetPaintRequestorType ())
1063+ return false;
1064+
1065+ if (top_requestor_)
1066+ if ((top_requestor_->GetPaintRequestorType () &
1067+ requestor->GetPaintRequestorType ()) && top_requestor_ != requestor)
1068+ return false;
1069+
1070+ paint_interface_->PaintDisplay (fbo_query);
1071+
1072+ shell_repaint_required_ = false;
1073+
1074+ return true;
1075+}
1076+
1077+bool
1078+ShellPaintDispatch::EnforceRequestor (ShellPaintRequestorInterface *requestor)
1079+{
1080+ if (top_requestor_)
1081+ return false;
1082+
1083+ top_requestor_ = requestor;
1084+
1085+ return true;
1086+}
1087+
1088+void
1089+ShellPaintDispatch::ClearRequestorEnforcement ()
1090+{
1091+ top_requestor_ = nullptr;
1092+}
1093+
1094+unsigned int
1095+ShellPaintDispatch::ProhibitedPaintRequestors ()
1096+{
1097+ return prohibited_paint_masks_func_ ();
1098+}
1099+
1100+void
1101+ShellPaintDispatch::RequireShellRepaint ()
1102+{
1103+ shell_repaint_required_ = true;
1104+}
1105+
1106+bool
1107+ShellPaintDispatch::RepaintPending ()
1108+{
1109+ return shell_repaint_required_;
1110+}
1111+
1112+}
1113
1114=== added file 'unity-shared/ShellPaintSchedule.h'
1115--- unity-shared/ShellPaintSchedule.h 1970-01-01 00:00:00 +0000
1116+++ unity-shared/ShellPaintSchedule.h 2012-06-14 09:04:28 +0000
1117@@ -0,0 +1,104 @@
1118+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1119+/*
1120+ * Copyright (C) 2012 Canonical Ltd
1121+ *
1122+ * This program is free software: you can redistribute it and/or modify
1123+ * it under the terms of the GNU General Public License version 3 as
1124+ * published by the Free Software Foundation.
1125+ *
1126+ * This program is distributed in the hope that it will be useful,
1127+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1128+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1129+ * GNU General Public License for more details.
1130+ *
1131+ * You should have received a copy of the GNU General Public License
1132+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1133+ *
1134+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1135+ */
1136+
1137+#ifndef UNITY_PAINT_SCHEDULE_H
1138+#define UNITY_PAINT_SCHEDULE_H
1139+
1140+#include <boost/bind.hpp>
1141+#include <boost/function.hpp>
1142+
1143+namespace unity
1144+{
1145+
1146+class ShellPaintRequestorInterface
1147+{
1148+public:
1149+
1150+
1151+ static const unsigned int WindowPaintRequestor = (1 << 0);
1152+ static const unsigned int ScreenPaintRequestor = (1 << 1);
1153+
1154+ virtual ~ShellPaintRequestorInterface () {}
1155+
1156+ virtual unsigned int GetPaintRequestorType () = 0;
1157+};
1158+
1159+class FBOBindingQueryInterface
1160+{
1161+public:
1162+
1163+ virtual ~FBOBindingQueryInterface () {}
1164+ virtual bool WasBound () = 0;
1165+};
1166+
1167+class ShellPaintInterface
1168+{
1169+public:
1170+
1171+ virtual ~ShellPaintInterface () {};
1172+
1173+ virtual void PaintDisplay (FBOBindingQueryInterface *) = 0;
1174+};
1175+
1176+class ShellPaintDispatchInterface
1177+{
1178+public:
1179+
1180+ virtual ~ShellPaintDispatchInterface () {}
1181+
1182+ virtual bool Paint (ShellPaintRequestorInterface *,
1183+ FBOBindingQueryInterface *) = 0;
1184+ virtual bool EnforceRequestor (ShellPaintRequestorInterface *) = 0;
1185+ virtual void ClearRequestorEnforcement () = 0;
1186+ virtual unsigned int ProhibitedPaintRequestors () = 0;
1187+ virtual void RequireShellRepaint () = 0;
1188+ virtual bool RepaintPending () = 0;
1189+
1190+};
1191+
1192+class ShellPaintDispatch :
1193+ public ShellPaintDispatchInterface
1194+{
1195+public:
1196+
1197+ typedef boost::function <unsigned int ()> GetProhibitedPaintMasksFunc;
1198+
1199+ ShellPaintDispatch (ShellPaintInterface * paint_interface,
1200+ const GetProhibitedPaintMasksFunc &func);
1201+
1202+ bool Paint (ShellPaintRequestorInterface *,
1203+ FBOBindingQueryInterface *);
1204+ bool EnforceRequestor (ShellPaintRequestorInterface *);
1205+ void ClearRequestorEnforcement ();
1206+ unsigned int ProhibitedPaintRequestors ();
1207+ void RequireShellRepaint ();
1208+ bool RepaintPending ();
1209+
1210+
1211+protected:
1212+
1213+ bool shell_repaint_required_;
1214+ ShellPaintRequestorInterface *top_requestor_;
1215+ GetProhibitedPaintMasksFunc prohibited_paint_masks_func_;
1216+ ShellPaintInterface *paint_interface_;
1217+};
1218+
1219+}
1220+
1221+#endif