Merge lp:~compiz-team/compiz/compiz.fix_1024304 into lp:compiz/0.9.9
- compiz.fix_1024304
- Merge into 0.9.9
Status: | Superseded |
---|---|
Proposed branch: | lp:~compiz-team/compiz/compiz.fix_1024304 |
Merge into: | lp:compiz/0.9.9 |
Diff against target: |
4049 lines (+1511/-1543) 42 files modified
include/core/CMakeLists.txt (+0/-1) include/core/configurerequestbuffer.h (+0/-73) include/core/window.h (+7/-26) plugins/animation/src/animation.cpp (+1/-1) plugins/composite/CMakeLists.txt (+6/-1) plugins/composite/include/composite/agedamagequery.h (+53/-0) plugins/composite/include/composite/composite.h (+49/-14) plugins/composite/src/backbuffertracking/CMakeLists.txt (+31/-0) plugins/composite/src/backbuffertracking/include/backbuffertracking.h (+125/-0) plugins/composite/src/backbuffertracking/src/backbuffertracking.cpp (+214/-0) plugins/composite/src/backbuffertracking/tests/CMakeLists.txt (+24/-0) plugins/composite/src/backbuffertracking/tests/test-composite-backbuffertracking.cpp (+450/-0) plugins/composite/src/privates.h (+18/-2) plugins/composite/src/screen.cpp (+137/-12) plugins/composite/src/window.cpp (+5/-1) plugins/kdecompat/src/kdecompat.cpp (+2/-2) plugins/move/src/move.cpp (+5/-12) plugins/move/src/move.h (+0/-2) plugins/opengl/include/opengl/opengl.h (+18/-3) plugins/opengl/src/doublebuffer/src/double-buffer.cpp (+1/-2) plugins/opengl/src/framebufferobject.cpp (+1/-1) plugins/opengl/src/paint.cpp (+13/-8) plugins/opengl/src/privates.h (+31/-4) plugins/opengl/src/screen.cpp (+301/-30) plugins/opengl/src/window.cpp (+1/-2) plugins/resize/src/resize.cpp (+1/-1) plugins/ring/src/ring.cpp (+1/-1) plugins/scale/src/scale.cpp (+3/-1) plugins/staticswitcher/src/staticswitcher.cpp (+1/-1) plugins/switcher/src/switcher.cpp (+1/-1) plugins/td/src/3d.cpp (+1/-1) plugins/water/src/water.cpp (+7/-0) plugins/water/src/water.h (+1/-0) src/CMakeLists.txt (+0/-7) src/asyncserverwindow.h (+0/-52) src/configurerequestbuffer-impl.h (+0/-145) src/configurerequestbuffer.cpp (+0/-363) src/event.cpp (+1/-1) src/privatewindow.h (+1/-45) src/syncserverwindow.h (+0/-49) src/tests/CMakeLists.txt (+0/-11) src/tests/test_configurerequestbuffer.cpp (+0/-667) |
To merge this branch: | bzr merge lp:~compiz-team/compiz/compiz.fix_1024304 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Esokrates | testing, benchmarking | Pending | |
Compiz Maintainers | Pending | ||
Review via email: mp+148842@code.launchpad.net |
This proposal supersedes a proposal from 2013-02-15.
This proposal has been superseded by a proposal from 2013-02-28.
Commit message
Add support for the GLX_EXT_buffer_age extension on hardware that supports it, which should result in a nice speed-boost due to the fact that we no longer have to abuse fillrate by retaining old frame contents, and instead asking the driver how defined the current frame is.
Added external API for plugins to register their own damage tracking objects - with a callback as to whether or not to track the specified damage. This allows plugins that rely on both the retrospective and new damage to the framebuffer to ignore feedback caused by their old damage events.
(LP: #1024304)
Description of the change
Add support for the GLX_EXT_buffer_age extension on hardware that supports it, which should result in a nice speed-boost due to the fact that we no longer have to abuse fillrate by retaining old frame contents, and instead asking the driver how defined the current frame is.
Note: I've marked this needs review for now, but it shouldn't be merged because it confuses unity a fair bit. I've got some branches on unity which will make it work with this code (albeit, the launcher and panel will be re-presented on every frame, but that is what was happening anyways and is harmless for performance).
1. https:/
2. https:/
Note 2: I don't have any solid numbers on this yet. Daniel reported a 10% difference with redirect-
Update: test results here: http://
I was careful to modify phoronix-test-suite to run tests in windowed mode only, and those were the only three tests I was able to get to run in windowed mode. Of particular interest was the fact that the unigine demos had a 5x performance improvement, probably because the driver was spending less time filling redundant pixels from the compositor. In other areas we had a roughly 5FPS boost.
Compiz framerate graph:
http://
You'll see that especially on the last test, it drops off quite a bit on the non buffer_age case, and is generally speaking lower across the board.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3557
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3560
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Esokrates (esokrarkose) wrote : Posted in a previous version of this proposal | # |
I have used the ppa containing these changes since the beginning and could confirm the performance improvements using Phoronix Test Suite (and of course my subjective feeling). Comparing benchmarks of compiz 0.9.9.0 and the branch containing the improvements (both disabled "unredirect fullscreen windows") clearly shows that there is an substantial performance improvement.
Part of my benchmark results can be downloaded here:
http://
MC Return (mc-return) wrote : Posted in a previous version of this proposal | # |
The change to debian/changelog seems to be unintended and should probably be removed.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3561
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3563
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3563
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3564
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 3565. By Sam Spilsbury
-
Revert more changes which should not have happened
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3565
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 3566. By Sam Spilsbury
-
Merge lp:compiz
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3566
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 3567. By Sam Spilsbury
-
Fix using the postprocess frame provider in situations where that isn't
actually allowed.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3567
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 3568. By Sam Spilsbury
-
Merge lp:compiz
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3568
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Unmerged revisions
- 3568. By Sam Spilsbury
-
Merge lp:compiz
- 3567. By Sam Spilsbury
-
Fix using the postprocess frame provider in situations where that isn't
actually allowed. - 3566. By Sam Spilsbury
-
Merge lp:compiz
- 3565. By Sam Spilsbury
-
Revert more changes which should not have happened
- 3564. By Sam Spilsbury
-
Merge lp:compiz
- 3563. By Sam Spilsbury
-
Fix broken merge
- 3562. By Sam Spilsbury
-
Merge lp:compiz
- 3561. By Sam Spilsbury
-
Fix typo
- 3560. By Sam Spilsbury
-
Unrevert changes which should not have been reverted
- 3559. By Sam Spilsbury
-
Merge lp:compiz
Preview Diff
1 | === modified file 'include/core/CMakeLists.txt' |
2 | --- include/core/CMakeLists.txt 2013-01-03 16:05:26 +0000 |
3 | +++ include/core/CMakeLists.txt 2013-02-28 03:13:24 +0000 |
4 | @@ -1,7 +1,6 @@ |
5 | set (_headers |
6 | action.h |
7 | atoms.h |
8 | - configurerequestbuffer.h |
9 | core.h |
10 | countedlist.h |
11 | global.h |
12 | |
13 | === removed file 'include/core/configurerequestbuffer.h' |
14 | --- include/core/configurerequestbuffer.h 2012-12-13 11:12:32 +0000 |
15 | +++ include/core/configurerequestbuffer.h 1970-01-01 00:00:00 +0000 |
16 | @@ -1,73 +0,0 @@ |
17 | -/* |
18 | - * Copyright © 2012 Sam Spilsbury |
19 | - * |
20 | - * Permission to use, copy, modify, distribute, and sell this software |
21 | - * and its documentation for any purpose is hereby granted without |
22 | - * fee, provided that the above copyright notice appear in all copies |
23 | - * and that both that copyright notice and this permission notice |
24 | - * appear in supporting documentation, and that the name of |
25 | - * Canonical Ltd. not be used in advertising or publicity pertaining to |
26 | - * distribution of the software without specific, written prior permission. |
27 | - * Canonical Ltd. makes no representations about the suitability of this |
28 | - * software for any purpose. It is provided "as is" without express or |
29 | - * implied warranty. |
30 | - * |
31 | - * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
32 | - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
33 | - * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
34 | - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
35 | - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
36 | - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
37 | - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
38 | - * |
39 | - * Authored by: Sam Spilsbury <smspillaz@gmail.com> |
40 | - */ |
41 | -#ifndef _COMPIZ_CONFIGURE_REQUEST_BUFFER_H |
42 | -#define _COMPIZ_CONFIGURE_REQUEST_BUFFER_H |
43 | - |
44 | -#include <boost/shared_ptr.hpp> |
45 | -#include <X11/Xlib.h> |
46 | -#include <syncserverwindow.h> |
47 | - |
48 | -namespace compiz |
49 | -{ |
50 | -namespace window |
51 | -{ |
52 | -namespace configure_buffers |
53 | -{ |
54 | -class Releasable |
55 | -{ |
56 | - public: |
57 | - |
58 | - typedef boost::shared_ptr <Releasable> Ptr; |
59 | - |
60 | - virtual void release () = 0; |
61 | -}; |
62 | - |
63 | -class Buffer : |
64 | - public SyncServerWindow |
65 | -{ |
66 | - public: |
67 | - |
68 | - typedef boost::shared_ptr <Buffer> Ptr; |
69 | - |
70 | - virtual ~Buffer () {} |
71 | - |
72 | - virtual void pushClientRequest (const XWindowChanges &xwc, unsigned int mask) = 0; |
73 | - virtual void pushWrapperRequest (const XWindowChanges &xwc, unsigned int mask) = 0; |
74 | - virtual void pushFrameRequest (const XWindowChanges &xwc, unsigned int mask) = 0; |
75 | - |
76 | - virtual void pushSyntheticConfigureNotify () = 0; |
77 | - |
78 | - virtual Releasable::Ptr obtainLock () = 0; |
79 | - |
80 | - /* This API will all configure requests to be |
81 | - * released. It should only be used in situations |
82 | - * where you have a server grab and need |
83 | - * to have complete sync with the server */ |
84 | - virtual void forceRelease () = 0; |
85 | -}; |
86 | -} |
87 | -} |
88 | -} |
89 | -#endif |
90 | |
91 | === modified file 'include/core/window.h' |
92 | --- include/core/window.h 2013-02-10 05:01:50 +0000 |
93 | +++ include/core/window.h 2013-02-28 03:13:24 +0000 |
94 | @@ -54,26 +54,13 @@ |
95 | class PrivateWindow; |
96 | struct CompStartupSequence; |
97 | |
98 | -namespace compiz |
99 | -{ |
100 | -namespace window |
101 | -{ |
102 | -namespace configure_buffers |
103 | -{ |
104 | -class Releasable; |
105 | -typedef boost::shared_ptr <Releasable> ReleasablePtr; |
106 | -} |
107 | -} |
108 | - |
109 | -namespace private_screen |
110 | -{ |
111 | -class Ping; |
112 | -class GrabManager; |
113 | -class OutputDevices; |
114 | -class WindowManager; |
115 | -class StartupSequence; |
116 | -} |
117 | -} |
118 | +namespace compiz { namespace private_screen { |
119 | + class Ping; |
120 | + class GrabManager; |
121 | + class OutputDevices; |
122 | + class WindowManager; |
123 | + class StartupSequence; |
124 | +}} |
125 | |
126 | #define ROOTPARENT(x) (((x)->frame ()) ? (x)->frame () : (x)->id ()) |
127 | |
128 | @@ -542,12 +529,6 @@ |
129 | bool updateStruts (); |
130 | const CompStruts *struts () const; |
131 | |
132 | - bool queryAttributes (XWindowAttributes &); |
133 | - bool queryFrameAttributes (XWindowAttributes &); |
134 | - |
135 | - compiz::window::configure_buffers::ReleasablePtr |
136 | - obtainLockOnConfigureRequests (); |
137 | - |
138 | WRAPABLE_HND (0, WindowInterface, void, getOutputExtents, |
139 | CompWindowExtents&); |
140 | WRAPABLE_HND (1, WindowInterface, void, getAllowedActions, |
141 | |
142 | === modified file 'plugins/animation/src/animation.cpp' |
143 | --- plugins/animation/src/animation.cpp 2013-01-11 08:28:51 +0000 |
144 | +++ plugins/animation/src/animation.cpp 2013-02-28 03:13:24 +0000 |
145 | @@ -1617,7 +1617,7 @@ |
146 | // Is this the first glPaint call this round |
147 | // without the mask PAINT_WINDOW_OCCLUSION_DETECTION_MASK? |
148 | if (mPAScreen->mStartingNewPaintRound && |
149 | - !(mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)) |
150 | + !(mask & PAINT_WINDOW_NO_DRAW_MASKS)) |
151 | { |
152 | mPAScreen->mStartingNewPaintRound = false; |
153 | |
154 | |
155 | === modified file 'plugins/composite/CMakeLists.txt' |
156 | --- plugins/composite/CMakeLists.txt 2012-09-25 01:15:36 +0000 |
157 | +++ plugins/composite/CMakeLists.txt 2013-02-28 03:13:24 +0000 |
158 | @@ -2,9 +2,14 @@ |
159 | |
160 | include (CompizPlugin) |
161 | |
162 | +include_directories (${CMAKE_CURRENT_SOURCE_DIR}/include) |
163 | include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/pixmapbinding/include) |
164 | +include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/backbuffertracking/include) |
165 | + |
166 | link_directories (${CMAKE_CURRENT_BINARY_DIR}/src/pixmapbinding) |
167 | +link_directories (${CMAKE_CURRENT_BINARY_DIR}/src/backbuffertracking) |
168 | |
169 | -compiz_plugin (composite LIBRARIES compiz_composite_pixmapbinding) |
170 | +compiz_plugin (composite LIBRARIES compiz_composite_pixmapbinding compiz_composite_backbuffertracking) |
171 | |
172 | add_subdirectory (src/pixmapbinding) |
173 | +add_subdirectory (src/backbuffertracking) |
174 | |
175 | === added file 'plugins/composite/include/composite/agedamagequery.h' |
176 | --- plugins/composite/include/composite/agedamagequery.h 1970-01-01 00:00:00 +0000 |
177 | +++ plugins/composite/include/composite/agedamagequery.h 2013-02-28 03:13:24 +0000 |
178 | @@ -0,0 +1,53 @@ |
179 | +/* |
180 | + * Compiz, composite plugin, GLX_EXT_buffer_age logic |
181 | + * |
182 | + * Copyright (c) 2012 Sam Spilsbury |
183 | + * Authors: Sam Spilsbury <smspillaz@gmail.com> |
184 | + * |
185 | + * Permission is hereby granted, free of charge, to any person obtaining a |
186 | + * copy of this software and associated documentation files (the "Software"), |
187 | + * to deal in the Software without restriction, including without limitation |
188 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
189 | + * and/or sell copies of the Software, and to permit persons to whom the |
190 | + * Software is furnished to do so, subject to the following conditions: |
191 | + * |
192 | + * The above copyright notice and this permission notice shall be included in |
193 | + * all copies or substantial portions of the Software. |
194 | + * |
195 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
196 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
197 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
198 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
199 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
200 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
201 | + * DEALINGS IN THE SOFTWARE. |
202 | + */ |
203 | +#ifndef _COMPIZ_COMPOSITE_AGEDAMAGEQUERY_H |
204 | +#define _COMPIZ_COMPOSITE_AGEDAMAGEQUERY_H |
205 | + |
206 | +#include <boost/shared_ptr.hpp> |
207 | +#include <core/region.h> |
208 | + |
209 | +namespace compiz |
210 | +{ |
211 | +namespace composite |
212 | +{ |
213 | +namespace buffertracking |
214 | +{ |
215 | +class AgeDamageQuery |
216 | +{ |
217 | + public: |
218 | + |
219 | + typedef boost::shared_ptr <AgeDamageQuery> Ptr; |
220 | + typedef boost::function <bool (const CompRegion &)> AreaShouldBeMarkedDirty; |
221 | + |
222 | + virtual ~AgeDamageQuery () {} |
223 | + virtual CompRegion damageForFrameAge (unsigned int) = 0; |
224 | + virtual const CompRegion & currentFrameDamage () = 0; |
225 | +}; |
226 | +} |
227 | +} |
228 | +} |
229 | + |
230 | +#endif |
231 | + |
232 | |
233 | === modified file 'plugins/composite/include/composite/composite.h' |
234 | --- plugins/composite/include/composite/composite.h 2012-10-16 05:11:10 +0000 |
235 | +++ plugins/composite/include/composite/composite.h 2013-02-28 03:13:24 +0000 |
236 | @@ -30,7 +30,7 @@ |
237 | |
238 | #include <X11/extensions/Xcomposite.h> |
239 | |
240 | -#define COMPIZ_COMPOSITE_ABI 5 |
241 | +#define COMPIZ_COMPOSITE_ABI 6 |
242 | |
243 | #include "core/pluginclasshandler.h" |
244 | #include "core/timer.h" |
245 | @@ -38,6 +38,8 @@ |
246 | #include "core/screen.h" |
247 | #include "core/wrapsystem.h" |
248 | |
249 | +#include "composite/agedamagequery.h" |
250 | + |
251 | #define COMPOSITE_SCREEN_DAMAGE_PENDING_MASK (1 << 0) |
252 | #define COMPOSITE_SCREEN_DAMAGE_REGION_MASK (1 << 1) |
253 | #define COMPOSITE_SCREEN_DAMAGE_ALL_MASK (1 << 2) |
254 | @@ -98,18 +100,19 @@ |
255 | namespace composite |
256 | { |
257 | class PaintHandler { |
258 | -public: |
259 | - virtual ~PaintHandler () {}; |
260 | - |
261 | - virtual void paintOutputs (CompOutput::ptrList &outputs, |
262 | - unsigned int mask, |
263 | - const CompRegion ®ion) = 0; |
264 | - |
265 | - virtual bool hasVSync () { return false; }; |
266 | - virtual bool requiredForcedRefreshRate () { return false; }; |
267 | - |
268 | - virtual void prepareDrawing () {}; |
269 | - virtual bool compositingActive () { return false; }; |
270 | + public: |
271 | + virtual ~PaintHandler () {}; |
272 | + |
273 | + virtual void paintOutputs (CompOutput::ptrList &outputs, |
274 | + unsigned int mask, |
275 | + const CompRegion ®ion) = 0; |
276 | + |
277 | + virtual bool hasVSync () { return false; }; |
278 | + virtual bool requiredForcedRefreshRate () { return false; }; |
279 | + |
280 | + virtual void prepareDrawing () {}; |
281 | + virtual bool compositingActive () { return false; }; |
282 | + virtual unsigned int getFrameAge () { return 1; } |
283 | }; |
284 | } |
285 | } |
286 | @@ -173,12 +176,19 @@ |
287 | * Hookable function to damage regions directly |
288 | */ |
289 | virtual void damageRegion (const CompRegion &r); |
290 | + |
291 | + /** |
292 | + * Hookable function to notify plugins that the last damage |
293 | + * event for this frame has been received, and all further damage |
294 | + * events will be for the next frame |
295 | + */ |
296 | + virtual void damageCutoff (); |
297 | }; |
298 | |
299 | extern template class PluginClassHandler<CompositeScreen, CompScreen, COMPIZ_COMPOSITE_ABI>; |
300 | |
301 | class CompositeScreen : |
302 | - public WrapableHandler<CompositeScreenInterface, 7>, |
303 | + public WrapableHandler<CompositeScreenInterface, 8>, |
304 | public PluginClassHandler<CompositeScreen, CompScreen, COMPIZ_COMPOSITE_ABI>, |
305 | public CompOption::Class |
306 | { |
307 | @@ -203,6 +213,24 @@ |
308 | void damageScreen (); |
309 | |
310 | void damagePending (); |
311 | + |
312 | + /** |
313 | + * Causes the damage that was recorded on N - 1 number of |
314 | + * frames ago to be added to the current frame, applied |
315 | + * culmulatively. An age of "zero" means that the entire frame |
316 | + * is considered undefined and must be completely repaired, |
317 | + * wheras an age of 1 means that this frame is the same as the |
318 | + * last frame, so no damage is required. |
319 | + */ |
320 | + void applyDamageForFrameAge (unsigned int); |
321 | + unsigned int getFrameAge (); |
322 | + void addOverdrawDamageRegion (const CompRegion &); |
323 | + |
324 | + typedef compiz::composite::buffertracking::AgeDamageQuery DamageQuery; |
325 | + typedef DamageQuery::AreaShouldBeMarkedDirty AreaShouldBeMarkedDirty; |
326 | + |
327 | + DamageQuery::Ptr |
328 | + getDamageQuery (const AreaShouldBeMarkedDirty &callback); |
329 | |
330 | |
331 | unsigned int damageMask (); |
332 | @@ -248,6 +276,7 @@ |
333 | * event loop |
334 | */ |
335 | WRAPABLE_HND (6, CompositeScreenInterface, void, damageRegion, const CompRegion &); |
336 | + WRAPABLE_HND (7, CompositeScreenInterface, void, damageCutoff); |
337 | |
338 | friend class PrivateCompositeDisplay; |
339 | |
340 | @@ -310,6 +339,12 @@ |
341 | */ |
342 | #define PAINT_WINDOW_BLEND_MASK (1 << 19) |
343 | |
344 | +/** |
345 | + * flags that would indicate the window is never actually drawn |
346 | + */ |
347 | +#define PAINT_WINDOW_NO_DRAW_MASKS (PAINT_WINDOW_OCCLUSION_DETECTION_MASK | \ |
348 | + PAINT_WINDOW_NO_CORE_INSTANCE_MASK) |
349 | + |
350 | class CompositeWindowInterface; |
351 | extern template class WrapableInterface<CompositeWindow, CompositeWindowInterface>; |
352 | |
353 | |
354 | === added directory 'plugins/composite/src/backbuffertracking' |
355 | === added file 'plugins/composite/src/backbuffertracking/CMakeLists.txt' |
356 | --- plugins/composite/src/backbuffertracking/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
357 | +++ plugins/composite/src/backbuffertracking/CMakeLists.txt 2013-02-28 03:13:24 +0000 |
358 | @@ -0,0 +1,31 @@ |
359 | +INCLUDE_DIRECTORIES ( |
360 | + ${CMAKE_CURRENT_SOURCE_DIR}/../../include |
361 | + ${CMAKE_CURRENT_SOURCE_DIR}/include |
362 | + ${CMAKE_CURRENT_SOURCE_DIR}/src |
363 | + |
364 | + ${Boost_INCLUDE_DIRS} |
365 | +) |
366 | + |
367 | +LINK_DIRECTORIES (${COMPIZ_LIBRARY_DIRS}) |
368 | + |
369 | +SET( |
370 | + SRCS |
371 | + ${CMAKE_CURRENT_SOURCE_DIR}/src/backbuffertracking.cpp |
372 | +) |
373 | + |
374 | +ADD_LIBRARY( |
375 | + compiz_composite_backbuffertracking STATIC |
376 | + |
377 | + ${SRCS} |
378 | +) |
379 | + |
380 | +if (COMPIZ_BUILD_TESTING) |
381 | +ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests ) |
382 | +endif (COMPIZ_BUILD_TESTING) |
383 | + |
384 | +TARGET_LINK_LIBRARIES( |
385 | + compiz_composite_backbuffertracking |
386 | + |
387 | + compiz_size |
388 | + compiz_core |
389 | +) |
390 | |
391 | === added directory 'plugins/composite/src/backbuffertracking/include' |
392 | === added file 'plugins/composite/src/backbuffertracking/include/backbuffertracking.h' |
393 | --- plugins/composite/src/backbuffertracking/include/backbuffertracking.h 1970-01-01 00:00:00 +0000 |
394 | +++ plugins/composite/src/backbuffertracking/include/backbuffertracking.h 2013-02-28 03:13:24 +0000 |
395 | @@ -0,0 +1,125 @@ |
396 | +/* |
397 | + * Compiz, composite plugin, GLX_EXT_buffer_age logic |
398 | + * |
399 | + * Copyright (c) 2012 Sam Spilsbury |
400 | + * Authors: Sam Spilsbury <smspillaz@gmail.com> |
401 | + * |
402 | + * Permission is hereby granted, free of charge, to any person obtaining a |
403 | + * copy of this software and associated documentation files (the "Software"), |
404 | + * to deal in the Software without restriction, including without limitation |
405 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
406 | + * and/or sell copies of the Software, and to permit persons to whom the |
407 | + * Software is furnished to do so, subject to the following conditions: |
408 | + * |
409 | + * The above copyright notice and this permission notice shall be included in |
410 | + * all copies or substantial portions of the Software. |
411 | + * |
412 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
413 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
414 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
415 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
416 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
417 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
418 | + * DEALINGS IN THE SOFTWARE. |
419 | + */ |
420 | +#ifndef _COMPIZ_COMPOSITE_BACKBUFFERTRACKING_H |
421 | +#define _COMPIZ_COMPOSITE_BACKBUFFERTRACKING_H |
422 | + |
423 | +#include <memory> |
424 | +#include <boost/noncopyable.hpp> |
425 | +#include <boost/shared_ptr.hpp> |
426 | +#include <boost/weak_ptr.hpp> |
427 | +#include <boost/function.hpp> |
428 | + |
429 | +#include <composite/agedamagequery.h> |
430 | + |
431 | +class CompSize; |
432 | +class CompRegion; |
433 | + |
434 | +namespace compiz |
435 | +{ |
436 | +namespace composite |
437 | +{ |
438 | +namespace buffertracking |
439 | +{ |
440 | +class DamageAgeTracking |
441 | +{ |
442 | + public: |
443 | + |
444 | + virtual ~DamageAgeTracking () {}; |
445 | + virtual void dirtyAreaOnCurrentFrame (const CompRegion &) = 0; |
446 | + virtual void overdrawRegionOnPaintingFrame (const CompRegion &) = 0; |
447 | + virtual void subtractObscuredArea (const CompRegion &) = 0; |
448 | + virtual void incrementFrameAges () = 0; |
449 | +}; |
450 | + |
451 | +class AgeingDamageBufferObserver |
452 | +{ |
453 | + public: |
454 | + |
455 | + virtual ~AgeingDamageBufferObserver () {}; |
456 | + virtual void observe (DamageAgeTracking &damageAgeTracker) = 0; |
457 | + virtual void unobserve (DamageAgeTracking &damageAgeTracker) = 0; |
458 | +}; |
459 | + |
460 | +class AgeingDamageBuffers : |
461 | + public AgeingDamageBufferObserver, |
462 | + boost::noncopyable |
463 | +{ |
464 | + public: |
465 | + |
466 | + AgeingDamageBuffers (); |
467 | + |
468 | + void observe (DamageAgeTracking &damageAgeTracker); |
469 | + void unobserve (DamageAgeTracking &damageAgeTracker); |
470 | + void incrementAges (); |
471 | + void markAreaDirty (const CompRegion ®); |
472 | + void markAreaDirtyOnLastFrame (const CompRegion ®); |
473 | + void subtractObscuredArea (const CompRegion ®); |
474 | + |
475 | + private: |
476 | + |
477 | + class Private; |
478 | + std::auto_ptr <Private> priv; |
479 | +}; |
480 | + |
481 | +class FrameRoster : |
482 | + public DamageAgeTracking, |
483 | + public AgeDamageQuery, |
484 | + boost::noncopyable |
485 | +{ |
486 | + public: |
487 | + |
488 | + typedef AgeDamageQuery::AreaShouldBeMarkedDirty AreaShouldBeMarkedDirty; |
489 | + typedef boost::shared_ptr <FrameRoster> Ptr; |
490 | + |
491 | + FrameRoster (const CompSize &size, |
492 | + AgeingDamageBufferObserver &tracker, |
493 | + const AreaShouldBeMarkedDirty &shouldMarkDirty); |
494 | + |
495 | + ~FrameRoster (); |
496 | + |
497 | + void dirtyAreaOnCurrentFrame (const CompRegion &); |
498 | + void overdrawRegionOnPaintingFrame (const CompRegion &); |
499 | + void subtractObscuredArea (const CompRegion &); |
500 | + void incrementFrameAges (); |
501 | + CompRegion damageForFrameAge (unsigned int); |
502 | + const CompRegion & currentFrameDamage (); |
503 | + |
504 | + class Private; |
505 | + std::auto_ptr <Private> priv; |
506 | + |
507 | + static const unsigned int NUM_TRACKED_FRAMES = 10; |
508 | + |
509 | + static |
510 | + FrameRoster::Ptr create (const CompSize &size, |
511 | + |
512 | + const AreaShouldBeMarkedDirty &shouldMarkDirty); |
513 | + |
514 | + private: |
515 | + |
516 | +}; |
517 | +} // namespace buffertracking |
518 | +} // namespace composite |
519 | +} // namespace compiz |
520 | +#endif |
521 | |
522 | === added directory 'plugins/composite/src/backbuffertracking/src' |
523 | === added file 'plugins/composite/src/backbuffertracking/src/backbuffertracking.cpp' |
524 | --- plugins/composite/src/backbuffertracking/src/backbuffertracking.cpp 1970-01-01 00:00:00 +0000 |
525 | +++ plugins/composite/src/backbuffertracking/src/backbuffertracking.cpp 2013-02-28 03:13:24 +0000 |
526 | @@ -0,0 +1,214 @@ |
527 | +/* |
528 | + * Compiz, composite plugin, GLX_EXT_buffer_age logic |
529 | + * |
530 | + * Copyright (c) 2012 Sam Spilsbury |
531 | + * Authors: Sam Spilsbury <smspillaz@gmail.com> |
532 | + * |
533 | + * Permission is hereby granted, free of charge, to any person obtaining a |
534 | + * copy of this software and associated documentation files (the "Software"), |
535 | + * to deal in the Software without restriction, including without limitation |
536 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
537 | + * and/or sell copies of the Software, and to permit persons to whom the |
538 | + * Software is furnished to do so, subject to the following conditions: |
539 | + * |
540 | + * The above copyright notice and this permission notice shall be included in |
541 | + * all copies or substantial portions of the Software. |
542 | + * |
543 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
544 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
545 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
546 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
547 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
548 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
549 | + * DEALINGS IN THE SOFTWARE. |
550 | + */ |
551 | +#include <deque> |
552 | +#include <core/size.h> |
553 | +#include <core/region.h> |
554 | +#include "backbuffertracking.h" |
555 | +#include <cstdio> |
556 | + |
557 | +namespace bt = compiz::composite::buffertracking; |
558 | + |
559 | +class bt::FrameRoster::Private |
560 | +{ |
561 | + public: |
562 | + |
563 | + Private (const CompSize &size, |
564 | + bt::AgeingDamageBufferObserver &observer, |
565 | + const bt::FrameRoster::AreaShouldBeMarkedDirty &shouldBeMarkedDirty) : |
566 | + screenSize (size), |
567 | + observer (observer), |
568 | + shouldBeMarkedDirty (shouldBeMarkedDirty), |
569 | + oldFrames (1) |
570 | + { |
571 | + } |
572 | + |
573 | + CompSize screenSize; |
574 | + bt::AgeingDamageBufferObserver &observer; |
575 | + bt::FrameRoster::AreaShouldBeMarkedDirty shouldBeMarkedDirty; |
576 | + std::deque <CompRegion> oldFrames; |
577 | +}; |
578 | + |
579 | +bt::FrameRoster::FrameRoster (const CompSize &size, |
580 | + bt::AgeingDamageBufferObserver &tracker, |
581 | + const AreaShouldBeMarkedDirty &shouldBeMarkedDirty) : |
582 | + priv (new bt::FrameRoster::Private (size, |
583 | + tracker, |
584 | + shouldBeMarkedDirty)) |
585 | +{ |
586 | + priv->observer.observe (*this); |
587 | +} |
588 | + |
589 | +bt::FrameRoster::~FrameRoster () |
590 | +{ |
591 | + priv->observer.unobserve (*this); |
592 | +} |
593 | + |
594 | +CompRegion |
595 | +bt::FrameRoster::damageForFrameAge (unsigned int age) |
596 | +{ |
597 | + if (!age) |
598 | + return CompRegion (0, 0, |
599 | + priv->screenSize.width (), |
600 | + priv->screenSize.height ()); |
601 | + |
602 | + if (age >= priv->oldFrames.size ()) |
603 | + return CompRegion (0, 0, |
604 | + priv->screenSize.width (), |
605 | + priv->screenSize.height ()); |
606 | + |
607 | + CompRegion accumulatedDamage; |
608 | + |
609 | + while (age--) |
610 | + { |
611 | + unsigned int frameNum = (priv->oldFrames.size () - age) - 1; |
612 | + accumulatedDamage += priv->oldFrames[frameNum]; |
613 | + } |
614 | + |
615 | + return accumulatedDamage; |
616 | +} |
617 | + |
618 | +void |
619 | +bt::FrameRoster::dirtyAreaOnCurrentFrame (const CompRegion &r) |
620 | +{ |
621 | + if (priv->shouldBeMarkedDirty (r)) |
622 | + (*priv->oldFrames.rbegin ()) += r; |
623 | +} |
624 | + |
625 | +void |
626 | +bt::FrameRoster::subtractObscuredArea (const CompRegion &r) |
627 | +{ |
628 | + (*priv->oldFrames.rbegin ()) -= r; |
629 | +} |
630 | + |
631 | +void |
632 | +bt::FrameRoster::overdrawRegionOnPaintingFrame (const CompRegion &r) |
633 | +{ |
634 | + assert (priv->oldFrames.size () > 1); |
635 | + std::deque <CompRegion>::reverse_iterator it = priv->oldFrames.rbegin (); |
636 | + ++it; |
637 | + (*it) += r; |
638 | +} |
639 | + |
640 | +void |
641 | +bt::FrameRoster::incrementFrameAges () |
642 | +{ |
643 | + priv->oldFrames.push_back (CompRegion ()); |
644 | + |
645 | + /* Get rid of old frames */ |
646 | + if (priv->oldFrames.size () > NUM_TRACKED_FRAMES) |
647 | + priv->oldFrames.pop_front (); |
648 | +} |
649 | + |
650 | +const CompRegion & |
651 | +bt::FrameRoster::currentFrameDamage () |
652 | +{ |
653 | + return *priv->oldFrames.rbegin (); |
654 | +} |
655 | + |
656 | +class bt::AgeingDamageBuffers::Private |
657 | +{ |
658 | + public: |
659 | + |
660 | + std::vector <bt::DamageAgeTracking *> damageAgeTrackers; |
661 | +}; |
662 | + |
663 | +bt::AgeingDamageBuffers::AgeingDamageBuffers () : |
664 | + priv (new bt::AgeingDamageBuffers::Private ()) |
665 | +{ |
666 | +} |
667 | + |
668 | +void |
669 | +bt::AgeingDamageBuffers::observe (bt::DamageAgeTracking &damageAgeTracker) |
670 | +{ |
671 | + priv->damageAgeTrackers.push_back (&damageAgeTracker); |
672 | +} |
673 | + |
674 | +void |
675 | +bt::AgeingDamageBuffers::unobserve (bt::DamageAgeTracking &damageAgeTracker) |
676 | +{ |
677 | + std::vector <bt::DamageAgeTracking *>::iterator it = |
678 | + std::find (priv->damageAgeTrackers.begin (), |
679 | + priv->damageAgeTrackers.end (), |
680 | + &damageAgeTracker); |
681 | + |
682 | + if (it != priv->damageAgeTrackers.end ()) |
683 | + priv->damageAgeTrackers.erase (it); |
684 | +} |
685 | + |
686 | +void |
687 | +bt::AgeingDamageBuffers::incrementAges () |
688 | +{ |
689 | + for (std::vector <bt::DamageAgeTracking *>::iterator it = |
690 | + priv->damageAgeTrackers.begin (); |
691 | + it != priv->damageAgeTrackers.end (); |
692 | + ++it) |
693 | + { |
694 | + bt::DamageAgeTracking *tracker = *it; |
695 | + |
696 | + tracker->incrementFrameAges (); |
697 | + } |
698 | +} |
699 | + |
700 | +void |
701 | +bt::AgeingDamageBuffers::markAreaDirty (const CompRegion ®) |
702 | +{ |
703 | + for (std::vector <bt::DamageAgeTracking *>::iterator it = |
704 | + priv->damageAgeTrackers.begin (); |
705 | + it != priv->damageAgeTrackers.end (); |
706 | + ++it) |
707 | + { |
708 | + bt::DamageAgeTracking *tracker = *it; |
709 | + |
710 | + tracker->dirtyAreaOnCurrentFrame (reg); |
711 | + } |
712 | +} |
713 | + |
714 | +void |
715 | +bt::AgeingDamageBuffers::subtractObscuredArea (const CompRegion ®) |
716 | +{ |
717 | + for (std::vector <bt::DamageAgeTracking *>::iterator it = |
718 | + priv->damageAgeTrackers.begin (); |
719 | + it != priv->damageAgeTrackers.end (); |
720 | + ++it) |
721 | + { |
722 | + bt::DamageAgeTracking *tracker = *it; |
723 | + |
724 | + tracker->subtractObscuredArea (reg); |
725 | + } |
726 | +} |
727 | + |
728 | +void |
729 | +bt::AgeingDamageBuffers::markAreaDirtyOnLastFrame (const CompRegion ®) |
730 | +{ |
731 | + for (std::vector <bt::DamageAgeTracking *>::iterator it = |
732 | + priv->damageAgeTrackers.begin (); |
733 | + it != priv->damageAgeTrackers.end (); |
734 | + ++it) |
735 | + { |
736 | + bt::DamageAgeTracking *tracker = *it; |
737 | + |
738 | + tracker->overdrawRegionOnPaintingFrame (reg); |
739 | + } |
740 | +} |
741 | |
742 | === added directory 'plugins/composite/src/backbuffertracking/tests' |
743 | === added file 'plugins/composite/src/backbuffertracking/tests/CMakeLists.txt' |
744 | --- plugins/composite/src/backbuffertracking/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
745 | +++ plugins/composite/src/backbuffertracking/tests/CMakeLists.txt 2013-02-28 03:13:24 +0000 |
746 | @@ -0,0 +1,24 @@ |
747 | +find_library (GMOCK_LIBRARY gmock) |
748 | +find_library (GMOCK_MAIN_LIBRARY gmock_main) |
749 | + |
750 | +if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND) |
751 | + message ("Google Mock and Google Test not found - cannot build tests!") |
752 | + set (COMPIZ_BUILD_TESTING OFF) |
753 | +endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND) |
754 | + |
755 | +include_directories (${GTEST_INCLUDE_DIRS}) |
756 | + |
757 | +link_directories (${COMPIZ_LIBRARY_DIRS}) |
758 | + |
759 | +add_executable (compiz_test_composite_backbuffertracking |
760 | + ${CMAKE_CURRENT_SOURCE_DIR}/test-composite-backbuffertracking.cpp) |
761 | + |
762 | +target_link_libraries (compiz_test_composite_backbuffertracking |
763 | + compiz_composite_backbuffertracking |
764 | + ${GTEST_BOTH_LIBRARIES} |
765 | + ${GMOCK_LIBRARY} |
766 | + ${GMOCK_MAIN_LIBRARY} |
767 | + ${CMAKE_THREAD_LIBS_INIT} # Link in pthread. |
768 | + ) |
769 | + |
770 | +compiz_discover_tests (compiz_test_composite_backbuffertracking COVERAGE compiz_composite_backbuffertracking) |
771 | |
772 | === added file 'plugins/composite/src/backbuffertracking/tests/test-composite-backbuffertracking.cpp' |
773 | --- plugins/composite/src/backbuffertracking/tests/test-composite-backbuffertracking.cpp 1970-01-01 00:00:00 +0000 |
774 | +++ plugins/composite/src/backbuffertracking/tests/test-composite-backbuffertracking.cpp 2013-02-28 03:13:24 +0000 |
775 | @@ -0,0 +1,450 @@ |
776 | +/* |
777 | + * Compiz, composite plugin, GLX_EXT_buffer_age logic |
778 | + * |
779 | + * Copyright (c) 2012 Sam Spilsbury |
780 | + * Authors: Sam Spilsbury <smspillaz@gmail.com> |
781 | + * |
782 | + * Permission is hereby granted, free of charge, to any person obtaining a |
783 | + * copy of this software and associated documentation files (the "Software"), |
784 | + * to deal in the Software without restriction, including without limitation |
785 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
786 | + * and/or sell copies of the Software, and to permit persons to whom the |
787 | + * Software is furnished to do so, subject to the following conditions: |
788 | + * |
789 | + * The above copyright notice and this permission notice shall be included in |
790 | + * all copies or substantial portions of the Software. |
791 | + * |
792 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
793 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
794 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
795 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
796 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
797 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
798 | + * DEALINGS IN THE SOFTWARE. |
799 | + */ |
800 | +#include <boost/bind.hpp> |
801 | + |
802 | +#include <gtest/gtest.h> |
803 | +#include <gmock/gmock.h> |
804 | + |
805 | +#include <core/region.h> |
806 | +#include <core/size.h> |
807 | + |
808 | +#include "backbuffertracking.h" |
809 | + |
810 | +using ::testing::NiceMock; |
811 | +using ::testing::_; |
812 | +using ::testing::AtLeast; |
813 | + |
814 | +namespace bt = compiz::composite::buffertracking; |
815 | + |
816 | +namespace |
817 | +{ |
818 | +class MockAgeingDamageBufferObserver : |
819 | + public bt::AgeingDamageBufferObserver |
820 | +{ |
821 | + public: |
822 | + |
823 | + MOCK_METHOD1 (observe, void (bt::DamageAgeTracking &)); |
824 | + MOCK_METHOD1 (unobserve, void (bt::DamageAgeTracking &)); |
825 | +}; |
826 | + |
827 | +bool alwaysTrackDamage (const CompRegion &) |
828 | +{ |
829 | + return true; |
830 | +} |
831 | + |
832 | + |
833 | +class BackbufferTracking : |
834 | + public ::testing::Test |
835 | +{ |
836 | + public: |
837 | + |
838 | + BackbufferTracking () : |
839 | + screen (1000, 1000), |
840 | + roster () |
841 | + { |
842 | + } |
843 | + |
844 | + virtual void SetUp () |
845 | + { |
846 | + SetupRoster (); |
847 | + } |
848 | + |
849 | + virtual void SetupRoster () |
850 | + { |
851 | + roster.reset (new bt::FrameRoster (screen, |
852 | + niceTracker, |
853 | + boost::bind (alwaysTrackDamage, |
854 | + _1))); |
855 | + } |
856 | + |
857 | + protected: |
858 | + |
859 | + CompSize screen; |
860 | + NiceMock <MockAgeingDamageBufferObserver> niceTracker; |
861 | + bt::FrameRoster::Ptr roster; |
862 | +}; |
863 | + |
864 | +class BackbufferTrackingCallbacks : |
865 | + public BackbufferTracking |
866 | +{ |
867 | + public: |
868 | + |
869 | + BackbufferTrackingCallbacks () : |
870 | + shouldDamage (false) |
871 | + { |
872 | + } |
873 | + |
874 | + protected: |
875 | + |
876 | + void allowDamage (bool allow) |
877 | + { |
878 | + shouldDamage = allow; |
879 | + } |
880 | + |
881 | + private: |
882 | + |
883 | + virtual void SetupRoster () |
884 | + { |
885 | + roster.reset (new bt::FrameRoster (screen, |
886 | + niceTracker, |
887 | + boost::bind (&BackbufferTrackingCallbacks::shouldDamageCallback, |
888 | + this, _1))); |
889 | + } |
890 | + |
891 | + bool shouldDamageCallback (const CompRegion &) |
892 | + { |
893 | + return shouldDamage; |
894 | + } |
895 | + |
896 | + bool shouldDamage; |
897 | +}; |
898 | +} |
899 | + |
900 | +std::ostream & |
901 | +operator<< (std::ostream &os, const CompRegion ®) |
902 | +{ |
903 | + os << "Region with Bounding Rectangle : " << |
904 | + reg.boundingRect ().x () << " " << |
905 | + reg.boundingRect ().y () << " " << |
906 | + reg.boundingRect ().width () << " " << |
907 | + reg.boundingRect ().height () << std::endl; |
908 | + CompRect::vector rects (reg.rects ()); |
909 | + for (CompRect::vector::iterator it = rects.begin (); |
910 | + it != rects.end (); |
911 | + it++) |
912 | + os << " - subrectangle: " << |
913 | + (*it).x () << " " << |
914 | + (*it).y () << " " << |
915 | + (*it).width () << " " << |
916 | + (*it).height () << " " << std::endl; |
917 | + |
918 | + return os; |
919 | +} |
920 | + |
921 | +TEST (BackbufferTrackingConstruction, CreateAddsToObserverList) |
922 | +{ |
923 | + MockAgeingDamageBufferObserver mockAgeingDamageBufferObserver; |
924 | + |
925 | + /* We can't verify the argument here, |
926 | + * but we can verify the function call */ |
927 | + EXPECT_CALL (mockAgeingDamageBufferObserver, observe (_)); |
928 | + EXPECT_CALL (mockAgeingDamageBufferObserver, unobserve (_)).Times (AtLeast (0)); |
929 | + bt::FrameRoster roster (CompSize (), |
930 | + mockAgeingDamageBufferObserver, |
931 | + boost::bind (alwaysTrackDamage, _1)); |
932 | +} |
933 | + |
934 | +TEST (BackbufferTrackingConstruction, DestroyRemovesFromObserverList) |
935 | +{ |
936 | + MockAgeingDamageBufferObserver mockAgeingDamageBufferObserver; |
937 | + |
938 | + /* We can't verify the argument here, |
939 | + * but we can verify the function call */ |
940 | + EXPECT_CALL (mockAgeingDamageBufferObserver, observe (_)).Times (AtLeast (0)); |
941 | + EXPECT_CALL (mockAgeingDamageBufferObserver, unobserve (_)); |
942 | + bt::FrameRoster roster (CompSize (), |
943 | + mockAgeingDamageBufferObserver, |
944 | + boost::bind (alwaysTrackDamage, _1)); |
945 | +} |
946 | + |
947 | +TEST_F (BackbufferTrackingCallbacks, TrackIntoCurrentIfCallbackTrue) |
948 | +{ |
949 | + allowDamage (true); |
950 | + CompRegion damage (100, 100, 100, 100); |
951 | + roster->dirtyAreaOnCurrentFrame (damage); |
952 | + EXPECT_EQ (damage, roster->currentFrameDamage ()); |
953 | +} |
954 | + |
955 | +TEST_F (BackbufferTrackingCallbacks, NoTrackIntoCurrentIfCallbackFalse) |
956 | +{ |
957 | + allowDamage (false); |
958 | + CompRegion damage (100, 100, 100, 100); |
959 | + roster->dirtyAreaOnCurrentFrame (damage); |
960 | + EXPECT_EQ (emptyRegion, roster->currentFrameDamage ()); |
961 | +} |
962 | + |
963 | +TEST_F (BackbufferTracking, DirtyAreaSubtraction) |
964 | +{ |
965 | + CompRegion dirty (100, 100, 100, 100); |
966 | + CompRegion obscured (150, 150, 50, 50); |
967 | + roster->dirtyAreaOnCurrentFrame (dirty); |
968 | + roster->subtractObscuredArea (obscured); |
969 | + EXPECT_EQ (dirty - obscured, roster->currentFrameDamage ()); |
970 | +} |
971 | + |
972 | +TEST_F (BackbufferTracking, DirtyAreaForAgeZeroAll) |
973 | +{ |
974 | + EXPECT_EQ (CompRegion (0, 0, screen.width (), screen.height ()), |
975 | + roster->damageForFrameAge (0)); |
976 | +} |
977 | + |
978 | +TEST_F (BackbufferTracking, DirtyAreaAllForOlderThanTrackedAge) |
979 | +{ |
980 | + EXPECT_EQ (CompRegion (0, 0, screen.width (), screen.height ()), |
981 | + roster->damageForFrameAge (1)); |
982 | +} |
983 | + |
984 | +TEST_F (BackbufferTracking, NoDirtyAreaForLastFrame) |
985 | +{ |
986 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
987 | + roster->dirtyAreaOnCurrentFrame (all); |
988 | + roster->incrementFrameAges (); |
989 | + EXPECT_EQ (emptyRegion, roster->damageForFrameAge (1)); |
990 | +} |
991 | + |
992 | +TEST_F (BackbufferTracking, DirtyAreaIfMoreSinceLastFrame) |
993 | +{ |
994 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
995 | + roster->dirtyAreaOnCurrentFrame (all); |
996 | + roster->incrementFrameAges (); |
997 | + roster->dirtyAreaOnCurrentFrame(all); |
998 | + EXPECT_EQ (all, roster->damageForFrameAge (1)); |
999 | +} |
1000 | + |
1001 | +TEST_F (BackbufferTracking, AddOverdrawRegionForLastFrame) |
1002 | +{ |
1003 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
1004 | + roster->dirtyAreaOnCurrentFrame (all); |
1005 | + roster->incrementFrameAges (); |
1006 | + roster->incrementFrameAges (); |
1007 | + roster->overdrawRegionOnPaintingFrame (all); |
1008 | + EXPECT_EQ (all, roster->damageForFrameAge (2)); |
1009 | +} |
1010 | + |
1011 | +TEST_F (BackbufferTracking, TwoFramesAgo) |
1012 | +{ |
1013 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
1014 | + CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2); |
1015 | + |
1016 | + roster->dirtyAreaOnCurrentFrame (all); |
1017 | + roster->incrementFrameAges (); |
1018 | + roster->dirtyAreaOnCurrentFrame (topleft); |
1019 | + roster->incrementFrameAges (); |
1020 | + EXPECT_EQ (topleft, roster->damageForFrameAge (2)); |
1021 | +} |
1022 | + |
1023 | +TEST_F (BackbufferTracking, TwoFramesAgoCulmulative) |
1024 | +{ |
1025 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
1026 | + CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2); |
1027 | + CompRegion topright (0, screen.width () / 2, |
1028 | + screen.width () / 2, |
1029 | + screen.height () / 2); |
1030 | + |
1031 | + roster->dirtyAreaOnCurrentFrame (all); |
1032 | + roster->incrementFrameAges (); |
1033 | + roster->dirtyAreaOnCurrentFrame (topleft); |
1034 | + roster->dirtyAreaOnCurrentFrame (topright); |
1035 | + roster->incrementFrameAges (); |
1036 | + EXPECT_EQ (topleft + topright, roster->damageForFrameAge (2)); |
1037 | +} |
1038 | + |
1039 | +TEST_F (BackbufferTracking, ThreeFramesAgo) |
1040 | +{ |
1041 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
1042 | + CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2); |
1043 | + CompRegion bottomright (screen.width () / 2, |
1044 | + screen.height () / 2, |
1045 | + screen.width () / 2, |
1046 | + screen.height () / 2); |
1047 | + |
1048 | + roster->dirtyAreaOnCurrentFrame (all); |
1049 | + roster->incrementFrameAges (); |
1050 | + roster->dirtyAreaOnCurrentFrame (topleft); |
1051 | + roster->incrementFrameAges (); |
1052 | + roster->dirtyAreaOnCurrentFrame (bottomright); |
1053 | + roster->incrementFrameAges (); |
1054 | + |
1055 | + EXPECT_EQ (topleft + bottomright, roster->damageForFrameAge (3)); |
1056 | +} |
1057 | + |
1058 | +/* These are more or less functional tests from this point forward |
1059 | + * just checking a number of different situations */ |
1060 | + |
1061 | +TEST_F (BackbufferTracking, ThreeFramesAgoWithFourFrames) |
1062 | +{ |
1063 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
1064 | + CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2); |
1065 | + CompRegion bottomright (screen.width () / 2, |
1066 | + screen.height () / 2, |
1067 | + screen.width () / 2, |
1068 | + screen.height () / 2); |
1069 | + CompRegion topright (screen.width () / 2, |
1070 | + 0, |
1071 | + screen.width () / 2, |
1072 | + screen.height () / 2); |
1073 | + |
1074 | + roster->dirtyAreaOnCurrentFrame (all); |
1075 | + roster->incrementFrameAges (); |
1076 | + roster->dirtyAreaOnCurrentFrame (topleft); |
1077 | + roster->incrementFrameAges (); |
1078 | + roster->dirtyAreaOnCurrentFrame (bottomright); |
1079 | + roster->incrementFrameAges (); |
1080 | + roster->dirtyAreaOnCurrentFrame (topright); |
1081 | + roster->incrementFrameAges (); |
1082 | + |
1083 | + EXPECT_EQ (topright + bottomright, roster->damageForFrameAge (3)); |
1084 | +} |
1085 | + |
1086 | +TEST_F (BackbufferTracking, ThreeFramesAgoWithFourFramesAndOverlap) |
1087 | +{ |
1088 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
1089 | + CompRegion topleft (0, 0, screen.width () / 2, screen.height () / 2); |
1090 | + CompRegion bottomright (screen.width () / 2, |
1091 | + screen.height () / 2, |
1092 | + screen.width () / 2, |
1093 | + screen.height () / 2); |
1094 | + CompRegion topright (screen.width () / 2, |
1095 | + 0, |
1096 | + screen.width () / 2, |
1097 | + screen.height () / 2); |
1098 | + |
1099 | + roster->dirtyAreaOnCurrentFrame (all); |
1100 | + roster->incrementFrameAges (); |
1101 | + roster->dirtyAreaOnCurrentFrame (topleft); |
1102 | + roster->incrementFrameAges (); |
1103 | + roster->dirtyAreaOnCurrentFrame (bottomright); |
1104 | + roster->incrementFrameAges (); |
1105 | + roster->dirtyAreaOnCurrentFrame (bottomright); |
1106 | + roster->incrementFrameAges (); |
1107 | + |
1108 | + EXPECT_EQ (bottomright, roster->damageForFrameAge (3)); |
1109 | +} |
1110 | + |
1111 | +TEST_F (BackbufferTracking, AllDamageForExceedingMaxTrackedFrames) |
1112 | +{ |
1113 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
1114 | + CompRegion damage (0, 0, 1, 1); |
1115 | + |
1116 | + roster->dirtyAreaOnCurrentFrame (all); |
1117 | + |
1118 | + for (unsigned int i = 0; i < bt::FrameRoster::NUM_TRACKED_FRAMES - 1; ++i) |
1119 | + { |
1120 | + roster->incrementFrameAges (); |
1121 | + roster->dirtyAreaOnCurrentFrame (damage); |
1122 | + } |
1123 | + |
1124 | + EXPECT_EQ (all, roster->damageForFrameAge (bt::FrameRoster::NUM_TRACKED_FRAMES + 1)); |
1125 | +} |
1126 | + |
1127 | +TEST_F (BackbufferTracking, DamageForMaxTrackedFrame) |
1128 | +{ |
1129 | + CompRegion all (0, 0, screen.width (), screen.height ()); |
1130 | + CompRegion damage (0, 0, 1, 1); |
1131 | + |
1132 | + roster->dirtyAreaOnCurrentFrame (all); |
1133 | + |
1134 | + for (unsigned int i = 0; i < bt::FrameRoster::NUM_TRACKED_FRAMES + 1; ++i) |
1135 | + { |
1136 | + roster->incrementFrameAges (); |
1137 | + roster->dirtyAreaOnCurrentFrame (damage); |
1138 | + } |
1139 | + |
1140 | + EXPECT_EQ (all, roster->damageForFrameAge (bt::FrameRoster::NUM_TRACKED_FRAMES)); |
1141 | +} |
1142 | + |
1143 | +class MockDamageAgeTracking : |
1144 | + public bt::DamageAgeTracking |
1145 | +{ |
1146 | + public: |
1147 | + |
1148 | + typedef boost::shared_ptr <MockDamageAgeTracking> Ptr; |
1149 | + |
1150 | + MOCK_METHOD0 (incrementFrameAges, void ()); |
1151 | + MOCK_METHOD1 (dirtyAreaOnCurrentFrame, void (const CompRegion &)); |
1152 | + MOCK_METHOD1 (subtractObscuredArea, void (const CompRegion &)); |
1153 | + MOCK_METHOD1 (overdrawRegionOnPaintingFrame, void (const CompRegion &)); |
1154 | +}; |
1155 | + |
1156 | +class AgeingDamageBuffers : |
1157 | + public ::testing::Test |
1158 | +{ |
1159 | + public: |
1160 | + |
1161 | + AgeingDamageBuffers () |
1162 | + { |
1163 | + ageing.observe (mockDamageAgeTracker); |
1164 | + } |
1165 | + |
1166 | + MockDamageAgeTracking mockDamageAgeTracker; |
1167 | + bt::AgeingDamageBuffers ageing; |
1168 | +}; |
1169 | + |
1170 | +TEST_F (AgeingDamageBuffers, IncrementAgesOnValidRosters) |
1171 | +{ |
1172 | + EXPECT_CALL (mockDamageAgeTracker, incrementFrameAges ()); |
1173 | + ageing.incrementAges (); |
1174 | +} |
1175 | + |
1176 | +TEST_F (AgeingDamageBuffers, DirtyAreaOnValidRosters) |
1177 | +{ |
1178 | + CompRegion dirtyArea (100, 100, 100, 100); |
1179 | + EXPECT_CALL (mockDamageAgeTracker, dirtyAreaOnCurrentFrame (dirtyArea)); |
1180 | + ageing.markAreaDirty (dirtyArea); |
1181 | +} |
1182 | + |
1183 | +TEST_F (AgeingDamageBuffers, SubtractObscuredAreaOnValidRosters) |
1184 | +{ |
1185 | + CompRegion obscuredArea (100, 100, 100, 100); |
1186 | + EXPECT_CALL (mockDamageAgeTracker, subtractObscuredArea (obscuredArea)); |
1187 | + ageing.subtractObscuredArea (obscuredArea); |
1188 | +} |
1189 | + |
1190 | +TEST_F (AgeingDamageBuffers, AddOverdrawAreaOnValidRosters) |
1191 | +{ |
1192 | + CompRegion overdrawArea (100, 100, 100, 100); |
1193 | + EXPECT_CALL (mockDamageAgeTracker, overdrawRegionOnPaintingFrame (overdrawArea)); |
1194 | + ageing.markAreaDirtyOnLastFrame (overdrawArea); |
1195 | +} |
1196 | + |
1197 | +TEST_F (AgeingDamageBuffers, IncrementAgesOnInvalidRosters) |
1198 | +{ |
1199 | + EXPECT_CALL (mockDamageAgeTracker, incrementFrameAges ()).Times (0); |
1200 | + ageing.unobserve (mockDamageAgeTracker); |
1201 | + ageing.incrementAges (); |
1202 | +} |
1203 | + |
1204 | +TEST_F (AgeingDamageBuffers, DirtyAreaOnInvalidRosters) |
1205 | +{ |
1206 | + EXPECT_CALL (mockDamageAgeTracker, dirtyAreaOnCurrentFrame (_)).Times (0); |
1207 | + ageing.unobserve (mockDamageAgeTracker); |
1208 | + ageing.markAreaDirty (emptyRegion); |
1209 | +} |
1210 | + |
1211 | +TEST_F (AgeingDamageBuffers, SubtractObscuredAreaOnInvalidRosters) |
1212 | +{ |
1213 | + EXPECT_CALL (mockDamageAgeTracker, subtractObscuredArea (_)).Times (0); |
1214 | + ageing.unobserve (mockDamageAgeTracker); |
1215 | + ageing.subtractObscuredArea (emptyRegion); |
1216 | +} |
1217 | + |
1218 | +TEST_F (AgeingDamageBuffers, AddOverdrawAreaOnInvalidRosters) |
1219 | +{ |
1220 | + EXPECT_CALL (mockDamageAgeTracker, overdrawRegionOnPaintingFrame (_)).Times (0); |
1221 | + ageing.unobserve (mockDamageAgeTracker); |
1222 | + ageing.markAreaDirtyOnLastFrame (emptyRegion); |
1223 | +} |
1224 | + |
1225 | + |
1226 | |
1227 | === modified file 'plugins/composite/src/privates.h' |
1228 | --- plugins/composite/src/privates.h 2012-09-20 09:35:40 +0000 |
1229 | +++ plugins/composite/src/privates.h 2013-02-28 03:13:24 +0000 |
1230 | @@ -36,12 +36,20 @@ |
1231 | #include <map> |
1232 | |
1233 | #include "pixmapbinding.h" |
1234 | +#include "backbuffertracking.h" |
1235 | #include "composite_options.h" |
1236 | |
1237 | extern CompPlugin::VTable *compositeVTable; |
1238 | |
1239 | extern CompWindow *lastDamagedWindow; |
1240 | |
1241 | +enum DamageTracking |
1242 | +{ |
1243 | + DamageForCurrentFrame = 0, |
1244 | + DamageForLastFrame = 1, |
1245 | + DamageFinalPaintRegion |
1246 | +}; |
1247 | + |
1248 | class PrivateCompositeScreen : |
1249 | ScreenInterface, |
1250 | public CompositeOptions |
1251 | @@ -66,6 +74,8 @@ |
1252 | |
1253 | void scheduleRepaint (); |
1254 | |
1255 | + const CompRegion * damageTrackedBuffer (const CompRegion &); |
1256 | + |
1257 | public: |
1258 | |
1259 | CompositeScreen *cScreen; |
1260 | @@ -80,10 +90,12 @@ |
1261 | bool randrExtension; |
1262 | int randrEvent, randrError; |
1263 | |
1264 | - CompRegion damage; |
1265 | + CompRegion lastFrameDamage; |
1266 | unsigned long damageMask; |
1267 | |
1268 | - CompRegion tmpRegion; |
1269 | + CompRegion tmpRegion; |
1270 | + |
1271 | + DamageTracking currentlyTrackingDamage; |
1272 | |
1273 | Window overlay; |
1274 | Window output; |
1275 | @@ -99,6 +111,7 @@ |
1276 | int redrawTime; |
1277 | int optimalRedrawTime; |
1278 | bool scheduled, painting, reschedule; |
1279 | + bool damageRequiresRepaintReschedule; |
1280 | |
1281 | bool slowAnimations; |
1282 | |
1283 | @@ -115,6 +128,9 @@ |
1284 | |
1285 | /* Map Damage handle to its bounding box */ |
1286 | std::map<Damage, XRectangle> damages; |
1287 | + |
1288 | + compiz::composite::buffertracking::AgeingDamageBuffers ageingBuffers; |
1289 | + compiz::composite::buffertracking::FrameRoster roster; |
1290 | }; |
1291 | |
1292 | class PrivateCompositeWindow : |
1293 | |
1294 | === modified file 'plugins/composite/src/screen.cpp' |
1295 | --- plugins/composite/src/screen.cpp 2013-01-28 19:22:29 +0000 |
1296 | +++ plugins/composite/src/screen.cpp 2013-02-28 03:13:24 +0000 |
1297 | @@ -47,6 +47,8 @@ |
1298 | |
1299 | template class WrapableInterface<CompositeScreen, CompositeScreenInterface>; |
1300 | |
1301 | +namespace bt = compiz::composite::buffertracking; |
1302 | + |
1303 | static const int FALLBACK_REFRESH_RATE = 60; /* if all else fails */ |
1304 | |
1305 | CompWindow *lastDamagedWindow = 0; |
1306 | @@ -276,6 +278,14 @@ |
1307 | delete priv; |
1308 | } |
1309 | |
1310 | +namespace |
1311 | +{ |
1312 | +bool alwaysMarkDirty () |
1313 | +{ |
1314 | + return true; |
1315 | +} |
1316 | +} |
1317 | + |
1318 | |
1319 | PrivateCompositeScreen::PrivateCompositeScreen (CompositeScreen *cs) : |
1320 | cScreen (cs), |
1321 | @@ -294,6 +304,7 @@ |
1322 | randrEvent (0), |
1323 | randrError (0), |
1324 | damageMask (COMPOSITE_SCREEN_DAMAGE_ALL_MASK), |
1325 | + currentlyTrackingDamage (DamageForCurrentFrame), |
1326 | overlay (None), |
1327 | output (None), |
1328 | exposeRects (), |
1329 | @@ -305,12 +316,16 @@ |
1330 | scheduled (false), |
1331 | painting (false), |
1332 | reschedule (false), |
1333 | + damageRequiresRepaintReschedule (true), |
1334 | slowAnimations (false), |
1335 | pHnd (NULL), |
1336 | FPSLimiterMode (CompositeFPSLimiterModeDefault), |
1337 | withDestroyedWindows (), |
1338 | cmSnAtom (0), |
1339 | - newCmSnOwner (None) |
1340 | + newCmSnOwner (None), |
1341 | + roster (*screen, |
1342 | + ageingBuffers, |
1343 | + boost::bind (alwaysMarkDirty)) |
1344 | { |
1345 | gettimeofday (&lastRedraw, 0); |
1346 | // wrap outputChangeNotify |
1347 | @@ -491,15 +506,47 @@ |
1348 | return false; |
1349 | } |
1350 | |
1351 | +const CompRegion * |
1352 | +PrivateCompositeScreen::damageTrackedBuffer (const CompRegion ®ion) |
1353 | +{ |
1354 | + const CompRegion *currentDamage = NULL; |
1355 | + |
1356 | + switch (currentlyTrackingDamage) |
1357 | + { |
1358 | + case DamageForCurrentFrame: |
1359 | + currentDamage = &(roster.currentFrameDamage ()); |
1360 | + ageingBuffers.markAreaDirty (region); |
1361 | + break; |
1362 | + case DamageForLastFrame: |
1363 | + currentDamage = &(lastFrameDamage); |
1364 | + lastFrameDamage += region; |
1365 | + break; |
1366 | + case DamageFinalPaintRegion: |
1367 | + currentDamage = &(tmpRegion); |
1368 | + tmpRegion += region; |
1369 | + break; |
1370 | + default: |
1371 | + compLogMessage ("composite", CompLogLevelFatal, "unreachable section"); |
1372 | + assert (false); |
1373 | + abort (); |
1374 | + } |
1375 | + |
1376 | + assert (currentDamage); |
1377 | + return currentDamage; |
1378 | +} |
1379 | + |
1380 | void |
1381 | CompositeScreen::damageScreen () |
1382 | { |
1383 | + /* Don't tell plugins about damage events when the damage buffer is already full */ |
1384 | bool alreadyDamaged = priv->damageMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK; |
1385 | + alreadyDamaged |= ((currentDamage () & screen->region ()) == screen->region ()); |
1386 | |
1387 | priv->damageMask |= COMPOSITE_SCREEN_DAMAGE_ALL_MASK; |
1388 | priv->damageMask &= ~COMPOSITE_SCREEN_DAMAGE_REGION_MASK; |
1389 | |
1390 | - priv->scheduleRepaint (); |
1391 | + if (priv->damageRequiresRepaintReschedule) |
1392 | + priv->scheduleRepaint (); |
1393 | |
1394 | /* |
1395 | * Call through damageRegion since plugins listening for incoming damage |
1396 | @@ -507,7 +554,15 @@ |
1397 | */ |
1398 | |
1399 | if (!alreadyDamaged) |
1400 | + { |
1401 | damageRegion (CompRegion (0, 0, screen->width (), screen->height ())); |
1402 | + |
1403 | + /* Set the damage region as the fullscreen region, because if |
1404 | + * windows are unredirected we need to correctly subtract from |
1405 | + * it later |
1406 | + */ |
1407 | + priv->damageTrackedBuffer (screen->region ()); |
1408 | + } |
1409 | } |
1410 | |
1411 | void |
1412 | @@ -518,7 +573,12 @@ |
1413 | if (priv->damageMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) |
1414 | return; |
1415 | |
1416 | - priv->damage += region; |
1417 | + /* Don't cause repaints to be scheduled for empty damage |
1418 | + * regions */ |
1419 | + if (region.isEmpty ()) |
1420 | + return; |
1421 | + |
1422 | + const CompRegion *currentDamage = priv->damageTrackedBuffer (region); |
1423 | priv->damageMask |= COMPOSITE_SCREEN_DAMAGE_REGION_MASK; |
1424 | |
1425 | /* if the number of damage rectangles grows two much between repaints, |
1426 | @@ -526,16 +586,61 @@ |
1427 | in order to make sure we're not having too much overhead, damage |
1428 | the whole screen if we have a lot of damage rects */ |
1429 | |
1430 | - if (priv->damage.numRects () > 100) |
1431 | - damageScreen (); |
1432 | - priv->scheduleRepaint (); |
1433 | + if (currentDamage->numRects () > 100) |
1434 | + damageScreen (); |
1435 | + |
1436 | + if (priv->damageRequiresRepaintReschedule) |
1437 | + priv->scheduleRepaint (); |
1438 | +} |
1439 | + |
1440 | +void |
1441 | +CompositeScreen::damageCutoff () |
1442 | +{ |
1443 | + WRAPABLE_HND_FUNCTN (damageCutoff); |
1444 | } |
1445 | |
1446 | void |
1447 | CompositeScreen::damagePending () |
1448 | { |
1449 | priv->damageMask |= COMPOSITE_SCREEN_DAMAGE_PENDING_MASK; |
1450 | - priv->scheduleRepaint (); |
1451 | + |
1452 | + if (priv->damageRequiresRepaintReschedule) |
1453 | + priv->scheduleRepaint (); |
1454 | +} |
1455 | + |
1456 | +void |
1457 | +CompositeScreen::applyDamageForFrameAge (unsigned int age) |
1458 | +{ |
1459 | + /* Track into "last frame damage" */ |
1460 | + priv->currentlyTrackingDamage = DamageForLastFrame; |
1461 | + damageRegion (priv->roster.damageForFrameAge (age)); |
1462 | + priv->currentlyTrackingDamage = DamageForCurrentFrame; |
1463 | +} |
1464 | + |
1465 | +unsigned int |
1466 | +CompositeScreen::getFrameAge () |
1467 | +{ |
1468 | + if (priv->pHnd) |
1469 | + return priv->pHnd->getFrameAge (); |
1470 | + |
1471 | + return 1; |
1472 | +} |
1473 | + |
1474 | +void |
1475 | +CompositeScreen::addOverdrawDamageRegion (const CompRegion &r) |
1476 | +{ |
1477 | + priv->ageingBuffers.markAreaDirtyOnLastFrame (r); |
1478 | +} |
1479 | + |
1480 | +typedef CompositeScreen::AreaShouldBeMarkedDirty ShouldMarkDirty; |
1481 | + |
1482 | +CompositeScreen::DamageQuery::Ptr |
1483 | +CompositeScreen::getDamageQuery (const ShouldMarkDirty &callback) |
1484 | +{ |
1485 | + /* No initial damage */ |
1486 | + return bt::FrameRoster::Ptr (new bt::FrameRoster (CompSize (), |
1487 | + priv->ageingBuffers, |
1488 | + callback)); |
1489 | } |
1490 | |
1491 | unsigned int |
1492 | @@ -780,6 +885,10 @@ |
1493 | { |
1494 | int timeDiff; |
1495 | |
1496 | + /* Damage that accumulates here does not require a repaint reschedule |
1497 | + * as it will end up on this frame */ |
1498 | + priv->damageRequiresRepaintReschedule = false; |
1499 | + |
1500 | if (priv->pHnd) |
1501 | priv->pHnd->prepareDrawing (); |
1502 | |
1503 | @@ -814,7 +923,7 @@ |
1504 | continue; |
1505 | |
1506 | if (!CompositeWindow::get (w)->redirected ()) |
1507 | - priv->damage -= w->region (); |
1508 | + priv->ageingBuffers.subtractObscuredArea (w->region ()); |
1509 | |
1510 | break; |
1511 | } |
1512 | @@ -826,7 +935,13 @@ |
1513 | } |
1514 | } |
1515 | |
1516 | - priv->tmpRegion = priv->damage & screen->region (); |
1517 | + /* All further damage is for the next frame now, as |
1518 | + * priv->tmpRegion will be assigned. Notify plugins that do |
1519 | + * damage tracking of this */ |
1520 | + damageCutoff (); |
1521 | + |
1522 | + priv->tmpRegion = (priv->roster.currentFrameDamage () + priv->lastFrameDamage) & screen->region (); |
1523 | + priv->currentlyTrackingDamage = DamageFinalPaintRegion; |
1524 | |
1525 | if (priv->damageMask & COMPOSITE_SCREEN_DAMAGE_REGION_MASK) |
1526 | { |
1527 | @@ -848,7 +963,9 @@ |
1528 | XSync (dpy, False); |
1529 | priv->damages.clear (); |
1530 | |
1531 | - priv->damage = CompRegion (); |
1532 | + /* Any more damage requires a repaint reschedule */ |
1533 | + priv->damageRequiresRepaintReschedule = true; |
1534 | + priv->lastFrameDamage = CompRegion (); |
1535 | |
1536 | int mask = priv->damageMask; |
1537 | priv->damageMask = 0; |
1538 | @@ -864,9 +981,13 @@ |
1539 | else |
1540 | outputs.push_back (&screen->fullscreenOutput ()); |
1541 | |
1542 | + priv->currentlyTrackingDamage = DamageForCurrentFrame; |
1543 | + |
1544 | + /* All new damage goes on the next frame */ |
1545 | + priv->ageingBuffers.incrementAges (); |
1546 | + |
1547 | paint (outputs, mask); |
1548 | |
1549 | - |
1550 | donePaint (); |
1551 | |
1552 | priv->outputShapeChanged = false; |
1553 | @@ -1023,8 +1144,12 @@ |
1554 | CompositeScreenInterface::damageRegion (const CompRegion &r) |
1555 | WRAPABLE_DEF (damageRegion, r); |
1556 | |
1557 | +void |
1558 | +CompositeScreenInterface::damageCutoff () |
1559 | + WRAPABLE_DEF (damageCutoff); |
1560 | + |
1561 | const CompRegion & |
1562 | CompositeScreen::currentDamage () const |
1563 | { |
1564 | - return priv->damage; |
1565 | + return priv->roster.currentFrameDamage (); |
1566 | } |
1567 | |
1568 | === modified file 'plugins/composite/src/window.cpp' |
1569 | --- plugins/composite/src/window.cpp 2013-01-03 16:05:26 +0000 |
1570 | +++ plugins/composite/src/window.cpp 2013-02-28 03:13:24 +0000 |
1571 | @@ -181,7 +181,11 @@ |
1572 | bool |
1573 | PrivateCompositeWindow::getAttributes (XWindowAttributes &attr) |
1574 | { |
1575 | - return window->queryFrameAttributes (attr); |
1576 | + if (XGetWindowAttributes (screen->dpy (), |
1577 | + ROOTPARENT (window), &attr)) |
1578 | + return true; |
1579 | + |
1580 | + return false; |
1581 | } |
1582 | |
1583 | bool |
1584 | |
1585 | === modified file 'plugins/kdecompat/src/kdecompat.cpp' |
1586 | --- plugins/kdecompat/src/kdecompat.cpp 2012-08-14 06:33:22 +0000 |
1587 | +++ plugins/kdecompat/src/kdecompat.cpp 2013-02-28 03:13:24 +0000 |
1588 | @@ -196,7 +196,7 @@ |
1589 | if ((!(ks->optionGetPlasmaThumbnails () || mPreviews.empty ()) && |
1590 | !(mSlideData || mSlideData->remaining)) || |
1591 | !window->mapNum () || |
1592 | - (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)) |
1593 | + (mask & PAINT_WINDOW_NO_DRAW_MASKS)) |
1594 | { |
1595 | status = gWindow->glPaint (attrib, transform, region, mask); |
1596 | return status; |
1597 | @@ -210,7 +210,7 @@ |
1598 | CompRect clipBox (window->x (), window->y (), |
1599 | window->width (), window->height ()); |
1600 | |
1601 | - if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) |
1602 | + if (mask & PAINT_WINDOW_NO_DRAW_MASKS) |
1603 | return false; |
1604 | |
1605 | remainder = (float) data->remaining / data->duration; |
1606 | |
1607 | === modified file 'plugins/move/src/move.cpp' |
1608 | --- plugins/move/src/move.cpp 2013-01-03 16:05:26 +0000 |
1609 | +++ plugins/move/src/move.cpp 2013-02-28 03:13:24 +0000 |
1610 | @@ -158,14 +158,6 @@ |
1611 | if (mw->gWindow) |
1612 | mw->gWindow->glPaintSetEnabled (mw, true); |
1613 | } |
1614 | - |
1615 | - if (ms->optionGetLazyPositioning ()) |
1616 | - { |
1617 | - MOVE_WINDOW (w); |
1618 | - |
1619 | - if (mw->gWindow) |
1620 | - mw->releasable = w->obtainLockOnConfigureRequests (); |
1621 | - } |
1622 | } |
1623 | } |
1624 | |
1625 | @@ -181,8 +173,6 @@ |
1626 | |
1627 | if (ms->w) |
1628 | { |
1629 | - MOVE_WINDOW (ms->w); |
1630 | - |
1631 | if (state & CompAction::StateCancel) |
1632 | ms->w->move (ms->savedX - ms->w->geometry ().x (), |
1633 | ms->savedY - ms->w->geometry ().y (), false); |
1634 | @@ -204,14 +194,14 @@ |
1635 | |
1636 | if (ms->moveOpacity != OPAQUE) |
1637 | { |
1638 | + MOVE_WINDOW (ms->w); |
1639 | + |
1640 | if (mw->cWindow) |
1641 | mw->cWindow->addDamage (); |
1642 | if (mw->gWindow) |
1643 | mw->gWindow->glPaintSetEnabled (mw, false); |
1644 | } |
1645 | |
1646 | - mw->releasable.reset (); |
1647 | - |
1648 | ms->w = 0; |
1649 | ms->releaseButton = 0; |
1650 | } |
1651 | @@ -499,6 +489,9 @@ |
1652 | w->move (wX + dx - w->geometry ().x (), |
1653 | wY + dy - w->geometry ().y (), false); |
1654 | |
1655 | + if (!ms->optionGetLazyPositioning ()) |
1656 | + w->syncPosition (); |
1657 | + |
1658 | ms->x -= dx; |
1659 | ms->y -= dy; |
1660 | } |
1661 | |
1662 | === modified file 'plugins/move/src/move.h' |
1663 | --- plugins/move/src/move.h 2013-01-03 16:05:26 +0000 |
1664 | +++ plugins/move/src/move.h 2013-02-28 03:13:24 +0000 |
1665 | @@ -27,7 +27,6 @@ |
1666 | |
1667 | #include <core/screen.h> |
1668 | #include <core/pluginclasshandler.h> |
1669 | -#include <core/configurerequestbuffer.h> |
1670 | |
1671 | #include <composite/composite.h> |
1672 | #include <opengl/opengl.h> |
1673 | @@ -118,7 +117,6 @@ |
1674 | CompWindow *window; |
1675 | GLWindow *gWindow; |
1676 | CompositeWindow *cWindow; |
1677 | - compiz::window::configure_buffers::Releasable::Ptr releasable; |
1678 | }; |
1679 | |
1680 | #define MOVE_SCREEN(s) \ |
1681 | |
1682 | === modified file 'plugins/opengl/include/opengl/opengl.h' |
1683 | --- plugins/opengl/include/opengl/opengl.h 2013-01-10 09:23:24 +0000 |
1684 | +++ plugins/opengl/include/opengl/opengl.h 2013-02-28 03:13:24 +0000 |
1685 | @@ -37,6 +37,13 @@ |
1686 | #else |
1687 | #include <GL/gl.h> |
1688 | #include <GL/glx.h> |
1689 | + |
1690 | +/* Some implementations have not yet given a definition |
1691 | + * to GLX_BACK_BUFFER_AGE_EXT but this is the token as defined |
1692 | + * in the spec (https://www.opengl.org/registry/specs/EXT/glx_buffer_age.txt) |
1693 | + */ |
1694 | +#define GLX_BACK_BUFFER_AGE_EXT 0x20F4 |
1695 | + |
1696 | #endif |
1697 | |
1698 | #include <core/size.h> |
1699 | @@ -50,7 +57,7 @@ |
1700 | #include <opengl/programcache.h> |
1701 | #include <opengl/shadercache.h> |
1702 | |
1703 | -#define COMPIZ_OPENGL_ABI 6 |
1704 | +#define COMPIZ_OPENGL_ABI 8 |
1705 | |
1706 | /* |
1707 | * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but |
1708 | @@ -525,6 +532,7 @@ |
1709 | extern bool shaders; |
1710 | extern bool stencilBuffer; |
1711 | extern GLint maxTextureUnits; |
1712 | + extern bool bufferAge; |
1713 | |
1714 | extern bool canDoSaturated; |
1715 | extern bool canDoSlightlySaturated; |
1716 | @@ -663,6 +671,11 @@ |
1717 | unsigned int mask); |
1718 | |
1719 | /** |
1720 | + * Return true if glPaintCompositedOutput is required for this frame |
1721 | + */ |
1722 | + virtual bool glPaintCompositedOutputRequired (); |
1723 | + |
1724 | + /** |
1725 | * Hookable function used by plugins to determine stenciling mask |
1726 | */ |
1727 | virtual void glBufferStencil (const GLMatrix &matrix, |
1728 | @@ -674,7 +687,7 @@ |
1729 | extern template class PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>; |
1730 | |
1731 | class GLScreen : |
1732 | - public WrapableHandler<GLScreenInterface, 8>, |
1733 | + public WrapableHandler<GLScreenInterface, 9>, |
1734 | public PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>, |
1735 | public CompOption::Class |
1736 | { |
1737 | @@ -788,7 +801,9 @@ |
1738 | WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput, |
1739 | const CompRegion &, GLFramebufferObject *, unsigned int); |
1740 | |
1741 | - WRAPABLE_HND (7, GLScreenInterface, void, glBufferStencil, const GLMatrix &, |
1742 | + WRAPABLE_HND (7, GLScreenInterface, bool, glPaintCompositedOutputRequired); |
1743 | + |
1744 | + WRAPABLE_HND (8, GLScreenInterface, void, glBufferStencil, const GLMatrix &, |
1745 | GLVertexBuffer &, |
1746 | CompOutput *); |
1747 | |
1748 | |
1749 | === modified file 'plugins/opengl/src/doublebuffer/src/double-buffer.cpp' |
1750 | --- plugins/opengl/src/doublebuffer/src/double-buffer.cpp 2012-11-09 06:13:00 +0000 |
1751 | +++ plugins/opengl/src/doublebuffer/src/double-buffer.cpp 2013-02-28 03:13:24 +0000 |
1752 | @@ -26,6 +26,7 @@ |
1753 | |
1754 | #include <cstdlib> |
1755 | #include <cassert> |
1756 | +#include <cstdio> |
1757 | #include "opengl/doublebuffer.h" |
1758 | |
1759 | using namespace compiz::opengl; |
1760 | @@ -77,9 +78,7 @@ |
1761 | |
1762 | if (setting[NEED_PERSISTENT_BACK_BUFFER] && |
1763 | !setting[HAVE_PERSISTENT_BACK_BUFFER]) |
1764 | - { |
1765 | copyFrontToBack (); |
1766 | - } |
1767 | } |
1768 | else |
1769 | { |
1770 | |
1771 | === modified file 'plugins/opengl/src/framebufferobject.cpp' |
1772 | --- plugins/opengl/src/framebufferobject.cpp 2012-08-06 09:44:49 +0000 |
1773 | +++ plugins/opengl/src/framebufferobject.cpp 2013-02-28 03:13:24 +0000 |
1774 | @@ -131,7 +131,7 @@ |
1775 | |
1776 | (*GL::framebufferTexture2D) (GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, |
1777 | priv->glTex->target (), |
1778 | - priv->glTex->name (), 0); |
1779 | + priv->glTex->name (), 0); |
1780 | |
1781 | priv->status = (*GL::checkFramebufferStatus) (GL::DRAW_FRAMEBUFFER); |
1782 | |
1783 | |
1784 | === modified file 'plugins/opengl/src/paint.cpp' |
1785 | --- plugins/opengl/src/paint.cpp 2013-01-03 16:05:26 +0000 |
1786 | +++ plugins/opengl/src/paint.cpp 2013-02-28 03:13:24 +0000 |
1787 | @@ -418,11 +418,6 @@ |
1788 | if (w->destroyed ()) |
1789 | continue; |
1790 | |
1791 | - gw = GLWindow::get (w); |
1792 | - |
1793 | - /* Release any queued ConfigureWindow requests now */ |
1794 | - gw->priv->configureLock->release (); |
1795 | - |
1796 | if (unredirected.find (w) != unredirected.end ()) |
1797 | continue; |
1798 | |
1799 | @@ -432,6 +427,8 @@ |
1800 | continue; |
1801 | } |
1802 | |
1803 | + gw = GLWindow::get (w); |
1804 | + |
1805 | const CompRegion &clip = |
1806 | (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) ? |
1807 | gw->clip () : region; |
1808 | @@ -629,8 +626,8 @@ |
1809 | if (mask & PAINT_SCREEN_FULL_MASK) |
1810 | { |
1811 | glPaintTransformedOutput (sAttrib, sTransform, |
1812 | - CompRegion (*output), output, mask); |
1813 | - |
1814 | + CompRegionRef (output->region ()), output, mask); |
1815 | + priv->cScreen->addOverdrawDamageRegion (CompRegionRef (output->region ())); |
1816 | return true; |
1817 | } |
1818 | |
1819 | @@ -660,8 +657,9 @@ |
1820 | } |
1821 | else if (mask & PAINT_SCREEN_FULL_MASK) |
1822 | { |
1823 | - glPaintTransformedOutput (sAttrib, sTransform, CompRegion (*output), |
1824 | + glPaintTransformedOutput (sAttrib, sTransform, CompRegionRef (output->region ()), |
1825 | output, mask); |
1826 | + priv->cScreen->addOverdrawDamageRegion (CompRegionRef (output->region ())); |
1827 | |
1828 | return true; |
1829 | } |
1830 | @@ -671,6 +669,13 @@ |
1831 | } |
1832 | } |
1833 | |
1834 | +bool |
1835 | +GLScreen::glPaintCompositedOutputRequired () |
1836 | +{ |
1837 | + WRAPABLE_HND_FUNCTN_RETURN (bool, glPaintCompositedOutputRequired); |
1838 | + return false; |
1839 | +} |
1840 | + |
1841 | void |
1842 | GLScreen::glPaintCompositedOutput (const CompRegion ®ion, |
1843 | GLFramebufferObject *fbo, |
1844 | |
1845 | === modified file 'plugins/opengl/src/privates.h' |
1846 | --- plugins/opengl/src/privates.h 2013-01-03 16:05:26 +0000 |
1847 | +++ plugins/opengl/src/privates.h 2013-02-28 03:13:24 +0000 |
1848 | @@ -29,11 +29,13 @@ |
1849 | #define _OPENGL_PRIVATES_H |
1850 | |
1851 | #include <memory> |
1852 | +#include <vector> |
1853 | +#include <tr1/tuple> |
1854 | +#include <boost/shared_ptr.hpp> |
1855 | |
1856 | #include <composite/composite.h> |
1857 | #include <opengl/opengl.h> |
1858 | #include <core/atoms.h> |
1859 | -#include <core/configurerequestbuffer.h> |
1860 | |
1861 | #ifdef USE_GLES |
1862 | #include <opengl/framebufferobject.h> |
1863 | @@ -120,8 +122,26 @@ |
1864 | GLTexture::List textures; |
1865 | }; |
1866 | |
1867 | +class FrameProvider |
1868 | +{ |
1869 | + public: |
1870 | + |
1871 | + typedef boost::shared_ptr <FrameProvider> Ptr; |
1872 | + typedef std::tr1::tuple <GLFramebufferObject *, int> Frame; |
1873 | + |
1874 | + virtual ~FrameProvider () {} |
1875 | + |
1876 | + virtual GLuint getCurrentFrame () = 0; |
1877 | + virtual void endFrame () = 0; |
1878 | + |
1879 | + virtual bool providesPersistence () = 0; |
1880 | + virtual bool alwaysPostprocess () = 0; |
1881 | + virtual void invalidateAll () = 0; |
1882 | +}; |
1883 | + |
1884 | class PrivateGLScreen : |
1885 | public ScreenInterface, |
1886 | + public CompositeScreenInterface, |
1887 | public compiz::composite::PaintHandler, |
1888 | public OpenglOptions |
1889 | { |
1890 | @@ -142,12 +162,17 @@ |
1891 | bool hasVSync (); |
1892 | bool requiredForcedRefreshRate (); |
1893 | |
1894 | + unsigned int getFrameAge (); |
1895 | + |
1896 | void updateRenderMode (); |
1897 | + void updateFrameProvider (); |
1898 | |
1899 | void prepareDrawing (); |
1900 | |
1901 | bool compositingActive (); |
1902 | |
1903 | + void damageCutoff (); |
1904 | + |
1905 | void paintBackground (const GLMatrix &transform, |
1906 | const CompRegion ®ion, |
1907 | bool transformed); |
1908 | @@ -163,6 +188,8 @@ |
1909 | |
1910 | bool driverIsBlacklisted (const char *regex) const; |
1911 | |
1912 | + bool postprocessRequiredForCurrentFrame (); |
1913 | + |
1914 | public: |
1915 | |
1916 | GLScreen *gScreen; |
1917 | @@ -197,7 +224,7 @@ |
1918 | GLXDoubleBuffer doubleBuffer; |
1919 | #endif |
1920 | |
1921 | - GLFramebufferObject *scratchFbo; |
1922 | + boost::shared_ptr <GLFramebufferObject> scratchFbo; |
1923 | CompRegion outputRegion; |
1924 | |
1925 | XRectangle lastViewport; |
1926 | @@ -222,8 +249,10 @@ |
1927 | Pixmap rootPixmapCopy; |
1928 | CompSize rootPixmapSize; |
1929 | |
1930 | + FrameProvider::Ptr frameProvider; |
1931 | const char *glVendor, *glRenderer, *glVersion; |
1932 | |
1933 | + bool postprocessingRequired; |
1934 | mutable CompString prevRegex; |
1935 | mutable bool prevBlacklisted; |
1936 | }; |
1937 | @@ -284,8 +313,6 @@ |
1938 | GLVertexBuffer::AutoProgram *autoProgram; |
1939 | |
1940 | std::list<GLIcon> icons; |
1941 | - |
1942 | - compiz::window::configure_buffers::Releasable::Ptr configureLock; |
1943 | }; |
1944 | |
1945 | #endif |
1946 | |
1947 | === modified file 'plugins/opengl/src/screen.cpp' |
1948 | --- plugins/opengl/src/screen.cpp 2013-01-09 10:57:03 +0000 |
1949 | +++ plugins/opengl/src/screen.cpp 2013-02-28 03:13:24 +0000 |
1950 | @@ -186,6 +186,7 @@ |
1951 | bool vboEnabled = false; |
1952 | bool shaders = false; |
1953 | GLint maxTextureUnits = 1; |
1954 | + bool bufferAge = false; |
1955 | |
1956 | bool canDoSaturated = false; |
1957 | bool canDoSlightlySaturated = false; |
1958 | @@ -301,6 +302,52 @@ |
1959 | |
1960 | #ifndef USE_GLES |
1961 | |
1962 | +class BufferAgeFrameProvider : |
1963 | + public FrameProvider |
1964 | +{ |
1965 | + public: |
1966 | + |
1967 | + BufferAgeFrameProvider (Display *disp, |
1968 | + GLXDrawable drawable) : |
1969 | + mDisplay (disp), |
1970 | + mDrawable (drawable) |
1971 | + { |
1972 | + } |
1973 | + |
1974 | + unsigned int getCurrentFrame () |
1975 | + { |
1976 | + unsigned int age = 0; |
1977 | + (*GL::queryDrawable) (mDisplay, |
1978 | + mDrawable, |
1979 | + GLX_BACK_BUFFER_AGE_EXT, |
1980 | + &age); |
1981 | + return age; |
1982 | + } |
1983 | + |
1984 | + void endFrame () |
1985 | + { |
1986 | + } |
1987 | + |
1988 | + void invalidateAll () |
1989 | + { |
1990 | + } |
1991 | + |
1992 | + bool providesPersistence () |
1993 | + { |
1994 | + return true; |
1995 | + } |
1996 | + |
1997 | + bool alwaysPostprocess () |
1998 | + { |
1999 | + return false; |
2000 | + } |
2001 | + |
2002 | + private: |
2003 | + |
2004 | + Display *mDisplay; |
2005 | + GLXDrawable mDrawable; |
2006 | +}; |
2007 | + |
2008 | namespace compiz |
2009 | { |
2010 | namespace opengl |
2011 | @@ -358,6 +405,137 @@ |
2012 | |
2013 | #endif |
2014 | |
2015 | +class UndefinedFrameProvider : |
2016 | + public FrameProvider |
2017 | +{ |
2018 | + public: |
2019 | + |
2020 | + unsigned int getCurrentFrame () |
2021 | + { |
2022 | + return 0; |
2023 | + } |
2024 | + |
2025 | + void endFrame () |
2026 | + { |
2027 | + } |
2028 | + |
2029 | + void invalidateAll () |
2030 | + { |
2031 | + } |
2032 | + |
2033 | + bool providesPersistence () |
2034 | + { |
2035 | + return false; |
2036 | + } |
2037 | + |
2038 | + bool alwaysPostprocess () |
2039 | + { |
2040 | + return false; |
2041 | + } |
2042 | +}; |
2043 | + |
2044 | +class PostprocessFrameProvider : |
2045 | + public FrameProvider |
2046 | +{ |
2047 | + public: |
2048 | + |
2049 | + PostprocessFrameProvider (GLFramebufferObject *object) : |
2050 | + mObject (object), |
2051 | + mAge (0) |
2052 | + { |
2053 | + } |
2054 | + |
2055 | + unsigned int getCurrentFrame () |
2056 | + { |
2057 | + /* We are now using this buffer, reset |
2058 | + * age back to zero */ |
2059 | + unsigned int lastAge = mAge; |
2060 | + mAge = 0; |
2061 | + |
2062 | + return lastAge; |
2063 | + } |
2064 | + |
2065 | + void endFrame () |
2066 | + { |
2067 | + ++mAge; |
2068 | + } |
2069 | + |
2070 | + void invalidateAll () |
2071 | + { |
2072 | + mAge = 0; |
2073 | + } |
2074 | + |
2075 | + bool providesPersistence () |
2076 | + { |
2077 | + return true; |
2078 | + } |
2079 | + |
2080 | + bool alwaysPostprocess () |
2081 | + { |
2082 | + return true; |
2083 | + } |
2084 | + |
2085 | + private: |
2086 | + |
2087 | + GLFramebufferObject *mObject; |
2088 | + unsigned int mAge; |
2089 | +}; |
2090 | + |
2091 | +class OptionalPostprocessFrameProvider : |
2092 | + public FrameProvider |
2093 | +{ |
2094 | + public: |
2095 | + |
2096 | + typedef boost::function <bool ()> PostprocessRequired; |
2097 | + |
2098 | + OptionalPostprocessFrameProvider (const FrameProvider::Ptr &backbuffer, |
2099 | + const FrameProvider::Ptr &scratchbuffer, |
2100 | + const PostprocessRequired &ppRequired) : |
2101 | + mBackbuffer (backbuffer), |
2102 | + mScratchbuffer (scratchbuffer), |
2103 | + mPPRequired (ppRequired) |
2104 | + { |
2105 | + } |
2106 | + |
2107 | + unsigned int getCurrentFrame () |
2108 | + { |
2109 | + if (mPPRequired ()) |
2110 | + return mScratchbuffer->getCurrentFrame (); |
2111 | + else |
2112 | + return mBackbuffer->getCurrentFrame (); |
2113 | + } |
2114 | + |
2115 | + void endFrame () |
2116 | + { |
2117 | + mScratchbuffer->endFrame (); |
2118 | + } |
2119 | + |
2120 | + void invalidateAll () |
2121 | + { |
2122 | + mScratchbuffer->invalidateAll (); |
2123 | + } |
2124 | + |
2125 | + bool providesPersistence () |
2126 | + { |
2127 | + /* We are only as good as the backbuffer is */ |
2128 | + return mBackbuffer->providesPersistence (); |
2129 | + } |
2130 | + |
2131 | + bool alwaysPostprocess () |
2132 | + { |
2133 | + if (mPPRequired ()) |
2134 | + return mScratchbuffer->alwaysPostprocess (); |
2135 | + else |
2136 | + return mBackbuffer->alwaysPostprocess (); |
2137 | + } |
2138 | + |
2139 | + private: |
2140 | + |
2141 | + FrameProvider::Ptr mBackbuffer; |
2142 | + FrameProvider::Ptr mScratchbuffer; |
2143 | + PostprocessRequired mPPRequired; |
2144 | +}; |
2145 | + |
2146 | bool |
2147 | GLScreen::glInitContext (XVisualInfo *visinfo) |
2148 | { |
2149 | @@ -593,6 +771,8 @@ |
2150 | |
2151 | priv->incorrectRefreshRate = false; |
2152 | |
2153 | + priv->frameProvider.reset (new PostprocessFrameProvider ()); |
2154 | + |
2155 | #else |
2156 | |
2157 | Display *dpy = screen->dpy (); |
2158 | @@ -899,12 +1079,17 @@ |
2159 | |
2160 | if (GL::fboSupported) |
2161 | { |
2162 | - priv->scratchFbo = new GLFramebufferObject; |
2163 | + priv->scratchFbo.reset (new GLFramebufferObject ()); |
2164 | priv->scratchFbo->allocate (*screen, NULL, GL_BGRA); |
2165 | } |
2166 | |
2167 | GLVertexBuffer::streamingBuffer ()->setAutoProgram (priv->autoProgram); |
2168 | |
2169 | + /* We need scratchFbo to be set before doing this, and it is common |
2170 | + * to both the GLES and non-GLES codepaths, so using another #ifdef |
2171 | + */ |
2172 | + priv->updateFrameProvider (); |
2173 | + |
2174 | return true; |
2175 | } |
2176 | |
2177 | @@ -993,6 +1178,13 @@ |
2178 | return; |
2179 | } |
2180 | |
2181 | + if (strstr (glxExtensions, "GLX_EXT_buffer_age")) |
2182 | + { |
2183 | + compLogMessage ("opengl", CompLogLevelInfo, |
2184 | + "GLX_EXT_buffer_age is supported"); |
2185 | + GL::bufferAge = true; |
2186 | + } |
2187 | + |
2188 | priv->getProcAddress = (GL::GLXGetProcAddressProc) |
2189 | getProcAddress ("glXGetProcAddressARB"); |
2190 | GL::bindTexImage = (GL::GLXBindTexImageProc) |
2191 | @@ -1209,9 +1401,6 @@ |
2192 | glXDestroyContext (screen->dpy (), priv->ctx); |
2193 | #endif |
2194 | |
2195 | - if (priv->scratchFbo) |
2196 | - delete priv->scratchFbo; |
2197 | - |
2198 | delete priv; |
2199 | } |
2200 | |
2201 | @@ -1233,7 +1422,7 @@ |
2202 | ctx (EGL_NO_CONTEXT), |
2203 | doubleBuffer (screen->dpy (), *screen, surface), |
2204 | #endif |
2205 | - scratchFbo (NULL), |
2206 | + scratchFbo (), |
2207 | outputRegion (), |
2208 | refreshSubBuffer (false), |
2209 | lastMask (0), |
2210 | @@ -1246,13 +1435,16 @@ |
2211 | autoProgram (new GLScreenAutoProgram(gs)), |
2212 | rootPixmapCopy (None), |
2213 | rootPixmapSize (), |
2214 | + frameProvider (), |
2215 | glVendor (NULL), |
2216 | glRenderer (NULL), |
2217 | glVersion (NULL), |
2218 | + postprocessingRequired (false), |
2219 | prevRegex (), |
2220 | prevBlacklisted (false) |
2221 | { |
2222 | ScreenInterface::setHandler (screen); |
2223 | + CompositeScreenInterface::setHandler (cScreen); |
2224 | } |
2225 | |
2226 | PrivateGLScreen::~PrivateGLScreen () |
2227 | @@ -1443,8 +1635,11 @@ |
2228 | { |
2229 | screen->outputChangeNotify (); |
2230 | |
2231 | + frameProvider->invalidateAll (); |
2232 | + |
2233 | if (scratchFbo) |
2234 | scratchFbo->allocate (*screen, NULL, GL_BGRA); |
2235 | + |
2236 | updateView (); |
2237 | } |
2238 | |
2239 | @@ -1669,6 +1864,10 @@ |
2240 | GLScreenInterface::projectionMatrix () |
2241 | WRAPABLE_DEF (projectionMatrix) |
2242 | |
2243 | +bool |
2244 | +GLScreenInterface::glPaintCompositedOutputRequired () |
2245 | + WRAPABLE_DEF (glPaintCompositedOutputRequired) |
2246 | + |
2247 | void |
2248 | GLScreenInterface::glPaintCompositedOutput (const CompRegion ®ion, |
2249 | GLFramebufferObject *fbo, |
2250 | @@ -1977,18 +2176,6 @@ |
2251 | glDepthMask (GL_FALSE); |
2252 | glStencilMask (0); |
2253 | |
2254 | - GLFramebufferObject *oldFbo = NULL; |
2255 | - bool useFbo = false; |
2256 | - |
2257 | - /* Clear the color buffer where appropriate */ |
2258 | - if (GL::fboEnabled && scratchFbo) |
2259 | - { |
2260 | - oldFbo = scratchFbo->bind (); |
2261 | - useFbo = scratchFbo->checkStatus () && scratchFbo->tex (); |
2262 | - if (!useFbo) |
2263 | - GLFramebufferObject::rebind (oldFbo); |
2264 | - } |
2265 | - |
2266 | #ifdef UNSAFE_ARM_SGX_FIXME |
2267 | refreshSubBuffer = ((lastMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) && |
2268 | !(mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) && |
2269 | @@ -2006,8 +2193,21 @@ |
2270 | } |
2271 | #endif |
2272 | |
2273 | - CompRegion tmpRegion = (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) ? |
2274 | - screen->region () : region; |
2275 | + CompRegion paintRegion ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) ? |
2276 | + screen->region () : region); |
2277 | + bool useFbo = false; |
2278 | + GLFramebufferObject *oldFbo = NULL; |
2279 | + |
2280 | + postprocessingRequired = gScreen->glPaintCompositedOutputRequired (); |
2281 | + postprocessingRequired |= frameProvider->alwaysPostprocess (); |
2282 | + |
2283 | + /* Clear the color buffer where appropriate */ |
2284 | + if ((GL::fboEnabled && postprocessRequiredForCurrentFrame ())) |
2285 | + { |
2286 | + oldFbo = scratchFbo->bind (); |
2287 | + if (scratchFbo->checkStatus ()) |
2288 | + useFbo = true; |
2289 | + } |
2290 | |
2291 | foreach (CompOutput *output, outputs) |
2292 | { |
2293 | @@ -2034,7 +2234,8 @@ |
2294 | |
2295 | gScreen->glPaintOutput (defaultScreenPaintAttrib, |
2296 | identity, |
2297 | - CompRegion (*output), output, |
2298 | + CompRegion (*output), |
2299 | + output, |
2300 | PAINT_SCREEN_REGION_MASK | |
2301 | PAINT_SCREEN_FULL_MASK); |
2302 | } |
2303 | @@ -2057,7 +2258,9 @@ |
2304 | tmpRegion = CompRegion (*output); |
2305 | #endif |
2306 | |
2307 | - outputRegion = tmpRegion & CompRegion (*output); |
2308 | + /* Clip current paint region to output extents */ |
2309 | + CompRegionRef wholeOutput (output->region ()); |
2310 | + outputRegion = (paintRegion & wholeOutput); |
2311 | |
2312 | if (!gScreen->glPaintOutput (defaultScreenPaintAttrib, |
2313 | identity, |
2314 | @@ -2068,10 +2271,11 @@ |
2315 | |
2316 | gScreen->glPaintOutput (defaultScreenPaintAttrib, |
2317 | identity, |
2318 | - CompRegion (*output), output, |
2319 | + wholeOutput, output, |
2320 | PAINT_SCREEN_FULL_MASK); |
2321 | |
2322 | - tmpRegion += *output; |
2323 | + paintRegion += wholeOutput; |
2324 | + cScreen->addOverdrawDamageRegion (wholeOutput); |
2325 | } |
2326 | } |
2327 | } |
2328 | @@ -2082,13 +2286,18 @@ |
2329 | |
2330 | if (useFbo) |
2331 | { |
2332 | - GLFramebufferObject::rebind (oldFbo); |
2333 | - |
2334 | // FIXME: does not work if screen dimensions exceed max texture size |
2335 | // We should try to use glBlitFramebuffer instead. |
2336 | - gScreen->glPaintCompositedOutput (screen->region (), scratchFbo, mask); |
2337 | + GLFramebufferObject::rebind (oldFbo); |
2338 | + /* If we must always postprocess, then we don't have any |
2339 | + * "real" backbuffer persistence, redraw the whole thing */ |
2340 | + gScreen->glPaintCompositedOutput (frameProvider->alwaysPostprocess () ? |
2341 | + screen->region () : |
2342 | + paintRegion, scratchFbo.get (), mask); |
2343 | } |
2344 | |
2345 | + frameProvider->endFrame (); |
2346 | + |
2347 | if (cScreen->outputWindowChanged ()) |
2348 | { |
2349 | /* |
2350 | @@ -2100,20 +2309,27 @@ |
2351 | return; |
2352 | } |
2353 | |
2354 | + bool persistence = frameProvider->providesPersistence (); |
2355 | bool alwaysSwap = optionGetAlwaysSwapBuffers (); |
2356 | - bool fullscreen = useFbo || |
2357 | + bool fullscreen = persistence || |
2358 | alwaysSwap || |
2359 | ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) && |
2360 | commonFrontbuffer); |
2361 | |
2362 | doubleBuffer.set (DoubleBuffer::VSYNC, optionGetSyncToVblank ()); |
2363 | - doubleBuffer.set (DoubleBuffer::HAVE_PERSISTENT_BACK_BUFFER, useFbo); |
2364 | + doubleBuffer.set (DoubleBuffer::HAVE_PERSISTENT_BACK_BUFFER, persistence); |
2365 | doubleBuffer.set (DoubleBuffer::NEED_PERSISTENT_BACK_BUFFER, alwaysSwap); |
2366 | - doubleBuffer.render (tmpRegion, fullscreen); |
2367 | + doubleBuffer.render (paintRegion, fullscreen); |
2368 | |
2369 | lastMask = mask; |
2370 | } |
2371 | |
2372 | +unsigned int |
2373 | +PrivateGLScreen::getFrameAge () |
2374 | +{ |
2375 | + return frameProvider->getCurrentFrame (); |
2376 | +} |
2377 | + |
2378 | bool |
2379 | PrivateGLScreen::hasVSync () |
2380 | { |
2381 | @@ -2138,6 +2354,13 @@ |
2382 | } |
2383 | |
2384 | void |
2385 | +PrivateGLScreen::damageCutoff () |
2386 | +{ |
2387 | + cScreen->applyDamageForFrameAge (frameProvider->getCurrentFrame ()); |
2388 | + cScreen->damageCutoff (); |
2389 | +} |
2390 | + |
2391 | +void |
2392 | PrivateGLScreen::updateRenderMode () |
2393 | { |
2394 | #ifndef USE_GLES |
2395 | @@ -2147,12 +2370,54 @@ |
2396 | } |
2397 | |
2398 | void |
2399 | +PrivateGLScreen::updateFrameProvider () |
2400 | +{ |
2401 | +#ifndef USE_GLES |
2402 | + const Window outputWindow = CompositeScreen::get (screen)->output (); |
2403 | + |
2404 | + if (GL::fboEnabled) |
2405 | + { |
2406 | + if (GL::bufferAge) |
2407 | + { |
2408 | + FrameProvider::Ptr back (new BufferAgeFrameProvider (screen->dpy (), |
2409 | + outputWindow)); |
2410 | + FrameProvider::Ptr scratch (new PostprocessFrameProvider (scratchFbo.get ())); |
2411 | + OptionalPostprocessFrameProvider::PostprocessRequired ppReq |
2412 | + (boost::bind (&PrivateGLScreen::postprocessRequiredForCurrentFrame, |
2413 | + this)); |
2414 | + frameProvider.reset (new OptionalPostprocessFrameProvider (back, |
2415 | + scratch, |
2416 | + ppReq)); |
2417 | + } |
2418 | + else |
2419 | + { |
2420 | + /* Prefer using FBO's instead of switching between a defined/undefined backbuffer */ |
2421 | + frameProvider.reset (new PostprocessFrameProvider (scratchFbo.get ())); |
2422 | + } |
2423 | + } |
2424 | + else |
2425 | + { |
2426 | + if (GL::bufferAge) |
2427 | + frameProvider.reset (new BufferAgeFrameProvider (screen->dpy (), |
2428 | + outputWindow)); |
2429 | + else |
2430 | + frameProvider.reset (new UndefinedFrameProvider ()); |
2431 | + } |
2432 | +#else |
2433 | + frameProvider.reset (new PostprocessFrameProvider (scratchFbo.get ())); |
2434 | +#endif |
2435 | +} |
2436 | + |
2437 | +void |
2438 | PrivateGLScreen::prepareDrawing () |
2439 | { |
2440 | bool wasFboEnabled = GL::fboEnabled; |
2441 | updateRenderMode (); |
2442 | if (wasFboEnabled != GL::fboEnabled) |
2443 | + { |
2444 | + updateFrameProvider (); |
2445 | CompositeScreen::get (screen)->damageScreen (); |
2446 | + } |
2447 | } |
2448 | |
2449 | bool |
2450 | @@ -2170,6 +2435,12 @@ |
2451 | return prevBlacklisted; |
2452 | } |
2453 | |
2454 | +bool |
2455 | +PrivateGLScreen::postprocessRequiredForCurrentFrame () |
2456 | +{ |
2457 | + return postprocessingRequired; |
2458 | +} |
2459 | + |
2460 | GLTexture::BindPixmapHandle |
2461 | GLScreen::registerBindPixmap (GLTexture::BindPixmapProc proc) |
2462 | { |
2463 | @@ -2198,7 +2469,7 @@ |
2464 | GLFramebufferObject * |
2465 | GLScreen::fbo () |
2466 | { |
2467 | - return priv->scratchFbo; |
2468 | + return priv->scratchFbo.get (); |
2469 | } |
2470 | |
2471 | GLTexture * |
2472 | |
2473 | === modified file 'plugins/opengl/src/window.cpp' |
2474 | --- plugins/opengl/src/window.cpp 2013-01-03 16:05:26 +0000 |
2475 | +++ plugins/opengl/src/window.cpp 2013-02-28 03:13:24 +0000 |
2476 | @@ -86,8 +86,7 @@ |
2477 | bindFailed (false), |
2478 | vertexBuffer (new GLVertexBuffer ()), |
2479 | autoProgram(new GLWindowAutoProgram(this)), |
2480 | - icons (), |
2481 | - configureLock (w->obtainLockOnConfigureRequests ()) |
2482 | + icons () |
2483 | { |
2484 | paint.xScale = 1.0f; |
2485 | paint.yScale = 1.0f; |
2486 | |
2487 | === modified file 'plugins/resize/src/resize.cpp' |
2488 | --- plugins/resize/src/resize.cpp 2012-10-19 09:23:11 +0000 |
2489 | +++ plugins/resize/src/resize.cpp 2013-02-28 03:13:24 +0000 |
2490 | @@ -257,7 +257,7 @@ |
2491 | float xScale, yScale; |
2492 | int x, y; |
2493 | |
2494 | - if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) |
2495 | + if (mask & PAINT_WINDOW_NO_DRAW_MASKS) |
2496 | return false; |
2497 | |
2498 | status = gWindow->glPaint (attrib, transform, region, |
2499 | |
2500 | === modified file 'plugins/ring/src/ring.cpp' |
2501 | --- plugins/ring/src/ring.cpp 2013-01-19 11:47:22 +0000 |
2502 | +++ plugins/ring/src/ring.cpp 2013-02-28 03:13:24 +0000 |
2503 | @@ -264,7 +264,7 @@ |
2504 | GLWindowPaintAttrib wAttrib (gWindow->lastPaintAttrib ()); |
2505 | GLMatrix wTransform = transform; |
2506 | |
2507 | - if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) |
2508 | + if (mask & PAINT_WINDOW_NO_DRAW_MASKS) |
2509 | return false; |
2510 | |
2511 | if (mSlot) |
2512 | |
2513 | === modified file 'plugins/scale/src/scale.cpp' |
2514 | --- plugins/scale/src/scale.cpp 2013-01-29 23:16:32 +0000 |
2515 | +++ plugins/scale/src/scale.cpp 2013-02-28 03:13:24 +0000 |
2516 | @@ -384,12 +384,14 @@ |
2517 | |
2518 | status = gWindow->glPaint (sAttrib, transform, region, mask); |
2519 | |
2520 | + mask &= ~(PAINT_WINDOW_NO_CORE_INSTANCE_MASK); |
2521 | + |
2522 | if (scaled) |
2523 | { |
2524 | GLWindowPaintAttrib lastAttrib (gWindow->lastPaintAttrib ()); |
2525 | GLMatrix wTransform (transform); |
2526 | |
2527 | - if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) |
2528 | + if (mask & PAINT_WINDOW_NO_DRAW_MASKS) |
2529 | return false; |
2530 | |
2531 | if (window->alpha () || lastAttrib.opacity != OPAQUE) |
2532 | |
2533 | === modified file 'plugins/staticswitcher/src/staticswitcher.cpp' |
2534 | --- plugins/staticswitcher/src/staticswitcher.cpp 2012-12-10 03:28:47 +0000 |
2535 | +++ plugins/staticswitcher/src/staticswitcher.cpp 2013-02-28 03:13:24 +0000 |
2536 | @@ -1246,7 +1246,7 @@ |
2537 | |
2538 | const CompWindow::Geometry &g = window->geometry (); |
2539 | |
2540 | - if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK || |
2541 | + if (mask & PAINT_WINDOW_NO_DRAW_MASKS || |
2542 | sScreen->ignoreSwitcher) |
2543 | return false; |
2544 | |
2545 | |
2546 | === modified file 'plugins/switcher/src/switcher.cpp' |
2547 | --- plugins/switcher/src/switcher.cpp 2012-12-10 03:28:47 +0000 |
2548 | +++ plugins/switcher/src/switcher.cpp 2013-02-28 03:13:24 +0000 |
2549 | @@ -971,7 +971,7 @@ |
2550 | |
2551 | const CompWindow::Geometry &g = window->geometry (); |
2552 | |
2553 | - if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK || |
2554 | + if (mask & PAINT_WINDOW_NO_DRAW_MASKS || |
2555 | sScreen->ignoreSwitcher) |
2556 | return false; |
2557 | |
2558 | |
2559 | === modified file 'plugins/td/src/3d.cpp' |
2560 | --- plugins/td/src/3d.cpp 2013-02-03 17:50:59 +0000 |
2561 | +++ plugins/td/src/3d.cpp 2013-02-28 03:13:24 +0000 |
2562 | @@ -163,7 +163,7 @@ |
2563 | glGetIntegerv (GL_CULL_FACE_MODE, &cull); |
2564 | cullInv = (cull == GL_BACK)? GL_FRONT : GL_BACK; |
2565 | |
2566 | - if (ww && wh && !(mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) && |
2567 | + if (ww && wh && !(mask & PAINT_WINDOW_NO_DRAW_MASKS) && |
2568 | ((cs->paintOrder () == FTB && mFtb) || |
2569 | (cs->paintOrder () == BTF && !mFtb))) |
2570 | { |
2571 | |
2572 | === modified file 'plugins/water/src/water.cpp' |
2573 | --- plugins/water/src/water.cpp 2013-01-28 19:45:04 +0000 |
2574 | +++ plugins/water/src/water.cpp 2013-02-28 03:13:24 +0000 |
2575 | @@ -317,6 +317,12 @@ |
2576 | } |
2577 | } |
2578 | |
2579 | +bool |
2580 | +WaterScreen::glPaintCompositedOutputRequired () |
2581 | +{ |
2582 | + return true; |
2583 | +} |
2584 | + |
2585 | void |
2586 | WaterScreen::glPaintCompositedOutput (const CompRegion ®ion, |
2587 | GLFramebufferObject *fbo, |
2588 | @@ -467,6 +473,7 @@ |
2589 | cScreen->preparePaintSetEnabled (this, false); |
2590 | gScreen->glPaintOutputSetEnabled (this, false); |
2591 | gScreen->glPaintCompositedOutputSetEnabled (this, false); |
2592 | + gScreen->glPaintCompositedOutputRequiredSetEnabled (this, false); |
2593 | cScreen->donePaintSetEnabled (this, false); |
2594 | } |
2595 | |
2596 | |
2597 | === modified file 'plugins/water/src/water.h' |
2598 | --- plugins/water/src/water.h 2012-09-07 23:56:21 +0000 |
2599 | +++ plugins/water/src/water.h 2013-02-28 03:13:24 +0000 |
2600 | @@ -64,6 +64,7 @@ |
2601 | |
2602 | void handleEvent (XEvent *); |
2603 | |
2604 | + bool glPaintCompositedOutputRequired (); |
2605 | void glPaintCompositedOutput (const CompRegion ®ion, |
2606 | GLFramebufferObject *fbo, |
2607 | unsigned int mask); |
2608 | |
2609 | === modified file 'src/CMakeLists.txt' |
2610 | --- src/CMakeLists.txt 2013-01-03 16:05:26 +0000 |
2611 | +++ src/CMakeLists.txt 2013-02-28 03:13:24 +0000 |
2612 | @@ -160,12 +160,6 @@ |
2613 | compiz_window_geometry |
2614 | ) |
2615 | |
2616 | -add_library (compiz_configurerequestbuffer STATIC |
2617 | - configurerequestbuffer.cpp) |
2618 | - |
2619 | -target_link_libraries (compiz_configurerequestbuffer |
2620 | - compiz_window_geometry) |
2621 | - |
2622 | # workaround for build race |
2623 | add_dependencies (compiz core-xml-file) |
2624 | |
2625 | @@ -198,7 +192,6 @@ |
2626 | compiz_servergrab |
2627 | compiz_output |
2628 | compiz_outputdevices |
2629 | - compiz_configurerequestbuffer |
2630 | -Wl,-no-whole-archive |
2631 | # ${CORE_MOD_LIBRARIES} |
2632 | ) |
2633 | |
2634 | === removed file 'src/asyncserverwindow.h' |
2635 | --- src/asyncserverwindow.h 2012-12-13 11:12:32 +0000 |
2636 | +++ src/asyncserverwindow.h 1970-01-01 00:00:00 +0000 |
2637 | @@ -1,52 +0,0 @@ |
2638 | -/* |
2639 | - * Copyright © 2012 Sam Spilsbury |
2640 | - * |
2641 | - * Permission to use, copy, modify, distribute, and sell this software |
2642 | - * and its documentation for any purpose is hereby granted without |
2643 | - * fee, provided that the above copyright notice appear in all copies |
2644 | - * and that both that copyright notice and this permission notice |
2645 | - * appear in supporting documentation, and that the name of |
2646 | - * Canonical Ltd. not be used in advertising or publicity pertaining to |
2647 | - * distribution of the software without specific, written prior permission. |
2648 | - * Canonical Ltd. makes no representations about the suitability of this |
2649 | - * software for any purpose. It is provided "as is" without express or |
2650 | - * implied warranty. |
2651 | - * |
2652 | - * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
2653 | - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
2654 | - * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
2655 | - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
2656 | - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
2657 | - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
2658 | - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
2659 | - * |
2660 | - * Authored by: Sam Spilsbury <smspillaz@gmail.com> |
2661 | - */ |
2662 | -#ifndef _COMPIZ_ASYNC_SERVER_WINDOW_H |
2663 | -#define _COMPIZ_ASYNC_SERVER_WINDOW_H |
2664 | - |
2665 | -#include <X11/Xlib.h> |
2666 | - |
2667 | -namespace compiz |
2668 | -{ |
2669 | -namespace window |
2670 | -{ |
2671 | -class AsyncServerWindow |
2672 | -{ |
2673 | - public: |
2674 | - |
2675 | - virtual ~AsyncServerWindow () {}; |
2676 | - |
2677 | - virtual int requestConfigureOnClient (const XWindowChanges &xwc, |
2678 | - unsigned int valueMask) = 0; |
2679 | - virtual int requestConfigureOnWrapper (const XWindowChanges &xwc, |
2680 | - unsigned int valueMask) = 0; |
2681 | - virtual int requestConfigureOnFrame (const XWindowChanges &xwc, |
2682 | - unsigned int valueMask) = 0; |
2683 | - virtual void sendSyntheticConfigureNotify () = 0; |
2684 | - virtual bool hasCustomShape () const = 0; |
2685 | -}; |
2686 | -} |
2687 | -} |
2688 | - |
2689 | -#endif |
2690 | |
2691 | === removed file 'src/configurerequestbuffer-impl.h' |
2692 | --- src/configurerequestbuffer-impl.h 2012-12-13 11:12:32 +0000 |
2693 | +++ src/configurerequestbuffer-impl.h 1970-01-01 00:00:00 +0000 |
2694 | @@ -1,145 +0,0 @@ |
2695 | -/* |
2696 | - * Copyright © 2012 Sam Spilsbury |
2697 | - * |
2698 | - * Permission to use, copy, modify, distribute, and sell this software |
2699 | - * and its documentation for any purpose is hereby granted without |
2700 | - * fee, provided that the above copyright notice appear in all copies |
2701 | - * and that both that copyright notice and this permission notice |
2702 | - * appear in supporting documentation, and that the name of |
2703 | - * Canonical Ltd. not be used in advertising or publicity pertaining to |
2704 | - * distribution of the software without specific, written prior permission. |
2705 | - * Canonical Ltd. makes no representations about the suitability of this |
2706 | - * software for any purpose. It is provided "as is" without express or |
2707 | - * implied warranty. |
2708 | - * |
2709 | - * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
2710 | - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
2711 | - * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
2712 | - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
2713 | - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
2714 | - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
2715 | - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
2716 | - * |
2717 | - * Authored by: Sam Spilsbury <smspillaz@gmail.com> |
2718 | - */ |
2719 | -#ifndef _COMPIZ_GEOMETRY_UPDATE_QUEUE_H |
2720 | -#define _COMPIZ_GEOMETRY_UPDATE_QUEUE_H |
2721 | - |
2722 | -#include <memory> |
2723 | -#include <vector> |
2724 | -#include <boost/weak_ptr.hpp> |
2725 | -#include <boost/shared_ptr.hpp> |
2726 | -#include <boost/function.hpp> |
2727 | -#include <X11/Xlib.h> |
2728 | - |
2729 | -#include <core/configurerequestbuffer.h> |
2730 | - |
2731 | -namespace compiz |
2732 | -{ |
2733 | -namespace window |
2734 | -{ |
2735 | -class AsyncServerWindow; |
2736 | -namespace configure_buffers |
2737 | -{ |
2738 | - |
2739 | -class Lockable |
2740 | -{ |
2741 | - public: |
2742 | - |
2743 | - typedef boost::shared_ptr <Lockable> Ptr; |
2744 | - typedef boost::weak_ptr <Lockable> Weak; |
2745 | - |
2746 | - virtual ~Lockable () {} |
2747 | - |
2748 | - virtual void lock () = 0; |
2749 | -}; |
2750 | - |
2751 | -class BufferLock : |
2752 | - public Lockable, |
2753 | - public Releasable |
2754 | -{ |
2755 | - public: |
2756 | - typedef boost::shared_ptr <BufferLock> Ptr; |
2757 | - |
2758 | - virtual ~BufferLock () {} |
2759 | -}; |
2760 | - |
2761 | -class CountedFreeze |
2762 | -{ |
2763 | - public: |
2764 | - |
2765 | - virtual ~CountedFreeze () {} |
2766 | - |
2767 | - virtual void freeze () = 0; |
2768 | - virtual void release () = 0; |
2769 | - |
2770 | - virtual void untrackLock (compiz::window::configure_buffers::BufferLock *lock) = 0; |
2771 | -}; |
2772 | - |
2773 | -class ConfigureRequestBuffer : |
2774 | - public CountedFreeze, |
2775 | - public Buffer |
2776 | -{ |
2777 | - public: |
2778 | - |
2779 | - typedef boost::function <BufferLock::Ptr (CountedFreeze *)> LockFactory; |
2780 | - |
2781 | - void freeze (); |
2782 | - void release (); |
2783 | - |
2784 | - void untrackLock (compiz::window::configure_buffers::BufferLock *lock); |
2785 | - |
2786 | - void pushClientRequest (const XWindowChanges &xwc, unsigned int mask); |
2787 | - void pushWrapperRequest (const XWindowChanges &xwc, unsigned int mask); |
2788 | - void pushFrameRequest (const XWindowChanges &xwc, unsigned int mask); |
2789 | - void pushSyntheticConfigureNotify (); |
2790 | - compiz::window::configure_buffers::Releasable::Ptr obtainLock (); |
2791 | - |
2792 | - /* Implement getAttributes and require that |
2793 | - * the queue is released before calling through |
2794 | - * to the SyncServerWindow */ |
2795 | - bool queryAttributes (XWindowAttributes &attrib); |
2796 | - bool queryFrameAttributes (XWindowAttributes &attrib); |
2797 | - XRectangle * queryShapeRectangles (int kind, |
2798 | - int *count, |
2799 | - int *ordering); |
2800 | - |
2801 | - void forceRelease (); |
2802 | - |
2803 | - static compiz::window::configure_buffers::Buffer::Ptr |
2804 | - Create (AsyncServerWindow *asyncServerWindow, |
2805 | - SyncServerWindow *syncServerWindow, |
2806 | - const LockFactory &factory); |
2807 | - |
2808 | - private: |
2809 | - |
2810 | - ConfigureRequestBuffer (AsyncServerWindow *asyncServerWindow, |
2811 | - SyncServerWindow *syncServerWindow, |
2812 | - const LockFactory &factory); |
2813 | - |
2814 | - class Private; |
2815 | - std::auto_ptr <Private> priv; |
2816 | -}; |
2817 | - |
2818 | -class ConfigureBufferLock : |
2819 | - public compiz::window::configure_buffers::BufferLock |
2820 | -{ |
2821 | - public: |
2822 | - |
2823 | - typedef boost::shared_ptr <ConfigureBufferLock> Ptr; |
2824 | - |
2825 | - ConfigureBufferLock (CountedFreeze *); |
2826 | - ~ConfigureBufferLock (); |
2827 | - |
2828 | - void lock (); |
2829 | - void release (); |
2830 | - |
2831 | - private: |
2832 | - |
2833 | - class Private; |
2834 | - std::auto_ptr <Private> priv; |
2835 | -}; |
2836 | -} |
2837 | -} |
2838 | -} |
2839 | -#endif |
2840 | |
2841 | === removed file 'src/configurerequestbuffer.cpp' |
2842 | --- src/configurerequestbuffer.cpp 2013-02-14 12:12:53 +0000 |
2843 | +++ src/configurerequestbuffer.cpp 1970-01-01 00:00:00 +0000 |
2844 | @@ -1,363 +0,0 @@ |
2845 | -/* |
2846 | - * Copyright © 2012 Sam Spilsbury |
2847 | - * |
2848 | - * Permission to use, copy, modify, distribute, and sell this software |
2849 | - * and its documentation for any purpose is hereby granted without |
2850 | - * fee, provided that the above copyright notice appear in all copies |
2851 | - * and that both that copyright notice and this permission notice |
2852 | - * appear in supporting documentation, and that the name of |
2853 | - * Canonical Ltd. not be used in advertising or publicity pertaining to |
2854 | - * distribution of the software without specific, written prior permission. |
2855 | - * Canonical Ltd. makes no representations about the suitability of this |
2856 | - * software for any purpose. It is provided "as is" without express or |
2857 | - * implied warranty. |
2858 | - * |
2859 | - * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
2860 | - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
2861 | - * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
2862 | - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
2863 | - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
2864 | - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
2865 | - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
2866 | - * |
2867 | - * Authored by: Sam Spilsbury <smspillaz@gmail.com> |
2868 | - */ |
2869 | -#include <cstdio> |
2870 | -#include <cassert> |
2871 | -#include <boost/foreach.hpp> |
2872 | -#include <boost/weak_ptr.hpp> |
2873 | -#include <boost/bind.hpp> |
2874 | -#include "asyncserverwindow.h" |
2875 | -#include "configurerequestbuffer-impl.h" |
2876 | - |
2877 | -#ifndef foreach |
2878 | -#define foreach BOOST_FOREACH |
2879 | -#endif |
2880 | - |
2881 | -namespace crb = compiz::window::configure_buffers; |
2882 | -namespace cw = compiz::window; |
2883 | - |
2884 | -class crb::ConfigureRequestBuffer::Private |
2885 | -{ |
2886 | - public: |
2887 | - |
2888 | - typedef crb::Lockable::Weak LockObserver; |
2889 | - |
2890 | - Private (cw::AsyncServerWindow *asyncServerWindow, |
2891 | - cw::SyncServerWindow *syncServerWindow, |
2892 | - const crb::ConfigureRequestBuffer::LockFactory &lockFactory) : |
2893 | - clientChangeMask (0), |
2894 | - wrapperChangeMask (0), |
2895 | - frameChangeMask (0), |
2896 | - sendSyntheticConfigure (false), |
2897 | - lockCount (0), |
2898 | - asyncServerWindow (asyncServerWindow), |
2899 | - syncServerWindow (syncServerWindow), |
2900 | - lockFactory (lockFactory) |
2901 | - { |
2902 | - } |
2903 | - |
2904 | - void dispatchConfigure (bool force = false); |
2905 | - |
2906 | - XWindowChanges clientChanges; |
2907 | - unsigned int clientChangeMask; |
2908 | - |
2909 | - XWindowChanges wrapperChanges; |
2910 | - unsigned int wrapperChangeMask; |
2911 | - |
2912 | - XWindowChanges frameChanges; |
2913 | - unsigned int frameChangeMask; |
2914 | - |
2915 | - bool sendSyntheticConfigure; |
2916 | - |
2917 | - unsigned int lockCount; |
2918 | - |
2919 | - cw::AsyncServerWindow *asyncServerWindow; |
2920 | - cw::SyncServerWindow *syncServerWindow; |
2921 | - |
2922 | - crb::ConfigureRequestBuffer::LockFactory lockFactory; |
2923 | - std::vector <LockObserver> locks; |
2924 | -}; |
2925 | - |
2926 | -void |
2927 | -crb::ConfigureRequestBuffer::Private::dispatchConfigure (bool force) |
2928 | -{ |
2929 | - const unsigned int allEventMasks = 0x7f; |
2930 | - bool immediate = frameChangeMask & (CWStackMode | CWSibling); |
2931 | - |
2932 | - /* This is a stop-gap solution for not having a plugin API to |
2933 | - * query the window shape. Once we have that, we can safely |
2934 | - * remove these and require the queue to be unlocked when that |
2935 | - * happens. Its a separate unit of work for improving resize |
2936 | - * performance anyways. |
2937 | - */ |
2938 | - immediate |= (frameChangeMask & (CWWidth | CWHeight | CWBorderWidth)); |
2939 | - immediate |= (wrapperChangeMask & (CWWidth | CWHeight | CWBorderWidth | CWX | CWY)); |
2940 | - immediate |= (clientChangeMask & (CWWidth | CWHeight | CWBorderWidth | CWX | CWY)); |
2941 | - immediate |= force; |
2942 | - |
2943 | - bool clientDispatch = (clientChangeMask & allEventMasks); |
2944 | - bool wrapperDispatch = (wrapperChangeMask & allEventMasks); |
2945 | - bool frameDispatch = (frameChangeMask & allEventMasks); |
2946 | - |
2947 | - bool dispatch = !lockCount && (clientDispatch || |
2948 | - wrapperDispatch || |
2949 | - frameDispatch || |
2950 | - sendSyntheticConfigure); |
2951 | - |
2952 | - if (dispatch || immediate) |
2953 | - { |
2954 | - if (frameDispatch) |
2955 | - { |
2956 | - asyncServerWindow->requestConfigureOnFrame (frameChanges, |
2957 | - frameChangeMask); |
2958 | - frameChangeMask = 0; |
2959 | - } |
2960 | - |
2961 | - if (wrapperDispatch) |
2962 | - { |
2963 | - asyncServerWindow->requestConfigureOnWrapper (wrapperChanges, |
2964 | - wrapperChangeMask); |
2965 | - wrapperChangeMask = 0; |
2966 | - } |
2967 | - |
2968 | - if (clientDispatch) |
2969 | - { |
2970 | - asyncServerWindow->requestConfigureOnClient (clientChanges, |
2971 | - clientChangeMask); |
2972 | - clientChangeMask = 0; |
2973 | - } |
2974 | - |
2975 | - if (sendSyntheticConfigure) |
2976 | - { |
2977 | - asyncServerWindow->sendSyntheticConfigureNotify (); |
2978 | - sendSyntheticConfigure = false; |
2979 | - } |
2980 | - |
2981 | - foreach (const LockObserver &lock, locks) |
2982 | - { |
2983 | - crb::Lockable::Ptr strongLock (lock.lock ()); |
2984 | - |
2985 | - /* We might be in a lock's destructor so check |
2986 | - * if this can really be re-locked, if not, its |
2987 | - * no big deal as the lock is going away anyways |
2988 | - */ |
2989 | - if (strongLock) |
2990 | - strongLock->lock (); |
2991 | - } |
2992 | - } |
2993 | -} |
2994 | - |
2995 | -void |
2996 | -crb::ConfigureRequestBuffer::freeze () |
2997 | -{ |
2998 | - priv->lockCount++; |
2999 | - |
3000 | - assert (priv->lockCount <= priv->locks.size ()); |
3001 | -} |
3002 | - |
3003 | -void |
3004 | -crb::ConfigureRequestBuffer::release () |
3005 | -{ |
3006 | - assert (priv->lockCount); |
3007 | - |
3008 | - priv->lockCount--; |
3009 | - |
3010 | - priv->dispatchConfigure (); |
3011 | -} |
3012 | - |
3013 | -namespace |
3014 | -{ |
3015 | -void applyChangeToXWC (const XWindowChanges &from, |
3016 | - XWindowChanges &to, |
3017 | - unsigned int mask) |
3018 | -{ |
3019 | - if (mask & CWX) |
3020 | - to.x = from.x; |
3021 | - |
3022 | - if (mask & CWY) |
3023 | - to.y = from.y; |
3024 | - |
3025 | - if (mask & CWWidth) |
3026 | - to.width = from.width; |
3027 | - |
3028 | - if (mask & CWHeight) |
3029 | - to.height = from.height; |
3030 | - |
3031 | - if (mask & CWBorderWidth) |
3032 | - to.border_width = from.border_width; |
3033 | - |
3034 | - if (mask & CWSibling) |
3035 | - to.sibling = from.sibling; |
3036 | - |
3037 | - if (mask & CWStackMode) |
3038 | - to.stack_mode = from.stack_mode; |
3039 | -} |
3040 | -} |
3041 | - |
3042 | -void |
3043 | -crb::ConfigureRequestBuffer::pushClientRequest (const XWindowChanges &xwc, |
3044 | - unsigned int mask) |
3045 | -{ |
3046 | - applyChangeToXWC (xwc, priv->clientChanges, mask); |
3047 | - priv->clientChangeMask |= mask; |
3048 | - |
3049 | - priv->dispatchConfigure (); |
3050 | -} |
3051 | - |
3052 | -void |
3053 | -crb::ConfigureRequestBuffer::pushWrapperRequest (const XWindowChanges &xwc, |
3054 | - unsigned int mask) |
3055 | -{ |
3056 | - applyChangeToXWC (xwc, priv->wrapperChanges, mask); |
3057 | - priv->wrapperChangeMask |= mask; |
3058 | - |
3059 | - priv->dispatchConfigure (); |
3060 | -} |
3061 | - |
3062 | -void |
3063 | -crb::ConfigureRequestBuffer::pushFrameRequest (const XWindowChanges &xwc, |
3064 | - unsigned int mask) |
3065 | -{ |
3066 | - applyChangeToXWC (xwc, priv->frameChanges, mask); |
3067 | - priv->frameChangeMask |= mask; |
3068 | - |
3069 | - priv->dispatchConfigure (); |
3070 | -} |
3071 | - |
3072 | -void |
3073 | -crb::ConfigureRequestBuffer::pushSyntheticConfigureNotify () |
3074 | -{ |
3075 | - priv->sendSyntheticConfigure = true; |
3076 | - |
3077 | - priv->dispatchConfigure (); |
3078 | -} |
3079 | - |
3080 | -crb::Releasable::Ptr |
3081 | -crb::ConfigureRequestBuffer::obtainLock () |
3082 | -{ |
3083 | - crb::BufferLock::Ptr lock (priv->lockFactory (this)); |
3084 | - |
3085 | - priv->locks.push_back (crb::Lockable::Weak (lock)); |
3086 | - lock->lock (); |
3087 | - |
3088 | - return lock; |
3089 | -} |
3090 | - |
3091 | -namespace |
3092 | -{ |
3093 | -bool isLock (const crb::Lockable::Weak &lockable, |
3094 | - crb::BufferLock *lock) |
3095 | -{ |
3096 | - crb::Lockable::Ptr strongLockable (lockable.lock ()); |
3097 | - |
3098 | - /* Asserting that the lock did not go away without telling |
3099 | - * us first */ |
3100 | - assert (strongLockable.get ()); |
3101 | - |
3102 | - if (strongLockable.get () == lock) |
3103 | - return true; |
3104 | - |
3105 | - return false; |
3106 | -} |
3107 | -} |
3108 | - |
3109 | -void |
3110 | -crb::ConfigureRequestBuffer::untrackLock (crb::BufferLock *lock) |
3111 | -{ |
3112 | - std::remove_if (priv->locks.begin (), |
3113 | - priv->locks.end (), |
3114 | - boost::bind (isLock, _1, lock)); |
3115 | -} |
3116 | - |
3117 | -bool crb::ConfigureRequestBuffer::queryAttributes (XWindowAttributes &attrib) |
3118 | -{ |
3119 | - priv->dispatchConfigure (true); |
3120 | - return priv->syncServerWindow->queryAttributes (attrib); |
3121 | -} |
3122 | - |
3123 | -bool crb::ConfigureRequestBuffer::queryFrameAttributes (XWindowAttributes &attrib) |
3124 | -{ |
3125 | - priv->dispatchConfigure (true); |
3126 | - return priv->syncServerWindow->queryFrameAttributes (attrib); |
3127 | -} |
3128 | - |
3129 | -/* This is more or less of a stop-gap for the fact that |
3130 | - * when resizing window we re-query the window shape |
3131 | - * and apply that to the frame. That's a separate unit of |
3132 | - * work and should be dealt with separately. For now, force |
3133 | - * a release of the queue whenever we do that so that |
3134 | - * XShapeGetRectangles doesn't return an unexpected value |
3135 | - */ |
3136 | -XRectangle * |
3137 | -crb::ConfigureRequestBuffer::queryShapeRectangles (int kind, |
3138 | - int *count, |
3139 | - int *ordering) |
3140 | -{ |
3141 | - priv->dispatchConfigure (true); |
3142 | - return priv->syncServerWindow->queryShapeRectangles (kind, count, ordering); |
3143 | -} |
3144 | - |
3145 | -void crb::ConfigureRequestBuffer::forceRelease () |
3146 | -{ |
3147 | - priv->dispatchConfigure (true); |
3148 | -} |
3149 | - |
3150 | -crb::ConfigureRequestBuffer::ConfigureRequestBuffer (AsyncServerWindow *asyncServerWindow, |
3151 | - SyncServerWindow *syncServerWindow, |
3152 | - const crb::ConfigureRequestBuffer::LockFactory &factory) : |
3153 | - priv (new crb::ConfigureRequestBuffer::Private (asyncServerWindow, syncServerWindow, factory)) |
3154 | -{ |
3155 | -} |
3156 | - |
3157 | -compiz::window::configure_buffers::Buffer::Ptr |
3158 | -crb::ConfigureRequestBuffer::Create (AsyncServerWindow *asyncServerWindow, |
3159 | - SyncServerWindow *syncServerWindow, |
3160 | - const LockFactory &factory) |
3161 | -{ |
3162 | - return crb::Buffer::Ptr (new crb::ConfigureRequestBuffer (asyncServerWindow, |
3163 | - syncServerWindow, |
3164 | - factory)); |
3165 | -} |
3166 | - |
3167 | -class crb::ConfigureBufferLock::Private |
3168 | -{ |
3169 | - public: |
3170 | - |
3171 | - Private (crb::CountedFreeze *freezable) : |
3172 | - freezable (freezable), |
3173 | - armed (false) |
3174 | - { |
3175 | - } |
3176 | - |
3177 | - crb::CountedFreeze *freezable; |
3178 | - bool armed; |
3179 | -}; |
3180 | - |
3181 | -crb::ConfigureBufferLock::ConfigureBufferLock (crb::CountedFreeze *freezable) : |
3182 | - priv (new crb::ConfigureBufferLock::Private (freezable)) |
3183 | -{ |
3184 | -} |
3185 | - |
3186 | -crb::ConfigureBufferLock::~ConfigureBufferLock () |
3187 | -{ |
3188 | - release (); |
3189 | -} |
3190 | - |
3191 | -void |
3192 | -crb::ConfigureBufferLock::lock () |
3193 | -{ |
3194 | - if (!priv->armed) |
3195 | - priv->freezable->freeze (); |
3196 | - |
3197 | - priv->armed = true; |
3198 | -} |
3199 | - |
3200 | -void |
3201 | -crb::ConfigureBufferLock::release () |
3202 | -{ |
3203 | - if (priv->armed) |
3204 | - priv->freezable->release (); |
3205 | - |
3206 | - priv->armed = false; |
3207 | -} |
3208 | |
3209 | === modified file 'src/event.cpp' |
3210 | --- src/event.cpp 2013-02-10 05:01:50 +0000 |
3211 | +++ src/event.cpp 2013-02-28 03:13:24 +0000 |
3212 | @@ -1947,7 +1947,7 @@ |
3213 | |
3214 | /* We should check the override_redirect flag here, because the |
3215 | client might have changed it while being unmapped. */ |
3216 | - if (w->queryAttributes (attr)) |
3217 | + if (XGetWindowAttributes (privateScreen.dpy, w->id (), &attr)) |
3218 | w->priv->setOverrideRedirect (attr.override_redirect != 0); |
3219 | |
3220 | if (w->state () & CompWindowStateHiddenMask) |
3221 | |
3222 | === modified file 'src/privatewindow.h' |
3223 | --- src/privatewindow.h 2013-02-10 05:01:50 +0000 |
3224 | +++ src/privatewindow.h 2013-02-28 03:13:24 +0000 |
3225 | @@ -35,11 +35,6 @@ |
3226 | |
3227 | #include <boost/shared_ptr.hpp> |
3228 | |
3229 | -#include <core/configurerequestbuffer.h> |
3230 | - |
3231 | -#include "syncserverwindow.h" |
3232 | -#include "asyncserverwindow.h" |
3233 | - |
3234 | #define XWINDOWCHANGES_INIT {0, 0, 0, 0, 0, None, 0} |
3235 | |
3236 | namespace compiz {namespace X11 |
3237 | @@ -112,47 +107,12 @@ |
3238 | |
3239 | typedef CompWindowExtents CompFullscreenMonitorSet; |
3240 | |
3241 | -class X11SyncServerWindow : |
3242 | - public compiz::window::SyncServerWindow |
3243 | -{ |
3244 | - public: |
3245 | - |
3246 | - X11SyncServerWindow (Display *dpy, |
3247 | - const Window *w, |
3248 | - const Window *frame); |
3249 | - |
3250 | - bool queryAttributes (XWindowAttributes &attrib); |
3251 | - bool queryFrameAttributes (XWindowAttributes &attrib); |
3252 | - XRectangle * queryShapeRectangles(int kind, int *count, int *ordering); |
3253 | - |
3254 | - private: |
3255 | - |
3256 | - Display *mDpy; |
3257 | - const Window *mWindow; |
3258 | - const Window *mFrame; |
3259 | -}; |
3260 | - |
3261 | -class PrivateWindow : |
3262 | - public compiz::window::SyncServerWindow, |
3263 | - public compiz::window::AsyncServerWindow |
3264 | -{ |
3265 | +class PrivateWindow { |
3266 | |
3267 | public: |
3268 | PrivateWindow (); |
3269 | ~PrivateWindow (); |
3270 | |
3271 | - bool queryAttributes (XWindowAttributes &attrib); |
3272 | - bool queryFrameAttributes (XWindowAttributes &attrib); |
3273 | - XRectangle * queryShapeRectangles (int kind, int *count, int *ordering); |
3274 | - int requestConfigureOnClient (const XWindowChanges &xwc, |
3275 | - unsigned int valueMask); |
3276 | - int requestConfigureOnWrapper (const XWindowChanges &xwc, |
3277 | - unsigned int valueMask); |
3278 | - int requestConfigureOnFrame (const XWindowChanges &xwc, |
3279 | - unsigned int valueMask); |
3280 | - void sendSyntheticConfigureNotify (); |
3281 | - bool hasCustomShape () const; |
3282 | - |
3283 | void recalcNormalHints (); |
3284 | |
3285 | void updateFrameWindow (); |
3286 | @@ -422,7 +382,6 @@ |
3287 | |
3288 | CompWindowExtents input; |
3289 | CompWindowExtents serverInput; |
3290 | - CompWindowExtents lastServerInput; |
3291 | CompWindowExtents border; |
3292 | CompWindowExtents output; |
3293 | |
3294 | @@ -448,9 +407,6 @@ |
3295 | Time lastCloseRequestTime; |
3296 | |
3297 | bool nextMoveImmediate; |
3298 | - |
3299 | - X11SyncServerWindow syncServerWindow; |
3300 | - compiz::window::configure_buffers::Buffer::Ptr configureBuffer; |
3301 | }; |
3302 | |
3303 | #endif |
3304 | |
3305 | === removed file 'src/serverwindow.h' |
3306 | === removed file 'src/syncserverwindow.h' |
3307 | --- src/syncserverwindow.h 2012-12-13 11:12:32 +0000 |
3308 | +++ src/syncserverwindow.h 1970-01-01 00:00:00 +0000 |
3309 | @@ -1,49 +0,0 @@ |
3310 | -/* |
3311 | - * Copyright © 2012 Sam Spilsbury |
3312 | - * |
3313 | - * Permission to use, copy, modify, distribute, and sell this software |
3314 | - * and its documentation for any purpose is hereby granted without |
3315 | - * fee, provided that the above copyright notice appear in all copies |
3316 | - * and that both that copyright notice and this permission notice |
3317 | - * appear in supporting documentation, and that the name of |
3318 | - * Canonical Ltd. not be used in advertising or publicity pertaining to |
3319 | - * distribution of the software without specific, written prior permission. |
3320 | - * Canonical Ltd. makes no representations about the suitability of this |
3321 | - * software for any purpose. It is provided "as is" without express or |
3322 | - * implied warranty. |
3323 | - * |
3324 | - * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
3325 | - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
3326 | - * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
3327 | - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
3328 | - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
3329 | - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
3330 | - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
3331 | - * |
3332 | - * Authored by: Sam Spilsbury <smspillaz@gmail.com> |
3333 | - */ |
3334 | -#ifndef _COMPIZ_SYNC_SERVER_WINDOW_H |
3335 | -#define _COMPIZ_SYNC_SERVER_WINDOW_H |
3336 | - |
3337 | -#include <X11/Xlib.h> |
3338 | - |
3339 | -namespace compiz |
3340 | -{ |
3341 | -namespace window |
3342 | -{ |
3343 | -class SyncServerWindow |
3344 | -{ |
3345 | - public: |
3346 | - |
3347 | - virtual ~SyncServerWindow () {} |
3348 | - |
3349 | - virtual bool queryAttributes (XWindowAttributes &attrib) = 0; |
3350 | - virtual bool queryFrameAttributes (XWindowAttributes &attrib) = 0; |
3351 | - virtual XRectangle * queryShapeRectangles (int kind, |
3352 | - int *count, |
3353 | - int *ordering) = 0; |
3354 | -}; |
3355 | -} |
3356 | -} |
3357 | - |
3358 | -#endif |
3359 | |
3360 | === modified file 'src/tests/CMakeLists.txt' |
3361 | --- src/tests/CMakeLists.txt 2013-02-10 05:01:50 +0000 |
3362 | +++ src/tests/CMakeLists.txt 2013-02-28 03:13:24 +0000 |
3363 | @@ -30,14 +30,3 @@ |
3364 | |
3365 | compiz_discover_tests(compiz_test_outputdevices COVERAGE compiz_core) |
3366 | |
3367 | -add_executable (compiz_test_configurerequestbuffer |
3368 | - test_configurerequestbuffer.cpp) |
3369 | - |
3370 | -target_link_libraries (compiz_test_configurerequestbuffer |
3371 | - compiz_configurerequestbuffer |
3372 | - ${GTEST_BOTH_LIBRARIES} |
3373 | - ${GMOCK_MAIN_LIBRARY} |
3374 | - ${GMOCK_LIBRARY} |
3375 | -) |
3376 | - |
3377 | -compiz_discover_tests(compiz_test_configurerequestbuffer COVERAGE compiz_configurerequestbuffer) |
3378 | |
3379 | === removed file 'src/tests/test_configurerequestbuffer.cpp' |
3380 | --- src/tests/test_configurerequestbuffer.cpp 2012-12-13 14:07:01 +0000 |
3381 | +++ src/tests/test_configurerequestbuffer.cpp 1970-01-01 00:00:00 +0000 |
3382 | @@ -1,667 +0,0 @@ |
3383 | -/* |
3384 | - * Copyright © 2012 Sam Spilsbury |
3385 | - * |
3386 | - * Permission to use, copy, modify, distribute, and sell this software |
3387 | - * and its documentation for any purpose is hereby granted without |
3388 | - * fee, provided that the above copyright notice appear in all copies |
3389 | - * and that both that copyright notice and this permission notice |
3390 | - * appear in supporting documentation, and that the name of |
3391 | - * Canonical Ltd. not be used in advertising or publicity pertaining to |
3392 | - * distribution of the software without specific, written prior permission. |
3393 | - * Canonical Ltd. makes no representations about the suitability of this |
3394 | - * software for any purpose. It is provided "as is" without express or |
3395 | - * implied warranty. |
3396 | - * |
3397 | - * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
3398 | - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
3399 | - * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
3400 | - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
3401 | - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
3402 | - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
3403 | - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
3404 | - * |
3405 | - * Authored by: Sam Spilsbury <smspillaz@gmail.com> |
3406 | - */ |
3407 | -#include <deque> |
3408 | -#include <boost/shared_ptr.hpp> |
3409 | -#include <boost/make_shared.hpp> |
3410 | -#include <boost/bind.hpp> |
3411 | -#include <gmock/gmock.h> |
3412 | -#include <gtest/gtest.h> |
3413 | -#include <X11/Xlib.h> |
3414 | - |
3415 | -#include "configurerequestbuffer-impl.h" |
3416 | -#include "asyncserverwindow.h" |
3417 | - |
3418 | -namespace crb = compiz::window::configure_buffers; |
3419 | -namespace cw = compiz::window; |
3420 | - |
3421 | -using testing::_; |
3422 | -using testing::NiceMock; |
3423 | -using testing::Return; |
3424 | -using testing::Invoke; |
3425 | -using testing::WithArgs; |
3426 | -using testing::SetArgReferee; |
3427 | -using testing::DoAll; |
3428 | -using testing::InSequence; |
3429 | -using testing::ReturnNull; |
3430 | -using testing::IsNull; |
3431 | - |
3432 | -class MockAsyncServerWindow : |
3433 | - public cw::AsyncServerWindow |
3434 | -{ |
3435 | - public: |
3436 | - |
3437 | - MOCK_METHOD2 (requestConfigureOnClient, int (const XWindowChanges &, unsigned int)); |
3438 | - MOCK_METHOD2 (requestConfigureOnFrame, int (const XWindowChanges &, unsigned int)); |
3439 | - MOCK_METHOD2 (requestConfigureOnWrapper, int (const XWindowChanges &, unsigned int)); |
3440 | - MOCK_METHOD0 (sendSyntheticConfigureNotify, void ()); |
3441 | - MOCK_CONST_METHOD0 (hasCustomShape, bool ()); |
3442 | -}; |
3443 | - |
3444 | -class MockSyncServerWindow : |
3445 | - public cw::SyncServerWindow |
3446 | -{ |
3447 | - public: |
3448 | - |
3449 | - MOCK_METHOD1 (queryAttributes, bool (XWindowAttributes &)); |
3450 | - MOCK_METHOD1 (queryFrameAttributes, bool (XWindowAttributes &)); |
3451 | - MOCK_METHOD3 (queryShapeRectangles, XRectangle * (int, int *, int *)); |
3452 | -}; |
3453 | - |
3454 | -namespace |
3455 | -{ |
3456 | -int REQUEST_X = 1; |
3457 | -int REQUEST_Y = 2; |
3458 | -int REQUEST_WIDTH = 3; |
3459 | -int REQUEST_HEIGHT = 4; |
3460 | -int REQUEST_BORDER = 5; |
3461 | - |
3462 | -Window REQUEST_ABOVE = 6; |
3463 | -unsigned int REQUEST_MODE = 7; |
3464 | - |
3465 | -crb::BufferLock::Ptr |
3466 | -CreateNormalLock (crb::CountedFreeze *cf) |
3467 | -{ |
3468 | - return boost::make_shared <crb::ConfigureBufferLock> (cf); |
3469 | -} |
3470 | - |
3471 | -} |
3472 | - |
3473 | -MATCHER_P2 (MaskXWC, xwc, vm, "Matches XWindowChanges") |
3474 | -{ |
3475 | - if (vm & CWX) |
3476 | - if (xwc.x != arg.x) |
3477 | - return false; |
3478 | - |
3479 | - if (vm & CWY) |
3480 | - if (xwc.y != arg.y) |
3481 | - return false; |
3482 | - |
3483 | - if (vm & CWWidth) |
3484 | - if (xwc.width != arg.width) |
3485 | - return false; |
3486 | - |
3487 | - if (vm & CWHeight) |
3488 | - if (xwc.height != arg.height) |
3489 | - return false; |
3490 | - |
3491 | - if (vm & CWBorderWidth) |
3492 | - if (xwc.border_width != arg.border_width) |
3493 | - return false; |
3494 | - |
3495 | - if (vm & CWStackMode) |
3496 | - if (xwc.stack_mode != arg.stack_mode) |
3497 | - return false; |
3498 | - |
3499 | - if (vm & CWSibling) |
3500 | - if (xwc.sibling != arg.sibling) |
3501 | - return false; |
3502 | - |
3503 | - return true; |
3504 | -} |
3505 | - |
3506 | -class ConfigureRequestBuffer : |
3507 | - public testing::Test |
3508 | -{ |
3509 | - public: |
3510 | - |
3511 | - ConfigureRequestBuffer () |
3512 | - { |
3513 | - /* Initialize xwc, we control it |
3514 | - * through the value masks */ |
3515 | - xwc.x = REQUEST_X; |
3516 | - xwc.y = REQUEST_Y; |
3517 | - xwc.width = REQUEST_WIDTH; |
3518 | - xwc.height = REQUEST_HEIGHT; |
3519 | - xwc.border_width = REQUEST_BORDER; |
3520 | - xwc.sibling = REQUEST_ABOVE; |
3521 | - xwc.stack_mode = REQUEST_MODE; |
3522 | - } |
3523 | - |
3524 | - protected: |
3525 | - |
3526 | - XWindowChanges xwc; |
3527 | - MockAsyncServerWindow asyncServerWindow; |
3528 | - MockSyncServerWindow syncServerWindow; |
3529 | -}; |
3530 | - |
3531 | -class ConfigureRequestBufferDispatch : |
3532 | - public ConfigureRequestBuffer |
3533 | -{ |
3534 | - protected: |
3535 | - |
3536 | - ConfigureRequestBufferDispatch () : |
3537 | - ConfigureRequestBuffer (), |
3538 | - factory (boost::bind (CreateNormalLock, _1)), |
3539 | - buffer ( |
3540 | - crb::ConfigureRequestBuffer::Create (&asyncServerWindow, |
3541 | - &syncServerWindow, |
3542 | - factory)) |
3543 | - { |
3544 | - } |
3545 | - |
3546 | - crb::ConfigureRequestBuffer::LockFactory factory; |
3547 | - crb::Buffer::Ptr buffer; |
3548 | -}; |
3549 | - |
3550 | -TEST_F (ConfigureRequestBufferDispatch, PushDirectSyntheticConfigureNotify) |
3551 | -{ |
3552 | - EXPECT_CALL (asyncServerWindow, sendSyntheticConfigureNotify ()); |
3553 | - |
3554 | - buffer->pushSyntheticConfigureNotify (); |
3555 | -} |
3556 | - |
3557 | -TEST_F (ConfigureRequestBufferDispatch, PushDirectClientUpdate) |
3558 | -{ |
3559 | - unsigned int valueMask = CWX | CWY | CWBorderWidth | |
3560 | - CWSibling | CWStackMode; |
3561 | - |
3562 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (MaskXWC (xwc, valueMask), |
3563 | - valueMask)); |
3564 | - |
3565 | - buffer->pushClientRequest (xwc, valueMask); |
3566 | -} |
3567 | - |
3568 | -TEST_F (ConfigureRequestBufferDispatch, PushDirectWrapperUpdate) |
3569 | -{ |
3570 | - unsigned int valueMask = CWX | CWY | CWBorderWidth | |
3571 | - CWSibling | CWStackMode; |
3572 | - |
3573 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (MaskXWC (xwc, valueMask), |
3574 | - valueMask)); |
3575 | - |
3576 | - buffer->pushWrapperRequest (xwc, valueMask); |
3577 | -} |
3578 | - |
3579 | -TEST_F (ConfigureRequestBufferDispatch, PushDirectFrameUpdate) |
3580 | -{ |
3581 | - unsigned int valueMask = CWX | CWY | CWBorderWidth | |
3582 | - CWSibling | CWStackMode; |
3583 | - |
3584 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), |
3585 | - valueMask)); |
3586 | - |
3587 | - buffer->pushFrameRequest (xwc, valueMask); |
3588 | -} |
3589 | - |
3590 | -TEST_F (ConfigureRequestBufferDispatch, PushUpdateLocked) |
3591 | -{ |
3592 | - crb::Releasable::Ptr lock (buffer->obtainLock ()); |
3593 | - |
3594 | - unsigned int valueMask = 0; |
3595 | - |
3596 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3597 | - |
3598 | - buffer->pushFrameRequest (xwc, valueMask); |
3599 | -} |
3600 | - |
3601 | -TEST_F (ConfigureRequestBufferDispatch, PushCombinedUpdateLocked) |
3602 | -{ |
3603 | - crb::Releasable::Ptr lock (buffer->obtainLock ()); |
3604 | - |
3605 | - unsigned int valueMask = CWX; |
3606 | - |
3607 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3608 | - |
3609 | - buffer->pushFrameRequest (xwc, valueMask); |
3610 | - |
3611 | - valueMask |= CWY; |
3612 | - |
3613 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3614 | - |
3615 | - buffer->pushFrameRequest (xwc, valueMask); |
3616 | - |
3617 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), |
3618 | - valueMask)); |
3619 | - |
3620 | - lock->release (); |
3621 | -} |
3622 | - |
3623 | -/* |
3624 | - * This test is disabled until we can expose the QueryShapeRectangles API |
3625 | - * to plugins |
3626 | - */ |
3627 | -TEST_F (ConfigureRequestBufferDispatch, DISABLED_PushUpdateLockedReleaseInOrder) |
3628 | -{ |
3629 | - crb::Releasable::Ptr lock (buffer->obtainLock ()); |
3630 | - |
3631 | - unsigned int valueMask = CWX | CWY; |
3632 | - |
3633 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3634 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (_, _)).Times (0); |
3635 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (_, _)).Times (0); |
3636 | - |
3637 | - buffer->pushClientRequest (xwc, valueMask); |
3638 | - buffer->pushWrapperRequest (xwc, 0); |
3639 | - buffer->pushFrameRequest (xwc, 0); |
3640 | - |
3641 | - InSequence s; |
3642 | - |
3643 | - /* Always frame -> wrapper -> client */ |
3644 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), |
3645 | - valueMask)); |
3646 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (MaskXWC (xwc, valueMask), |
3647 | - valueMask)); |
3648 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (MaskXWC (xwc, valueMask), |
3649 | - valueMask)); |
3650 | - |
3651 | - lock->release (); |
3652 | -} |
3653 | - |
3654 | -TEST_F (ConfigureRequestBufferDispatch, UnlockBuffer) |
3655 | -{ |
3656 | - crb::Releasable::Ptr lock (buffer->obtainLock ()); |
3657 | - |
3658 | - unsigned int valueMask = CWX | CWY; |
3659 | - |
3660 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3661 | - |
3662 | - buffer->pushFrameRequest (xwc, valueMask); |
3663 | - |
3664 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), |
3665 | - valueMask)); |
3666 | - |
3667 | - lock->release (); |
3668 | -} |
3669 | - |
3670 | -TEST_F (ConfigureRequestBufferDispatch, ImplicitUnlockBuffer) |
3671 | -{ |
3672 | - crb::Releasable::Ptr lock (buffer->obtainLock ()); |
3673 | - |
3674 | - unsigned int valueMask = CWX | CWY; |
3675 | - |
3676 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3677 | - |
3678 | - buffer->pushFrameRequest (xwc, valueMask); |
3679 | - |
3680 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), |
3681 | - valueMask)); |
3682 | -} |
3683 | - |
3684 | -TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnRestack) |
3685 | -{ |
3686 | - crb::Releasable::Ptr lock (buffer->obtainLock ()); |
3687 | - |
3688 | - unsigned int valueMask = CWStackMode | CWSibling; |
3689 | - |
3690 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), |
3691 | - valueMask)); |
3692 | - |
3693 | - buffer->pushFrameRequest (xwc, valueMask); |
3694 | -} |
3695 | - |
3696 | -TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnWindowSizeChange) |
3697 | -{ |
3698 | - crb::Releasable::Ptr lock (buffer->obtainLock ()); |
3699 | - |
3700 | - unsigned int valueMask = CWWidth | CWHeight | CWBorderWidth; |
3701 | - |
3702 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), |
3703 | - valueMask)); |
3704 | - |
3705 | - buffer->pushFrameRequest (xwc, valueMask); |
3706 | -} |
3707 | - |
3708 | -TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnClientReposition) |
3709 | -{ |
3710 | - crb::Releasable::Ptr lock (buffer->obtainLock ()); |
3711 | - |
3712 | - unsigned int valueMask = CWX | CWY; |
3713 | - |
3714 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (MaskXWC (xwc, valueMask), |
3715 | - valueMask)); |
3716 | - |
3717 | - buffer->pushClientRequest (xwc, valueMask); |
3718 | -} |
3719 | - |
3720 | -TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnWrapperReposition) |
3721 | -{ |
3722 | - crb::Releasable::Ptr lock (buffer->obtainLock ()); |
3723 | - |
3724 | - unsigned int valueMask = CWX | CWY; |
3725 | - |
3726 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (MaskXWC (xwc, valueMask), |
3727 | - valueMask)); |
3728 | - |
3729 | - buffer->pushWrapperRequest (xwc, valueMask); |
3730 | -} |
3731 | - |
3732 | -namespace |
3733 | -{ |
3734 | -class MockLock : |
3735 | - public crb::BufferLock |
3736 | -{ |
3737 | - public: |
3738 | - |
3739 | - /* We're currently importing the locks statefulness and coupling |
3740 | - * the caller with that */ |
3741 | - MockLock () : |
3742 | - armed (false) |
3743 | - { |
3744 | - ON_CALL (*this, lock ()).WillByDefault ( |
3745 | - Invoke (this, &MockLock::FreezeIfUnarmed)); |
3746 | - ON_CALL (*this, release ()).WillByDefault ( |
3747 | - Invoke (this, &MockLock::ReleaseIfArmed)); |
3748 | - } |
3749 | - |
3750 | - void OperateOver (crb::CountedFreeze *cf) |
3751 | - { |
3752 | - countedFreeze = cf; |
3753 | - } |
3754 | - |
3755 | - void FreezeIfUnarmed () |
3756 | - { |
3757 | - if (!armed) |
3758 | - { |
3759 | - countedFreeze->freeze (); |
3760 | - armed = true; |
3761 | - } |
3762 | - } |
3763 | - |
3764 | - void ReleaseIfArmed () |
3765 | - { |
3766 | - if (armed) |
3767 | - { |
3768 | - countedFreeze->release (); |
3769 | - armed = false; |
3770 | - } |
3771 | - } |
3772 | - |
3773 | - typedef boost::shared_ptr <MockLock> Ptr; |
3774 | - |
3775 | - MOCK_METHOD0 (lock, void ()); |
3776 | - MOCK_METHOD0 (release, void ()); |
3777 | - |
3778 | - private: |
3779 | - |
3780 | - crb::CountedFreeze *countedFreeze; |
3781 | - bool armed; |
3782 | -}; |
3783 | - |
3784 | -class MockLockFactory |
3785 | -{ |
3786 | - public: |
3787 | - |
3788 | - crb::BufferLock::Ptr |
3789 | - CreateMockLock (crb::CountedFreeze *cf) |
3790 | - { |
3791 | - MockLock::Ptr mockLock (locks.front ()); |
3792 | - mockLock->OperateOver (cf); |
3793 | - |
3794 | - locks.pop_front (); |
3795 | - |
3796 | - return mockLock; |
3797 | - } |
3798 | - |
3799 | - void |
3800 | - QueueLockForCreation (const MockLock::Ptr &lock) |
3801 | - { |
3802 | - locks.push_back (lock); |
3803 | - } |
3804 | - |
3805 | - private: |
3806 | - |
3807 | - std::deque <MockLock::Ptr> locks; |
3808 | -}; |
3809 | -} |
3810 | - |
3811 | -class ConfigureRequestBufferLockBehaviour : |
3812 | - public ConfigureRequestBuffer |
3813 | -{ |
3814 | - public: |
3815 | - |
3816 | - ConfigureRequestBufferLockBehaviour () : |
3817 | - ConfigureRequestBuffer (), |
3818 | - lock (boost::make_shared <MockLock> ()), |
3819 | - factory ( |
3820 | - boost::bind (&MockLockFactory::CreateMockLock, |
3821 | - &mockLockFactory, |
3822 | - _1)), |
3823 | - buffer ( |
3824 | - crb::ConfigureRequestBuffer::Create ( |
3825 | - &asyncServerWindow, |
3826 | - &syncServerWindow, |
3827 | - factory)) |
3828 | - |
3829 | - { |
3830 | - mockLockFactory.QueueLockForCreation (lock); |
3831 | - } |
3832 | - |
3833 | - protected: |
3834 | - |
3835 | - typedef NiceMock <MockAsyncServerWindow> NiceServerWindow; |
3836 | - typedef crb::ConfigureRequestBuffer::LockFactory LockFactory; |
3837 | - |
3838 | - MockLock::Ptr lock; |
3839 | - MockLockFactory mockLockFactory; |
3840 | - |
3841 | - LockFactory factory; |
3842 | - crb::Buffer::Ptr buffer; |
3843 | -}; |
3844 | - |
3845 | -TEST_F (ConfigureRequestBufferLockBehaviour, RearmBufferLockOnRelease) |
3846 | -{ |
3847 | - EXPECT_CALL (*lock, lock ()); |
3848 | - crb::Releasable::Ptr releasable (buffer->obtainLock ()); |
3849 | - |
3850 | - unsigned int valueMask = CWX | CWY; |
3851 | - |
3852 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3853 | - |
3854 | - buffer->pushFrameRequest (xwc, valueMask); |
3855 | - |
3856 | - /* We are releasing this lock */ |
3857 | - EXPECT_CALL (*lock, release ()); |
3858 | - |
3859 | - /* Now the buffer will dispatch is configure request */ |
3860 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); |
3861 | - |
3862 | - /* Rearm locks on release */ |
3863 | - EXPECT_CALL (*lock, lock ()); |
3864 | - |
3865 | - /* Directly release the queue */ |
3866 | - releasable->release (); |
3867 | -} |
3868 | - |
3869 | -TEST_F (ConfigureRequestBufferLockBehaviour, NoRearmBufferLockNoReleaseRequired) |
3870 | -{ |
3871 | - /* Locks get armed on construction */ |
3872 | - EXPECT_CALL (*lock, lock ()); |
3873 | - crb::Releasable::Ptr releasable (buffer->obtainLock ()); |
3874 | - |
3875 | - /* No call to requestConfigureOnFrame if there's nothing to be configured */ |
3876 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3877 | - |
3878 | - /* We are releasing this lock */ |
3879 | - EXPECT_CALL (*lock, release ()); |
3880 | - |
3881 | - /* No rearm - we haven't released the whole buffer */ |
3882 | - EXPECT_CALL (*lock, lock ()).Times (0); |
3883 | - |
3884 | - /* Directly release the queue */ |
3885 | - releasable->release (); |
3886 | -} |
3887 | - |
3888 | -TEST_F (ConfigureRequestBufferLockBehaviour, RearmWhenPushReady) |
3889 | -{ |
3890 | - /* Locks get armed on construction */ |
3891 | - EXPECT_CALL (*lock, lock ()); |
3892 | - crb::Releasable::Ptr releasable (buffer->obtainLock ()); |
3893 | - |
3894 | - /* We are releasing this lock */ |
3895 | - EXPECT_CALL (*lock, release ()); |
3896 | - |
3897 | - /* No call to requestConfigureOnFrame if there's nothing to be configured */ |
3898 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3899 | - |
3900 | - /* No rearm - we haven't released it */ |
3901 | - EXPECT_CALL (*lock, lock ()).Times (0); |
3902 | - |
3903 | - /* Directly release the queue */ |
3904 | - releasable->release (); |
3905 | - |
3906 | - /* Since we're now going to push something to a queue |
3907 | - * that's effectively not locked, the locks should now |
3908 | - * be released */ |
3909 | - unsigned int valueMask = CWX | CWY; |
3910 | - |
3911 | - /* Now rearm it */ |
3912 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); |
3913 | - EXPECT_CALL (*lock, lock ()); |
3914 | - |
3915 | - buffer->pushFrameRequest (xwc, valueMask); |
3916 | -} |
3917 | - |
3918 | -TEST_F (ConfigureRequestBufferLockBehaviour, NoRearmBufferLockOnNoRelease) |
3919 | -{ |
3920 | - MockLock::Ptr second (boost::make_shared <MockLock> ()); |
3921 | - mockLockFactory.QueueLockForCreation (second); |
3922 | - |
3923 | - /* Locks get armed on construction */ |
3924 | - EXPECT_CALL (*lock, lock ()); |
3925 | - EXPECT_CALL (*second, lock ()); |
3926 | - |
3927 | - crb::Releasable::Ptr releasable (buffer->obtainLock ()); |
3928 | - crb::Releasable::Ptr otherReleasable (buffer->obtainLock ()); |
3929 | - |
3930 | - /* We are releasing this lock */ |
3931 | - EXPECT_CALL (*lock, release ()); |
3932 | - |
3933 | - /* No call to requestConfigureOnFrame if there's nothing to be configured */ |
3934 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3935 | - |
3936 | - /* No rearm - we haven't released it */ |
3937 | - EXPECT_CALL (*lock, lock ()).Times (0); |
3938 | - |
3939 | - releasable->release (); |
3940 | -} |
3941 | - |
3942 | -TEST_F (ConfigureRequestBufferLockBehaviour, QueryAttributesDispatchAndRearm) |
3943 | -{ |
3944 | - /* Locks get armed on construction */ |
3945 | - EXPECT_CALL (*lock, lock ()); |
3946 | - |
3947 | - crb::Releasable::Ptr releasable (buffer->obtainLock ()); |
3948 | - |
3949 | - unsigned int valueMask = CWX | CWY; |
3950 | - |
3951 | - /* Queue locked */ |
3952 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3953 | - |
3954 | - buffer->pushFrameRequest (xwc, valueMask); |
3955 | - |
3956 | - /* Queue forceably unlocked, locks rearmed */ |
3957 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); |
3958 | - EXPECT_CALL (*lock, lock ()); |
3959 | - |
3960 | - /* Expect a call to XGetWindowAttributes */ |
3961 | - EXPECT_CALL (syncServerWindow, queryShapeRectangles (_, _, _)) |
3962 | - .WillOnce ( |
3963 | - ReturnNull ()); |
3964 | - |
3965 | - int a, b; |
3966 | - |
3967 | - EXPECT_THAT (buffer->queryShapeRectangles (0, &a, &b), IsNull ()); |
3968 | -} |
3969 | - |
3970 | -TEST_F (ConfigureRequestBufferLockBehaviour, QueryFrameAttributesDispatchAndRearm) |
3971 | -{ |
3972 | - /* Locks get armed on construction */ |
3973 | - EXPECT_CALL (*lock, lock ()); |
3974 | - |
3975 | - crb::Releasable::Ptr releasable (buffer->obtainLock ()); |
3976 | - |
3977 | - unsigned int valueMask = CWX | CWY; |
3978 | - |
3979 | - /* Queue locked */ |
3980 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
3981 | - |
3982 | - buffer->pushFrameRequest (xwc, valueMask); |
3983 | - |
3984 | - /* Queue forceably unlocked, locks rearmed */ |
3985 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); |
3986 | - EXPECT_CALL (*lock, lock ()); |
3987 | - |
3988 | - /* Expect a call to XGetWindowAttributes */ |
3989 | - XWindowAttributes xwa; |
3990 | - EXPECT_CALL (syncServerWindow, queryFrameAttributes (_)) |
3991 | - .WillOnce ( |
3992 | - DoAll ( |
3993 | - SetArgReferee <0> (xwa), |
3994 | - Return (true))); |
3995 | - |
3996 | - buffer->queryFrameAttributes (xwa); |
3997 | -} |
3998 | - |
3999 | -TEST_F (ConfigureRequestBufferLockBehaviour, QueryShapeRectanglesDispatchAndRearm) |
4000 | -{ |
4001 | - /* Locks get armed on construction */ |
4002 | - EXPECT_CALL (*lock, lock ()); |
4003 | - |
4004 | - crb::Releasable::Ptr releasable (buffer->obtainLock ()); |
4005 | - |
4006 | - unsigned int valueMask = CWX | CWY; |
4007 | - |
4008 | - /* Queue locked */ |
4009 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
4010 | - |
4011 | - buffer->pushFrameRequest (xwc, valueMask); |
4012 | - |
4013 | - /* Queue forceably unlocked, locks rearmed */ |
4014 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); |
4015 | - EXPECT_CALL (*lock, lock ()); |
4016 | - |
4017 | - /* Expect a call to XGetWindowAttributes */ |
4018 | - XWindowAttributes xwa; |
4019 | - EXPECT_CALL (syncServerWindow, queryFrameAttributes (_)) |
4020 | - .WillOnce ( |
4021 | - DoAll ( |
4022 | - SetArgReferee <0> (xwa), |
4023 | - Return (true))); |
4024 | - |
4025 | - buffer->queryFrameAttributes (xwa); |
4026 | -} |
4027 | - |
4028 | -TEST_F (ConfigureRequestBufferLockBehaviour, ForceReleaseDispatchAndRearm) |
4029 | -{ |
4030 | - /* Locks get armed on construction */ |
4031 | - EXPECT_CALL (*lock, lock ()); |
4032 | - |
4033 | - crb::Releasable::Ptr releasable (buffer->obtainLock ()); |
4034 | - |
4035 | - unsigned int valueMask = CWX | CWY; |
4036 | - |
4037 | - /* Queue locked */ |
4038 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); |
4039 | - |
4040 | - buffer->pushFrameRequest (xwc, valueMask); |
4041 | - |
4042 | - /* Queue forceably unlocked, locks rearmed */ |
4043 | - EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); |
4044 | - EXPECT_CALL (*lock, lock ()); |
4045 | - |
4046 | - /* Force release */ |
4047 | - buffer->forceRelease (); |
4048 | -} |
4049 | - |
FAILED: Continuous integration, rev:3556 jenkins. qa.ubuntu. com/job/ compiz- ci/8/ jenkins. qa.ubuntu. com/job/ compiz- clang-ci/ ./build= pbuilder, distribution= quantal, flavor= amd64/46/ console jenkins. qa.ubuntu. com/job/ compiz- gles-ci/ ./build= pbuilder, distribution= quantal, flavor= amd64/45/ console jenkins. qa.ubuntu. com/job/ compiz- pbuilder/ ./build= pbuilder, distribution= quantal, flavor= amd64/397/ console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: jenkins. qa.ubuntu. com/job/ compiz- ci/8//rebuild/?
http://