Merge lp:~compiz-team/compiz/compiz.performance_1040478 into lp:compiz/0.9.9
- compiz.performance_1040478
- Merge into 0.9.9
Status: | Superseded |
---|---|
Proposed branch: | lp:~compiz-team/compiz/compiz.performance_1040478 |
Merge into: | lp:compiz/0.9.9 |
Diff against target: |
4940 lines (+1336/-1650) 21 files modified
include/core/configurerequestbuffer.h (+0/-73) plugins/opengl/CMakeLists.txt (+6/-0) plugins/opengl/include/opengl/framebufferobject.h (+182/-41) plugins/opengl/include/opengl/opengl-api.h (+42/-0) plugins/opengl/include/opengl/opengl.h (+82/-22) plugins/opengl/src/fbdirectdraw/CMakeLists.txt (+32/-0) plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h (+111/-0) plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp (+177/-0) plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt (+24/-0) plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp (+237/-0) plugins/opengl/src/framebufferobject.cpp (+112/-104) plugins/opengl/src/paint.cpp (+10/-80) plugins/opengl/src/privates.h (+49/-7) plugins/opengl/src/screen.cpp (+251/-34) plugins/water/src/water.cpp (+17/-9) plugins/water/src/water.h (+4/-4) src/asyncserverwindow.h (+0/-52) src/configurerequestbuffer-impl.h (+0/-145) src/configurerequestbuffer.cpp (+0/-363) src/syncserverwindow.h (+0/-49) src/tests/test_configurerequestbuffer.cpp (+0/-667) |
To merge this branch: | bzr merge lp:~compiz-team/compiz/compiz.performance_1040478 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Sam Spilsbury | Pending | ||
jenkins | continuous-integration | Pending | |
Review via email: mp+150738@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
Implement support for glBlitFramebuffer. On some platforms this may speed up the final composite operation as we skip the fragment processor entirely.
The logic around this code is basically that if glBlitFramebuffer fails, then we don't use it again (the failure case is it not being available), and use the fallback textured draw code.
Tests added for the new module FramebufferDire
Description of the change
Proposing this now so I can get some early feedback.
Implement support for glBlitFramebuffer. On some platforms this may speed up the final composite operation as we skip the fragment processor entirely.
The logic around this code is basically that if glBlitFramebuffer fails, then we don't use it again (the failure case is it not being available), and use the fallback textured draw code.
Tests added for the new module FramebufferDire
The API and ABI of GLFramebufferObject were broken too so that we could specify which buffer we actually wanted to bind.
Also added new concepts of framebuffer binding points. These are now responsible for binding framebuffers to the GL_DRAW_FRAMEBUFFER or GL_READ_FRAMEBUFFER rather than the object itself. This effectively means that we can optimize out multiple binds of the same object, or leave objects bound until they /actually/ need to change.
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal | # |
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3388
http://
Executed test runs:
SUCCESS: http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
I have not seen any improvement yet myself. It would have to be quite significant to risk large changes to the 0.9.8 tree right now.
As far as I can tell, this is not required for quantal. So please repropose it after we've branched for 0.9.9.
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3388
http://
Executed test runs:
FAILURE: http://
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3389
http://
Executed test runs:
FAILURE: http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Don't we want to fix bug 1051287 before merging this?
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
Probably a good idea. Lets do that.
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
Though, I'm not entirely certain. In order to fix it properly I'll need to add a concept of framebuffer bindings points to opengl, that could inflate this change a little more (or at least introduce a dependency)
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
OK, then. Bug 1051287 needs fixing here.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3389
http://
Executed test runs:
FAILURE: 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:3394
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild:
http://
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
Lets look into this again post 0.9.9.0
MC Return (mc-return) wrote : Posted in a previous version of this proposal | # |
165 + * This since this code only draws a rectangular region from one
should probably be:
165 + * Since this code only draws a rectangular region from one
The copyright in plugins/
Is the fallthrough in plugins/
1323 switch (status)
1324 {
1325 - case GL::FRAMEBUFFER
1326 + case GL::FRAMEBUFFER
1327 return "GL::FRAMEBUFFE
1328 - case GL::FRAMEBUFFER
1329 + case GL::FRAMEBUFFER
1330 return "GL::FRAMEBUFFE
1331 - case GL::FRAMEBUFFER
1332 + case GL::FRAMEBUFFER
1333 return "GL::FRAMEBUFFE
1334 - case GL::FRAMEBUFFER
1335 + case GL::FRAMEBUFFER
1336 return "GL::FRAMEBUFFE
1337 - case GL::FRAMEBUFFER
1338 + case GL::FRAMEBUFFER
1339 return "GL::FRAMEBUFFE
1340 default:
1341 return "unexpected status";
1342 }
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
On Sun, Feb 10, 2013 at 8:28 PM, MC Return <email address hidden> wrote:
> 165 + * This since this code only draws a rectangular region from one
> should probably be:
> 165 + * Since this code only draws a rectangular region from one
>
> The copyright in plugins/
Thanks, I'll update it.
>
> Is the fallthrough in plugins/
> 1323 switch (status)
> 1324 {
> 1325 - case GL::FRAMEBUFFER
> 1326 + case GL::FRAMEBUFFER
> 1327 return "GL::FRAMEBUFFE
> 1328 - case GL::FRAMEBUFFER
> 1329 + case GL::FRAMEBUFFER
> 1330 return "GL::FRAMEBUFFE
> 1331 - case GL::FRAMEBUFFER
> 1332 + case GL::FRAMEBUFFER
> 1333 return "GL::FRAMEBUFFE
> 1334 - case GL::FRAMEBUFFER
> 1335 + case GL::FRAMEBUFFER
> 1336 return "GL::FRAMEBUFFE
> 1337 - case GL::FRAMEBUFFER
> 1338 + case GL::FRAMEBUFFER
> 1339 return "GL::FRAMEBUFFE
> 1340 default:
> 1341 return "unexpected status";
> 1342 }
>
No fall-through is possible, since we return directly.
> --
> https:/
> You proposed lp:~compiz-team/compiz/compiz.performance_1040478 for merging.
--
Sam Spilsbury
MC Return (mc-return) wrote : Posted in a previous version of this proposal | # |
>
> No fall-through is possible, since we return directly.
>
Ah, yeah - you are right ofc. - sorry 'bout that.
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
Checking the copyright again on opengl-api.h, I don't think there is any problem there. All I did for that code was cut-and-paste part of private.h, no actual modification on my part.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3405
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 | # |
PASSED: Continuous integration, rev:3409
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:3410
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
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 here as well.
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
Thanks. I fixed that yesterday but seemed to forget to push it here.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3411
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:3413
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:3413
http://
Executed test runs:
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 | # |
PASSED: Continuous integration, rev:3414
http://
Executed test runs:
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:3415
http://
Executed test runs:
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:3416
http://
Executed test runs:
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:3417
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3417
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 3418. By Sam Spilsbury
-
Merge lp:compiz
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3418
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 3419. By Sam Spilsbury
-
Unrevert changes reverted by a merge
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:3419
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Unmerged revisions
- 3419. By Sam Spilsbury
-
Unrevert changes reverted by a merge
- 3418. By Sam Spilsbury
-
Merge lp:compiz
- 3417. By Sam Spilsbury
-
Merge lp:compiz
- 3416. By Sam Spilsbury
-
Make the currently bound drawbuffer available to plugins (as they might want
to do a read/draw swap) - 3415. By Sam Spilsbury
-
Revert more changes which should not have happened
- 3414. By Sam Spilsbury
-
Merge lp:compiz
- 3413. By Sam Spilsbury
-
Fix merge errors
- 3412. By Sam Spilsbury
-
Merge lp:compiz
- 3411. By Sam Spilsbury
-
Another botched merge
- 3410. By Sam Spilsbury
-
Unrevert changes which shouldn't have been reverted
Preview Diff
1 | === added file 'include/core/configurerequestbuffer.h' | |||
2 | --- include/core/configurerequestbuffer.h 1970-01-01 00:00:00 +0000 | |||
3 | +++ include/core/configurerequestbuffer.h 2013-02-28 02:29:22 +0000 | |||
4 | @@ -0,0 +1,73 @@ | |||
5 | 1 | /* | ||
6 | 2 | * Copyright © 2012 Sam Spilsbury | ||
7 | 3 | * | ||
8 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
9 | 5 | * and its documentation for any purpose is hereby granted without | ||
10 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
11 | 7 | * and that both that copyright notice and this permission notice | ||
12 | 8 | * appear in supporting documentation, and that the name of | ||
13 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
14 | 10 | * distribution of the software without specific, written prior permission. | ||
15 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
16 | 12 | * software for any purpose. It is provided "as is" without express or | ||
17 | 13 | * implied warranty. | ||
18 | 14 | * | ||
19 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
20 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
21 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
22 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
23 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
24 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
25 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
26 | 22 | * | ||
27 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
28 | 24 | */ | ||
29 | 25 | #ifndef _COMPIZ_CONFIGURE_REQUEST_BUFFER_H | ||
30 | 26 | #define _COMPIZ_CONFIGURE_REQUEST_BUFFER_H | ||
31 | 27 | |||
32 | 28 | #include <boost/shared_ptr.hpp> | ||
33 | 29 | #include <X11/Xlib.h> | ||
34 | 30 | #include <syncserverwindow.h> | ||
35 | 31 | |||
36 | 32 | namespace compiz | ||
37 | 33 | { | ||
38 | 34 | namespace window | ||
39 | 35 | { | ||
40 | 36 | namespace configure_buffers | ||
41 | 37 | { | ||
42 | 38 | class Releasable | ||
43 | 39 | { | ||
44 | 40 | public: | ||
45 | 41 | |||
46 | 42 | typedef boost::shared_ptr <Releasable> Ptr; | ||
47 | 43 | |||
48 | 44 | virtual void release () = 0; | ||
49 | 45 | }; | ||
50 | 46 | |||
51 | 47 | class Buffer : | ||
52 | 48 | public SyncServerWindow | ||
53 | 49 | { | ||
54 | 50 | public: | ||
55 | 51 | |||
56 | 52 | typedef boost::shared_ptr <Buffer> Ptr; | ||
57 | 53 | |||
58 | 54 | virtual ~Buffer () {} | ||
59 | 55 | |||
60 | 56 | virtual void pushClientRequest (const XWindowChanges &xwc, unsigned int mask) = 0; | ||
61 | 57 | virtual void pushWrapperRequest (const XWindowChanges &xwc, unsigned int mask) = 0; | ||
62 | 58 | virtual void pushFrameRequest (const XWindowChanges &xwc, unsigned int mask) = 0; | ||
63 | 59 | |||
64 | 60 | virtual void pushSyntheticConfigureNotify () = 0; | ||
65 | 61 | |||
66 | 62 | virtual Releasable::Ptr obtainLock () = 0; | ||
67 | 63 | |||
68 | 64 | /* This API will all configure requests to be | ||
69 | 65 | * released. It should only be used in situations | ||
70 | 66 | * where you have a server grab and need | ||
71 | 67 | * to have complete sync with the server */ | ||
72 | 68 | virtual void forceRelease () = 0; | ||
73 | 69 | }; | ||
74 | 70 | } | ||
75 | 71 | } | ||
76 | 72 | } | ||
77 | 73 | #endif | ||
78 | 0 | 74 | ||
79 | === removed file 'include/core/configurerequestbuffer.h' | |||
80 | --- include/core/configurerequestbuffer.h 2012-12-13 11:12:32 +0000 | |||
81 | +++ include/core/configurerequestbuffer.h 1970-01-01 00:00:00 +0000 | |||
82 | @@ -1,73 +0,0 @@ | |||
83 | 1 | /* | ||
84 | 2 | * Copyright © 2012 Sam Spilsbury | ||
85 | 3 | * | ||
86 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
87 | 5 | * and its documentation for any purpose is hereby granted without | ||
88 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
89 | 7 | * and that both that copyright notice and this permission notice | ||
90 | 8 | * appear in supporting documentation, and that the name of | ||
91 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
92 | 10 | * distribution of the software without specific, written prior permission. | ||
93 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
94 | 12 | * software for any purpose. It is provided "as is" without express or | ||
95 | 13 | * implied warranty. | ||
96 | 14 | * | ||
97 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
98 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
99 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
100 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
101 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
102 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
103 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
104 | 22 | * | ||
105 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
106 | 24 | */ | ||
107 | 25 | #ifndef _COMPIZ_CONFIGURE_REQUEST_BUFFER_H | ||
108 | 26 | #define _COMPIZ_CONFIGURE_REQUEST_BUFFER_H | ||
109 | 27 | |||
110 | 28 | #include <boost/shared_ptr.hpp> | ||
111 | 29 | #include <X11/Xlib.h> | ||
112 | 30 | #include <syncserverwindow.h> | ||
113 | 31 | |||
114 | 32 | namespace compiz | ||
115 | 33 | { | ||
116 | 34 | namespace window | ||
117 | 35 | { | ||
118 | 36 | namespace configure_buffers | ||
119 | 37 | { | ||
120 | 38 | class Releasable | ||
121 | 39 | { | ||
122 | 40 | public: | ||
123 | 41 | |||
124 | 42 | typedef boost::shared_ptr <Releasable> Ptr; | ||
125 | 43 | |||
126 | 44 | virtual void release () = 0; | ||
127 | 45 | }; | ||
128 | 46 | |||
129 | 47 | class Buffer : | ||
130 | 48 | public SyncServerWindow | ||
131 | 49 | { | ||
132 | 50 | public: | ||
133 | 51 | |||
134 | 52 | typedef boost::shared_ptr <Buffer> Ptr; | ||
135 | 53 | |||
136 | 54 | virtual ~Buffer () {} | ||
137 | 55 | |||
138 | 56 | virtual void pushClientRequest (const XWindowChanges &xwc, unsigned int mask) = 0; | ||
139 | 57 | virtual void pushWrapperRequest (const XWindowChanges &xwc, unsigned int mask) = 0; | ||
140 | 58 | virtual void pushFrameRequest (const XWindowChanges &xwc, unsigned int mask) = 0; | ||
141 | 59 | |||
142 | 60 | virtual void pushSyntheticConfigureNotify () = 0; | ||
143 | 61 | |||
144 | 62 | virtual Releasable::Ptr obtainLock () = 0; | ||
145 | 63 | |||
146 | 64 | /* This API will all configure requests to be | ||
147 | 65 | * released. It should only be used in situations | ||
148 | 66 | * where you have a server grab and need | ||
149 | 67 | * to have complete sync with the server */ | ||
150 | 68 | virtual void forceRelease () = 0; | ||
151 | 69 | }; | ||
152 | 70 | } | ||
153 | 71 | } | ||
154 | 72 | } | ||
155 | 73 | #endif | ||
156 | 74 | 0 | ||
157 | === modified file 'plugins/opengl/CMakeLists.txt' | |||
158 | --- plugins/opengl/CMakeLists.txt 2012-12-12 07:33:12 +0000 | |||
159 | +++ plugins/opengl/CMakeLists.txt 2013-02-28 02:29:22 +0000 | |||
160 | @@ -5,15 +5,21 @@ | |||
161 | 5 | set (INTERNAL_LIBRARIES | 5 | set (INTERNAL_LIBRARIES |
162 | 6 | compiz_opengl_double_buffer | 6 | compiz_opengl_double_buffer |
163 | 7 | compiz_opengl_fsregion | 7 | compiz_opengl_fsregion |
164 | 8 | compiz_opengl_framebuffer_direct_draw | ||
165 | 8 | compiz_opengl_blacklist | 9 | compiz_opengl_blacklist |
166 | 9 | compiz_opengl_glx_tfp_bind | 10 | compiz_opengl_glx_tfp_bind |
167 | 10 | ) | 11 | ) |
168 | 11 | 12 | ||
169 | 13 | set (COMPIZ_OPENGL_PLUGIN_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) | ||
170 | 14 | set (COMPIZ_OPENGL_PLUGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) | ||
171 | 15 | |||
172 | 12 | add_subdirectory (src/doublebuffer) | 16 | add_subdirectory (src/doublebuffer) |
173 | 13 | add_subdirectory (src/fsregion) | 17 | add_subdirectory (src/fsregion) |
174 | 18 | add_subdirectory (src/fbdirectdraw) | ||
175 | 14 | add_subdirectory (src/blacklist) | 19 | add_subdirectory (src/blacklist) |
176 | 15 | add_subdirectory (src/glxtfpbind) | 20 | add_subdirectory (src/glxtfpbind) |
177 | 16 | 21 | ||
178 | 22 | include_directories (src/fbdirectdraw/include) | ||
179 | 17 | include_directories (src/glxtfpbind/include) | 23 | include_directories (src/glxtfpbind/include) |
180 | 18 | 24 | ||
181 | 19 | if (USE_GLES) | 25 | if (USE_GLES) |
182 | 20 | 26 | ||
183 | === modified file 'plugins/opengl/include/opengl/framebufferobject.h' | |||
184 | --- plugins/opengl/include/opengl/framebufferobject.h 2012-08-09 02:19:26 +0000 | |||
185 | +++ plugins/opengl/include/opengl/framebufferobject.h 2013-02-28 02:29:22 +0000 | |||
186 | @@ -26,29 +26,177 @@ | |||
187 | 26 | #ifndef _COMPIZ_GLFRAMEBUFFEROBJECT_H | 26 | #ifndef _COMPIZ_GLFRAMEBUFFEROBJECT_H |
188 | 27 | #define _COMPIZ_GLFRAMEBUFFEROBJECT_H | 27 | #define _COMPIZ_GLFRAMEBUFFEROBJECT_H |
189 | 28 | 28 | ||
191 | 29 | #include <opengl/opengl.h> | 29 | #include <list> |
192 | 30 | #include <boost/function.hpp> | ||
193 | 31 | #include <opengl/opengl-api.h> | ||
194 | 32 | #include <core/size.h> | ||
195 | 33 | #include <core/rect.h> | ||
196 | 34 | |||
197 | 35 | class GLVertexBuffer; | ||
198 | 36 | class GLTexture; | ||
199 | 37 | |||
200 | 38 | namespace compiz | ||
201 | 39 | { | ||
202 | 40 | namespace opengl | ||
203 | 41 | { | ||
204 | 42 | typedef enum _BlitMask | ||
205 | 43 | { | ||
206 | 44 | ColorData = (1 << 0), | ||
207 | 45 | StencilData = (1 << 1) | ||
208 | 46 | } BlitMask; | ||
209 | 47 | |||
210 | 48 | typedef enum _Filter | ||
211 | 49 | { | ||
212 | 50 | Fast = 0, | ||
213 | 51 | Good = 1, | ||
214 | 52 | } Filter; | ||
215 | 53 | |||
216 | 54 | typedef enum _BindPoint | ||
217 | 55 | { | ||
218 | 56 | Read = 0, | ||
219 | 57 | Draw = 1 | ||
220 | 58 | } BindPoint; | ||
221 | 59 | |||
222 | 60 | class BindableFramebuffer | ||
223 | 61 | { | ||
224 | 62 | public: | ||
225 | 63 | |||
226 | 64 | virtual ~BindableFramebuffer () {} | ||
227 | 65 | |||
228 | 66 | virtual GLuint getResourceId () const = 0; | ||
229 | 67 | virtual bool setBindStatus (GLenum) = 0; | ||
230 | 68 | virtual void updateAllocation (GLenum) = 0; | ||
231 | 69 | }; | ||
232 | 70 | |||
233 | 71 | class BindLocation | ||
234 | 72 | { | ||
235 | 73 | public: | ||
236 | 74 | |||
237 | 75 | virtual ~BindLocation () {} | ||
238 | 76 | |||
239 | 77 | /** | ||
240 | 78 | * Bind the specified BindableFramebuffer to this bind location | ||
241 | 79 | * usually either as the read target or the draw target | ||
242 | 80 | * | ||
243 | 81 | * The previous FBO is no longer bound. If it was bound to the | ||
244 | 82 | * draw target, it will be safe to use its texture. | ||
245 | 83 | * | ||
246 | 84 | * This returns the last-bound BindableFramebuffer object on | ||
247 | 85 | * success and NULL on failure (no change). Call this again | ||
248 | 86 | * in order to restore that framebuffer | ||
249 | 87 | */ | ||
250 | 88 | virtual BindableFramebuffer * bind (BindableFramebuffer *) = 0; | ||
251 | 89 | virtual BindableFramebuffer * getCurrentlyBound () = 0; | ||
252 | 90 | }; | ||
253 | 91 | |||
254 | 92 | typedef boost::function <bool (const CompRect &src, | ||
255 | 93 | const CompRect &dst, | ||
256 | 94 | GLbitfield mask, | ||
257 | 95 | GLenum filter)> RectangularDraw; | ||
258 | 96 | typedef std::list <RectangularDraw> RectangularDrawList; | ||
259 | 97 | |||
260 | 98 | class DirectDrawStrategies | ||
261 | 99 | { | ||
262 | 100 | public: | ||
263 | 101 | |||
264 | 102 | typedef boost::shared_ptr <DirectDrawStrategies> Ptr; | ||
265 | 103 | |||
266 | 104 | virtual ~DirectDrawStrategies () {} | ||
267 | 105 | virtual void draw (const CompRect &src, | ||
268 | 106 | const CompRect &dst, | ||
269 | 107 | BlitMask mask, | ||
270 | 108 | Filter filter) = 0; | ||
271 | 109 | }; | ||
272 | 110 | |||
273 | 111 | class FramebufferObject | ||
274 | 112 | { | ||
275 | 113 | public: | ||
276 | 114 | |||
277 | 115 | virtual ~FramebufferObject () {} | ||
278 | 116 | |||
279 | 117 | /** | ||
280 | 118 | * Ensure the texture is of the given size, recreating it if needed, | ||
281 | 119 | * and replace the FBO color attachment with it. The texture contents | ||
282 | 120 | * become undefined, unless specified in the 'image' argument. | ||
283 | 121 | * When specifying 'image', it's also possible to pass-in the | ||
284 | 122 | * desired image's 'format' and 'type'. | ||
285 | 123 | * | ||
286 | 124 | * Returns true on success, and false on texture allocation failure. | ||
287 | 125 | */ | ||
288 | 126 | virtual bool allocate (const CompSize &size, | ||
289 | 127 | const char *image = NULL, | ||
290 | 128 | GLenum format = GL_RGBA, | ||
291 | 129 | GLenum type = GL_UNSIGNED_BYTE) = 0; | ||
292 | 130 | |||
293 | 131 | /** | ||
294 | 132 | * Check the FBO completeness. Returns true on complete. | ||
295 | 133 | * Otherwise returns false and reports the error to log. | ||
296 | 134 | */ | ||
297 | 135 | virtual bool checkStatus () = 0; | ||
298 | 136 | |||
299 | 137 | /** | ||
300 | 138 | * Return a pointer to the texture that is the color attachment. | ||
301 | 139 | * This will return NULL, if allocate () has not been called, or | ||
302 | 140 | * the last allocate () call failed. | ||
303 | 141 | */ | ||
304 | 142 | virtual GLTexture * tex () = 0; | ||
305 | 143 | }; | ||
306 | 144 | |||
307 | 145 | class DirectDrawObject : | ||
308 | 146 | virtual public compiz::opengl::FramebufferObject, | ||
309 | 147 | virtual public compiz::opengl::BindableFramebuffer | ||
310 | 148 | { | ||
311 | 149 | public: | ||
312 | 150 | |||
313 | 151 | virtual ~DirectDrawObject () {}; | ||
314 | 152 | |||
315 | 153 | /** | ||
316 | 154 | * Draws a region of the framebuffer object as specified in | ||
317 | 155 | * framebuffer-specified co-ordinates as @src co-ordinates in | ||
318 | 156 | * the buffer currently bound co-ordinates @dst . @mask indicates | ||
319 | 157 | * what kind of data should be propogated downwards. @filter indicates | ||
320 | 158 | * what kind of filter should be used when drawing this buffer | ||
321 | 159 | * | ||
322 | 160 | * This since this code only draws a rectangular region from one | ||
323 | 161 | * framebuffer to another, it will try and use the fastest codepath | ||
324 | 162 | * possible, falling back to a simple textured draw if | ||
325 | 163 | * glBlitFramebuffer is not available | ||
326 | 164 | * | ||
327 | 165 | */ | ||
328 | 166 | virtual void directDraw (const CompRect &src, | ||
329 | 167 | const CompRect &dst, | ||
330 | 168 | compiz::opengl::BlitMask mask, | ||
331 | 169 | compiz::opengl::Filter filter) = 0; | ||
332 | 170 | }; | ||
333 | 171 | |||
334 | 172 | namespace impl | ||
335 | 173 | { | ||
336 | 174 | namespace cgl = compiz::opengl; | ||
337 | 30 | 175 | ||
338 | 31 | struct PrivateGLFramebufferObject; | 176 | struct PrivateGLFramebufferObject; |
339 | 32 | 177 | ||
359 | 33 | /** | 178 | class FBOBindLocation : |
360 | 34 | * Class representing a framebuffer object in GL, supporting only one | 179 | public cgl::BindLocation |
361 | 35 | * color attachment as per GLES 2 spec. The color attachment is referred | 180 | { |
362 | 36 | * to as the texture (of the FBO). | 181 | public: |
363 | 37 | * | 182 | |
364 | 38 | * Usage: | 183 | FBOBindLocation (GLenum binding, BindableFramebuffer *back); |
365 | 39 | * 1. create a GLFramebufferObject (requires a GL context) | 184 | BindableFramebuffer * bind (BindableFramebuffer *); |
366 | 40 | * 2. call allocate (size), and check status () | 185 | BindableFramebuffer * getCurrentlyBound (); |
367 | 41 | * 3. old = bind () | 186 | |
368 | 42 | * 4. do your rendering | 187 | private: |
369 | 43 | * 5. rebind (old) | 188 | |
370 | 44 | * 6. use the rendered texture via tex () | 189 | class Private; |
371 | 45 | * 7. go to 2 or 3, or delete to quit (requires a GL context) | 190 | std::auto_ptr <Private> priv; |
372 | 46 | */ | 191 | }; |
373 | 47 | class GLFramebufferObject | 192 | |
374 | 48 | { | 193 | class FramebufferObject : |
375 | 49 | public: | 194 | public cgl::FramebufferObject, |
376 | 50 | GLFramebufferObject (); | 195 | public cgl::BindableFramebuffer |
377 | 51 | ~GLFramebufferObject (); | 196 | { |
378 | 197 | public: | ||
379 | 198 | FramebufferObject (); | ||
380 | 199 | ~FramebufferObject (); | ||
381 | 52 | 200 | ||
382 | 53 | /** | 201 | /** |
383 | 54 | * Ensure the texture is of the given size, recreating it if needed, | 202 | * Ensure the texture is of the given size, recreating it if needed, |
384 | @@ -65,26 +213,6 @@ | |||
385 | 65 | GLenum type = GL_UNSIGNED_BYTE); | 213 | GLenum type = GL_UNSIGNED_BYTE); |
386 | 66 | 214 | ||
387 | 67 | /** | 215 | /** |
388 | 68 | * Bind this as the current FBO, previous binding in GL context is | ||
389 | 69 | * undone. GL rendering is now targeted to this FBO. | ||
390 | 70 | * Returns a pointer to the previously bound FBO, or NULL if | ||
391 | 71 | * the previous binding was zero (the window system provided | ||
392 | 72 | * framebuffer). | ||
393 | 73 | * | ||
394 | 74 | * The previous FBO is no longer bound, so you can use its | ||
395 | 75 | * texture. To restore the previous FBO, call rebind (FBO) with | ||
396 | 76 | * the returned pointer as the argument. | ||
397 | 77 | */ | ||
398 | 78 | GLFramebufferObject *bind (); | ||
399 | 79 | |||
400 | 80 | /** | ||
401 | 81 | * Bind the given FBO as the current FBO, without looking up the | ||
402 | 82 | * previous binding. The argument can be NULL, in which case the | ||
403 | 83 | * window system provided framebuffer gets bound (FBO is unbound). | ||
404 | 84 | */ | ||
405 | 85 | static void rebind (GLFramebufferObject *fbo); | ||
406 | 86 | |||
407 | 87 | /** | ||
408 | 88 | * Check the FBO completeness. Returns true on complete. | 216 | * Check the FBO completeness. Returns true on complete. |
409 | 89 | * Otherwise returns false and reports the error to log. | 217 | * Otherwise returns false and reports the error to log. |
410 | 90 | */ | 218 | */ |
411 | @@ -95,10 +223,23 @@ | |||
412 | 95 | * This will return NULL, if allocate () has not been called, or | 223 | * This will return NULL, if allocate () has not been called, or |
413 | 96 | * the last allocate () call failed. | 224 | * the last allocate () call failed. |
414 | 97 | */ | 225 | */ |
416 | 98 | GLTexture *tex (); | 226 | GLTexture * tex (); |
417 | 99 | 227 | ||
418 | 100 | private: | 228 | private: |
419 | 229 | |||
420 | 230 | /** | ||
421 | 231 | * Returns the framebuffer identifier | ||
422 | 232 | */ | ||
423 | 233 | GLuint getResourceId () const; | ||
424 | 234 | bool setBindStatus (GLenum); | ||
425 | 235 | void updateAllocation (GLenum bindingLocation); | ||
426 | 236 | |||
427 | 101 | PrivateGLFramebufferObject *priv; | 237 | PrivateGLFramebufferObject *priv; |
428 | 102 | }; | 238 | }; |
429 | 239 | } | ||
430 | 240 | } | ||
431 | 241 | } | ||
432 | 242 | |||
433 | 243 | typedef compiz::opengl::impl::FramebufferObject GLFramebufferObject; | ||
434 | 103 | 244 | ||
435 | 104 | #endif // _COMPIZ_GLFRAMEBUFFEROBJECT_H | 245 | #endif // _COMPIZ_GLFRAMEBUFFEROBJECT_H |
436 | 105 | 246 | ||
437 | === added file 'plugins/opengl/include/opengl/opengl-api.h' | |||
438 | --- plugins/opengl/include/opengl/opengl-api.h 1970-01-01 00:00:00 +0000 | |||
439 | +++ plugins/opengl/include/opengl/opengl-api.h 2013-02-28 02:29:22 +0000 | |||
440 | @@ -0,0 +1,42 @@ | |||
441 | 1 | /* | ||
442 | 2 | * Copyright © 2008 Dennis Kasprzyk | ||
443 | 3 | * Copyright © 2007 Novell, Inc. | ||
444 | 4 | * | ||
445 | 5 | * Permission to use, copy, modify, distribute, and sell this software | ||
446 | 6 | * and its documentation for any purpose is hereby granted without | ||
447 | 7 | * fee, provided that the above copyright notice appear in all copies | ||
448 | 8 | * and that both that copyright notice and this permission notice | ||
449 | 9 | * appear in supporting documentation, and that the name of | ||
450 | 10 | * Dennis Kasprzyk not be used in advertising or publicity pertaining to | ||
451 | 11 | * distribution of the software without specific, written prior permission. | ||
452 | 12 | * Dennis Kasprzyk makes no representations about the suitability of this | ||
453 | 13 | * software for any purpose. It is provided "as is" without express or | ||
454 | 14 | * implied warranty. | ||
455 | 15 | * | ||
456 | 16 | * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
457 | 17 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
458 | 18 | * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
459 | 19 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
460 | 20 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
461 | 21 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
462 | 22 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
463 | 23 | * | ||
464 | 24 | * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org> | ||
465 | 25 | * David Reveman <davidr@novell.com> | ||
466 | 26 | */ | ||
467 | 27 | |||
468 | 28 | #ifndef _COMPIZ_OPENGL_API_H | ||
469 | 29 | #define _COMPIZ_OPENGL_API_H | ||
470 | 30 | |||
471 | 31 | #ifdef USE_GLES | ||
472 | 32 | #define SUPPORT_X11 | ||
473 | 33 | #include <GLES2/gl2.h> | ||
474 | 34 | #include <GLES2/gl2ext.h> | ||
475 | 35 | #include <EGL/egl.h> | ||
476 | 36 | #include <EGL/eglext.h> | ||
477 | 37 | #else | ||
478 | 38 | #include <GL/gl.h> | ||
479 | 39 | #include <GL/glx.h> | ||
480 | 40 | #endif | ||
481 | 41 | |||
482 | 42 | #endif | ||
483 | 0 | 43 | ||
484 | === modified file 'plugins/opengl/include/opengl/opengl.h' | |||
485 | --- plugins/opengl/include/opengl/opengl.h 2013-01-10 09:23:24 +0000 | |||
486 | +++ plugins/opengl/include/opengl/opengl.h 2013-02-28 02:29:22 +0000 | |||
487 | @@ -28,29 +28,19 @@ | |||
488 | 28 | #ifndef _COMPIZ_OPENGL_H | 28 | #ifndef _COMPIZ_OPENGL_H |
489 | 29 | #define _COMPIZ_OPENGL_H | 29 | #define _COMPIZ_OPENGL_H |
490 | 30 | 30 | ||
501 | 31 | #ifdef USE_GLES | 31 | #include <opengl/opengl-api.h> |
492 | 32 | #define SUPPORT_X11 | ||
493 | 33 | #include <GLES2/gl2.h> | ||
494 | 34 | #include <GLES2/gl2ext.h> | ||
495 | 35 | #include <EGL/egl.h> | ||
496 | 36 | #include <EGL/eglext.h> | ||
497 | 37 | #else | ||
498 | 38 | #include <GL/gl.h> | ||
499 | 39 | #include <GL/glx.h> | ||
500 | 40 | #endif | ||
502 | 41 | 32 | ||
503 | 42 | #include <core/size.h> | 33 | #include <core/size.h> |
504 | 43 | #include <core/pluginclasshandler.h> | 34 | #include <core/pluginclasshandler.h> |
505 | 44 | 35 | ||
506 | 45 | #include <opengl/matrix.h> | 36 | #include <opengl/matrix.h> |
507 | 46 | #include <opengl/texture.h> | 37 | #include <opengl/texture.h> |
508 | 47 | #include <opengl/framebufferobject.h> | ||
509 | 48 | #include <opengl/vertexbuffer.h> | 38 | #include <opengl/vertexbuffer.h> |
510 | 49 | #include <opengl/program.h> | 39 | #include <opengl/program.h> |
511 | 50 | #include <opengl/programcache.h> | 40 | #include <opengl/programcache.h> |
512 | 51 | #include <opengl/shadercache.h> | 41 | #include <opengl/shadercache.h> |
513 | 52 | 42 | ||
515 | 53 | #define COMPIZ_OPENGL_ABI 6 | 43 | #define COMPIZ_OPENGL_ABI 7 |
516 | 54 | 44 | ||
517 | 55 | /* | 45 | /* |
518 | 56 | * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but | 46 | * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but |
519 | @@ -84,9 +74,38 @@ | |||
520 | 84 | extern const float GREEN_SATURATION_WEIGHT; | 74 | extern const float GREEN_SATURATION_WEIGHT; |
521 | 85 | extern const float BLUE_SATURATION_WEIGHT; | 75 | extern const float BLUE_SATURATION_WEIGHT; |
522 | 86 | 76 | ||
523 | 77 | class GLScreen; | ||
524 | 87 | class PrivateGLScreen; | 78 | class PrivateGLScreen; |
525 | 88 | class PrivateGLWindow; | 79 | class PrivateGLWindow; |
526 | 89 | 80 | ||
527 | 81 | namespace compiz | ||
528 | 82 | { | ||
529 | 83 | namespace opengl | ||
530 | 84 | { | ||
531 | 85 | typedef boost::function <bool (const CompRect &src, | ||
532 | 86 | const CompRect &dst, | ||
533 | 87 | GLbitfield mask, | ||
534 | 88 | GLenum filter)> BlitFramebufferFunc; | ||
535 | 89 | |||
536 | 90 | class DirectDrawObject; | ||
537 | 91 | class FramebufferObject; | ||
538 | 92 | class BindableFramebuffer; | ||
539 | 93 | |||
540 | 94 | /** | ||
541 | 95 | * Convenience method to construct a framebuffer object that | ||
542 | 96 | * supports GLX_EXT_blit_framebuffer and a fallback path | ||
543 | 97 | */ | ||
544 | 98 | DirectDrawObject *createBlittableFramebufferObjectWithFallback(const CompSize &sz, GLScreen *gScreen); | ||
545 | 99 | |||
546 | 100 | namespace impl | ||
547 | 101 | { | ||
548 | 102 | class FramebufferObject; | ||
549 | 103 | } | ||
550 | 104 | } | ||
551 | 105 | } | ||
552 | 106 | |||
553 | 107 | typedef compiz::opengl::impl::FramebufferObject GLFramebufferObject; | ||
554 | 108 | |||
555 | 90 | extern GLushort defaultColor[4]; | 109 | extern GLushort defaultColor[4]; |
556 | 91 | 110 | ||
557 | 92 | #ifndef GLX_EXT_texture_from_pixmap | 111 | #ifndef GLX_EXT_texture_from_pixmap |
558 | @@ -313,6 +332,18 @@ | |||
559 | 313 | GLsizei width, | 332 | GLsizei width, |
560 | 314 | GLsizei height); | 333 | GLsizei height); |
561 | 315 | 334 | ||
562 | 335 | /* GLX_EXT_blit_framebuffer */ | ||
563 | 336 | typedef void (*GLBlitFramebufferProc) (GLint srcX0, | ||
564 | 337 | GLint srcY0, | ||
565 | 338 | GLint srcX1, | ||
566 | 339 | GLint srcY1, | ||
567 | 340 | GLint dstX0, | ||
568 | 341 | GLint dstY0, | ||
569 | 342 | GLint dstX1, | ||
570 | 343 | GLint dstY1, | ||
571 | 344 | GLbitfield mask, | ||
572 | 345 | GLenum filter); | ||
573 | 346 | |||
574 | 316 | 347 | ||
575 | 317 | /* GL_ARB_shader_objects */ | 348 | /* GL_ARB_shader_objects */ |
576 | 318 | #ifndef USE_GLES | 349 | #ifndef USE_GLES |
577 | @@ -413,11 +444,12 @@ | |||
578 | 413 | extern GLDisableVertexAttribArrayProc disableVertexAttribArray; | 444 | extern GLDisableVertexAttribArrayProc disableVertexAttribArray; |
579 | 414 | extern GLVertexAttribPointerProc vertexAttribPointer; | 445 | extern GLVertexAttribPointerProc vertexAttribPointer; |
580 | 415 | 446 | ||
584 | 416 | extern GLGenRenderbuffersProc genRenderbuffers; | 447 | extern GLGenRenderbuffersProc genRenderbuffers; |
585 | 417 | extern GLDeleteRenderbuffersProc deleteRenderbuffers; | 448 | extern GLDeleteRenderbuffersProc deleteRenderbuffers; |
586 | 418 | extern GLBindRenderbufferProc bindRenderbuffer; | 449 | extern GLBindRenderbufferProc bindRenderbuffer; |
587 | 419 | extern GLFramebufferRenderbufferProc framebufferRenderbuffer; | 450 | extern GLFramebufferRenderbufferProc framebufferRenderbuffer; |
589 | 420 | extern GLRenderbufferStorageProc renderbufferStorage; | 451 | extern GLRenderbufferStorageProc renderbufferStorage; |
590 | 452 | extern GLBlitFramebufferProc blitFramebuffer; | ||
591 | 421 | 453 | ||
592 | 422 | #ifndef USE_GLES | 454 | #ifndef USE_GLES |
593 | 423 | extern GLCreateShaderObjectARBProc createShaderObjectARB; | 455 | extern GLCreateShaderObjectARBProc createShaderObjectARB; |
594 | @@ -579,7 +611,6 @@ | |||
595 | 579 | extern GLScreenPaintAttrib defaultScreenPaintAttrib; | 611 | extern GLScreenPaintAttrib defaultScreenPaintAttrib; |
596 | 580 | 612 | ||
597 | 581 | class GLScreen; | 613 | class GLScreen; |
598 | 582 | class GLFramebufferObject; | ||
599 | 583 | class GLScreenInterface; | 614 | class GLScreenInterface; |
600 | 584 | extern template class WrapableInterface<GLScreen, GLScreenInterface>; | 615 | extern template class WrapableInterface<GLScreen, GLScreenInterface>; |
601 | 585 | 616 | ||
602 | @@ -658,9 +689,9 @@ | |||
603 | 658 | * @param scratchFbo Describes the final composited FBO that is | 689 | * @param scratchFbo Describes the final composited FBO that is |
604 | 659 | * to be rendered. | 690 | * to be rendered. |
605 | 660 | */ | 691 | */ |
609 | 661 | virtual void glPaintCompositedOutput (const CompRegion ®ion, | 692 | virtual void glPaintCompositedOutput (const CompRegion ®ion, |
610 | 662 | GLFramebufferObject *fbo, | 693 | compiz::opengl::DirectDrawObject *fbo, |
611 | 663 | unsigned int mask); | 694 | unsigned int mask); |
612 | 664 | 695 | ||
613 | 665 | /** | 696 | /** |
614 | 666 | * Hookable function used by plugins to determine stenciling mask | 697 | * Hookable function used by plugins to determine stenciling mask |
615 | @@ -759,13 +790,42 @@ | |||
616 | 759 | /** | 790 | /** |
617 | 760 | * Returns the FBO compiz is using for the screen | 791 | * Returns the FBO compiz is using for the screen |
618 | 761 | */ | 792 | */ |
620 | 762 | GLFramebufferObject *fbo (); | 793 | compiz::opengl::FramebufferObject * fbo (); |
621 | 794 | |||
622 | 795 | /** | ||
623 | 796 | * Binds a framebuffer for drawing, returns the old bindable | ||
624 | 797 | */ | ||
625 | 798 | compiz::opengl::BindableFramebuffer * | ||
626 | 799 | bindFramebufferForDrawing (compiz::opengl::BindableFramebuffer *); | ||
627 | 800 | |||
628 | 801 | /** | ||
629 | 802 | * Binds a framebuffer for reading, returns the old reading | ||
630 | 803 | */ | ||
631 | 804 | compiz::opengl::BindableFramebuffer * | ||
632 | 805 | bindFramebufferForReading (compiz::opengl::BindableFramebuffer *); | ||
633 | 806 | |||
634 | 807 | /** | ||
635 | 808 | * Gets the currently bound draw framebuffer | ||
636 | 809 | */ | ||
637 | 810 | compiz::opengl::BindableFramebuffer * | ||
638 | 811 | drawFramebuffer (); | ||
639 | 812 | |||
640 | 813 | /** | ||
641 | 814 | * Gets the backbuffer as a BindableFramebuffer | ||
642 | 815 | */ | ||
643 | 816 | compiz::opengl::BindableFramebuffer * | ||
644 | 817 | backbuffer (); | ||
645 | 763 | 818 | ||
646 | 764 | /** | 819 | /** |
647 | 765 | * Returns a default icon texture | 820 | * Returns a default icon texture |
648 | 766 | */ | 821 | */ |
649 | 767 | GLTexture *defaultIcon (); | 822 | GLTexture *defaultIcon (); |
650 | 768 | 823 | ||
651 | 824 | /** | ||
652 | 825 | * Returns the current framebuffer function for blitting the framebuffer | ||
653 | 826 | */ | ||
654 | 827 | const compiz::opengl::BlitFramebufferFunc & blitFramebufferFunc (); | ||
655 | 828 | |||
656 | 769 | void resetRasterPos (); | 829 | void resetRasterPos (); |
657 | 770 | 830 | ||
658 | 771 | bool glInitContext (XVisualInfo *); | 831 | bool glInitContext (XVisualInfo *); |
659 | @@ -786,7 +846,7 @@ | |||
660 | 786 | 846 | ||
661 | 787 | WRAPABLE_HND (5, GLScreenInterface, GLMatrix *, projectionMatrix); | 847 | WRAPABLE_HND (5, GLScreenInterface, GLMatrix *, projectionMatrix); |
662 | 788 | WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput, | 848 | WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput, |
664 | 789 | const CompRegion &, GLFramebufferObject *, unsigned int); | 849 | const CompRegion &, compiz::opengl::DirectDrawObject *, unsigned int); |
665 | 790 | 850 | ||
666 | 791 | WRAPABLE_HND (7, GLScreenInterface, void, glBufferStencil, const GLMatrix &, | 851 | WRAPABLE_HND (7, GLScreenInterface, void, glBufferStencil, const GLMatrix &, |
667 | 792 | GLVertexBuffer &, | 852 | GLVertexBuffer &, |
668 | 793 | 853 | ||
669 | === added directory 'plugins/opengl/src/fbdirectdraw' | |||
670 | === added file 'plugins/opengl/src/fbdirectdraw/CMakeLists.txt' | |||
671 | --- plugins/opengl/src/fbdirectdraw/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
672 | +++ plugins/opengl/src/fbdirectdraw/CMakeLists.txt 2013-02-28 02:29:22 +0000 | |||
673 | @@ -0,0 +1,32 @@ | |||
674 | 1 | INCLUDE_DIRECTORIES ( | ||
675 | 2 | ${COMPIZ_OPENGL_PLUGIN_SOURCE_DIR} | ||
676 | 3 | ${COMPIZ_OPENGL_PLUGIN_INCLUDE_DIR} | ||
677 | 4 | ${CMAKE_CURRENT_SOURCE_DIR}/include | ||
678 | 5 | ${CMAKE_CURRENT_SOURCE_DIR}/src | ||
679 | 6 | |||
680 | 7 | ${Boost_INCLUDE_DIRS} | ||
681 | 8 | ) | ||
682 | 9 | |||
683 | 10 | LINK_DIRECTORIES (${COMPIZ_LIBRARY_DIRS}) | ||
684 | 11 | |||
685 | 12 | SET( | ||
686 | 13 | SRCS | ||
687 | 14 | ${CMAKE_CURRENT_SOURCE_DIR}/src/framebuffer-direct-draw.cpp | ||
688 | 15 | ) | ||
689 | 16 | |||
690 | 17 | ADD_LIBRARY( | ||
691 | 18 | compiz_opengl_framebuffer_direct_draw STATIC | ||
692 | 19 | |||
693 | 20 | ${SRCS} | ||
694 | 21 | ) | ||
695 | 22 | |||
696 | 23 | if (COMPIZ_BUILD_TESTING) | ||
697 | 24 | ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests ) | ||
698 | 25 | endif (COMPIZ_BUILD_TESTING) | ||
699 | 26 | |||
700 | 27 | TARGET_LINK_LIBRARIES( | ||
701 | 28 | compiz_opengl_framebuffer_direct_draw | ||
702 | 29 | |||
703 | 30 | compiz_region | ||
704 | 31 | compiz_logmessage | ||
705 | 32 | ) | ||
706 | 0 | 33 | ||
707 | === added directory 'plugins/opengl/src/fbdirectdraw/include' | |||
708 | === added file 'plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h' | |||
709 | --- plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h 1970-01-01 00:00:00 +0000 | |||
710 | +++ plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h 2013-02-28 02:29:22 +0000 | |||
711 | @@ -0,0 +1,111 @@ | |||
712 | 1 | /* | ||
713 | 2 | * Compiz, opengl plugin, FramebufferDirectDraw class | ||
714 | 3 | * | ||
715 | 4 | * Copyright (c) 2012 Canonical Ltd. | ||
716 | 5 | * Authors: Sam Spilsbury <sam.spilsbury@canonical.com> | ||
717 | 6 | * | ||
718 | 7 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
719 | 8 | * copy of this software and associated documentation files (the "Software"), | ||
720 | 9 | * to deal in the Software without restriction, including without limitation | ||
721 | 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
722 | 11 | * and/or sell copies of the Software, and to permit persons to whom the | ||
723 | 12 | * Software is furnished to do so, subject to the following conditions: | ||
724 | 13 | * | ||
725 | 14 | * The above copyright notice and this permission notice shall be included in | ||
726 | 15 | * all copies or substantial portions of the Software. | ||
727 | 16 | * | ||
728 | 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
729 | 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
730 | 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
731 | 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
732 | 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
733 | 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
734 | 23 | * DEALINGS IN THE SOFTWARE. | ||
735 | 24 | */ | ||
736 | 25 | #ifndef _COMPIZ_OPENGL_FRAMEBUFFER_DIRECT_DRAW_H | ||
737 | 26 | #define _COMPIZ_OPENGL_FRAMEBUFFER_DIRECT_DRAW_H | ||
738 | 27 | |||
739 | 28 | #include <memory> | ||
740 | 29 | #include <boost/shared_ptr.hpp> | ||
741 | 30 | #include <core/rect.h> | ||
742 | 31 | #include <opengl/framebufferobject.h> | ||
743 | 32 | |||
744 | 33 | class GLVertexBuffer; | ||
745 | 34 | |||
746 | 35 | namespace compiz | ||
747 | 36 | { | ||
748 | 37 | namespace opengl | ||
749 | 38 | { | ||
750 | 39 | namespace impl | ||
751 | 40 | { | ||
752 | 41 | namespace cglfb = compiz::opengl; | ||
753 | 42 | |||
754 | 43 | class PrivateDirectDrawStrategies; | ||
755 | 44 | |||
756 | 45 | class DirectDrawStrategies : | ||
757 | 46 | public cglfb::DirectDrawStrategies | ||
758 | 47 | { | ||
759 | 48 | public: | ||
760 | 49 | |||
761 | 50 | typedef boost::shared_ptr <DirectDrawStrategies> Ptr; | ||
762 | 51 | |||
763 | 52 | DirectDrawStrategies (const RectangularDrawList &strategies); | ||
764 | 53 | |||
765 | 54 | void draw (const CompRect &src, | ||
766 | 55 | const CompRect &dst, | ||
767 | 56 | BlitMask mask, | ||
768 | 57 | Filter filter); | ||
769 | 58 | |||
770 | 59 | private: | ||
771 | 60 | |||
772 | 61 | std::auto_ptr <PrivateDirectDrawStrategies> priv; | ||
773 | 62 | }; | ||
774 | 63 | |||
775 | 64 | class PrivateDirectDrawObject; | ||
776 | 65 | |||
777 | 66 | class DirectDrawObject : | ||
778 | 67 | virtual public cglfb::FramebufferObject, | ||
779 | 68 | public cglfb::DirectDrawObject | ||
780 | 69 | { | ||
781 | 70 | public: | ||
782 | 71 | |||
783 | 72 | DirectDrawObject (const boost::shared_ptr <cglfb::DirectDrawStrategies> &, | ||
784 | 73 | const boost::shared_ptr <cglfb::FramebufferObject> &, | ||
785 | 74 | const boost::shared_ptr <cglfb::BindableFramebuffer> &); | ||
786 | 75 | |||
787 | 76 | bool allocate (const CompSize &size, | ||
788 | 77 | const char *image = NULL, | ||
789 | 78 | GLenum format = GL_RGBA, | ||
790 | 79 | GLenum type = GL_UNSIGNED_BYTE); | ||
791 | 80 | bool checkStatus (); | ||
792 | 81 | GLTexture * tex (); | ||
793 | 82 | |||
794 | 83 | void directDraw (const CompRect &src, | ||
795 | 84 | const CompRect &dst, | ||
796 | 85 | cglfb::BlitMask mask, | ||
797 | 86 | cglfb::Filter filter); | ||
798 | 87 | |||
799 | 88 | private: | ||
800 | 89 | |||
801 | 90 | GLuint getResourceId () const; | ||
802 | 91 | bool setBindStatus (GLenum); | ||
803 | 92 | void updateAllocation (GLenum); | ||
804 | 93 | |||
805 | 94 | PrivateDirectDrawObject *priv; | ||
806 | 95 | }; | ||
807 | 96 | |||
808 | 97 | typedef boost::function <cglfb::BindableFramebuffer * (cglfb::BindableFramebuffer *)> | ||
809 | 98 | BindReadBufferFunc; | ||
810 | 99 | |||
811 | 100 | bool rectangleDrawFromReadBuffer (const CompRect &src, | ||
812 | 101 | const CompRect &dst, | ||
813 | 102 | GLbitfield mask, | ||
814 | 103 | GLenum filter, | ||
815 | 104 | cglfb::BindableFramebuffer *bindable, | ||
816 | 105 | const BindReadBufferFunc &func, | ||
817 | 106 | cglfb::RectangularDraw strategy); | ||
818 | 107 | } | ||
819 | 108 | } | ||
820 | 109 | } | ||
821 | 110 | |||
822 | 111 | #endif | ||
823 | 0 | 112 | ||
824 | === added directory 'plugins/opengl/src/fbdirectdraw/src' | |||
825 | === added file 'plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp' | |||
826 | --- plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp 1970-01-01 00:00:00 +0000 | |||
827 | +++ plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp 2013-02-28 02:29:22 +0000 | |||
828 | @@ -0,0 +1,177 @@ | |||
829 | 1 | /* | ||
830 | 2 | * Compiz, opengl plugin, DirectDrawFramebufferStrategies class | ||
831 | 3 | * | ||
832 | 4 | * Copyright (c) 2012 Canonical Ltd. | ||
833 | 5 | * Authors: Sam Spilsbury <sam.spilsbury@canonical.com> | ||
834 | 6 | * | ||
835 | 7 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
836 | 8 | * copy of this software and associated documentation files (the "Software"), | ||
837 | 9 | * to deal in the Software without restriction, including without limitation | ||
838 | 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
839 | 11 | * and/or sell copies of the Software, and to permit persons to whom the | ||
840 | 12 | * Software is furnished to do so, subject to the following conditions: | ||
841 | 13 | * | ||
842 | 14 | * The above copyright notice and this permission notice shall be included in | ||
843 | 15 | * all copies or substantial portions of the Software. | ||
844 | 16 | * | ||
845 | 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
846 | 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
847 | 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
848 | 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
849 | 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
850 | 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
851 | 23 | * DEALINGS IN THE SOFTWARE. | ||
852 | 24 | */ | ||
853 | 25 | #include "framebuffer-direct-draw.h" | ||
854 | 26 | |||
855 | 27 | namespace cglfb = compiz::opengl; | ||
856 | 28 | namespace cglfbi = compiz::opengl::impl; | ||
857 | 29 | |||
858 | 30 | class GLTexture; | ||
859 | 31 | class GLVertexBuffer; | ||
860 | 32 | |||
861 | 33 | namespace compiz | ||
862 | 34 | { | ||
863 | 35 | namespace opengl | ||
864 | 36 | { | ||
865 | 37 | namespace impl | ||
866 | 38 | { | ||
867 | 39 | class PrivateDirectDrawStrategies | ||
868 | 40 | { | ||
869 | 41 | public: | ||
870 | 42 | |||
871 | 43 | PrivateDirectDrawStrategies (const cglfb::RectangularDrawList &strategies) : | ||
872 | 44 | rectDrawList (strategies) | ||
873 | 45 | { | ||
874 | 46 | } | ||
875 | 47 | |||
876 | 48 | cglfb::RectangularDrawList rectDrawList; | ||
877 | 49 | }; | ||
878 | 50 | |||
879 | 51 | class PrivateDirectDrawObject | ||
880 | 52 | { | ||
881 | 53 | public: | ||
882 | 54 | |||
883 | 55 | PrivateDirectDrawObject (const boost::shared_ptr <cglfb::DirectDrawStrategies> &strategies, | ||
884 | 56 | const boost::shared_ptr <cglfb::FramebufferObject> &object, | ||
885 | 57 | const boost::shared_ptr <cglfb::BindableFramebuffer> &bindable) : | ||
886 | 58 | directDrawStrategies (strategies), | ||
887 | 59 | framebufferObject (object), | ||
888 | 60 | bindableFramebuffer (bindable) | ||
889 | 61 | { | ||
890 | 62 | }; | ||
891 | 63 | |||
892 | 64 | boost::shared_ptr <cglfb::DirectDrawStrategies> directDrawStrategies; | ||
893 | 65 | boost::shared_ptr <cglfb::FramebufferObject> framebufferObject; | ||
894 | 66 | boost::shared_ptr <cglfb::BindableFramebuffer> bindableFramebuffer; | ||
895 | 67 | }; | ||
896 | 68 | } | ||
897 | 69 | } | ||
898 | 70 | } | ||
899 | 71 | |||
900 | 72 | cglfbi::DirectDrawObject::DirectDrawObject (const boost::shared_ptr <cglfb::DirectDrawStrategies> &strategies, | ||
901 | 73 | const boost::shared_ptr <cglfb::FramebufferObject> &object, | ||
902 | 74 | const boost::shared_ptr <cglfb::BindableFramebuffer> &bindable) : | ||
903 | 75 | priv (new cglfbi::PrivateDirectDrawObject (strategies, object, bindable)) | ||
904 | 76 | { | ||
905 | 77 | } | ||
906 | 78 | |||
907 | 79 | bool | ||
908 | 80 | cglfbi::DirectDrawObject::allocate (const CompSize &size, const char *image, | ||
909 | 81 | GLenum format, GLenum type) | ||
910 | 82 | { | ||
911 | 83 | return priv->framebufferObject->allocate (size, image, format, type); | ||
912 | 84 | } | ||
913 | 85 | |||
914 | 86 | bool | ||
915 | 87 | cglfbi::DirectDrawObject::checkStatus () | ||
916 | 88 | { | ||
917 | 89 | return priv->framebufferObject->checkStatus (); | ||
918 | 90 | } | ||
919 | 91 | |||
920 | 92 | GLTexture * | ||
921 | 93 | cglfbi::DirectDrawObject::tex () | ||
922 | 94 | { | ||
923 | 95 | return priv->framebufferObject->tex (); | ||
924 | 96 | } | ||
925 | 97 | |||
926 | 98 | GLuint | ||
927 | 99 | cglfbi::DirectDrawObject::getResourceId () const | ||
928 | 100 | { | ||
929 | 101 | return priv->bindableFramebuffer->getResourceId (); | ||
930 | 102 | } | ||
931 | 103 | |||
932 | 104 | bool | ||
933 | 105 | cglfbi::DirectDrawObject::setBindStatus (GLenum status) | ||
934 | 106 | { | ||
935 | 107 | return priv->bindableFramebuffer->setBindStatus (status); | ||
936 | 108 | } | ||
937 | 109 | |||
938 | 110 | void | ||
939 | 111 | cglfbi::DirectDrawObject::updateAllocation (GLenum bindPoint) | ||
940 | 112 | { | ||
941 | 113 | return priv->bindableFramebuffer->updateAllocation (bindPoint); | ||
942 | 114 | } | ||
943 | 115 | |||
944 | 116 | void | ||
945 | 117 | cglfbi::DirectDrawObject::directDraw (const CompRect &src, | ||
946 | 118 | const CompRect &dst, | ||
947 | 119 | cglfb::BlitMask mask, | ||
948 | 120 | cglfb::Filter filter) | ||
949 | 121 | { | ||
950 | 122 | if (!checkStatus ()) | ||
951 | 123 | return; | ||
952 | 124 | |||
953 | 125 | priv->directDrawStrategies->draw (src, dst, mask, filter); | ||
954 | 126 | } | ||
955 | 127 | |||
956 | 128 | bool | ||
957 | 129 | cglfbi::rectangleDrawFromReadBuffer (const CompRect &src, | ||
958 | 130 | const CompRect &dst, | ||
959 | 131 | GLbitfield mask, | ||
960 | 132 | GLenum filter, | ||
961 | 133 | cglfb::BindableFramebuffer *bindable, | ||
962 | 134 | const cglfbi::BindReadBufferFunc &bindReadBuffer, | ||
963 | 135 | cglfb::RectangularDraw strategy) | ||
964 | 136 | { | ||
965 | 137 | bool status = false; | ||
966 | 138 | /* Bind to the read framebuffer first */ | ||
967 | 139 | cglfb::BindableFramebuffer *old = bindReadBuffer (bindable); | ||
968 | 140 | |||
969 | 141 | if (old) | ||
970 | 142 | status = strategy (src, dst, mask, filter); | ||
971 | 143 | |||
972 | 144 | /* Intentionally not rebinding the old one */ | ||
973 | 145 | |||
974 | 146 | return status; | ||
975 | 147 | } | ||
976 | 148 | |||
977 | 149 | cglfbi::DirectDrawStrategies::DirectDrawStrategies (const cglfb::RectangularDrawList &strategies) : | ||
978 | 150 | priv (new cglfbi::PrivateDirectDrawStrategies (strategies)) | ||
979 | 151 | { | ||
980 | 152 | } | ||
981 | 153 | |||
982 | 154 | void | ||
983 | 155 | cglfbi::DirectDrawStrategies::draw (const CompRect &src, | ||
984 | 156 | const CompRect &dst, | ||
985 | 157 | cglfb::BlitMask mask, | ||
986 | 158 | cglfb::Filter filter) | ||
987 | 159 | { | ||
988 | 160 | if (!mask) | ||
989 | 161 | return; | ||
990 | 162 | |||
991 | 163 | const GLbitfield glMask = (mask & cglfb::ColorData ? GL_COLOR_BUFFER_BIT : 0) | | ||
992 | 164 | (mask & cglfb::StencilData ? GL_STENCIL_BUFFER_BIT : 0); | ||
993 | 165 | const GLenum glFilter = (filter == cglfb::Fast ? GL_NEAREST : GL_LINEAR); | ||
994 | 166 | |||
995 | 167 | while (!priv->rectDrawList.empty ()) | ||
996 | 168 | { | ||
997 | 169 | const cglfb::RectangularDraw &strategy = priv->rectDrawList.back (); | ||
998 | 170 | |||
999 | 171 | /* If one method fails, try the next */ | ||
1000 | 172 | if (!strategy (src, dst, glMask, glFilter)) | ||
1001 | 173 | priv->rectDrawList.pop_back (); | ||
1002 | 174 | else | ||
1003 | 175 | break; | ||
1004 | 176 | } | ||
1005 | 177 | } | ||
1006 | 0 | 178 | ||
1007 | === added directory 'plugins/opengl/src/fbdirectdraw/tests' | |||
1008 | === added file 'plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt' | |||
1009 | --- plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
1010 | +++ plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt 2013-02-28 02:29:22 +0000 | |||
1011 | @@ -0,0 +1,24 @@ | |||
1012 | 1 | find_library (GMOCK_LIBRARY gmock) | ||
1013 | 2 | find_library (GMOCK_MAIN_LIBRARY gmock_main) | ||
1014 | 3 | |||
1015 | 4 | if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND) | ||
1016 | 5 | message ("Google Mock and Google Test not found - cannot build tests!") | ||
1017 | 6 | set (COMPIZ_BUILD_TESTING OFF) | ||
1018 | 7 | endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND) | ||
1019 | 8 | |||
1020 | 9 | include_directories (${GTEST_INCLUDE_DIRS}) | ||
1021 | 10 | |||
1022 | 11 | link_directories (${COMPIZ_LIBRARY_DIRS}) | ||
1023 | 12 | |||
1024 | 13 | add_executable (compiz_test_opengl_framebuffer_direct_draw | ||
1025 | 14 | ${CMAKE_CURRENT_SOURCE_DIR}/test-opengl-framebuffer-direct-draw.cpp) | ||
1026 | 15 | |||
1027 | 16 | target_link_libraries (compiz_test_opengl_framebuffer_direct_draw | ||
1028 | 17 | compiz_opengl_framebuffer_direct_draw | ||
1029 | 18 | ${GTEST_BOTH_LIBRARIES} | ||
1030 | 19 | ${GMOCK_LIBRARY} | ||
1031 | 20 | ${GMOCK_MAIN_LIBRARY} | ||
1032 | 21 | ${CMAKE_THREAD_LIBS_INIT} # Link in pthread. | ||
1033 | 22 | ) | ||
1034 | 23 | |||
1035 | 24 | compiz_discover_tests (compiz_test_opengl_framebuffer_direct_draw COVERAGE compiz_opengl_framebuffer_direct_draw) | ||
1036 | 0 | 25 | ||
1037 | === added file 'plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp' | |||
1038 | --- plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp 1970-01-01 00:00:00 +0000 | |||
1039 | +++ plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp 2013-02-28 02:29:22 +0000 | |||
1040 | @@ -0,0 +1,237 @@ | |||
1041 | 1 | /* | ||
1042 | 2 | * Compiz, opengl plugin, DirectDrawFramebufferStrategies class | ||
1043 | 3 | * | ||
1044 | 4 | * Copyright (c) 2012 Canonical Ltd. | ||
1045 | 5 | * Authors: Sam Spilsbury <sam.spilsbury@canonical.com> | ||
1046 | 6 | * | ||
1047 | 7 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
1048 | 8 | * copy of this software and associated documentation files (the "Software"), | ||
1049 | 9 | * to deal in the Software without restriction, including without limitation | ||
1050 | 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
1051 | 11 | * and/or sell copies of the Software, and to permit persons to whom the | ||
1052 | 12 | * Software is furnished to do so, subject to the following conditions: | ||
1053 | 13 | * | ||
1054 | 14 | * The above copyright notice and this permission notice shall be included in | ||
1055 | 15 | * all copies or substantial portions of the Software. | ||
1056 | 16 | * | ||
1057 | 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
1058 | 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
1059 | 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
1060 | 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
1061 | 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
1062 | 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
1063 | 23 | * DEALINGS IN THE SOFTWARE. | ||
1064 | 24 | */ | ||
1065 | 25 | #include <memory> | ||
1066 | 26 | #include <boost/function.hpp> | ||
1067 | 27 | #include <boost/bind.hpp> | ||
1068 | 28 | #include <gtest/gtest.h> | ||
1069 | 29 | #include <gmock/gmock.h> | ||
1070 | 30 | #include <opengl/opengl-api.h> | ||
1071 | 31 | #include <opengl/framebufferobject.h> | ||
1072 | 32 | #include "framebuffer-direct-draw.h" | ||
1073 | 33 | |||
1074 | 34 | using ::testing::Return; | ||
1075 | 35 | using ::testing::_; | ||
1076 | 36 | using ::testing::Expectation; | ||
1077 | 37 | using ::testing::StrictMock; | ||
1078 | 38 | using ::testing::NiceMock; | ||
1079 | 39 | using ::testing::ReturnNull; | ||
1080 | 40 | |||
1081 | 41 | namespace cglfb = compiz::opengl; | ||
1082 | 42 | namespace cglfbi = compiz::opengl::impl; | ||
1083 | 43 | |||
1084 | 44 | namespace | ||
1085 | 45 | { | ||
1086 | 46 | class MockDrawStrategy | ||
1087 | 47 | { | ||
1088 | 48 | public: | ||
1089 | 49 | |||
1090 | 50 | MOCK_METHOD4 (draw, bool (const CompRect &, | ||
1091 | 51 | const CompRect &, | ||
1092 | 52 | GLbitfield, | ||
1093 | 53 | GLenum)); | ||
1094 | 54 | }; | ||
1095 | 55 | |||
1096 | 56 | class MockBindLocation : | ||
1097 | 57 | public cglfb::BindLocation | ||
1098 | 58 | { | ||
1099 | 59 | public: | ||
1100 | 60 | |||
1101 | 61 | MOCK_METHOD1 (bind, cglfb::BindableFramebuffer * (cglfb::BindableFramebuffer *)); | ||
1102 | 62 | MOCK_METHOD0 (getCurrentlyBound, cglfb::BindableFramebuffer * ()); | ||
1103 | 63 | }; | ||
1104 | 64 | |||
1105 | 65 | class MockBindable : | ||
1106 | 66 | public cglfb::BindableFramebuffer | ||
1107 | 67 | { | ||
1108 | 68 | public: | ||
1109 | 69 | |||
1110 | 70 | MOCK_METHOD1 (updateAllocation, void (GLenum)); | ||
1111 | 71 | MOCK_METHOD1 (setBindStatus, bool (GLenum)); | ||
1112 | 72 | MOCK_CONST_METHOD0 (getResourceId, GLuint ()); | ||
1113 | 73 | }; | ||
1114 | 74 | |||
1115 | 75 | } | ||
1116 | 76 | |||
1117 | 77 | class FBDirectDrawStrategies : | ||
1118 | 78 | public ::testing::Test | ||
1119 | 79 | { | ||
1120 | 80 | public: | ||
1121 | 81 | |||
1122 | 82 | FBDirectDrawStrategies () : | ||
1123 | 83 | blitFramebuffer (boost::bind (&MockDrawStrategy::draw, &mpfb, _1, _2, _3, _4)), | ||
1124 | 84 | rtdraw (boost::bind (&MockDrawStrategy::draw, &mdr, | ||
1125 | 85 | _1, _2, _3, _4)) | ||
1126 | 86 | { | ||
1127 | 87 | } | ||
1128 | 88 | |||
1129 | 89 | void SetUpStrategyList (const cglfb::RectangularDraw &blit, | ||
1130 | 90 | const cglfb::RectangularDraw &draw) | ||
1131 | 91 | { | ||
1132 | 92 | strategyList.clear (); | ||
1133 | 93 | strategyList.push_back (draw); | ||
1134 | 94 | strategyList.push_back (blit); | ||
1135 | 95 | } | ||
1136 | 96 | |||
1137 | 97 | virtual void SetUp () | ||
1138 | 98 | { | ||
1139 | 99 | boost::function <cglfb::BindableFramebuffer * (cglfb::BindableFramebuffer *)> readBind | ||
1140 | 100 | (boost::bind (&MockBindLocation::bind, &mockBindLocation, _1)); | ||
1141 | 101 | blitFramebufferWithReadPushed = boost::bind (&cglfbi::rectangleDrawFromReadBuffer, | ||
1142 | 102 | _1, _2, _3, _4, | ||
1143 | 103 | &mockBindable, | ||
1144 | 104 | readBind, | ||
1145 | 105 | blitFramebuffer); | ||
1146 | 106 | |||
1147 | 107 | SetUpStrategyList (blitFramebuffer, rtdraw); | ||
1148 | 108 | directDraw.reset (new cglfbi::DirectDrawStrategies (strategyList)); | ||
1149 | 109 | } | ||
1150 | 110 | |||
1151 | 111 | std::auto_ptr <cglfbi::DirectDrawStrategies> directDraw; | ||
1152 | 112 | MockDrawStrategy mpfb; | ||
1153 | 113 | cglfb::RectangularDraw blitFramebuffer; | ||
1154 | 114 | cglfb::RectangularDraw blitFramebufferWithReadPushed; | ||
1155 | 115 | MockDrawStrategy mdr; | ||
1156 | 116 | StrictMock <MockBindable> mockBindable; | ||
1157 | 117 | StrictMock <MockBindLocation> mockBindLocation; | ||
1158 | 118 | cglfb::RectangularDraw rtdraw; | ||
1159 | 119 | cglfb::RectangularDrawList strategyList; | ||
1160 | 120 | |||
1161 | 121 | }; | ||
1162 | 122 | |||
1163 | 123 | TEST_F (FBDirectDrawStrategies, BufferBitsSet) | ||
1164 | 124 | { | ||
1165 | 125 | CompRect srcAndDst (0, 0, 0, 0); | ||
1166 | 126 | |||
1167 | 127 | EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, GL_COLOR_BUFFER_BIT | | ||
1168 | 128 | GL_STENCIL_BUFFER_BIT, | ||
1169 | 129 | _)).WillOnce (Return (true)); | ||
1170 | 130 | |||
1171 | 131 | directDraw->draw (srcAndDst, | ||
1172 | 132 | srcAndDst, | ||
1173 | 133 | static_cast <cglfb::BlitMask> (cglfb::ColorData | | ||
1174 | 134 | cglfb::StencilData), | ||
1175 | 135 | cglfb::Good); | ||
1176 | 136 | } | ||
1177 | 137 | |||
1178 | 138 | TEST_F (FBDirectDrawStrategies, BufferNoBitsSet) | ||
1179 | 139 | { | ||
1180 | 140 | CompRect srcAndDst (0, 0, 0, 0); | ||
1181 | 141 | |||
1182 | 142 | EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, 0, | ||
1183 | 143 | _)).Times (0); | ||
1184 | 144 | |||
1185 | 145 | directDraw->draw (srcAndDst, | ||
1186 | 146 | srcAndDst, | ||
1187 | 147 | static_cast <cglfb::BlitMask> (0), | ||
1188 | 148 | cglfb::Good); | ||
1189 | 149 | } | ||
1190 | 150 | |||
1191 | 151 | TEST_F (FBDirectDrawStrategies, GoodToLinear) | ||
1192 | 152 | { | ||
1193 | 153 | CompRect srcAndDst (0, 0, 0, 0); | ||
1194 | 154 | |||
1195 | 155 | EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, | ||
1196 | 156 | GL_LINEAR)).WillOnce (Return (true)); | ||
1197 | 157 | |||
1198 | 158 | directDraw->draw (srcAndDst, | ||
1199 | 159 | srcAndDst, | ||
1200 | 160 | cglfb::ColorData, | ||
1201 | 161 | cglfb::Good); | ||
1202 | 162 | } | ||
1203 | 163 | |||
1204 | 164 | TEST_F (FBDirectDrawStrategies, FastToNearest) | ||
1205 | 165 | { | ||
1206 | 166 | CompRect srcAndDst (0, 0, 0, 0); | ||
1207 | 167 | |||
1208 | 168 | EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, | ||
1209 | 169 | GL_NEAREST)).WillOnce (Return (true)); | ||
1210 | 170 | |||
1211 | 171 | directDraw->draw (srcAndDst, | ||
1212 | 172 | srcAndDst, | ||
1213 | 173 | cglfb::ColorData, | ||
1214 | 174 | cglfb::Fast); | ||
1215 | 175 | } | ||
1216 | 176 | |||
1217 | 177 | TEST_F (FBDirectDrawStrategies, RevertToPaintWhenBlitUnavailable) | ||
1218 | 178 | { | ||
1219 | 179 | CompRect srcAndDst (0, 0, 0, 0); | ||
1220 | 180 | |||
1221 | 181 | EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, | ||
1222 | 182 | _)).WillOnce (Return (false)); | ||
1223 | 183 | EXPECT_CALL (mdr, draw (srcAndDst, srcAndDst, _, _)); | ||
1224 | 184 | |||
1225 | 185 | directDraw->draw (srcAndDst, | ||
1226 | 186 | srcAndDst, | ||
1227 | 187 | cglfb::ColorData, | ||
1228 | 188 | cglfb::Fast); | ||
1229 | 189 | } | ||
1230 | 190 | |||
1231 | 191 | TEST_F (FBDirectDrawStrategies, RevertOnBlitUnavailablePermanent) | ||
1232 | 192 | { | ||
1233 | 193 | StrictMock <MockDrawStrategy> strictMdr; | ||
1234 | 194 | CompRect srcAndDst (0, 0, 0, 0); | ||
1235 | 195 | |||
1236 | 196 | rtdraw = boost::bind (&MockDrawStrategy::draw, &strictMdr, _1, _2, _3, _4); | ||
1237 | 197 | |||
1238 | 198 | SetUpStrategyList (blitFramebuffer, rtdraw); | ||
1239 | 199 | directDraw.reset (new cglfbi::DirectDrawStrategies (strategyList)); | ||
1240 | 200 | |||
1241 | 201 | EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, _)).WillOnce (Return (false)); | ||
1242 | 202 | ON_CALL (strictMdr, draw (_, _, _, _)).WillByDefault (Return (true)); | ||
1243 | 203 | EXPECT_CALL (strictMdr, draw (srcAndDst, srcAndDst, _, _)).Times (2); | ||
1244 | 204 | |||
1245 | 205 | directDraw->draw (srcAndDst, | ||
1246 | 206 | srcAndDst, | ||
1247 | 207 | cglfb::ColorData, | ||
1248 | 208 | cglfb::Fast); | ||
1249 | 209 | directDraw->draw (srcAndDst, | ||
1250 | 210 | srcAndDst, | ||
1251 | 211 | cglfb::ColorData, | ||
1252 | 212 | cglfb::Fast); | ||
1253 | 213 | } | ||
1254 | 214 | |||
1255 | 215 | TEST_F (FBDirectDrawStrategies, BindReadFramebufferOnBlit) | ||
1256 | 216 | { | ||
1257 | 217 | CompRect srcAndDst (0, 0, 0, 0); | ||
1258 | 218 | |||
1259 | 219 | SetUpStrategyList (blitFramebufferWithReadPushed, rtdraw); | ||
1260 | 220 | directDraw.reset (new cglfbi::DirectDrawStrategies (strategyList)); | ||
1261 | 221 | |||
1262 | 222 | MockBindable backBuffer; | ||
1263 | 223 | |||
1264 | 224 | EXPECT_CALL (mockBindLocation, bind (&mockBindable)).WillOnce (Return (&backBuffer)); | ||
1265 | 225 | EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, _)).WillOnce (Return (false)); | ||
1266 | 226 | ON_CALL (mdr, draw (_, _, _, _)).WillByDefault (Return (true)); | ||
1267 | 227 | EXPECT_CALL (mdr, draw (srcAndDst, srcAndDst, _, _)).Times (2); | ||
1268 | 228 | |||
1269 | 229 | directDraw->draw (srcAndDst, | ||
1270 | 230 | srcAndDst, | ||
1271 | 231 | cglfb::ColorData, | ||
1272 | 232 | cglfb::Fast); | ||
1273 | 233 | directDraw->draw (srcAndDst, | ||
1274 | 234 | srcAndDst, | ||
1275 | 235 | cglfb::ColorData, | ||
1276 | 236 | cglfb::Fast); | ||
1277 | 237 | } | ||
1278 | 0 | 238 | ||
1279 | === modified file 'plugins/opengl/src/framebufferobject.cpp' | |||
1280 | --- plugins/opengl/src/framebufferobject.cpp 2012-08-06 09:44:49 +0000 | |||
1281 | +++ plugins/opengl/src/framebufferobject.cpp 2013-02-28 02:29:22 +0000 | |||
1282 | @@ -22,88 +22,96 @@ | |||
1283 | 22 | * | 22 | * |
1284 | 23 | * Authors: Pekka Paalanen <ppaalanen@gmail.com> | 23 | * Authors: Pekka Paalanen <ppaalanen@gmail.com> |
1285 | 24 | */ | 24 | */ |
1287 | 25 | 25 | #include <memory> | |
1288 | 26 | #include <map> | 26 | #include <map> |
1289 | 27 | #include <opengl/opengl.h> | ||
1290 | 27 | #include <opengl/framebufferobject.h> | 28 | #include <opengl/framebufferobject.h> |
1291 | 28 | #include <opengl/texture.h> | 29 | #include <opengl/texture.h> |
1292 | 29 | 30 | ||
1293 | 31 | #include "framebuffer-direct-draw.h" | ||
1294 | 32 | |||
1295 | 33 | namespace cglfb = compiz::opengl; | ||
1296 | 34 | namespace cglfbi = compiz::opengl::impl; | ||
1297 | 35 | |||
1298 | 36 | namespace compiz | ||
1299 | 37 | { | ||
1300 | 38 | namespace opengl | ||
1301 | 39 | { | ||
1302 | 40 | namespace impl | ||
1303 | 41 | { | ||
1304 | 30 | struct PrivateGLFramebufferObject | 42 | struct PrivateGLFramebufferObject |
1305 | 31 | { | 43 | { |
1306 | 32 | PrivateGLFramebufferObject () : | 44 | PrivateGLFramebufferObject () : |
1307 | 33 | fboId (0), | 45 | fboId (0), |
1308 | 34 | pushedId (0), | ||
1309 | 35 | glTex (NULL), | 46 | glTex (NULL), |
1310 | 36 | status (-1) | 47 | status (-1) |
1311 | 37 | { | 48 | { |
1312 | 38 | } | 49 | } |
1313 | 39 | 50 | ||
1314 | 40 | void pushFBO (); | ||
1315 | 41 | void popFBO (); | ||
1316 | 42 | |||
1317 | 43 | GLuint fboId; | 51 | GLuint fboId; |
1318 | 44 | GLuint pushedId; | ||
1319 | 45 | GLuint rbStencilId; | 52 | GLuint rbStencilId; |
1320 | 46 | GLTexture *glTex; | 53 | GLTexture *glTex; |
1321 | 47 | 54 | ||
1322 | 48 | GLint status; | 55 | GLint status; |
1323 | 49 | 56 | ||
1326 | 50 | static GLuint boundId; | 57 | std::auto_ptr <cglfb::DirectDrawStrategies> mDirectDraw; |
1327 | 51 | static std::map<GLuint, GLFramebufferObject *> idMap; | 58 | GLVertexBuffer *vertexBuffer; |
1328 | 52 | }; | 59 | }; |
1329 | 53 | 60 | ||
1356 | 54 | GLuint PrivateGLFramebufferObject::boundId = 0; | 61 | } |
1357 | 55 | std::map<GLuint, GLFramebufferObject *> PrivateGLFramebufferObject::idMap; | 62 | } |
1358 | 56 | 63 | } | |
1359 | 57 | void | 64 | |
1360 | 58 | PrivateGLFramebufferObject::pushFBO () | 65 | GLuint |
1361 | 59 | { | 66 | cglfbi::FramebufferObject::getResourceId () const |
1362 | 60 | pushedId = boundId; | 67 | { |
1363 | 61 | if (boundId != fboId) | 68 | return priv->fboId; |
1364 | 62 | { | 69 | } |
1365 | 63 | (*GL::bindFramebuffer) (GL::FRAMEBUFFER, fboId); | 70 | |
1366 | 64 | boundId = fboId; | 71 | bool |
1367 | 65 | } | 72 | cglfbi::FramebufferObject::setBindStatus (GLenum status) |
1368 | 66 | } | 73 | { |
1369 | 67 | 74 | priv->status = status; | |
1370 | 68 | void | 75 | return checkStatus (); |
1371 | 69 | PrivateGLFramebufferObject::popFBO () | 76 | } |
1372 | 70 | { | 77 | |
1373 | 71 | if (boundId != pushedId) | 78 | void |
1374 | 72 | { | 79 | cglfbi::FramebufferObject::updateAllocation (GLenum bindingLocation) |
1375 | 73 | (*GL::bindFramebuffer) (GL::FRAMEBUFFER, pushedId); | 80 | { |
1376 | 74 | boundId = pushedId; | 81 | if (priv->status == -1) |
1377 | 75 | } | 82 | { |
1378 | 76 | } | 83 | (*GL::framebufferTexture2D) (bindingLocation, GL::COLOR_ATTACHMENT0, |
1379 | 77 | 84 | priv->glTex->target (), | |
1380 | 78 | GLFramebufferObject::GLFramebufferObject () : | 85 | priv->glTex->name (), 0); |
1381 | 79 | priv (new PrivateGLFramebufferObject) | 86 | (*GL::framebufferRenderbuffer) (bindingLocation, GL::DEPTH_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId); |
1382 | 87 | (*GL::framebufferRenderbuffer) (bindingLocation, GL::STENCIL_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId); | ||
1383 | 88 | } | ||
1384 | 89 | |||
1385 | 90 | } | ||
1386 | 91 | |||
1387 | 92 | cglfbi::FramebufferObject::FramebufferObject () : | ||
1388 | 93 | priv (new cglfbi::PrivateGLFramebufferObject ()) | ||
1389 | 80 | { | 94 | { |
1390 | 81 | (*GL::genFramebuffers) (1, &priv->fboId); | 95 | (*GL::genFramebuffers) (1, &priv->fboId); |
1391 | 82 | (*GL::genRenderbuffers) (1, &priv->rbStencilId); | 96 | (*GL::genRenderbuffers) (1, &priv->rbStencilId); |
1392 | 83 | |||
1393 | 84 | if (priv->fboId != 0) | ||
1394 | 85 | PrivateGLFramebufferObject::idMap[priv->fboId] = this; | ||
1395 | 86 | } | 97 | } |
1396 | 87 | 98 | ||
1398 | 88 | GLFramebufferObject::~GLFramebufferObject () | 99 | cglfbi::FramebufferObject::~FramebufferObject () |
1399 | 89 | { | 100 | { |
1400 | 90 | if (priv->glTex) | 101 | if (priv->glTex) |
1401 | 91 | GLTexture::decRef (priv->glTex); | 102 | GLTexture::decRef (priv->glTex); |
1402 | 92 | 103 | ||
1403 | 93 | PrivateGLFramebufferObject::idMap.erase (priv->fboId); | ||
1404 | 94 | (*GL::deleteFramebuffers) (1, &priv->fboId); | 104 | (*GL::deleteFramebuffers) (1, &priv->fboId); |
1405 | 95 | (*GL::deleteRenderbuffers) (1, &priv->rbStencilId); | 105 | (*GL::deleteRenderbuffers) (1, &priv->rbStencilId); |
1406 | 96 | 106 | ||
1407 | 97 | |||
1408 | 98 | delete priv; | 107 | delete priv; |
1409 | 99 | } | 108 | } |
1410 | 100 | 109 | ||
1411 | 101 | bool | 110 | bool |
1414 | 102 | GLFramebufferObject::allocate (const CompSize &size, const char *image, | 111 | cglfbi::FramebufferObject::allocate (const CompSize &size, |
1415 | 103 | GLenum format, GLenum type) | 112 | const char *image, |
1416 | 113 | GLenum format, GLenum type) | ||
1417 | 104 | { | 114 | { |
1418 | 105 | priv->status = -1; | ||
1419 | 106 | |||
1420 | 107 | if (!priv->glTex || | 115 | if (!priv->glTex || |
1421 | 108 | size.width () != priv->glTex->width () || | 116 | size.width () != priv->glTex->width () || |
1422 | 109 | size.height () != priv->glTex->height ()) | 117 | size.height () != priv->glTex->height ()) |
1423 | @@ -125,86 +133,39 @@ | |||
1424 | 125 | (*GL::bindRenderbuffer) (GL::RENDERBUFFER, priv->rbStencilId); | 133 | (*GL::bindRenderbuffer) (GL::RENDERBUFFER, priv->rbStencilId); |
1425 | 126 | (*GL::renderbufferStorage) (GL::RENDERBUFFER, GL::DEPTH24_STENCIL8, size.width (), size.height ()); | 134 | (*GL::renderbufferStorage) (GL::RENDERBUFFER, GL::DEPTH24_STENCIL8, size.width (), size.height ()); |
1426 | 127 | } | 135 | } |
1427 | 136 | |||
1428 | 137 | priv->status = -1; | ||
1429 | 128 | } | 138 | } |
1430 | 129 | 139 | ||
1431 | 130 | priv->pushFBO (); | ||
1432 | 131 | |||
1433 | 132 | (*GL::framebufferTexture2D) (GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, | ||
1434 | 133 | priv->glTex->target (), | ||
1435 | 134 | priv->glTex->name (), 0); | ||
1436 | 135 | |||
1437 | 136 | priv->status = (*GL::checkFramebufferStatus) (GL::DRAW_FRAMEBUFFER); | ||
1438 | 137 | |||
1439 | 138 | priv->popFBO (); | ||
1440 | 139 | return true; | 140 | return true; |
1441 | 140 | } | 141 | } |
1442 | 141 | 142 | ||
1483 | 142 | GLFramebufferObject * | 143 | namespace |
1484 | 143 | GLFramebufferObject::bind () | 144 | { |
1485 | 144 | { | 145 | const char * |
1446 | 145 | GLFramebufferObject *old = NULL; | ||
1447 | 146 | |||
1448 | 147 | if (priv->boundId != 0) | ||
1449 | 148 | { | ||
1450 | 149 | std::map<GLuint, GLFramebufferObject *>::iterator it; | ||
1451 | 150 | it = PrivateGLFramebufferObject::idMap.find (priv->boundId); | ||
1452 | 151 | |||
1453 | 152 | if (it != PrivateGLFramebufferObject::idMap.end ()) | ||
1454 | 153 | old = it->second; | ||
1455 | 154 | else | ||
1456 | 155 | compLogMessage ("opengl", CompLogLevelError, | ||
1457 | 156 | "An FBO without GLFramebufferObject cannot be restored"); | ||
1458 | 157 | } | ||
1459 | 158 | |||
1460 | 159 | (*GL::bindFramebuffer) (GL::FRAMEBUFFER, priv->fboId); | ||
1461 | 160 | priv->boundId = priv->fboId; | ||
1462 | 161 | |||
1463 | 162 | (*GL::framebufferRenderbuffer) (GL::FRAMEBUFFER, GL::DEPTH_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId); | ||
1464 | 163 | (*GL::framebufferRenderbuffer) (GL::FRAMEBUFFER, GL::STENCIL_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId); | ||
1465 | 164 | |||
1466 | 165 | return old; | ||
1467 | 166 | } | ||
1468 | 167 | |||
1469 | 168 | // static | ||
1470 | 169 | void | ||
1471 | 170 | GLFramebufferObject::rebind (GLFramebufferObject *fbo) | ||
1472 | 171 | { | ||
1473 | 172 | GLuint id = fbo ? fbo->priv->fboId : 0; | ||
1474 | 173 | |||
1475 | 174 | if (id != fbo->priv->boundId) | ||
1476 | 175 | { | ||
1477 | 176 | (*GL::bindFramebuffer) (GL::FRAMEBUFFER, id); | ||
1478 | 177 | fbo->priv->boundId = id; | ||
1479 | 178 | } | ||
1480 | 179 | } | ||
1481 | 180 | |||
1482 | 181 | static const char * | ||
1486 | 182 | getFboErrorString (GLint status) | 146 | getFboErrorString (GLint status) |
1487 | 183 | { | 147 | { |
1488 | 184 | switch (status) | 148 | switch (status) |
1489 | 185 | { | 149 | { |
1491 | 186 | case GL::FRAMEBUFFER_COMPLETE: | 150 | case GL::FRAMEBUFFER_COMPLETE: |
1492 | 187 | return "GL::FRAMEBUFFER_COMPLETE"; | 151 | return "GL::FRAMEBUFFER_COMPLETE"; |
1494 | 188 | case GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT: | 152 | case GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT: |
1495 | 189 | return "GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; | 153 | return "GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; |
1497 | 190 | case GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: | 154 | case GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: |
1498 | 191 | return "GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; | 155 | return "GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; |
1500 | 192 | case GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS: | 156 | case GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS: |
1501 | 193 | return "GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; | 157 | return "GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; |
1503 | 194 | case GL::FRAMEBUFFER_UNSUPPORTED: | 158 | case GL::FRAMEBUFFER_UNSUPPORTED: |
1504 | 195 | return "GL::FRAMEBUFFER_UNSUPPORTED"; | 159 | return "GL::FRAMEBUFFER_UNSUPPORTED"; |
1505 | 196 | default: | 160 | default: |
1506 | 197 | return "unexpected status"; | 161 | return "unexpected status"; |
1507 | 198 | } | 162 | } |
1508 | 199 | } | 163 | } |
1509 | 164 | } | ||
1510 | 200 | 165 | ||
1511 | 201 | bool | 166 | bool |
1513 | 202 | GLFramebufferObject::checkStatus () | 167 | cglfbi::FramebufferObject::checkStatus () |
1514 | 203 | { | 168 | { |
1515 | 204 | priv->pushFBO (); | ||
1516 | 205 | priv-> status = (*GL::checkFramebufferStatus) (GL_FRAMEBUFFER); | ||
1517 | 206 | priv->popFBO (); | ||
1518 | 207 | |||
1519 | 208 | if (priv->status == static_cast <GLint> (GL::FRAMEBUFFER_COMPLETE)) | 169 | if (priv->status == static_cast <GLint> (GL::FRAMEBUFFER_COMPLETE)) |
1520 | 209 | return true; | 170 | return true; |
1521 | 210 | 171 | ||
1522 | @@ -215,7 +176,54 @@ | |||
1523 | 215 | } | 176 | } |
1524 | 216 | 177 | ||
1525 | 217 | GLTexture * | 178 | GLTexture * |
1527 | 218 | GLFramebufferObject::tex () | 179 | cglfbi::FramebufferObject::tex () |
1528 | 219 | { | 180 | { |
1529 | 220 | return priv->glTex; | 181 | return priv->glTex; |
1530 | 221 | } | 182 | } |
1531 | 183 | |||
1532 | 184 | class cglfbi::FBOBindLocation::Private | ||
1533 | 185 | { | ||
1534 | 186 | public: | ||
1535 | 187 | |||
1536 | 188 | Private (GLenum binding, | ||
1537 | 189 | cglfb::BindableFramebuffer *back) : | ||
1538 | 190 | mCurrentlyBound (back), | ||
1539 | 191 | mBindPoint (binding) | ||
1540 | 192 | { | ||
1541 | 193 | } | ||
1542 | 194 | |||
1543 | 195 | cglfb::BindableFramebuffer *mCurrentlyBound; | ||
1544 | 196 | GLenum mBindPoint; | ||
1545 | 197 | }; | ||
1546 | 198 | |||
1547 | 199 | cglfbi::FBOBindLocation::FBOBindLocation (GLenum binding, | ||
1548 | 200 | cglfb::BindableFramebuffer *back) : | ||
1549 | 201 | priv (new cglfbi::FBOBindLocation::Private (binding, back)) | ||
1550 | 202 | { | ||
1551 | 203 | } | ||
1552 | 204 | |||
1553 | 205 | cglfb::BindableFramebuffer * | ||
1554 | 206 | cglfbi::FBOBindLocation::bind (cglfb::BindableFramebuffer *next) | ||
1555 | 207 | { | ||
1556 | 208 | if (priv->mCurrentlyBound == next) | ||
1557 | 209 | return next; | ||
1558 | 210 | |||
1559 | 211 | (*GL::bindFramebuffer) (priv->mBindPoint, next->getResourceId ()); | ||
1560 | 212 | next->updateAllocation (priv->mBindPoint); | ||
1561 | 213 | if (!next->setBindStatus ((*GL::checkFramebufferStatus) (priv->mBindPoint))) | ||
1562 | 214 | { | ||
1563 | 215 | (*GL::bindFramebuffer) (priv->mBindPoint, priv->mCurrentlyBound->getResourceId ()); | ||
1564 | 216 | return NULL; | ||
1565 | 217 | } | ||
1566 | 218 | |||
1567 | 219 | cglfb::BindableFramebuffer *last = priv->mCurrentlyBound; | ||
1568 | 220 | priv->mCurrentlyBound = next; | ||
1569 | 221 | return last; | ||
1570 | 222 | } | ||
1571 | 223 | |||
1572 | 224 | cglfb::BindableFramebuffer * | ||
1573 | 225 | cglfbi::FBOBindLocation::getCurrentlyBound () | ||
1574 | 226 | { | ||
1575 | 227 | return priv->mCurrentlyBound; | ||
1576 | 228 | } | ||
1577 | 229 | |||
1578 | 222 | 230 | ||
1579 | === modified file 'plugins/opengl/src/paint.cpp' | |||
1580 | --- plugins/opengl/src/paint.cpp 2013-01-03 16:05:26 +0000 | |||
1581 | +++ plugins/opengl/src/paint.cpp 2013-02-28 02:29:22 +0000 | |||
1582 | @@ -44,6 +44,7 @@ | |||
1583 | 44 | #define DEG2RAD (M_PI / 180.0f) | 44 | #define DEG2RAD (M_PI / 180.0f) |
1584 | 45 | 45 | ||
1585 | 46 | using namespace compiz::opengl; | 46 | using namespace compiz::opengl; |
1586 | 47 | namespace cglfb = compiz::opengl; | ||
1587 | 47 | 48 | ||
1588 | 48 | GLScreenPaintAttrib defaultScreenPaintAttrib = { | 49 | GLScreenPaintAttrib defaultScreenPaintAttrib = { |
1589 | 49 | 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA | 50 | 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA |
1590 | @@ -432,6 +433,8 @@ | |||
1591 | 432 | continue; | 433 | continue; |
1592 | 433 | } | 434 | } |
1593 | 434 | 435 | ||
1594 | 436 | gw = GLWindow::get (w); | ||
1595 | 437 | |||
1596 | 435 | const CompRegion &clip = | 438 | const CompRegion &clip = |
1597 | 436 | (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) ? | 439 | (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK)) ? |
1598 | 437 | gw->clip () : region; | 440 | gw->clip () : region; |
1599 | @@ -672,89 +675,16 @@ | |||
1600 | 672 | } | 675 | } |
1601 | 673 | 676 | ||
1602 | 674 | void | 677 | void |
1606 | 675 | GLScreen::glPaintCompositedOutput (const CompRegion ®ion, | 678 | GLScreen::glPaintCompositedOutput (const CompRegion ®ion, |
1607 | 676 | GLFramebufferObject *fbo, | 679 | compiz::opengl::DirectDrawObject *fbo, |
1608 | 677 | unsigned int mask) | 680 | unsigned int mask) |
1609 | 678 | { | 681 | { |
1610 | 679 | WRAPABLE_HND_FUNCTN (glPaintCompositedOutput, region, fbo, mask) | 682 | WRAPABLE_HND_FUNCTN (glPaintCompositedOutput, region, fbo, mask) |
1611 | 680 | 683 | ||
1689 | 681 | GLMatrix sTransform; | 684 | /* Draw every rect individually, this could be a little slow |
1690 | 682 | const GLTexture::Matrix & texmatrix = fbo->tex ()->matrix (); | 685 | * for lots of rects, but the general usecase isn't that */ |
1691 | 683 | GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer (); | 686 | foreach (const CompRect &r, region.rects ()) |
1692 | 684 | 687 | fbo->directDraw (r, r, cglfb::ColorData, cglfb::Fast); | |
1616 | 685 | streamingBuffer->begin (GL_TRIANGLES); | ||
1617 | 686 | |||
1618 | 687 | if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) | ||
1619 | 688 | { | ||
1620 | 689 | GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, 0.0f); | ||
1621 | 690 | GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, screen->width ()); | ||
1622 | 691 | GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, 0.0f); | ||
1623 | 692 | GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, screen->height ()); | ||
1624 | 693 | |||
1625 | 694 | const GLfloat vertexData[] = { | ||
1626 | 695 | 0.0f, 0.0f, 0.0f, | ||
1627 | 696 | 0.0f, (float)screen->height (), 0.0f, | ||
1628 | 697 | (float)screen->width (), 0.0f, 0.0f, | ||
1629 | 698 | |||
1630 | 699 | 0.0f, (float)screen->height (), 0.0f, | ||
1631 | 700 | (float)screen->width (), (float)screen->height (), 0.0f, | ||
1632 | 701 | (float)screen->width (), 0.0f, 0.0f, | ||
1633 | 702 | }; | ||
1634 | 703 | |||
1635 | 704 | const GLfloat textureData[] = { | ||
1636 | 705 | tx1, ty1, | ||
1637 | 706 | tx1, ty2, | ||
1638 | 707 | tx2, ty1, | ||
1639 | 708 | tx1, ty2, | ||
1640 | 709 | tx2, ty2, | ||
1641 | 710 | tx2, ty1, | ||
1642 | 711 | }; | ||
1643 | 712 | |||
1644 | 713 | streamingBuffer->addVertices (6, &vertexData[0]); | ||
1645 | 714 | streamingBuffer->addTexCoords (0, 6, &textureData[0]); | ||
1646 | 715 | } | ||
1647 | 716 | else | ||
1648 | 717 | { | ||
1649 | 718 | BoxPtr pBox = const_cast <Region> (region.handle ())->rects; | ||
1650 | 719 | int nBox = const_cast <Region> (region.handle ())->numRects; | ||
1651 | 720 | |||
1652 | 721 | while (nBox--) | ||
1653 | 722 | { | ||
1654 | 723 | GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, pBox->x1); | ||
1655 | 724 | GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, pBox->x2); | ||
1656 | 725 | GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y1); | ||
1657 | 726 | GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y2); | ||
1658 | 727 | |||
1659 | 728 | const GLfloat vertexData[] = { | ||
1660 | 729 | (float)pBox->x1, (float)pBox->y1, 0.0f, | ||
1661 | 730 | (float)pBox->x1, (float)pBox->y2, 0.0f, | ||
1662 | 731 | (float)pBox->x2, (float)pBox->y1, 0.0f, | ||
1663 | 732 | |||
1664 | 733 | (float)pBox->x1, (float)pBox->y2, 0.0f, | ||
1665 | 734 | (float)pBox->x2, (float)pBox->y2, 0.0f, | ||
1666 | 735 | (float)pBox->x2, (float)pBox->y1, 0.0f, | ||
1667 | 736 | }; | ||
1668 | 737 | |||
1669 | 738 | const GLfloat textureData[] = { | ||
1670 | 739 | tx1, ty1, | ||
1671 | 740 | tx1, ty2, | ||
1672 | 741 | tx2, ty1, | ||
1673 | 742 | tx1, ty2, | ||
1674 | 743 | tx2, ty2, | ||
1675 | 744 | tx2, ty1, | ||
1676 | 745 | }; | ||
1677 | 746 | |||
1678 | 747 | streamingBuffer->addVertices (6, &vertexData[0]); | ||
1679 | 748 | streamingBuffer->addTexCoords (0, 6, &textureData[0]); | ||
1680 | 749 | pBox++; | ||
1681 | 750 | } | ||
1682 | 751 | } | ||
1683 | 752 | |||
1684 | 753 | streamingBuffer->end (); | ||
1685 | 754 | fbo->tex ()->enable (GLTexture::Fast); | ||
1686 | 755 | sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA); | ||
1687 | 756 | streamingBuffer->render (sTransform); | ||
1688 | 757 | fbo->tex ()->disable (); | ||
1693 | 758 | } | 688 | } |
1694 | 759 | 689 | ||
1695 | 760 | static void | 690 | static void |
1696 | 761 | 691 | ||
1697 | === modified file 'plugins/opengl/src/privates.h' | |||
1698 | --- plugins/opengl/src/privates.h 2013-01-03 16:05:26 +0000 | |||
1699 | +++ plugins/opengl/src/privates.h 2013-02-28 02:29:22 +0000 | |||
1700 | @@ -29,22 +29,28 @@ | |||
1701 | 29 | #define _OPENGL_PRIVATES_H | 29 | #define _OPENGL_PRIVATES_H |
1702 | 30 | 30 | ||
1703 | 31 | #include <memory> | 31 | #include <memory> |
1704 | 32 | |||
1705 | 33 | #include <composite/composite.h> | 32 | #include <composite/composite.h> |
1706 | 34 | #include <opengl/opengl.h> | 33 | #include <opengl/opengl.h> |
1707 | 35 | #include <core/atoms.h> | 34 | #include <core/atoms.h> |
1708 | 36 | #include <core/configurerequestbuffer.h> | 35 | #include <core/configurerequestbuffer.h> |
1709 | 37 | |||
1710 | 38 | #ifdef USE_GLES | ||
1711 | 39 | #include <opengl/framebufferobject.h> | 36 | #include <opengl/framebufferobject.h> |
1712 | 40 | #endif | ||
1713 | 41 | |||
1714 | 42 | #include <opengl/doublebuffer.h> | 37 | #include <opengl/doublebuffer.h> |
1715 | 43 | 38 | ||
1716 | 44 | #include "privatetexture.h" | 39 | #include "privatetexture.h" |
1717 | 45 | #include "privatevertexbuffer.h" | 40 | #include "privatevertexbuffer.h" |
1718 | 46 | #include "opengl_options.h" | 41 | #include "opengl_options.h" |
1719 | 47 | 42 | ||
1720 | 43 | namespace compiz | ||
1721 | 44 | { | ||
1722 | 45 | namespace opengl | ||
1723 | 46 | { | ||
1724 | 47 | namespace impl | ||
1725 | 48 | { | ||
1726 | 49 | class DirectDrawObject; | ||
1727 | 50 | } | ||
1728 | 51 | } | ||
1729 | 52 | } | ||
1730 | 53 | |||
1731 | 48 | extern CompOutput *targetOutput; | 54 | extern CompOutput *targetOutput; |
1732 | 49 | 55 | ||
1733 | 50 | class GLDoubleBuffer : | 56 | class GLDoubleBuffer : |
1734 | @@ -86,6 +92,17 @@ | |||
1735 | 86 | Window mOutput; | 92 | Window mOutput; |
1736 | 87 | }; | 93 | }; |
1737 | 88 | 94 | ||
1738 | 95 | namespace compiz | ||
1739 | 96 | { | ||
1740 | 97 | namespace opengl | ||
1741 | 98 | { | ||
1742 | 99 | bool blitFramebufferGLX (const CompRect &src, | ||
1743 | 100 | const CompRect &dst, | ||
1744 | 101 | GLbitfield mask, | ||
1745 | 102 | GLenum filter); | ||
1746 | 103 | } | ||
1747 | 104 | } | ||
1748 | 105 | |||
1749 | 89 | #else | 106 | #else |
1750 | 90 | 107 | ||
1751 | 91 | class EGLDoubleBuffer : | 108 | class EGLDoubleBuffer : |
1752 | @@ -109,6 +126,17 @@ | |||
1753 | 109 | EGLSurface const & mSurface; | 126 | EGLSurface const & mSurface; |
1754 | 110 | }; | 127 | }; |
1755 | 111 | 128 | ||
1756 | 129 | namespace compiz | ||
1757 | 130 | { | ||
1758 | 131 | namespace opengl | ||
1759 | 132 | { | ||
1760 | 133 | bool blitFramebufferEGL (const CompRect &src, | ||
1761 | 134 | const CompRect &dst, | ||
1762 | 135 | GLbitfield mask, | ||
1763 | 136 | GLenum filter); | ||
1764 | 137 | } | ||
1765 | 138 | } | ||
1766 | 139 | |||
1767 | 112 | #endif | 140 | #endif |
1768 | 113 | 141 | ||
1769 | 114 | class GLIcon | 142 | class GLIcon |
1770 | @@ -120,6 +148,16 @@ | |||
1771 | 120 | GLTexture::List textures; | 148 | GLTexture::List textures; |
1772 | 121 | }; | 149 | }; |
1773 | 122 | 150 | ||
1774 | 151 | class BindableBackbuffer : | ||
1775 | 152 | public compiz::opengl::BindableFramebuffer | ||
1776 | 153 | { | ||
1777 | 154 | public: | ||
1778 | 155 | |||
1779 | 156 | GLuint getResourceId () const; | ||
1780 | 157 | bool setBindStatus (GLenum); | ||
1781 | 158 | void updateAllocation (GLenum); | ||
1782 | 159 | }; | ||
1783 | 160 | |||
1784 | 123 | class PrivateGLScreen : | 161 | class PrivateGLScreen : |
1785 | 124 | public ScreenInterface, | 162 | public ScreenInterface, |
1786 | 125 | public compiz::composite::PaintHandler, | 163 | public compiz::composite::PaintHandler, |
1787 | @@ -197,8 +235,9 @@ | |||
1788 | 197 | GLXDoubleBuffer doubleBuffer; | 235 | GLXDoubleBuffer doubleBuffer; |
1789 | 198 | #endif | 236 | #endif |
1790 | 199 | 237 | ||
1793 | 200 | GLFramebufferObject *scratchFbo; | 238 | std::auto_ptr <compiz::opengl::DirectDrawObject> scratchFbo; |
1794 | 201 | CompRegion outputRegion; | 239 | compiz::opengl::BlitFramebufferFunc blitFramebuffer; |
1795 | 240 | CompRegion outputRegion; | ||
1796 | 202 | 241 | ||
1797 | 203 | XRectangle lastViewport; | 242 | XRectangle lastViewport; |
1798 | 204 | bool refreshSubBuffer; | 243 | bool refreshSubBuffer; |
1799 | @@ -222,6 +261,9 @@ | |||
1800 | 222 | Pixmap rootPixmapCopy; | 261 | Pixmap rootPixmapCopy; |
1801 | 223 | CompSize rootPixmapSize; | 262 | CompSize rootPixmapSize; |
1802 | 224 | 263 | ||
1803 | 264 | BindableBackbuffer backbuffer; | ||
1804 | 265 | compiz::opengl::impl::FBOBindLocation drawFramebufferBinding; | ||
1805 | 266 | compiz::opengl::impl::FBOBindLocation readFramebufferBinding; | ||
1806 | 225 | const char *glVendor, *glRenderer, *glVersion; | 267 | const char *glVendor, *glRenderer, *glVersion; |
1807 | 226 | 268 | ||
1808 | 227 | mutable CompString prevRegex; | 269 | mutable CompString prevRegex; |
1809 | 228 | 270 | ||
1810 | === modified file 'plugins/opengl/src/screen.cpp' | |||
1811 | --- plugins/opengl/src/screen.cpp 2013-01-09 10:57:03 +0000 | |||
1812 | +++ plugins/opengl/src/screen.cpp 2013-02-28 02:29:22 +0000 | |||
1813 | @@ -36,6 +36,7 @@ | |||
1814 | 36 | #include <boost/make_shared.hpp> | 36 | #include <boost/make_shared.hpp> |
1815 | 37 | 37 | ||
1816 | 38 | #include "privates.h" | 38 | #include "privates.h" |
1817 | 39 | #include "framebuffer-direct-draw.h" | ||
1818 | 39 | #include "blacklist/blacklist.h" | 40 | #include "blacklist/blacklist.h" |
1819 | 40 | 41 | ||
1820 | 41 | #include <dlfcn.h> | 42 | #include <dlfcn.h> |
1821 | @@ -67,6 +68,26 @@ | |||
1822 | 67 | 68 | ||
1823 | 68 | 69 | ||
1824 | 69 | using namespace compiz::opengl; | 70 | using namespace compiz::opengl; |
1825 | 71 | namespace cglfb = compiz::opengl; | ||
1826 | 72 | namespace cgli = compiz::opengl::impl; | ||
1827 | 73 | |||
1828 | 74 | namespace compiz | ||
1829 | 75 | { | ||
1830 | 76 | namespace opengl | ||
1831 | 77 | { | ||
1832 | 78 | #ifndef USE_GLES | ||
1833 | 79 | bool blitFramebufferGLX (const CompRect &src, | ||
1834 | 80 | const CompRect &dst, | ||
1835 | 81 | GLbitfield mask, | ||
1836 | 82 | GLenum filter); | ||
1837 | 83 | #else | ||
1838 | 84 | bool blitFramebufferEGL (const CompRect &src, | ||
1839 | 85 | const CompRect &dst, | ||
1840 | 86 | GLbitfield mask, | ||
1841 | 87 | GLenum filter); | ||
1842 | 88 | #endif | ||
1843 | 89 | } | ||
1844 | 90 | } | ||
1845 | 70 | 91 | ||
1846 | 71 | namespace GL { | 92 | namespace GL { |
1847 | 72 | #ifdef USE_GLES | 93 | #ifdef USE_GLES |
1848 | @@ -164,11 +185,12 @@ | |||
1849 | 164 | GLDisableVertexAttribArrayProc disableVertexAttribArray = NULL; | 185 | GLDisableVertexAttribArrayProc disableVertexAttribArray = NULL; |
1850 | 165 | GLVertexAttribPointerProc vertexAttribPointer = NULL; | 186 | GLVertexAttribPointerProc vertexAttribPointer = NULL; |
1851 | 166 | 187 | ||
1854 | 167 | GLGenRenderbuffersProc genRenderbuffers = NULL; | 188 | GLGenRenderbuffersProc genRenderbuffers = NULL; |
1855 | 168 | GLDeleteRenderbuffersProc deleteRenderbuffers = NULL; | 189 | GLDeleteRenderbuffersProc deleteRenderbuffers = NULL; |
1856 | 169 | GLFramebufferRenderbufferProc framebufferRenderbuffer = NULL; | 190 | GLFramebufferRenderbufferProc framebufferRenderbuffer = NULL; |
1859 | 170 | GLBindRenderbufferProc bindRenderbuffer = NULL; | 191 | GLBindRenderbufferProc bindRenderbuffer = NULL; |
1860 | 171 | GLRenderbufferStorageProc renderbufferStorage = NULL; | 192 | GLRenderbufferStorageProc renderbufferStorage = NULL; |
1861 | 193 | GLBlitFramebufferProc blitFramebuffer = NULL; | ||
1862 | 172 | 194 | ||
1863 | 173 | bool textureFromPixmap = true; | 195 | bool textureFromPixmap = true; |
1864 | 174 | bool textureRectangle = false; | 196 | bool textureRectangle = false; |
1865 | @@ -299,6 +321,115 @@ | |||
1866 | 299 | GLScreen *gScreen; | 321 | GLScreen *gScreen; |
1867 | 300 | }; | 322 | }; |
1868 | 301 | 323 | ||
1869 | 324 | namespace | ||
1870 | 325 | { | ||
1871 | 326 | bool defaultRectangularFramebufferDraw (GLVertexBuffer *vertexBuffer, | ||
1872 | 327 | GLFramebufferObject *fbo, | ||
1873 | 328 | const CompRect &src, | ||
1874 | 329 | const CompRect &dst, | ||
1875 | 330 | GLbitfield mask, | ||
1876 | 331 | GLenum filter) | ||
1877 | 332 | { | ||
1878 | 333 | GLTexture *texture = fbo->tex (); | ||
1879 | 334 | GLMatrix sTransform; | ||
1880 | 335 | const GLTexture::Matrix & texmatrix = texture->matrix (); | ||
1881 | 336 | const GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, src.x1 ()); | ||
1882 | 337 | const GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, src.x2 ()); | ||
1883 | 338 | const GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, src.y1 ()); | ||
1884 | 339 | const GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, src.y2 ()); | ||
1885 | 340 | |||
1886 | 341 | const GLfloat vx1 = src.x1 (); | ||
1887 | 342 | const GLfloat vx2 = src.x2 (); | ||
1888 | 343 | const GLfloat vy1 = src.y1 (); | ||
1889 | 344 | const GLfloat vy2 = src.y2 (); | ||
1890 | 345 | |||
1891 | 346 | const GLTexture::Filter texFilter = | ||
1892 | 347 | (filter == GL_LINEAR) ? GLTexture::Good : | ||
1893 | 348 | GLTexture::Fast; | ||
1894 | 349 | |||
1895 | 350 | GLfloat vertexData[] = { | ||
1896 | 351 | vx1, vy1, 0.0f, | ||
1897 | 352 | vx1, vy2, 0.0f, | ||
1898 | 353 | vx2, vy1, 0.0f, | ||
1899 | 354 | |||
1900 | 355 | vx1, vy2, 0.0f, | ||
1901 | 356 | vx2, vy2, 0.0f, | ||
1902 | 357 | vx2, vy1, 0.0f, | ||
1903 | 358 | }; | ||
1904 | 359 | |||
1905 | 360 | GLfloat textureData[] = { | ||
1906 | 361 | tx1, ty1, | ||
1907 | 362 | tx1, ty2, | ||
1908 | 363 | tx2, ty1, | ||
1909 | 364 | tx1, ty2, | ||
1910 | 365 | tx2, ty2, | ||
1911 | 366 | tx2, ty1, | ||
1912 | 367 | }; | ||
1913 | 368 | |||
1914 | 369 | vertexBuffer->begin (GL_TRIANGLES); | ||
1915 | 370 | vertexBuffer->addVertices (6, vertexData); | ||
1916 | 371 | vertexBuffer->addTexCoords (0, 6, textureData); | ||
1917 | 372 | |||
1918 | 373 | if (vertexBuffer->end ()) | ||
1919 | 374 | { | ||
1920 | 375 | texture->enable (texFilter); | ||
1921 | 376 | sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA); | ||
1922 | 377 | vertexBuffer->render (sTransform); | ||
1923 | 378 | texture->disable (); | ||
1924 | 379 | } | ||
1925 | 380 | |||
1926 | 381 | return true; | ||
1927 | 382 | } | ||
1928 | 383 | |||
1929 | 384 | void initDirectDraw (cgli::DirectDrawStrategies::Ptr &directDraw, | ||
1930 | 385 | const compiz::opengl::RectangularDraw &blitFramebuffer, | ||
1931 | 386 | const compiz::opengl::RectangularDraw &rectangularTextureDraw, | ||
1932 | 387 | const cgli::BindReadBufferFunc &func, | ||
1933 | 388 | compiz::opengl::BindableFramebuffer *bindable) | ||
1934 | 389 | { | ||
1935 | 390 | cglfb::RectangularDraw blitFramebufferBound ( | ||
1936 | 391 | boost::bind ( | ||
1937 | 392 | cgli::rectangleDrawFromReadBuffer, | ||
1938 | 393 | _1, _2, _3, _4, | ||
1939 | 394 | bindable, | ||
1940 | 395 | func, | ||
1941 | 396 | blitFramebuffer)); | ||
1942 | 397 | |||
1943 | 398 | /* Tries each of these from back to front */ | ||
1944 | 399 | cglfb::RectangularDrawList strategies; | ||
1945 | 400 | |||
1946 | 401 | strategies.push_back (rectangularTextureDraw); | ||
1947 | 402 | strategies.push_back (blitFramebufferBound); | ||
1948 | 403 | directDraw.reset (new cgli::DirectDrawStrategies (strategies)); | ||
1949 | 404 | } | ||
1950 | 405 | } | ||
1951 | 406 | |||
1952 | 407 | namespace compiz | ||
1953 | 408 | { | ||
1954 | 409 | namespace opengl | ||
1955 | 410 | { | ||
1956 | 411 | DirectDrawObject * | ||
1957 | 412 | createBlittableFramebufferObjectWithFallback (const CompSize &sz, | ||
1958 | 413 | GLScreen *gScreen) | ||
1959 | 414 | { | ||
1960 | 415 | boost::shared_ptr <cgli::DirectDrawStrategies> directDraw; | ||
1961 | 416 | boost::shared_ptr <cgli::FramebufferObject> fbo (boost::make_shared <cgli::FramebufferObject> ()); | ||
1962 | 417 | cglfb::RectangularDraw rectangularTextureDraw (boost::bind (defaultRectangularFramebufferDraw, | ||
1963 | 418 | GLVertexBuffer::streamingBuffer (), | ||
1964 | 419 | fbo.get (), | ||
1965 | 420 | _1, _2, _3, _4)); | ||
1966 | 421 | initDirectDraw (directDraw, | ||
1967 | 422 | gScreen->blitFramebufferFunc (), | ||
1968 | 423 | rectangularTextureDraw, | ||
1969 | 424 | boost::bind (&GLScreen::bindFramebufferForReading, gScreen, _1), | ||
1970 | 425 | fbo.get ()); | ||
1971 | 426 | DirectDrawObject *dd (new cgli::DirectDrawObject (directDraw, fbo, fbo)); | ||
1972 | 427 | dd->allocate (*screen, NULL, GL_BGRA); | ||
1973 | 428 | return dd; | ||
1974 | 429 | } | ||
1975 | 430 | } | ||
1976 | 431 | } | ||
1977 | 432 | |||
1978 | 302 | #ifndef USE_GLES | 433 | #ifndef USE_GLES |
1979 | 303 | 434 | ||
1980 | 304 | namespace compiz | 435 | namespace compiz |
1981 | @@ -591,6 +722,7 @@ | |||
1982 | 591 | if (GL::textureFromPixmap) | 722 | if (GL::textureFromPixmap) |
1983 | 592 | registerBindPixmap (EglTexture::bindPixmapToTexture); | 723 | registerBindPixmap (EglTexture::bindPixmapToTexture); |
1984 | 593 | 724 | ||
1985 | 725 | priv->blitFramebuffer = boost::bind (compiz::opengl::blitFramebufferEGL, _1, _2, _3, _4); | ||
1986 | 594 | priv->incorrectRefreshRate = false; | 726 | priv->incorrectRefreshRate = false; |
1987 | 595 | 727 | ||
1988 | 596 | #else | 728 | #else |
1989 | @@ -779,6 +911,10 @@ | |||
1990 | 779 | GL::fboSupported = true; | 911 | GL::fboSupported = true; |
1991 | 780 | } | 912 | } |
1992 | 781 | 913 | ||
1993 | 914 | if (GL::fboSupported && | ||
1994 | 915 | strstr (glExtensions, "GL_EXT_framebuffer_blit")) | ||
1995 | 916 | GL::blitFramebuffer = (GL::GLBlitFramebufferProc) getProcAddress ("glBlitFramebufferEXT"); | ||
1996 | 917 | |||
1997 | 782 | GL::fboStencilSupported = GL::fboSupported && | 918 | GL::fboStencilSupported = GL::fboSupported && |
1998 | 783 | strstr (glExtensions, "GL_EXT_packed_depth_stencil"); | 919 | strstr (glExtensions, "GL_EXT_packed_depth_stencil"); |
1999 | 784 | 920 | ||
2000 | @@ -895,13 +1031,13 @@ | |||
2001 | 895 | 1031 | ||
2002 | 896 | if (GL::textureFromPixmap) | 1032 | if (GL::textureFromPixmap) |
2003 | 897 | registerBindPixmap (TfpTexture::bindPixmapToTexture); | 1033 | registerBindPixmap (TfpTexture::bindPixmapToTexture); |
2004 | 1034 | |||
2005 | 1035 | priv->blitFramebuffer = boost::bind (compiz::opengl::blitFramebufferGLX, _1, _2, _3, _4); | ||
2006 | 898 | #endif | 1036 | #endif |
2007 | 899 | 1037 | ||
2008 | 900 | if (GL::fboSupported) | 1038 | if (GL::fboSupported) |
2013 | 901 | { | 1039 | priv->scratchFbo.reset (compiz::opengl::createBlittableFramebufferObjectWithFallback (*screen, |
2014 | 902 | priv->scratchFbo = new GLFramebufferObject; | 1040 | this)); |
2011 | 903 | priv->scratchFbo->allocate (*screen, NULL, GL_BGRA); | ||
2012 | 904 | } | ||
2015 | 905 | 1041 | ||
2016 | 906 | GLVertexBuffer::streamingBuffer ()->setAutoProgram (priv->autoProgram); | 1042 | GLVertexBuffer::streamingBuffer ()->setAutoProgram (priv->autoProgram); |
2017 | 907 | 1043 | ||
2018 | @@ -1209,9 +1345,6 @@ | |||
2019 | 1209 | glXDestroyContext (screen->dpy (), priv->ctx); | 1345 | glXDestroyContext (screen->dpy (), priv->ctx); |
2020 | 1210 | #endif | 1346 | #endif |
2021 | 1211 | 1347 | ||
2022 | 1212 | if (priv->scratchFbo) | ||
2023 | 1213 | delete priv->scratchFbo; | ||
2024 | 1214 | |||
2025 | 1215 | delete priv; | 1348 | delete priv; |
2026 | 1216 | } | 1349 | } |
2027 | 1217 | 1350 | ||
2028 | @@ -1234,6 +1367,7 @@ | |||
2029 | 1234 | doubleBuffer (screen->dpy (), *screen, surface), | 1367 | doubleBuffer (screen->dpy (), *screen, surface), |
2030 | 1235 | #endif | 1368 | #endif |
2031 | 1236 | scratchFbo (NULL), | 1369 | scratchFbo (NULL), |
2032 | 1370 | blitFramebuffer (), | ||
2033 | 1237 | outputRegion (), | 1371 | outputRegion (), |
2034 | 1238 | refreshSubBuffer (false), | 1372 | refreshSubBuffer (false), |
2035 | 1239 | lastMask (0), | 1373 | lastMask (0), |
2036 | @@ -1246,6 +1380,10 @@ | |||
2037 | 1246 | autoProgram (new GLScreenAutoProgram(gs)), | 1380 | autoProgram (new GLScreenAutoProgram(gs)), |
2038 | 1247 | rootPixmapCopy (None), | 1381 | rootPixmapCopy (None), |
2039 | 1248 | rootPixmapSize (), | 1382 | rootPixmapSize (), |
2040 | 1383 | drawFramebufferBinding (GL::DRAW_FRAMEBUFFER, | ||
2041 | 1384 | &backbuffer), | ||
2042 | 1385 | readFramebufferBinding (GL::READ_FRAMEBUFFER, | ||
2043 | 1386 | &backbuffer), | ||
2044 | 1249 | glVendor (NULL), | 1387 | glVendor (NULL), |
2045 | 1250 | glRenderer (NULL), | 1388 | glRenderer (NULL), |
2046 | 1251 | glVersion (NULL), | 1389 | glVersion (NULL), |
2047 | @@ -1441,11 +1579,19 @@ | |||
2048 | 1441 | void | 1579 | void |
2049 | 1442 | PrivateGLScreen::outputChangeNotify () | 1580 | PrivateGLScreen::outputChangeNotify () |
2050 | 1443 | { | 1581 | { |
2051 | 1582 | compiz::opengl::BindableFramebuffer *previousReadBuffer = | ||
2052 | 1583 | readFramebufferBinding.bind (&backbuffer); | ||
2053 | 1584 | compiz::opengl::BindableFramebuffer *previousDrawBuffer = | ||
2054 | 1585 | drawFramebufferBinding.bind (&backbuffer); | ||
2055 | 1586 | |||
2056 | 1444 | screen->outputChangeNotify (); | 1587 | screen->outputChangeNotify (); |
2057 | 1445 | 1588 | ||
2059 | 1446 | if (scratchFbo) | 1589 | if (scratchFbo.get ()) |
2060 | 1447 | scratchFbo->allocate (*screen, NULL, GL_BGRA); | 1590 | scratchFbo->allocate (*screen, NULL, GL_BGRA); |
2061 | 1448 | updateView (); | 1591 | updateView (); |
2062 | 1592 | |||
2063 | 1593 | readFramebufferBinding.bind (previousReadBuffer); | ||
2064 | 1594 | drawFramebufferBinding.bind (previousDrawBuffer); | ||
2065 | 1449 | } | 1595 | } |
2066 | 1450 | 1596 | ||
2067 | 1451 | #ifndef USE_GLES | 1597 | #ifndef USE_GLES |
2068 | @@ -1670,9 +1816,9 @@ | |||
2069 | 1670 | WRAPABLE_DEF (projectionMatrix) | 1816 | WRAPABLE_DEF (projectionMatrix) |
2070 | 1671 | 1817 | ||
2071 | 1672 | void | 1818 | void |
2075 | 1673 | GLScreenInterface::glPaintCompositedOutput (const CompRegion ®ion, | 1819 | GLScreenInterface::glPaintCompositedOutput (const CompRegion ®ion, |
2076 | 1674 | GLFramebufferObject *fbo, | 1820 | compiz::opengl::DirectDrawObject *fbo, |
2077 | 1675 | unsigned int mask) | 1821 | unsigned int mask) |
2078 | 1676 | WRAPABLE_DEF (glPaintCompositedOutput, region, fbo, mask) | 1822 | WRAPABLE_DEF (glPaintCompositedOutput, region, fbo, mask) |
2079 | 1677 | 1823 | ||
2080 | 1678 | void | 1824 | void |
2081 | @@ -1899,6 +2045,30 @@ | |||
2082 | 1899 | 2045 | ||
2083 | 1900 | } | 2046 | } |
2084 | 1901 | 2047 | ||
2085 | 2048 | bool | ||
2086 | 2049 | cglfb::blitFramebufferGLX (const CompRect &src, | ||
2087 | 2050 | const CompRect &dst, | ||
2088 | 2051 | GLbitfield mask, | ||
2089 | 2052 | GLenum filter) | ||
2090 | 2053 | { | ||
2091 | 2054 | /* Must have GL_EXT_blit_framebuffer */ | ||
2092 | 2055 | if (!GL::blitFramebuffer) | ||
2093 | 2056 | return false; | ||
2094 | 2057 | |||
2095 | 2058 | /* Be sure to invert y-coords too */ | ||
2096 | 2059 | (*GL::blitFramebuffer) (src.x1 (), // sx0 | ||
2097 | 2060 | screen->height () - src.y2 (), // sy0 | ||
2098 | 2061 | src.x2 (), // sx1 | ||
2099 | 2062 | screen->height () - src.y1 (), // sy1 | ||
2100 | 2063 | dst.x1 (), // dx0 | ||
2101 | 2064 | screen->height () - dst.y2 (), // dy0 | ||
2102 | 2065 | dst.x2 (), // dx1, | ||
2103 | 2066 | screen->height () - dst.y1 (), // dy1 | ||
2104 | 2067 | GL_COLOR_BUFFER_BIT, | ||
2105 | 2068 | GL_LINEAR); | ||
2106 | 2069 | return true; | ||
2107 | 2070 | } | ||
2108 | 2071 | |||
2109 | 1902 | #else | 2072 | #else |
2110 | 1903 | 2073 | ||
2111 | 1904 | EGLDoubleBuffer::EGLDoubleBuffer (Display *d, | 2074 | EGLDoubleBuffer::EGLDoubleBuffer (Display *d, |
2112 | @@ -1957,6 +2127,16 @@ | |||
2113 | 1957 | { | 2127 | { |
2114 | 1958 | } | 2128 | } |
2115 | 1959 | 2129 | ||
2116 | 2130 | bool | ||
2117 | 2131 | cglfb::blitFramebufferEGL (const CompRect &src, | ||
2118 | 2132 | const CompRect &dst, | ||
2119 | 2133 | GLbitfield mask, | ||
2120 | 2134 | GLenum filter) | ||
2121 | 2135 | { | ||
2122 | 2136 | /* Not supported on OpenGL|ES2 */ | ||
2123 | 2137 | return false; | ||
2124 | 2138 | } | ||
2125 | 2139 | |||
2126 | 1960 | #endif | 2140 | #endif |
2127 | 1961 | 2141 | ||
2128 | 1962 | void | 2142 | void |
2129 | @@ -1977,17 +2157,11 @@ | |||
2130 | 1977 | glDepthMask (GL_FALSE); | 2157 | glDepthMask (GL_FALSE); |
2131 | 1978 | glStencilMask (0); | 2158 | glStencilMask (0); |
2132 | 1979 | 2159 | ||
2135 | 1980 | GLFramebufferObject *oldFbo = NULL; | 2160 | compiz::opengl::BindableFramebuffer *oldFbo = NULL; |
2134 | 1981 | bool useFbo = false; | ||
2136 | 1982 | 2161 | ||
2137 | 1983 | /* Clear the color buffer where appropriate */ | 2162 | /* Clear the color buffer where appropriate */ |
2145 | 1984 | if (GL::fboEnabled && scratchFbo) | 2163 | if (GL::fboEnabled && scratchFbo.get ()) |
2146 | 1985 | { | 2164 | oldFbo = drawFramebufferBinding.bind (scratchFbo.get ()); |
2140 | 1986 | oldFbo = scratchFbo->bind (); | ||
2141 | 1987 | useFbo = scratchFbo->checkStatus () && scratchFbo->tex (); | ||
2142 | 1988 | if (!useFbo) | ||
2143 | 1989 | GLFramebufferObject::rebind (oldFbo); | ||
2144 | 1990 | } | ||
2147 | 1991 | 2165 | ||
2148 | 1992 | #ifdef UNSAFE_ARM_SGX_FIXME | 2166 | #ifdef UNSAFE_ARM_SGX_FIXME |
2149 | 1993 | refreshSubBuffer = ((lastMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) && | 2167 | refreshSubBuffer = ((lastMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) && |
2150 | @@ -2080,13 +2254,10 @@ | |||
2151 | 2080 | 2254 | ||
2152 | 2081 | glViewport (0, 0, screen->width (), screen->height ()); | 2255 | glViewport (0, 0, screen->width (), screen->height ()); |
2153 | 2082 | 2256 | ||
2155 | 2083 | if (useFbo) | 2257 | if (oldFbo) |
2156 | 2084 | { | 2258 | { |
2162 | 2085 | GLFramebufferObject::rebind (oldFbo); | 2259 | drawFramebufferBinding.bind (oldFbo); |
2163 | 2086 | 2260 | gScreen->glPaintCompositedOutput (screen->region (), scratchFbo.get (), mask); | |
2159 | 2087 | // FIXME: does not work if screen dimensions exceed max texture size | ||
2160 | 2088 | // We should try to use glBlitFramebuffer instead. | ||
2161 | 2089 | gScreen->glPaintCompositedOutput (screen->region (), scratchFbo, mask); | ||
2164 | 2090 | } | 2261 | } |
2165 | 2091 | 2262 | ||
2166 | 2092 | if (cScreen->outputWindowChanged ()) | 2263 | if (cScreen->outputWindowChanged ()) |
2167 | @@ -2101,13 +2272,13 @@ | |||
2168 | 2101 | } | 2272 | } |
2169 | 2102 | 2273 | ||
2170 | 2103 | bool alwaysSwap = optionGetAlwaysSwapBuffers (); | 2274 | bool alwaysSwap = optionGetAlwaysSwapBuffers (); |
2172 | 2104 | bool fullscreen = useFbo || | 2275 | bool fullscreen = oldFbo || |
2173 | 2105 | alwaysSwap || | 2276 | alwaysSwap || |
2174 | 2106 | ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) && | 2277 | ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) && |
2175 | 2107 | commonFrontbuffer); | 2278 | commonFrontbuffer); |
2176 | 2108 | 2279 | ||
2177 | 2109 | doubleBuffer.set (DoubleBuffer::VSYNC, optionGetSyncToVblank ()); | 2280 | doubleBuffer.set (DoubleBuffer::VSYNC, optionGetSyncToVblank ()); |
2179 | 2110 | doubleBuffer.set (DoubleBuffer::HAVE_PERSISTENT_BACK_BUFFER, useFbo); | 2281 | doubleBuffer.set (DoubleBuffer::HAVE_PERSISTENT_BACK_BUFFER, oldFbo ? true : false); |
2180 | 2111 | doubleBuffer.set (DoubleBuffer::NEED_PERSISTENT_BACK_BUFFER, alwaysSwap); | 2282 | doubleBuffer.set (DoubleBuffer::NEED_PERSISTENT_BACK_BUFFER, alwaysSwap); |
2181 | 2112 | doubleBuffer.render (tmpRegion, fullscreen); | 2283 | doubleBuffer.render (tmpRegion, fullscreen); |
2182 | 2113 | 2284 | ||
2183 | @@ -2195,10 +2366,40 @@ | |||
2184 | 2195 | } | 2366 | } |
2185 | 2196 | } | 2367 | } |
2186 | 2197 | 2368 | ||
2188 | 2198 | GLFramebufferObject * | 2369 | compiz::opengl::FramebufferObject * |
2189 | 2199 | GLScreen::fbo () | 2370 | GLScreen::fbo () |
2190 | 2200 | { | 2371 | { |
2192 | 2201 | return priv->scratchFbo; | 2372 | return priv->scratchFbo.get (); |
2193 | 2373 | } | ||
2194 | 2374 | |||
2195 | 2375 | compiz::opengl::BindableFramebuffer * | ||
2196 | 2376 | GLScreen::backbuffer () | ||
2197 | 2377 | { | ||
2198 | 2378 | return &priv->backbuffer; | ||
2199 | 2379 | } | ||
2200 | 2380 | |||
2201 | 2381 | compiz::opengl::BindableFramebuffer * | ||
2202 | 2382 | GLScreen::drawFramebuffer () | ||
2203 | 2383 | { | ||
2204 | 2384 | return priv->drawFramebufferBinding.getCurrentlyBound (); | ||
2205 | 2385 | } | ||
2206 | 2386 | |||
2207 | 2387 | compiz::opengl::BindableFramebuffer * | ||
2208 | 2388 | GLScreen::bindFramebufferForDrawing (compiz::opengl::BindableFramebuffer *next) | ||
2209 | 2389 | { | ||
2210 | 2390 | return priv->drawFramebufferBinding.bind (next); | ||
2211 | 2391 | } | ||
2212 | 2392 | |||
2213 | 2393 | compiz::opengl::BindableFramebuffer * | ||
2214 | 2394 | GLScreen::bindFramebufferForReading (compiz::opengl::BindableFramebuffer *next) | ||
2215 | 2395 | { | ||
2216 | 2396 | return priv->readFramebufferBinding.bind (next); | ||
2217 | 2397 | } | ||
2218 | 2398 | |||
2219 | 2399 | const cglfb::BlitFramebufferFunc & | ||
2220 | 2400 | GLScreen::blitFramebufferFunc () | ||
2221 | 2401 | { | ||
2222 | 2402 | return priv->blitFramebuffer; | ||
2223 | 2202 | } | 2403 | } |
2224 | 2203 | 2404 | ||
2225 | 2204 | GLTexture * | 2405 | GLTexture * |
2226 | @@ -2240,3 +2441,19 @@ | |||
2227 | 2240 | priv->rasterPos.setY (0); | 2441 | priv->rasterPos.setY (0); |
2228 | 2241 | } | 2442 | } |
2229 | 2242 | 2443 | ||
2230 | 2444 | GLuint | ||
2231 | 2445 | BindableBackbuffer::getResourceId () const | ||
2232 | 2446 | { | ||
2233 | 2447 | return 0; | ||
2234 | 2448 | } | ||
2235 | 2449 | |||
2236 | 2450 | bool | ||
2237 | 2451 | BindableBackbuffer::setBindStatus (GLenum) | ||
2238 | 2452 | { | ||
2239 | 2453 | return true; | ||
2240 | 2454 | } | ||
2241 | 2455 | |||
2242 | 2456 | void | ||
2243 | 2457 | BindableBackbuffer::updateAllocation (GLenum) | ||
2244 | 2458 | { | ||
2245 | 2459 | } | ||
2246 | 2243 | 2460 | ||
2247 | === modified file 'plugins/water/src/water.cpp' | |||
2248 | --- plugins/water/src/water.cpp 2013-01-28 19:45:04 +0000 | |||
2249 | +++ plugins/water/src/water.cpp 2013-02-28 02:29:22 +0000 | |||
2250 | @@ -62,7 +62,11 @@ | |||
2251 | 62 | if (!useFbo) | 62 | if (!useFbo) |
2252 | 63 | return false; | 63 | return false; |
2253 | 64 | 64 | ||
2255 | 65 | oldFbo = waterFbo[fIndex]->bind (); | 65 | oldFbo = gScreen->bindFramebufferForDrawing (waterFbo[fIndex]); |
2256 | 66 | |||
2257 | 67 | if (!oldFbo) | ||
2258 | 68 | return false; | ||
2259 | 69 | |||
2260 | 66 | glGetIntegerv(GL_VIEWPORT, &oldViewport[0]); | 70 | glGetIntegerv(GL_VIEWPORT, &oldViewport[0]); |
2261 | 67 | glViewport (0, 0, texWidth, texHeight); | 71 | glViewport (0, 0, texWidth, texHeight); |
2262 | 68 | 72 | ||
2263 | @@ -72,7 +76,7 @@ | |||
2264 | 72 | void | 76 | void |
2265 | 73 | WaterScreen::fboEpilogue () | 77 | WaterScreen::fboEpilogue () |
2266 | 74 | { | 78 | { |
2268 | 75 | GLFramebufferObject::rebind (oldFbo); | 79 | gScreen->bindFramebufferForDrawing (oldFbo); |
2269 | 76 | glViewport (oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]); | 80 | glViewport (oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]); |
2270 | 77 | } | 81 | } |
2271 | 78 | 82 | ||
2272 | @@ -305,28 +309,32 @@ | |||
2273 | 305 | waterFbo[i]->allocate (size, (char *) t0, | 309 | waterFbo[i]->allocate (size, (char *) t0, |
2274 | 306 | GL_BGRA, GL_UNSIGNED_BYTE); | 310 | GL_BGRA, GL_UNSIGNED_BYTE); |
2275 | 307 | // check if FBOs are working. If not, fallback to software textures | 311 | // check if FBOs are working. If not, fallback to software textures |
2279 | 308 | oldFbo = waterFbo[i]->bind (); | 312 | oldFbo = gScreen->bindFramebufferForDrawing (waterFbo[i]); |
2280 | 309 | waterFbo[i]->rebind (oldFbo); | 313 | if (!oldFbo) |
2278 | 310 | if (!waterFbo[i]->checkStatus ()) | ||
2281 | 311 | { | 314 | { |
2282 | 312 | useFbo = false; | 315 | useFbo = false; |
2283 | 313 | delete waterFbo[i]; | 316 | delete waterFbo[i]; |
2284 | 314 | break; | 317 | break; |
2285 | 315 | } | 318 | } |
2286 | 319 | gScreen->bindFramebufferForDrawing (oldFbo); | ||
2287 | 316 | } | 320 | } |
2288 | 317 | } | 321 | } |
2289 | 318 | } | 322 | } |
2290 | 319 | 323 | ||
2291 | 320 | void | 324 | void |
2295 | 321 | WaterScreen::glPaintCompositedOutput (const CompRegion ®ion, | 325 | WaterScreen::glPaintCompositedOutput (const CompRegion ®ion, |
2296 | 322 | GLFramebufferObject *fbo, | 326 | compiz::opengl::DirectDrawObject *fbo, |
2297 | 323 | unsigned int mask) | 327 | unsigned int mask) |
2298 | 324 | { | 328 | { |
2299 | 325 | if (count) | 329 | if (count) |
2300 | 326 | { | 330 | { |
2301 | 327 | if (GL::vboEnabled && GL::shaders) | 331 | if (GL::vboEnabled && GL::shaders) |
2302 | 328 | { | 332 | { |
2304 | 329 | GLFramebufferObject::rebind (oldFbo); | 333 | /* This seems redundant to me */ |
2305 | 334 | gScreen->bindFramebufferForDrawing (oldFbo); | ||
2306 | 335 | |||
2307 | 336 | oldFbo = NULL; | ||
2308 | 337 | |||
2309 | 330 | glViewport (oldViewport[0], oldViewport[1], | 338 | glViewport (oldViewport[0], oldViewport[1], |
2310 | 331 | oldViewport[2], oldViewport[3]); | 339 | oldViewport[2], oldViewport[3]); |
2311 | 332 | 340 | ||
2312 | 333 | 341 | ||
2313 | === modified file 'plugins/water/src/water.h' | |||
2314 | --- plugins/water/src/water.h 2012-09-07 23:56:21 +0000 | |||
2315 | +++ plugins/water/src/water.h 2013-02-28 02:29:22 +0000 | |||
2316 | @@ -64,9 +64,9 @@ | |||
2317 | 64 | 64 | ||
2318 | 65 | void handleEvent (XEvent *); | 65 | void handleEvent (XEvent *); |
2319 | 66 | 66 | ||
2323 | 67 | void glPaintCompositedOutput (const CompRegion ®ion, | 67 | void glPaintCompositedOutput (const CompRegion ®ion, |
2324 | 68 | GLFramebufferObject *fbo, | 68 | compiz::opengl::DirectDrawObject *fbo, |
2325 | 69 | unsigned int mask); | 69 | unsigned int mask); |
2326 | 70 | void preparePaint (int); | 70 | void preparePaint (int); |
2327 | 71 | void donePaint (); | 71 | void donePaint (); |
2328 | 72 | 72 | ||
2329 | @@ -100,7 +100,7 @@ | |||
2330 | 100 | 100 | ||
2331 | 101 | GLFramebufferObject *waterFbo[TEXTURE_NUM]; | 101 | GLFramebufferObject *waterFbo[TEXTURE_NUM]; |
2332 | 102 | 102 | ||
2334 | 103 | GLFramebufferObject *oldFbo; | 103 | compiz::opengl::BindableFramebuffer *oldFbo; |
2335 | 104 | GLint oldViewport[4]; | 104 | GLint oldViewport[4]; |
2336 | 105 | int fboIndex; | 105 | int fboIndex; |
2337 | 106 | bool useFbo; | 106 | bool useFbo; |
2338 | 107 | 107 | ||
2339 | === added file 'src/asyncserverwindow.h' | |||
2340 | --- src/asyncserverwindow.h 1970-01-01 00:00:00 +0000 | |||
2341 | +++ src/asyncserverwindow.h 2013-02-28 02:29:22 +0000 | |||
2342 | @@ -0,0 +1,52 @@ | |||
2343 | 1 | /* | ||
2344 | 2 | * Copyright © 2012 Sam Spilsbury | ||
2345 | 3 | * | ||
2346 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
2347 | 5 | * and its documentation for any purpose is hereby granted without | ||
2348 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
2349 | 7 | * and that both that copyright notice and this permission notice | ||
2350 | 8 | * appear in supporting documentation, and that the name of | ||
2351 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
2352 | 10 | * distribution of the software without specific, written prior permission. | ||
2353 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
2354 | 12 | * software for any purpose. It is provided "as is" without express or | ||
2355 | 13 | * implied warranty. | ||
2356 | 14 | * | ||
2357 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
2358 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
2359 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
2360 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
2361 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
2362 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
2363 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
2364 | 22 | * | ||
2365 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
2366 | 24 | */ | ||
2367 | 25 | #ifndef _COMPIZ_ASYNC_SERVER_WINDOW_H | ||
2368 | 26 | #define _COMPIZ_ASYNC_SERVER_WINDOW_H | ||
2369 | 27 | |||
2370 | 28 | #include <X11/Xlib.h> | ||
2371 | 29 | |||
2372 | 30 | namespace compiz | ||
2373 | 31 | { | ||
2374 | 32 | namespace window | ||
2375 | 33 | { | ||
2376 | 34 | class AsyncServerWindow | ||
2377 | 35 | { | ||
2378 | 36 | public: | ||
2379 | 37 | |||
2380 | 38 | virtual ~AsyncServerWindow () {}; | ||
2381 | 39 | |||
2382 | 40 | virtual int requestConfigureOnClient (const XWindowChanges &xwc, | ||
2383 | 41 | unsigned int valueMask) = 0; | ||
2384 | 42 | virtual int requestConfigureOnWrapper (const XWindowChanges &xwc, | ||
2385 | 43 | unsigned int valueMask) = 0; | ||
2386 | 44 | virtual int requestConfigureOnFrame (const XWindowChanges &xwc, | ||
2387 | 45 | unsigned int valueMask) = 0; | ||
2388 | 46 | virtual void sendSyntheticConfigureNotify () = 0; | ||
2389 | 47 | virtual bool hasCustomShape () const = 0; | ||
2390 | 48 | }; | ||
2391 | 49 | } | ||
2392 | 50 | } | ||
2393 | 51 | |||
2394 | 52 | #endif | ||
2395 | 0 | 53 | ||
2396 | === removed file 'src/asyncserverwindow.h' | |||
2397 | --- src/asyncserverwindow.h 2012-12-13 11:12:32 +0000 | |||
2398 | +++ src/asyncserverwindow.h 1970-01-01 00:00:00 +0000 | |||
2399 | @@ -1,52 +0,0 @@ | |||
2400 | 1 | /* | ||
2401 | 2 | * Copyright © 2012 Sam Spilsbury | ||
2402 | 3 | * | ||
2403 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
2404 | 5 | * and its documentation for any purpose is hereby granted without | ||
2405 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
2406 | 7 | * and that both that copyright notice and this permission notice | ||
2407 | 8 | * appear in supporting documentation, and that the name of | ||
2408 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
2409 | 10 | * distribution of the software without specific, written prior permission. | ||
2410 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
2411 | 12 | * software for any purpose. It is provided "as is" without express or | ||
2412 | 13 | * implied warranty. | ||
2413 | 14 | * | ||
2414 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
2415 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
2416 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
2417 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
2418 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
2419 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
2420 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
2421 | 22 | * | ||
2422 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
2423 | 24 | */ | ||
2424 | 25 | #ifndef _COMPIZ_ASYNC_SERVER_WINDOW_H | ||
2425 | 26 | #define _COMPIZ_ASYNC_SERVER_WINDOW_H | ||
2426 | 27 | |||
2427 | 28 | #include <X11/Xlib.h> | ||
2428 | 29 | |||
2429 | 30 | namespace compiz | ||
2430 | 31 | { | ||
2431 | 32 | namespace window | ||
2432 | 33 | { | ||
2433 | 34 | class AsyncServerWindow | ||
2434 | 35 | { | ||
2435 | 36 | public: | ||
2436 | 37 | |||
2437 | 38 | virtual ~AsyncServerWindow () {}; | ||
2438 | 39 | |||
2439 | 40 | virtual int requestConfigureOnClient (const XWindowChanges &xwc, | ||
2440 | 41 | unsigned int valueMask) = 0; | ||
2441 | 42 | virtual int requestConfigureOnWrapper (const XWindowChanges &xwc, | ||
2442 | 43 | unsigned int valueMask) = 0; | ||
2443 | 44 | virtual int requestConfigureOnFrame (const XWindowChanges &xwc, | ||
2444 | 45 | unsigned int valueMask) = 0; | ||
2445 | 46 | virtual void sendSyntheticConfigureNotify () = 0; | ||
2446 | 47 | virtual bool hasCustomShape () const = 0; | ||
2447 | 48 | }; | ||
2448 | 49 | } | ||
2449 | 50 | } | ||
2450 | 51 | |||
2451 | 52 | #endif | ||
2452 | 53 | 0 | ||
2453 | === added file 'src/configurerequestbuffer-impl.h' | |||
2454 | --- src/configurerequestbuffer-impl.h 1970-01-01 00:00:00 +0000 | |||
2455 | +++ src/configurerequestbuffer-impl.h 2013-02-28 02:29:22 +0000 | |||
2456 | @@ -0,0 +1,145 @@ | |||
2457 | 1 | /* | ||
2458 | 2 | * Copyright © 2012 Sam Spilsbury | ||
2459 | 3 | * | ||
2460 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
2461 | 5 | * and its documentation for any purpose is hereby granted without | ||
2462 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
2463 | 7 | * and that both that copyright notice and this permission notice | ||
2464 | 8 | * appear in supporting documentation, and that the name of | ||
2465 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
2466 | 10 | * distribution of the software without specific, written prior permission. | ||
2467 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
2468 | 12 | * software for any purpose. It is provided "as is" without express or | ||
2469 | 13 | * implied warranty. | ||
2470 | 14 | * | ||
2471 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
2472 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
2473 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
2474 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
2475 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
2476 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
2477 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
2478 | 22 | * | ||
2479 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
2480 | 24 | */ | ||
2481 | 25 | #ifndef _COMPIZ_GEOMETRY_UPDATE_QUEUE_H | ||
2482 | 26 | #define _COMPIZ_GEOMETRY_UPDATE_QUEUE_H | ||
2483 | 27 | |||
2484 | 28 | #include <memory> | ||
2485 | 29 | #include <vector> | ||
2486 | 30 | #include <boost/weak_ptr.hpp> | ||
2487 | 31 | #include <boost/shared_ptr.hpp> | ||
2488 | 32 | #include <boost/function.hpp> | ||
2489 | 33 | #include <X11/Xlib.h> | ||
2490 | 34 | |||
2491 | 35 | #include <core/configurerequestbuffer.h> | ||
2492 | 36 | |||
2493 | 37 | namespace compiz | ||
2494 | 38 | { | ||
2495 | 39 | namespace window | ||
2496 | 40 | { | ||
2497 | 41 | class AsyncServerWindow; | ||
2498 | 42 | namespace configure_buffers | ||
2499 | 43 | { | ||
2500 | 44 | |||
2501 | 45 | class Lockable | ||
2502 | 46 | { | ||
2503 | 47 | public: | ||
2504 | 48 | |||
2505 | 49 | typedef boost::shared_ptr <Lockable> Ptr; | ||
2506 | 50 | typedef boost::weak_ptr <Lockable> Weak; | ||
2507 | 51 | |||
2508 | 52 | virtual ~Lockable () {} | ||
2509 | 53 | |||
2510 | 54 | virtual void lock () = 0; | ||
2511 | 55 | }; | ||
2512 | 56 | |||
2513 | 57 | class BufferLock : | ||
2514 | 58 | public Lockable, | ||
2515 | 59 | public Releasable | ||
2516 | 60 | { | ||
2517 | 61 | public: | ||
2518 | 62 | typedef boost::shared_ptr <BufferLock> Ptr; | ||
2519 | 63 | |||
2520 | 64 | virtual ~BufferLock () {} | ||
2521 | 65 | }; | ||
2522 | 66 | |||
2523 | 67 | class CountedFreeze | ||
2524 | 68 | { | ||
2525 | 69 | public: | ||
2526 | 70 | |||
2527 | 71 | virtual ~CountedFreeze () {} | ||
2528 | 72 | |||
2529 | 73 | virtual void freeze () = 0; | ||
2530 | 74 | virtual void release () = 0; | ||
2531 | 75 | |||
2532 | 76 | virtual void untrackLock (compiz::window::configure_buffers::BufferLock *lock) = 0; | ||
2533 | 77 | }; | ||
2534 | 78 | |||
2535 | 79 | class ConfigureRequestBuffer : | ||
2536 | 80 | public CountedFreeze, | ||
2537 | 81 | public Buffer | ||
2538 | 82 | { | ||
2539 | 83 | public: | ||
2540 | 84 | |||
2541 | 85 | typedef boost::function <BufferLock::Ptr (CountedFreeze *)> LockFactory; | ||
2542 | 86 | |||
2543 | 87 | void freeze (); | ||
2544 | 88 | void release (); | ||
2545 | 89 | |||
2546 | 90 | void untrackLock (compiz::window::configure_buffers::BufferLock *lock); | ||
2547 | 91 | |||
2548 | 92 | void pushClientRequest (const XWindowChanges &xwc, unsigned int mask); | ||
2549 | 93 | void pushWrapperRequest (const XWindowChanges &xwc, unsigned int mask); | ||
2550 | 94 | void pushFrameRequest (const XWindowChanges &xwc, unsigned int mask); | ||
2551 | 95 | void pushSyntheticConfigureNotify (); | ||
2552 | 96 | compiz::window::configure_buffers::Releasable::Ptr obtainLock (); | ||
2553 | 97 | |||
2554 | 98 | /* Implement getAttributes and require that | ||
2555 | 99 | * the queue is released before calling through | ||
2556 | 100 | * to the SyncServerWindow */ | ||
2557 | 101 | bool queryAttributes (XWindowAttributes &attrib); | ||
2558 | 102 | bool queryFrameAttributes (XWindowAttributes &attrib); | ||
2559 | 103 | XRectangle * queryShapeRectangles (int kind, | ||
2560 | 104 | int *count, | ||
2561 | 105 | int *ordering); | ||
2562 | 106 | |||
2563 | 107 | void forceRelease (); | ||
2564 | 108 | |||
2565 | 109 | static compiz::window::configure_buffers::Buffer::Ptr | ||
2566 | 110 | Create (AsyncServerWindow *asyncServerWindow, | ||
2567 | 111 | SyncServerWindow *syncServerWindow, | ||
2568 | 112 | const LockFactory &factory); | ||
2569 | 113 | |||
2570 | 114 | private: | ||
2571 | 115 | |||
2572 | 116 | ConfigureRequestBuffer (AsyncServerWindow *asyncServerWindow, | ||
2573 | 117 | SyncServerWindow *syncServerWindow, | ||
2574 | 118 | const LockFactory &factory); | ||
2575 | 119 | |||
2576 | 120 | class Private; | ||
2577 | 121 | std::auto_ptr <Private> priv; | ||
2578 | 122 | }; | ||
2579 | 123 | |||
2580 | 124 | class ConfigureBufferLock : | ||
2581 | 125 | public compiz::window::configure_buffers::BufferLock | ||
2582 | 126 | { | ||
2583 | 127 | public: | ||
2584 | 128 | |||
2585 | 129 | typedef boost::shared_ptr <ConfigureBufferLock> Ptr; | ||
2586 | 130 | |||
2587 | 131 | ConfigureBufferLock (CountedFreeze *); | ||
2588 | 132 | ~ConfigureBufferLock (); | ||
2589 | 133 | |||
2590 | 134 | void lock (); | ||
2591 | 135 | void release (); | ||
2592 | 136 | |||
2593 | 137 | private: | ||
2594 | 138 | |||
2595 | 139 | class Private; | ||
2596 | 140 | std::auto_ptr <Private> priv; | ||
2597 | 141 | }; | ||
2598 | 142 | } | ||
2599 | 143 | } | ||
2600 | 144 | } | ||
2601 | 145 | #endif | ||
2602 | 0 | 146 | ||
2603 | === removed file 'src/configurerequestbuffer-impl.h' | |||
2604 | --- src/configurerequestbuffer-impl.h 2012-12-13 11:12:32 +0000 | |||
2605 | +++ src/configurerequestbuffer-impl.h 1970-01-01 00:00:00 +0000 | |||
2606 | @@ -1,145 +0,0 @@ | |||
2607 | 1 | /* | ||
2608 | 2 | * Copyright © 2012 Sam Spilsbury | ||
2609 | 3 | * | ||
2610 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
2611 | 5 | * and its documentation for any purpose is hereby granted without | ||
2612 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
2613 | 7 | * and that both that copyright notice and this permission notice | ||
2614 | 8 | * appear in supporting documentation, and that the name of | ||
2615 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
2616 | 10 | * distribution of the software without specific, written prior permission. | ||
2617 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
2618 | 12 | * software for any purpose. It is provided "as is" without express or | ||
2619 | 13 | * implied warranty. | ||
2620 | 14 | * | ||
2621 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
2622 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
2623 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
2624 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
2625 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
2626 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
2627 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
2628 | 22 | * | ||
2629 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
2630 | 24 | */ | ||
2631 | 25 | #ifndef _COMPIZ_GEOMETRY_UPDATE_QUEUE_H | ||
2632 | 26 | #define _COMPIZ_GEOMETRY_UPDATE_QUEUE_H | ||
2633 | 27 | |||
2634 | 28 | #include <memory> | ||
2635 | 29 | #include <vector> | ||
2636 | 30 | #include <boost/weak_ptr.hpp> | ||
2637 | 31 | #include <boost/shared_ptr.hpp> | ||
2638 | 32 | #include <boost/function.hpp> | ||
2639 | 33 | #include <X11/Xlib.h> | ||
2640 | 34 | |||
2641 | 35 | #include <core/configurerequestbuffer.h> | ||
2642 | 36 | |||
2643 | 37 | namespace compiz | ||
2644 | 38 | { | ||
2645 | 39 | namespace window | ||
2646 | 40 | { | ||
2647 | 41 | class AsyncServerWindow; | ||
2648 | 42 | namespace configure_buffers | ||
2649 | 43 | { | ||
2650 | 44 | |||
2651 | 45 | class Lockable | ||
2652 | 46 | { | ||
2653 | 47 | public: | ||
2654 | 48 | |||
2655 | 49 | typedef boost::shared_ptr <Lockable> Ptr; | ||
2656 | 50 | typedef boost::weak_ptr <Lockable> Weak; | ||
2657 | 51 | |||
2658 | 52 | virtual ~Lockable () {} | ||
2659 | 53 | |||
2660 | 54 | virtual void lock () = 0; | ||
2661 | 55 | }; | ||
2662 | 56 | |||
2663 | 57 | class BufferLock : | ||
2664 | 58 | public Lockable, | ||
2665 | 59 | public Releasable | ||
2666 | 60 | { | ||
2667 | 61 | public: | ||
2668 | 62 | typedef boost::shared_ptr <BufferLock> Ptr; | ||
2669 | 63 | |||
2670 | 64 | virtual ~BufferLock () {} | ||
2671 | 65 | }; | ||
2672 | 66 | |||
2673 | 67 | class CountedFreeze | ||
2674 | 68 | { | ||
2675 | 69 | public: | ||
2676 | 70 | |||
2677 | 71 | virtual ~CountedFreeze () {} | ||
2678 | 72 | |||
2679 | 73 | virtual void freeze () = 0; | ||
2680 | 74 | virtual void release () = 0; | ||
2681 | 75 | |||
2682 | 76 | virtual void untrackLock (compiz::window::configure_buffers::BufferLock *lock) = 0; | ||
2683 | 77 | }; | ||
2684 | 78 | |||
2685 | 79 | class ConfigureRequestBuffer : | ||
2686 | 80 | public CountedFreeze, | ||
2687 | 81 | public Buffer | ||
2688 | 82 | { | ||
2689 | 83 | public: | ||
2690 | 84 | |||
2691 | 85 | typedef boost::function <BufferLock::Ptr (CountedFreeze *)> LockFactory; | ||
2692 | 86 | |||
2693 | 87 | void freeze (); | ||
2694 | 88 | void release (); | ||
2695 | 89 | |||
2696 | 90 | void untrackLock (compiz::window::configure_buffers::BufferLock *lock); | ||
2697 | 91 | |||
2698 | 92 | void pushClientRequest (const XWindowChanges &xwc, unsigned int mask); | ||
2699 | 93 | void pushWrapperRequest (const XWindowChanges &xwc, unsigned int mask); | ||
2700 | 94 | void pushFrameRequest (const XWindowChanges &xwc, unsigned int mask); | ||
2701 | 95 | void pushSyntheticConfigureNotify (); | ||
2702 | 96 | compiz::window::configure_buffers::Releasable::Ptr obtainLock (); | ||
2703 | 97 | |||
2704 | 98 | /* Implement getAttributes and require that | ||
2705 | 99 | * the queue is released before calling through | ||
2706 | 100 | * to the SyncServerWindow */ | ||
2707 | 101 | bool queryAttributes (XWindowAttributes &attrib); | ||
2708 | 102 | bool queryFrameAttributes (XWindowAttributes &attrib); | ||
2709 | 103 | XRectangle * queryShapeRectangles (int kind, | ||
2710 | 104 | int *count, | ||
2711 | 105 | int *ordering); | ||
2712 | 106 | |||
2713 | 107 | void forceRelease (); | ||
2714 | 108 | |||
2715 | 109 | static compiz::window::configure_buffers::Buffer::Ptr | ||
2716 | 110 | Create (AsyncServerWindow *asyncServerWindow, | ||
2717 | 111 | SyncServerWindow *syncServerWindow, | ||
2718 | 112 | const LockFactory &factory); | ||
2719 | 113 | |||
2720 | 114 | private: | ||
2721 | 115 | |||
2722 | 116 | ConfigureRequestBuffer (AsyncServerWindow *asyncServerWindow, | ||
2723 | 117 | SyncServerWindow *syncServerWindow, | ||
2724 | 118 | const LockFactory &factory); | ||
2725 | 119 | |||
2726 | 120 | class Private; | ||
2727 | 121 | std::auto_ptr <Private> priv; | ||
2728 | 122 | }; | ||
2729 | 123 | |||
2730 | 124 | class ConfigureBufferLock : | ||
2731 | 125 | public compiz::window::configure_buffers::BufferLock | ||
2732 | 126 | { | ||
2733 | 127 | public: | ||
2734 | 128 | |||
2735 | 129 | typedef boost::shared_ptr <ConfigureBufferLock> Ptr; | ||
2736 | 130 | |||
2737 | 131 | ConfigureBufferLock (CountedFreeze *); | ||
2738 | 132 | ~ConfigureBufferLock (); | ||
2739 | 133 | |||
2740 | 134 | void lock (); | ||
2741 | 135 | void release (); | ||
2742 | 136 | |||
2743 | 137 | private: | ||
2744 | 138 | |||
2745 | 139 | class Private; | ||
2746 | 140 | std::auto_ptr <Private> priv; | ||
2747 | 141 | }; | ||
2748 | 142 | } | ||
2749 | 143 | } | ||
2750 | 144 | } | ||
2751 | 145 | #endif | ||
2752 | 146 | 0 | ||
2753 | === added file 'src/configurerequestbuffer.cpp' | |||
2754 | --- src/configurerequestbuffer.cpp 1970-01-01 00:00:00 +0000 | |||
2755 | +++ src/configurerequestbuffer.cpp 2013-02-28 02:29:22 +0000 | |||
2756 | @@ -0,0 +1,363 @@ | |||
2757 | 1 | /* | ||
2758 | 2 | * Copyright © 2012 Sam Spilsbury | ||
2759 | 3 | * | ||
2760 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
2761 | 5 | * and its documentation for any purpose is hereby granted without | ||
2762 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
2763 | 7 | * and that both that copyright notice and this permission notice | ||
2764 | 8 | * appear in supporting documentation, and that the name of | ||
2765 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
2766 | 10 | * distribution of the software without specific, written prior permission. | ||
2767 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
2768 | 12 | * software for any purpose. It is provided "as is" without express or | ||
2769 | 13 | * implied warranty. | ||
2770 | 14 | * | ||
2771 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
2772 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
2773 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
2774 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
2775 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
2776 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
2777 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
2778 | 22 | * | ||
2779 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
2780 | 24 | */ | ||
2781 | 25 | #include <cstdio> | ||
2782 | 26 | #include <cassert> | ||
2783 | 27 | #include <boost/foreach.hpp> | ||
2784 | 28 | #include <boost/weak_ptr.hpp> | ||
2785 | 29 | #include <boost/bind.hpp> | ||
2786 | 30 | #include "asyncserverwindow.h" | ||
2787 | 31 | #include "configurerequestbuffer-impl.h" | ||
2788 | 32 | |||
2789 | 33 | #ifndef foreach | ||
2790 | 34 | #define foreach BOOST_FOREACH | ||
2791 | 35 | #endif | ||
2792 | 36 | |||
2793 | 37 | namespace crb = compiz::window::configure_buffers; | ||
2794 | 38 | namespace cw = compiz::window; | ||
2795 | 39 | |||
2796 | 40 | class crb::ConfigureRequestBuffer::Private | ||
2797 | 41 | { | ||
2798 | 42 | public: | ||
2799 | 43 | |||
2800 | 44 | typedef crb::Lockable::Weak LockObserver; | ||
2801 | 45 | |||
2802 | 46 | Private (cw::AsyncServerWindow *asyncServerWindow, | ||
2803 | 47 | cw::SyncServerWindow *syncServerWindow, | ||
2804 | 48 | const crb::ConfigureRequestBuffer::LockFactory &lockFactory) : | ||
2805 | 49 | clientChangeMask (0), | ||
2806 | 50 | wrapperChangeMask (0), | ||
2807 | 51 | frameChangeMask (0), | ||
2808 | 52 | sendSyntheticConfigure (false), | ||
2809 | 53 | lockCount (0), | ||
2810 | 54 | asyncServerWindow (asyncServerWindow), | ||
2811 | 55 | syncServerWindow (syncServerWindow), | ||
2812 | 56 | lockFactory (lockFactory) | ||
2813 | 57 | { | ||
2814 | 58 | } | ||
2815 | 59 | |||
2816 | 60 | void dispatchConfigure (bool force = false); | ||
2817 | 61 | |||
2818 | 62 | XWindowChanges clientChanges; | ||
2819 | 63 | unsigned int clientChangeMask; | ||
2820 | 64 | |||
2821 | 65 | XWindowChanges wrapperChanges; | ||
2822 | 66 | unsigned int wrapperChangeMask; | ||
2823 | 67 | |||
2824 | 68 | XWindowChanges frameChanges; | ||
2825 | 69 | unsigned int frameChangeMask; | ||
2826 | 70 | |||
2827 | 71 | bool sendSyntheticConfigure; | ||
2828 | 72 | |||
2829 | 73 | unsigned int lockCount; | ||
2830 | 74 | |||
2831 | 75 | cw::AsyncServerWindow *asyncServerWindow; | ||
2832 | 76 | cw::SyncServerWindow *syncServerWindow; | ||
2833 | 77 | |||
2834 | 78 | crb::ConfigureRequestBuffer::LockFactory lockFactory; | ||
2835 | 79 | std::vector <LockObserver> locks; | ||
2836 | 80 | }; | ||
2837 | 81 | |||
2838 | 82 | void | ||
2839 | 83 | crb::ConfigureRequestBuffer::Private::dispatchConfigure (bool force) | ||
2840 | 84 | { | ||
2841 | 85 | const unsigned int allEventMasks = 0x7f; | ||
2842 | 86 | bool immediate = frameChangeMask & (CWStackMode | CWSibling); | ||
2843 | 87 | |||
2844 | 88 | /* This is a stop-gap solution for not having a plugin API to | ||
2845 | 89 | * query the window shape. Once we have that, we can safely | ||
2846 | 90 | * remove these and require the queue to be unlocked when that | ||
2847 | 91 | * happens. Its a separate unit of work for improving resize | ||
2848 | 92 | * performance anyways. | ||
2849 | 93 | */ | ||
2850 | 94 | immediate |= (frameChangeMask & (CWWidth | CWHeight | CWBorderWidth)); | ||
2851 | 95 | immediate |= (wrapperChangeMask & (CWWidth | CWHeight | CWBorderWidth | CWX | CWY)); | ||
2852 | 96 | immediate |= (clientChangeMask & (CWWidth | CWHeight | CWBorderWidth | CWX | CWY)); | ||
2853 | 97 | immediate |= force; | ||
2854 | 98 | |||
2855 | 99 | bool clientDispatch = (clientChangeMask & allEventMasks); | ||
2856 | 100 | bool wrapperDispatch = (wrapperChangeMask & allEventMasks); | ||
2857 | 101 | bool frameDispatch = (frameChangeMask & allEventMasks); | ||
2858 | 102 | |||
2859 | 103 | bool dispatch = !lockCount && (clientDispatch || | ||
2860 | 104 | wrapperDispatch || | ||
2861 | 105 | frameDispatch || | ||
2862 | 106 | sendSyntheticConfigure); | ||
2863 | 107 | |||
2864 | 108 | if (dispatch || immediate) | ||
2865 | 109 | { | ||
2866 | 110 | if (frameDispatch) | ||
2867 | 111 | { | ||
2868 | 112 | asyncServerWindow->requestConfigureOnFrame (frameChanges, | ||
2869 | 113 | frameChangeMask); | ||
2870 | 114 | frameChangeMask = 0; | ||
2871 | 115 | } | ||
2872 | 116 | |||
2873 | 117 | if (wrapperDispatch) | ||
2874 | 118 | { | ||
2875 | 119 | asyncServerWindow->requestConfigureOnWrapper (wrapperChanges, | ||
2876 | 120 | wrapperChangeMask); | ||
2877 | 121 | wrapperChangeMask = 0; | ||
2878 | 122 | } | ||
2879 | 123 | |||
2880 | 124 | if (clientDispatch) | ||
2881 | 125 | { | ||
2882 | 126 | asyncServerWindow->requestConfigureOnClient (clientChanges, | ||
2883 | 127 | clientChangeMask); | ||
2884 | 128 | clientChangeMask = 0; | ||
2885 | 129 | } | ||
2886 | 130 | |||
2887 | 131 | if (sendSyntheticConfigure) | ||
2888 | 132 | { | ||
2889 | 133 | asyncServerWindow->sendSyntheticConfigureNotify (); | ||
2890 | 134 | sendSyntheticConfigure = false; | ||
2891 | 135 | } | ||
2892 | 136 | |||
2893 | 137 | foreach (const LockObserver &lock, locks) | ||
2894 | 138 | { | ||
2895 | 139 | crb::Lockable::Ptr strongLock (lock.lock ()); | ||
2896 | 140 | |||
2897 | 141 | /* We might be in a lock's destructor so check | ||
2898 | 142 | * if this can really be re-locked, if not, its | ||
2899 | 143 | * no big deal as the lock is going away anyways | ||
2900 | 144 | */ | ||
2901 | 145 | if (strongLock) | ||
2902 | 146 | strongLock->lock (); | ||
2903 | 147 | } | ||
2904 | 148 | } | ||
2905 | 149 | } | ||
2906 | 150 | |||
2907 | 151 | void | ||
2908 | 152 | crb::ConfigureRequestBuffer::freeze () | ||
2909 | 153 | { | ||
2910 | 154 | priv->lockCount++; | ||
2911 | 155 | |||
2912 | 156 | assert (priv->lockCount <= priv->locks.size ()); | ||
2913 | 157 | } | ||
2914 | 158 | |||
2915 | 159 | void | ||
2916 | 160 | crb::ConfigureRequestBuffer::release () | ||
2917 | 161 | { | ||
2918 | 162 | assert (priv->lockCount); | ||
2919 | 163 | |||
2920 | 164 | priv->lockCount--; | ||
2921 | 165 | |||
2922 | 166 | priv->dispatchConfigure (); | ||
2923 | 167 | } | ||
2924 | 168 | |||
2925 | 169 | namespace | ||
2926 | 170 | { | ||
2927 | 171 | void applyChangeToXWC (const XWindowChanges &from, | ||
2928 | 172 | XWindowChanges &to, | ||
2929 | 173 | unsigned int mask) | ||
2930 | 174 | { | ||
2931 | 175 | if (mask & CWX) | ||
2932 | 176 | to.x = from.x; | ||
2933 | 177 | |||
2934 | 178 | if (mask & CWY) | ||
2935 | 179 | to.y = from.y; | ||
2936 | 180 | |||
2937 | 181 | if (mask & CWWidth) | ||
2938 | 182 | to.width = from.width; | ||
2939 | 183 | |||
2940 | 184 | if (mask & CWHeight) | ||
2941 | 185 | to.height = from.height; | ||
2942 | 186 | |||
2943 | 187 | if (mask & CWBorderWidth) | ||
2944 | 188 | to.border_width = from.border_width; | ||
2945 | 189 | |||
2946 | 190 | if (mask & CWSibling) | ||
2947 | 191 | to.sibling = from.sibling; | ||
2948 | 192 | |||
2949 | 193 | if (mask & CWStackMode) | ||
2950 | 194 | to.stack_mode = from.stack_mode; | ||
2951 | 195 | } | ||
2952 | 196 | } | ||
2953 | 197 | |||
2954 | 198 | void | ||
2955 | 199 | crb::ConfigureRequestBuffer::pushClientRequest (const XWindowChanges &xwc, | ||
2956 | 200 | unsigned int mask) | ||
2957 | 201 | { | ||
2958 | 202 | applyChangeToXWC (xwc, priv->clientChanges, mask); | ||
2959 | 203 | priv->clientChangeMask |= mask; | ||
2960 | 204 | |||
2961 | 205 | priv->dispatchConfigure (); | ||
2962 | 206 | } | ||
2963 | 207 | |||
2964 | 208 | void | ||
2965 | 209 | crb::ConfigureRequestBuffer::pushWrapperRequest (const XWindowChanges &xwc, | ||
2966 | 210 | unsigned int mask) | ||
2967 | 211 | { | ||
2968 | 212 | applyChangeToXWC (xwc, priv->wrapperChanges, mask); | ||
2969 | 213 | priv->wrapperChangeMask |= mask; | ||
2970 | 214 | |||
2971 | 215 | priv->dispatchConfigure (); | ||
2972 | 216 | } | ||
2973 | 217 | |||
2974 | 218 | void | ||
2975 | 219 | crb::ConfigureRequestBuffer::pushFrameRequest (const XWindowChanges &xwc, | ||
2976 | 220 | unsigned int mask) | ||
2977 | 221 | { | ||
2978 | 222 | applyChangeToXWC (xwc, priv->frameChanges, mask); | ||
2979 | 223 | priv->frameChangeMask |= mask; | ||
2980 | 224 | |||
2981 | 225 | priv->dispatchConfigure (); | ||
2982 | 226 | } | ||
2983 | 227 | |||
2984 | 228 | void | ||
2985 | 229 | crb::ConfigureRequestBuffer::pushSyntheticConfigureNotify () | ||
2986 | 230 | { | ||
2987 | 231 | priv->sendSyntheticConfigure = true; | ||
2988 | 232 | |||
2989 | 233 | priv->dispatchConfigure (); | ||
2990 | 234 | } | ||
2991 | 235 | |||
2992 | 236 | crb::Releasable::Ptr | ||
2993 | 237 | crb::ConfigureRequestBuffer::obtainLock () | ||
2994 | 238 | { | ||
2995 | 239 | crb::BufferLock::Ptr lock (priv->lockFactory (this)); | ||
2996 | 240 | |||
2997 | 241 | priv->locks.push_back (crb::Lockable::Weak (lock)); | ||
2998 | 242 | lock->lock (); | ||
2999 | 243 | |||
3000 | 244 | return lock; | ||
3001 | 245 | } | ||
3002 | 246 | |||
3003 | 247 | namespace | ||
3004 | 248 | { | ||
3005 | 249 | bool isLock (const crb::Lockable::Weak &lockable, | ||
3006 | 250 | crb::BufferLock *lock) | ||
3007 | 251 | { | ||
3008 | 252 | crb::Lockable::Ptr strongLockable (lockable.lock ()); | ||
3009 | 253 | |||
3010 | 254 | /* Asserting that the lock did not go away without telling | ||
3011 | 255 | * us first */ | ||
3012 | 256 | assert (strongLockable.get ()); | ||
3013 | 257 | |||
3014 | 258 | if (strongLockable.get () == lock) | ||
3015 | 259 | return true; | ||
3016 | 260 | |||
3017 | 261 | return false; | ||
3018 | 262 | } | ||
3019 | 263 | } | ||
3020 | 264 | |||
3021 | 265 | void | ||
3022 | 266 | crb::ConfigureRequestBuffer::untrackLock (crb::BufferLock *lock) | ||
3023 | 267 | { | ||
3024 | 268 | std::remove_if (priv->locks.begin (), | ||
3025 | 269 | priv->locks.end (), | ||
3026 | 270 | boost::bind (isLock, _1, lock)); | ||
3027 | 271 | } | ||
3028 | 272 | |||
3029 | 273 | bool crb::ConfigureRequestBuffer::queryAttributes (XWindowAttributes &attrib) | ||
3030 | 274 | { | ||
3031 | 275 | priv->dispatchConfigure (true); | ||
3032 | 276 | return priv->syncServerWindow->queryAttributes (attrib); | ||
3033 | 277 | } | ||
3034 | 278 | |||
3035 | 279 | bool crb::ConfigureRequestBuffer::queryFrameAttributes (XWindowAttributes &attrib) | ||
3036 | 280 | { | ||
3037 | 281 | priv->dispatchConfigure (true); | ||
3038 | 282 | return priv->syncServerWindow->queryFrameAttributes (attrib); | ||
3039 | 283 | } | ||
3040 | 284 | |||
3041 | 285 | /* This is more or less of a stop-gap for the fact that | ||
3042 | 286 | * when resizing window we re-query the window shape | ||
3043 | 287 | * and apply that to the frame. That's a separate unit of | ||
3044 | 288 | * work and should be dealt with separately. For now, force | ||
3045 | 289 | * a release of the queue whenever we do that so that | ||
3046 | 290 | * XShapeGetRectangles doesn't return an unexpected value | ||
3047 | 291 | */ | ||
3048 | 292 | XRectangle * | ||
3049 | 293 | crb::ConfigureRequestBuffer::queryShapeRectangles (int kind, | ||
3050 | 294 | int *count, | ||
3051 | 295 | int *ordering) | ||
3052 | 296 | { | ||
3053 | 297 | priv->dispatchConfigure (true); | ||
3054 | 298 | return priv->syncServerWindow->queryShapeRectangles (kind, count, ordering); | ||
3055 | 299 | } | ||
3056 | 300 | |||
3057 | 301 | void crb::ConfigureRequestBuffer::forceRelease () | ||
3058 | 302 | { | ||
3059 | 303 | priv->dispatchConfigure (true); | ||
3060 | 304 | } | ||
3061 | 305 | |||
3062 | 306 | crb::ConfigureRequestBuffer::ConfigureRequestBuffer (AsyncServerWindow *asyncServerWindow, | ||
3063 | 307 | SyncServerWindow *syncServerWindow, | ||
3064 | 308 | const crb::ConfigureRequestBuffer::LockFactory &factory) : | ||
3065 | 309 | priv (new crb::ConfigureRequestBuffer::Private (asyncServerWindow, syncServerWindow, factory)) | ||
3066 | 310 | { | ||
3067 | 311 | } | ||
3068 | 312 | |||
3069 | 313 | compiz::window::configure_buffers::Buffer::Ptr | ||
3070 | 314 | crb::ConfigureRequestBuffer::Create (AsyncServerWindow *asyncServerWindow, | ||
3071 | 315 | SyncServerWindow *syncServerWindow, | ||
3072 | 316 | const LockFactory &factory) | ||
3073 | 317 | { | ||
3074 | 318 | return crb::Buffer::Ptr (new crb::ConfigureRequestBuffer (asyncServerWindow, | ||
3075 | 319 | syncServerWindow, | ||
3076 | 320 | factory)); | ||
3077 | 321 | } | ||
3078 | 322 | |||
3079 | 323 | class crb::ConfigureBufferLock::Private | ||
3080 | 324 | { | ||
3081 | 325 | public: | ||
3082 | 326 | |||
3083 | 327 | Private (crb::CountedFreeze *freezable) : | ||
3084 | 328 | freezable (freezable), | ||
3085 | 329 | armed (false) | ||
3086 | 330 | { | ||
3087 | 331 | } | ||
3088 | 332 | |||
3089 | 333 | crb::CountedFreeze *freezable; | ||
3090 | 334 | bool armed; | ||
3091 | 335 | }; | ||
3092 | 336 | |||
3093 | 337 | crb::ConfigureBufferLock::ConfigureBufferLock (crb::CountedFreeze *freezable) : | ||
3094 | 338 | priv (new crb::ConfigureBufferLock::Private (freezable)) | ||
3095 | 339 | { | ||
3096 | 340 | } | ||
3097 | 341 | |||
3098 | 342 | crb::ConfigureBufferLock::~ConfigureBufferLock () | ||
3099 | 343 | { | ||
3100 | 344 | release (); | ||
3101 | 345 | } | ||
3102 | 346 | |||
3103 | 347 | void | ||
3104 | 348 | crb::ConfigureBufferLock::lock () | ||
3105 | 349 | { | ||
3106 | 350 | if (!priv->armed) | ||
3107 | 351 | priv->freezable->freeze (); | ||
3108 | 352 | |||
3109 | 353 | priv->armed = true; | ||
3110 | 354 | } | ||
3111 | 355 | |||
3112 | 356 | void | ||
3113 | 357 | crb::ConfigureBufferLock::release () | ||
3114 | 358 | { | ||
3115 | 359 | if (priv->armed) | ||
3116 | 360 | priv->freezable->release (); | ||
3117 | 361 | |||
3118 | 362 | priv->armed = false; | ||
3119 | 363 | } | ||
3120 | 0 | 364 | ||
3121 | === removed file 'src/configurerequestbuffer.cpp' | |||
3122 | --- src/configurerequestbuffer.cpp 2013-02-14 12:12:53 +0000 | |||
3123 | +++ src/configurerequestbuffer.cpp 1970-01-01 00:00:00 +0000 | |||
3124 | @@ -1,363 +0,0 @@ | |||
3125 | 1 | /* | ||
3126 | 2 | * Copyright © 2012 Sam Spilsbury | ||
3127 | 3 | * | ||
3128 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
3129 | 5 | * and its documentation for any purpose is hereby granted without | ||
3130 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
3131 | 7 | * and that both that copyright notice and this permission notice | ||
3132 | 8 | * appear in supporting documentation, and that the name of | ||
3133 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
3134 | 10 | * distribution of the software without specific, written prior permission. | ||
3135 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
3136 | 12 | * software for any purpose. It is provided "as is" without express or | ||
3137 | 13 | * implied warranty. | ||
3138 | 14 | * | ||
3139 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
3140 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
3141 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
3142 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
3143 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
3144 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
3145 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
3146 | 22 | * | ||
3147 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
3148 | 24 | */ | ||
3149 | 25 | #include <cstdio> | ||
3150 | 26 | #include <cassert> | ||
3151 | 27 | #include <boost/foreach.hpp> | ||
3152 | 28 | #include <boost/weak_ptr.hpp> | ||
3153 | 29 | #include <boost/bind.hpp> | ||
3154 | 30 | #include "asyncserverwindow.h" | ||
3155 | 31 | #include "configurerequestbuffer-impl.h" | ||
3156 | 32 | |||
3157 | 33 | #ifndef foreach | ||
3158 | 34 | #define foreach BOOST_FOREACH | ||
3159 | 35 | #endif | ||
3160 | 36 | |||
3161 | 37 | namespace crb = compiz::window::configure_buffers; | ||
3162 | 38 | namespace cw = compiz::window; | ||
3163 | 39 | |||
3164 | 40 | class crb::ConfigureRequestBuffer::Private | ||
3165 | 41 | { | ||
3166 | 42 | public: | ||
3167 | 43 | |||
3168 | 44 | typedef crb::Lockable::Weak LockObserver; | ||
3169 | 45 | |||
3170 | 46 | Private (cw::AsyncServerWindow *asyncServerWindow, | ||
3171 | 47 | cw::SyncServerWindow *syncServerWindow, | ||
3172 | 48 | const crb::ConfigureRequestBuffer::LockFactory &lockFactory) : | ||
3173 | 49 | clientChangeMask (0), | ||
3174 | 50 | wrapperChangeMask (0), | ||
3175 | 51 | frameChangeMask (0), | ||
3176 | 52 | sendSyntheticConfigure (false), | ||
3177 | 53 | lockCount (0), | ||
3178 | 54 | asyncServerWindow (asyncServerWindow), | ||
3179 | 55 | syncServerWindow (syncServerWindow), | ||
3180 | 56 | lockFactory (lockFactory) | ||
3181 | 57 | { | ||
3182 | 58 | } | ||
3183 | 59 | |||
3184 | 60 | void dispatchConfigure (bool force = false); | ||
3185 | 61 | |||
3186 | 62 | XWindowChanges clientChanges; | ||
3187 | 63 | unsigned int clientChangeMask; | ||
3188 | 64 | |||
3189 | 65 | XWindowChanges wrapperChanges; | ||
3190 | 66 | unsigned int wrapperChangeMask; | ||
3191 | 67 | |||
3192 | 68 | XWindowChanges frameChanges; | ||
3193 | 69 | unsigned int frameChangeMask; | ||
3194 | 70 | |||
3195 | 71 | bool sendSyntheticConfigure; | ||
3196 | 72 | |||
3197 | 73 | unsigned int lockCount; | ||
3198 | 74 | |||
3199 | 75 | cw::AsyncServerWindow *asyncServerWindow; | ||
3200 | 76 | cw::SyncServerWindow *syncServerWindow; | ||
3201 | 77 | |||
3202 | 78 | crb::ConfigureRequestBuffer::LockFactory lockFactory; | ||
3203 | 79 | std::vector <LockObserver> locks; | ||
3204 | 80 | }; | ||
3205 | 81 | |||
3206 | 82 | void | ||
3207 | 83 | crb::ConfigureRequestBuffer::Private::dispatchConfigure (bool force) | ||
3208 | 84 | { | ||
3209 | 85 | const unsigned int allEventMasks = 0x7f; | ||
3210 | 86 | bool immediate = frameChangeMask & (CWStackMode | CWSibling); | ||
3211 | 87 | |||
3212 | 88 | /* This is a stop-gap solution for not having a plugin API to | ||
3213 | 89 | * query the window shape. Once we have that, we can safely | ||
3214 | 90 | * remove these and require the queue to be unlocked when that | ||
3215 | 91 | * happens. Its a separate unit of work for improving resize | ||
3216 | 92 | * performance anyways. | ||
3217 | 93 | */ | ||
3218 | 94 | immediate |= (frameChangeMask & (CWWidth | CWHeight | CWBorderWidth)); | ||
3219 | 95 | immediate |= (wrapperChangeMask & (CWWidth | CWHeight | CWBorderWidth | CWX | CWY)); | ||
3220 | 96 | immediate |= (clientChangeMask & (CWWidth | CWHeight | CWBorderWidth | CWX | CWY)); | ||
3221 | 97 | immediate |= force; | ||
3222 | 98 | |||
3223 | 99 | bool clientDispatch = (clientChangeMask & allEventMasks); | ||
3224 | 100 | bool wrapperDispatch = (wrapperChangeMask & allEventMasks); | ||
3225 | 101 | bool frameDispatch = (frameChangeMask & allEventMasks); | ||
3226 | 102 | |||
3227 | 103 | bool dispatch = !lockCount && (clientDispatch || | ||
3228 | 104 | wrapperDispatch || | ||
3229 | 105 | frameDispatch || | ||
3230 | 106 | sendSyntheticConfigure); | ||
3231 | 107 | |||
3232 | 108 | if (dispatch || immediate) | ||
3233 | 109 | { | ||
3234 | 110 | if (frameDispatch) | ||
3235 | 111 | { | ||
3236 | 112 | asyncServerWindow->requestConfigureOnFrame (frameChanges, | ||
3237 | 113 | frameChangeMask); | ||
3238 | 114 | frameChangeMask = 0; | ||
3239 | 115 | } | ||
3240 | 116 | |||
3241 | 117 | if (wrapperDispatch) | ||
3242 | 118 | { | ||
3243 | 119 | asyncServerWindow->requestConfigureOnWrapper (wrapperChanges, | ||
3244 | 120 | wrapperChangeMask); | ||
3245 | 121 | wrapperChangeMask = 0; | ||
3246 | 122 | } | ||
3247 | 123 | |||
3248 | 124 | if (clientDispatch) | ||
3249 | 125 | { | ||
3250 | 126 | asyncServerWindow->requestConfigureOnClient (clientChanges, | ||
3251 | 127 | clientChangeMask); | ||
3252 | 128 | clientChangeMask = 0; | ||
3253 | 129 | } | ||
3254 | 130 | |||
3255 | 131 | if (sendSyntheticConfigure) | ||
3256 | 132 | { | ||
3257 | 133 | asyncServerWindow->sendSyntheticConfigureNotify (); | ||
3258 | 134 | sendSyntheticConfigure = false; | ||
3259 | 135 | } | ||
3260 | 136 | |||
3261 | 137 | foreach (const LockObserver &lock, locks) | ||
3262 | 138 | { | ||
3263 | 139 | crb::Lockable::Ptr strongLock (lock.lock ()); | ||
3264 | 140 | |||
3265 | 141 | /* We might be in a lock's destructor so check | ||
3266 | 142 | * if this can really be re-locked, if not, its | ||
3267 | 143 | * no big deal as the lock is going away anyways | ||
3268 | 144 | */ | ||
3269 | 145 | if (strongLock) | ||
3270 | 146 | strongLock->lock (); | ||
3271 | 147 | } | ||
3272 | 148 | } | ||
3273 | 149 | } | ||
3274 | 150 | |||
3275 | 151 | void | ||
3276 | 152 | crb::ConfigureRequestBuffer::freeze () | ||
3277 | 153 | { | ||
3278 | 154 | priv->lockCount++; | ||
3279 | 155 | |||
3280 | 156 | assert (priv->lockCount <= priv->locks.size ()); | ||
3281 | 157 | } | ||
3282 | 158 | |||
3283 | 159 | void | ||
3284 | 160 | crb::ConfigureRequestBuffer::release () | ||
3285 | 161 | { | ||
3286 | 162 | assert (priv->lockCount); | ||
3287 | 163 | |||
3288 | 164 | priv->lockCount--; | ||
3289 | 165 | |||
3290 | 166 | priv->dispatchConfigure (); | ||
3291 | 167 | } | ||
3292 | 168 | |||
3293 | 169 | namespace | ||
3294 | 170 | { | ||
3295 | 171 | void applyChangeToXWC (const XWindowChanges &from, | ||
3296 | 172 | XWindowChanges &to, | ||
3297 | 173 | unsigned int mask) | ||
3298 | 174 | { | ||
3299 | 175 | if (mask & CWX) | ||
3300 | 176 | to.x = from.x; | ||
3301 | 177 | |||
3302 | 178 | if (mask & CWY) | ||
3303 | 179 | to.y = from.y; | ||
3304 | 180 | |||
3305 | 181 | if (mask & CWWidth) | ||
3306 | 182 | to.width = from.width; | ||
3307 | 183 | |||
3308 | 184 | if (mask & CWHeight) | ||
3309 | 185 | to.height = from.height; | ||
3310 | 186 | |||
3311 | 187 | if (mask & CWBorderWidth) | ||
3312 | 188 | to.border_width = from.border_width; | ||
3313 | 189 | |||
3314 | 190 | if (mask & CWSibling) | ||
3315 | 191 | to.sibling = from.sibling; | ||
3316 | 192 | |||
3317 | 193 | if (mask & CWStackMode) | ||
3318 | 194 | to.stack_mode = from.stack_mode; | ||
3319 | 195 | } | ||
3320 | 196 | } | ||
3321 | 197 | |||
3322 | 198 | void | ||
3323 | 199 | crb::ConfigureRequestBuffer::pushClientRequest (const XWindowChanges &xwc, | ||
3324 | 200 | unsigned int mask) | ||
3325 | 201 | { | ||
3326 | 202 | applyChangeToXWC (xwc, priv->clientChanges, mask); | ||
3327 | 203 | priv->clientChangeMask |= mask; | ||
3328 | 204 | |||
3329 | 205 | priv->dispatchConfigure (); | ||
3330 | 206 | } | ||
3331 | 207 | |||
3332 | 208 | void | ||
3333 | 209 | crb::ConfigureRequestBuffer::pushWrapperRequest (const XWindowChanges &xwc, | ||
3334 | 210 | unsigned int mask) | ||
3335 | 211 | { | ||
3336 | 212 | applyChangeToXWC (xwc, priv->wrapperChanges, mask); | ||
3337 | 213 | priv->wrapperChangeMask |= mask; | ||
3338 | 214 | |||
3339 | 215 | priv->dispatchConfigure (); | ||
3340 | 216 | } | ||
3341 | 217 | |||
3342 | 218 | void | ||
3343 | 219 | crb::ConfigureRequestBuffer::pushFrameRequest (const XWindowChanges &xwc, | ||
3344 | 220 | unsigned int mask) | ||
3345 | 221 | { | ||
3346 | 222 | applyChangeToXWC (xwc, priv->frameChanges, mask); | ||
3347 | 223 | priv->frameChangeMask |= mask; | ||
3348 | 224 | |||
3349 | 225 | priv->dispatchConfigure (); | ||
3350 | 226 | } | ||
3351 | 227 | |||
3352 | 228 | void | ||
3353 | 229 | crb::ConfigureRequestBuffer::pushSyntheticConfigureNotify () | ||
3354 | 230 | { | ||
3355 | 231 | priv->sendSyntheticConfigure = true; | ||
3356 | 232 | |||
3357 | 233 | priv->dispatchConfigure (); | ||
3358 | 234 | } | ||
3359 | 235 | |||
3360 | 236 | crb::Releasable::Ptr | ||
3361 | 237 | crb::ConfigureRequestBuffer::obtainLock () | ||
3362 | 238 | { | ||
3363 | 239 | crb::BufferLock::Ptr lock (priv->lockFactory (this)); | ||
3364 | 240 | |||
3365 | 241 | priv->locks.push_back (crb::Lockable::Weak (lock)); | ||
3366 | 242 | lock->lock (); | ||
3367 | 243 | |||
3368 | 244 | return lock; | ||
3369 | 245 | } | ||
3370 | 246 | |||
3371 | 247 | namespace | ||
3372 | 248 | { | ||
3373 | 249 | bool isLock (const crb::Lockable::Weak &lockable, | ||
3374 | 250 | crb::BufferLock *lock) | ||
3375 | 251 | { | ||
3376 | 252 | crb::Lockable::Ptr strongLockable (lockable.lock ()); | ||
3377 | 253 | |||
3378 | 254 | /* Asserting that the lock did not go away without telling | ||
3379 | 255 | * us first */ | ||
3380 | 256 | assert (strongLockable.get ()); | ||
3381 | 257 | |||
3382 | 258 | if (strongLockable.get () == lock) | ||
3383 | 259 | return true; | ||
3384 | 260 | |||
3385 | 261 | return false; | ||
3386 | 262 | } | ||
3387 | 263 | } | ||
3388 | 264 | |||
3389 | 265 | void | ||
3390 | 266 | crb::ConfigureRequestBuffer::untrackLock (crb::BufferLock *lock) | ||
3391 | 267 | { | ||
3392 | 268 | std::remove_if (priv->locks.begin (), | ||
3393 | 269 | priv->locks.end (), | ||
3394 | 270 | boost::bind (isLock, _1, lock)); | ||
3395 | 271 | } | ||
3396 | 272 | |||
3397 | 273 | bool crb::ConfigureRequestBuffer::queryAttributes (XWindowAttributes &attrib) | ||
3398 | 274 | { | ||
3399 | 275 | priv->dispatchConfigure (true); | ||
3400 | 276 | return priv->syncServerWindow->queryAttributes (attrib); | ||
3401 | 277 | } | ||
3402 | 278 | |||
3403 | 279 | bool crb::ConfigureRequestBuffer::queryFrameAttributes (XWindowAttributes &attrib) | ||
3404 | 280 | { | ||
3405 | 281 | priv->dispatchConfigure (true); | ||
3406 | 282 | return priv->syncServerWindow->queryFrameAttributes (attrib); | ||
3407 | 283 | } | ||
3408 | 284 | |||
3409 | 285 | /* This is more or less of a stop-gap for the fact that | ||
3410 | 286 | * when resizing window we re-query the window shape | ||
3411 | 287 | * and apply that to the frame. That's a separate unit of | ||
3412 | 288 | * work and should be dealt with separately. For now, force | ||
3413 | 289 | * a release of the queue whenever we do that so that | ||
3414 | 290 | * XShapeGetRectangles doesn't return an unexpected value | ||
3415 | 291 | */ | ||
3416 | 292 | XRectangle * | ||
3417 | 293 | crb::ConfigureRequestBuffer::queryShapeRectangles (int kind, | ||
3418 | 294 | int *count, | ||
3419 | 295 | int *ordering) | ||
3420 | 296 | { | ||
3421 | 297 | priv->dispatchConfigure (true); | ||
3422 | 298 | return priv->syncServerWindow->queryShapeRectangles (kind, count, ordering); | ||
3423 | 299 | } | ||
3424 | 300 | |||
3425 | 301 | void crb::ConfigureRequestBuffer::forceRelease () | ||
3426 | 302 | { | ||
3427 | 303 | priv->dispatchConfigure (true); | ||
3428 | 304 | } | ||
3429 | 305 | |||
3430 | 306 | crb::ConfigureRequestBuffer::ConfigureRequestBuffer (AsyncServerWindow *asyncServerWindow, | ||
3431 | 307 | SyncServerWindow *syncServerWindow, | ||
3432 | 308 | const crb::ConfigureRequestBuffer::LockFactory &factory) : | ||
3433 | 309 | priv (new crb::ConfigureRequestBuffer::Private (asyncServerWindow, syncServerWindow, factory)) | ||
3434 | 310 | { | ||
3435 | 311 | } | ||
3436 | 312 | |||
3437 | 313 | compiz::window::configure_buffers::Buffer::Ptr | ||
3438 | 314 | crb::ConfigureRequestBuffer::Create (AsyncServerWindow *asyncServerWindow, | ||
3439 | 315 | SyncServerWindow *syncServerWindow, | ||
3440 | 316 | const LockFactory &factory) | ||
3441 | 317 | { | ||
3442 | 318 | return crb::Buffer::Ptr (new crb::ConfigureRequestBuffer (asyncServerWindow, | ||
3443 | 319 | syncServerWindow, | ||
3444 | 320 | factory)); | ||
3445 | 321 | } | ||
3446 | 322 | |||
3447 | 323 | class crb::ConfigureBufferLock::Private | ||
3448 | 324 | { | ||
3449 | 325 | public: | ||
3450 | 326 | |||
3451 | 327 | Private (crb::CountedFreeze *freezable) : | ||
3452 | 328 | freezable (freezable), | ||
3453 | 329 | armed (false) | ||
3454 | 330 | { | ||
3455 | 331 | } | ||
3456 | 332 | |||
3457 | 333 | crb::CountedFreeze *freezable; | ||
3458 | 334 | bool armed; | ||
3459 | 335 | }; | ||
3460 | 336 | |||
3461 | 337 | crb::ConfigureBufferLock::ConfigureBufferLock (crb::CountedFreeze *freezable) : | ||
3462 | 338 | priv (new crb::ConfigureBufferLock::Private (freezable)) | ||
3463 | 339 | { | ||
3464 | 340 | } | ||
3465 | 341 | |||
3466 | 342 | crb::ConfigureBufferLock::~ConfigureBufferLock () | ||
3467 | 343 | { | ||
3468 | 344 | release (); | ||
3469 | 345 | } | ||
3470 | 346 | |||
3471 | 347 | void | ||
3472 | 348 | crb::ConfigureBufferLock::lock () | ||
3473 | 349 | { | ||
3474 | 350 | if (!priv->armed) | ||
3475 | 351 | priv->freezable->freeze (); | ||
3476 | 352 | |||
3477 | 353 | priv->armed = true; | ||
3478 | 354 | } | ||
3479 | 355 | |||
3480 | 356 | void | ||
3481 | 357 | crb::ConfigureBufferLock::release () | ||
3482 | 358 | { | ||
3483 | 359 | if (priv->armed) | ||
3484 | 360 | priv->freezable->release (); | ||
3485 | 361 | |||
3486 | 362 | priv->armed = false; | ||
3487 | 363 | } | ||
3488 | 364 | 0 | ||
3489 | === removed file 'src/serverwindow.h' | |||
3490 | === added file 'src/syncserverwindow.h' | |||
3491 | --- src/syncserverwindow.h 1970-01-01 00:00:00 +0000 | |||
3492 | +++ src/syncserverwindow.h 2013-02-28 02:29:22 +0000 | |||
3493 | @@ -0,0 +1,49 @@ | |||
3494 | 1 | /* | ||
3495 | 2 | * Copyright © 2012 Sam Spilsbury | ||
3496 | 3 | * | ||
3497 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
3498 | 5 | * and its documentation for any purpose is hereby granted without | ||
3499 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
3500 | 7 | * and that both that copyright notice and this permission notice | ||
3501 | 8 | * appear in supporting documentation, and that the name of | ||
3502 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
3503 | 10 | * distribution of the software without specific, written prior permission. | ||
3504 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
3505 | 12 | * software for any purpose. It is provided "as is" without express or | ||
3506 | 13 | * implied warranty. | ||
3507 | 14 | * | ||
3508 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
3509 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
3510 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
3511 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
3512 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
3513 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
3514 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
3515 | 22 | * | ||
3516 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
3517 | 24 | */ | ||
3518 | 25 | #ifndef _COMPIZ_SYNC_SERVER_WINDOW_H | ||
3519 | 26 | #define _COMPIZ_SYNC_SERVER_WINDOW_H | ||
3520 | 27 | |||
3521 | 28 | #include <X11/Xlib.h> | ||
3522 | 29 | |||
3523 | 30 | namespace compiz | ||
3524 | 31 | { | ||
3525 | 32 | namespace window | ||
3526 | 33 | { | ||
3527 | 34 | class SyncServerWindow | ||
3528 | 35 | { | ||
3529 | 36 | public: | ||
3530 | 37 | |||
3531 | 38 | virtual ~SyncServerWindow () {} | ||
3532 | 39 | |||
3533 | 40 | virtual bool queryAttributes (XWindowAttributes &attrib) = 0; | ||
3534 | 41 | virtual bool queryFrameAttributes (XWindowAttributes &attrib) = 0; | ||
3535 | 42 | virtual XRectangle * queryShapeRectangles (int kind, | ||
3536 | 43 | int *count, | ||
3537 | 44 | int *ordering) = 0; | ||
3538 | 45 | }; | ||
3539 | 46 | } | ||
3540 | 47 | } | ||
3541 | 48 | |||
3542 | 49 | #endif | ||
3543 | 0 | 50 | ||
3544 | === removed file 'src/syncserverwindow.h' | |||
3545 | --- src/syncserverwindow.h 2012-12-13 11:12:32 +0000 | |||
3546 | +++ src/syncserverwindow.h 1970-01-01 00:00:00 +0000 | |||
3547 | @@ -1,49 +0,0 @@ | |||
3548 | 1 | /* | ||
3549 | 2 | * Copyright © 2012 Sam Spilsbury | ||
3550 | 3 | * | ||
3551 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
3552 | 5 | * and its documentation for any purpose is hereby granted without | ||
3553 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
3554 | 7 | * and that both that copyright notice and this permission notice | ||
3555 | 8 | * appear in supporting documentation, and that the name of | ||
3556 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
3557 | 10 | * distribution of the software without specific, written prior permission. | ||
3558 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
3559 | 12 | * software for any purpose. It is provided "as is" without express or | ||
3560 | 13 | * implied warranty. | ||
3561 | 14 | * | ||
3562 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
3563 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
3564 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
3565 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
3566 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
3567 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
3568 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
3569 | 22 | * | ||
3570 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
3571 | 24 | */ | ||
3572 | 25 | #ifndef _COMPIZ_SYNC_SERVER_WINDOW_H | ||
3573 | 26 | #define _COMPIZ_SYNC_SERVER_WINDOW_H | ||
3574 | 27 | |||
3575 | 28 | #include <X11/Xlib.h> | ||
3576 | 29 | |||
3577 | 30 | namespace compiz | ||
3578 | 31 | { | ||
3579 | 32 | namespace window | ||
3580 | 33 | { | ||
3581 | 34 | class SyncServerWindow | ||
3582 | 35 | { | ||
3583 | 36 | public: | ||
3584 | 37 | |||
3585 | 38 | virtual ~SyncServerWindow () {} | ||
3586 | 39 | |||
3587 | 40 | virtual bool queryAttributes (XWindowAttributes &attrib) = 0; | ||
3588 | 41 | virtual bool queryFrameAttributes (XWindowAttributes &attrib) = 0; | ||
3589 | 42 | virtual XRectangle * queryShapeRectangles (int kind, | ||
3590 | 43 | int *count, | ||
3591 | 44 | int *ordering) = 0; | ||
3592 | 45 | }; | ||
3593 | 46 | } | ||
3594 | 47 | } | ||
3595 | 48 | |||
3596 | 49 | #endif | ||
3597 | 50 | 0 | ||
3598 | === added file 'src/tests/test_configurerequestbuffer.cpp' | |||
3599 | --- src/tests/test_configurerequestbuffer.cpp 1970-01-01 00:00:00 +0000 | |||
3600 | +++ src/tests/test_configurerequestbuffer.cpp 2013-02-28 02:29:22 +0000 | |||
3601 | @@ -0,0 +1,667 @@ | |||
3602 | 1 | /* | ||
3603 | 2 | * Copyright © 2012 Sam Spilsbury | ||
3604 | 3 | * | ||
3605 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
3606 | 5 | * and its documentation for any purpose is hereby granted without | ||
3607 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
3608 | 7 | * and that both that copyright notice and this permission notice | ||
3609 | 8 | * appear in supporting documentation, and that the name of | ||
3610 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
3611 | 10 | * distribution of the software without specific, written prior permission. | ||
3612 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
3613 | 12 | * software for any purpose. It is provided "as is" without express or | ||
3614 | 13 | * implied warranty. | ||
3615 | 14 | * | ||
3616 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
3617 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
3618 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
3619 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
3620 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
3621 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
3622 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
3623 | 22 | * | ||
3624 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
3625 | 24 | */ | ||
3626 | 25 | #include <deque> | ||
3627 | 26 | #include <boost/shared_ptr.hpp> | ||
3628 | 27 | #include <boost/make_shared.hpp> | ||
3629 | 28 | #include <boost/bind.hpp> | ||
3630 | 29 | #include <gmock/gmock.h> | ||
3631 | 30 | #include <gtest/gtest.h> | ||
3632 | 31 | #include <X11/Xlib.h> | ||
3633 | 32 | |||
3634 | 33 | #include "configurerequestbuffer-impl.h" | ||
3635 | 34 | #include "asyncserverwindow.h" | ||
3636 | 35 | |||
3637 | 36 | namespace crb = compiz::window::configure_buffers; | ||
3638 | 37 | namespace cw = compiz::window; | ||
3639 | 38 | |||
3640 | 39 | using testing::_; | ||
3641 | 40 | using testing::NiceMock; | ||
3642 | 41 | using testing::Return; | ||
3643 | 42 | using testing::Invoke; | ||
3644 | 43 | using testing::WithArgs; | ||
3645 | 44 | using testing::SetArgReferee; | ||
3646 | 45 | using testing::DoAll; | ||
3647 | 46 | using testing::InSequence; | ||
3648 | 47 | using testing::ReturnNull; | ||
3649 | 48 | using testing::IsNull; | ||
3650 | 49 | |||
3651 | 50 | class MockAsyncServerWindow : | ||
3652 | 51 | public cw::AsyncServerWindow | ||
3653 | 52 | { | ||
3654 | 53 | public: | ||
3655 | 54 | |||
3656 | 55 | MOCK_METHOD2 (requestConfigureOnClient, int (const XWindowChanges &, unsigned int)); | ||
3657 | 56 | MOCK_METHOD2 (requestConfigureOnFrame, int (const XWindowChanges &, unsigned int)); | ||
3658 | 57 | MOCK_METHOD2 (requestConfigureOnWrapper, int (const XWindowChanges &, unsigned int)); | ||
3659 | 58 | MOCK_METHOD0 (sendSyntheticConfigureNotify, void ()); | ||
3660 | 59 | MOCK_CONST_METHOD0 (hasCustomShape, bool ()); | ||
3661 | 60 | }; | ||
3662 | 61 | |||
3663 | 62 | class MockSyncServerWindow : | ||
3664 | 63 | public cw::SyncServerWindow | ||
3665 | 64 | { | ||
3666 | 65 | public: | ||
3667 | 66 | |||
3668 | 67 | MOCK_METHOD1 (queryAttributes, bool (XWindowAttributes &)); | ||
3669 | 68 | MOCK_METHOD1 (queryFrameAttributes, bool (XWindowAttributes &)); | ||
3670 | 69 | MOCK_METHOD3 (queryShapeRectangles, XRectangle * (int, int *, int *)); | ||
3671 | 70 | }; | ||
3672 | 71 | |||
3673 | 72 | namespace | ||
3674 | 73 | { | ||
3675 | 74 | int REQUEST_X = 1; | ||
3676 | 75 | int REQUEST_Y = 2; | ||
3677 | 76 | int REQUEST_WIDTH = 3; | ||
3678 | 77 | int REQUEST_HEIGHT = 4; | ||
3679 | 78 | int REQUEST_BORDER = 5; | ||
3680 | 79 | |||
3681 | 80 | Window REQUEST_ABOVE = 6; | ||
3682 | 81 | unsigned int REQUEST_MODE = 7; | ||
3683 | 82 | |||
3684 | 83 | crb::BufferLock::Ptr | ||
3685 | 84 | CreateNormalLock (crb::CountedFreeze *cf) | ||
3686 | 85 | { | ||
3687 | 86 | return boost::make_shared <crb::ConfigureBufferLock> (cf); | ||
3688 | 87 | } | ||
3689 | 88 | |||
3690 | 89 | } | ||
3691 | 90 | |||
3692 | 91 | MATCHER_P2 (MaskXWC, xwc, vm, "Matches XWindowChanges") | ||
3693 | 92 | { | ||
3694 | 93 | if (vm & CWX) | ||
3695 | 94 | if (xwc.x != arg.x) | ||
3696 | 95 | return false; | ||
3697 | 96 | |||
3698 | 97 | if (vm & CWY) | ||
3699 | 98 | if (xwc.y != arg.y) | ||
3700 | 99 | return false; | ||
3701 | 100 | |||
3702 | 101 | if (vm & CWWidth) | ||
3703 | 102 | if (xwc.width != arg.width) | ||
3704 | 103 | return false; | ||
3705 | 104 | |||
3706 | 105 | if (vm & CWHeight) | ||
3707 | 106 | if (xwc.height != arg.height) | ||
3708 | 107 | return false; | ||
3709 | 108 | |||
3710 | 109 | if (vm & CWBorderWidth) | ||
3711 | 110 | if (xwc.border_width != arg.border_width) | ||
3712 | 111 | return false; | ||
3713 | 112 | |||
3714 | 113 | if (vm & CWStackMode) | ||
3715 | 114 | if (xwc.stack_mode != arg.stack_mode) | ||
3716 | 115 | return false; | ||
3717 | 116 | |||
3718 | 117 | if (vm & CWSibling) | ||
3719 | 118 | if (xwc.sibling != arg.sibling) | ||
3720 | 119 | return false; | ||
3721 | 120 | |||
3722 | 121 | return true; | ||
3723 | 122 | } | ||
3724 | 123 | |||
3725 | 124 | class ConfigureRequestBuffer : | ||
3726 | 125 | public testing::Test | ||
3727 | 126 | { | ||
3728 | 127 | public: | ||
3729 | 128 | |||
3730 | 129 | ConfigureRequestBuffer () | ||
3731 | 130 | { | ||
3732 | 131 | /* Initialize xwc, we control it | ||
3733 | 132 | * through the value masks */ | ||
3734 | 133 | xwc.x = REQUEST_X; | ||
3735 | 134 | xwc.y = REQUEST_Y; | ||
3736 | 135 | xwc.width = REQUEST_WIDTH; | ||
3737 | 136 | xwc.height = REQUEST_HEIGHT; | ||
3738 | 137 | xwc.border_width = REQUEST_BORDER; | ||
3739 | 138 | xwc.sibling = REQUEST_ABOVE; | ||
3740 | 139 | xwc.stack_mode = REQUEST_MODE; | ||
3741 | 140 | } | ||
3742 | 141 | |||
3743 | 142 | protected: | ||
3744 | 143 | |||
3745 | 144 | XWindowChanges xwc; | ||
3746 | 145 | MockAsyncServerWindow asyncServerWindow; | ||
3747 | 146 | MockSyncServerWindow syncServerWindow; | ||
3748 | 147 | }; | ||
3749 | 148 | |||
3750 | 149 | class ConfigureRequestBufferDispatch : | ||
3751 | 150 | public ConfigureRequestBuffer | ||
3752 | 151 | { | ||
3753 | 152 | protected: | ||
3754 | 153 | |||
3755 | 154 | ConfigureRequestBufferDispatch () : | ||
3756 | 155 | ConfigureRequestBuffer (), | ||
3757 | 156 | factory (boost::bind (CreateNormalLock, _1)), | ||
3758 | 157 | buffer ( | ||
3759 | 158 | crb::ConfigureRequestBuffer::Create (&asyncServerWindow, | ||
3760 | 159 | &syncServerWindow, | ||
3761 | 160 | factory)) | ||
3762 | 161 | { | ||
3763 | 162 | } | ||
3764 | 163 | |||
3765 | 164 | crb::ConfigureRequestBuffer::LockFactory factory; | ||
3766 | 165 | crb::Buffer::Ptr buffer; | ||
3767 | 166 | }; | ||
3768 | 167 | |||
3769 | 168 | TEST_F (ConfigureRequestBufferDispatch, PushDirectSyntheticConfigureNotify) | ||
3770 | 169 | { | ||
3771 | 170 | EXPECT_CALL (asyncServerWindow, sendSyntheticConfigureNotify ()); | ||
3772 | 171 | |||
3773 | 172 | buffer->pushSyntheticConfigureNotify (); | ||
3774 | 173 | } | ||
3775 | 174 | |||
3776 | 175 | TEST_F (ConfigureRequestBufferDispatch, PushDirectClientUpdate) | ||
3777 | 176 | { | ||
3778 | 177 | unsigned int valueMask = CWX | CWY | CWBorderWidth | | ||
3779 | 178 | CWSibling | CWStackMode; | ||
3780 | 179 | |||
3781 | 180 | EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (MaskXWC (xwc, valueMask), | ||
3782 | 181 | valueMask)); | ||
3783 | 182 | |||
3784 | 183 | buffer->pushClientRequest (xwc, valueMask); | ||
3785 | 184 | } | ||
3786 | 185 | |||
3787 | 186 | TEST_F (ConfigureRequestBufferDispatch, PushDirectWrapperUpdate) | ||
3788 | 187 | { | ||
3789 | 188 | unsigned int valueMask = CWX | CWY | CWBorderWidth | | ||
3790 | 189 | CWSibling | CWStackMode; | ||
3791 | 190 | |||
3792 | 191 | EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (MaskXWC (xwc, valueMask), | ||
3793 | 192 | valueMask)); | ||
3794 | 193 | |||
3795 | 194 | buffer->pushWrapperRequest (xwc, valueMask); | ||
3796 | 195 | } | ||
3797 | 196 | |||
3798 | 197 | TEST_F (ConfigureRequestBufferDispatch, PushDirectFrameUpdate) | ||
3799 | 198 | { | ||
3800 | 199 | unsigned int valueMask = CWX | CWY | CWBorderWidth | | ||
3801 | 200 | CWSibling | CWStackMode; | ||
3802 | 201 | |||
3803 | 202 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
3804 | 203 | valueMask)); | ||
3805 | 204 | |||
3806 | 205 | buffer->pushFrameRequest (xwc, valueMask); | ||
3807 | 206 | } | ||
3808 | 207 | |||
3809 | 208 | TEST_F (ConfigureRequestBufferDispatch, PushUpdateLocked) | ||
3810 | 209 | { | ||
3811 | 210 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
3812 | 211 | |||
3813 | 212 | unsigned int valueMask = 0; | ||
3814 | 213 | |||
3815 | 214 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
3816 | 215 | |||
3817 | 216 | buffer->pushFrameRequest (xwc, valueMask); | ||
3818 | 217 | } | ||
3819 | 218 | |||
3820 | 219 | TEST_F (ConfigureRequestBufferDispatch, PushCombinedUpdateLocked) | ||
3821 | 220 | { | ||
3822 | 221 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
3823 | 222 | |||
3824 | 223 | unsigned int valueMask = CWX; | ||
3825 | 224 | |||
3826 | 225 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
3827 | 226 | |||
3828 | 227 | buffer->pushFrameRequest (xwc, valueMask); | ||
3829 | 228 | |||
3830 | 229 | valueMask |= CWY; | ||
3831 | 230 | |||
3832 | 231 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
3833 | 232 | |||
3834 | 233 | buffer->pushFrameRequest (xwc, valueMask); | ||
3835 | 234 | |||
3836 | 235 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
3837 | 236 | valueMask)); | ||
3838 | 237 | |||
3839 | 238 | lock->release (); | ||
3840 | 239 | } | ||
3841 | 240 | |||
3842 | 241 | /* | ||
3843 | 242 | * This test is disabled until we can expose the QueryShapeRectangles API | ||
3844 | 243 | * to plugins | ||
3845 | 244 | */ | ||
3846 | 245 | TEST_F (ConfigureRequestBufferDispatch, DISABLED_PushUpdateLockedReleaseInOrder) | ||
3847 | 246 | { | ||
3848 | 247 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
3849 | 248 | |||
3850 | 249 | unsigned int valueMask = CWX | CWY; | ||
3851 | 250 | |||
3852 | 251 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
3853 | 252 | EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (_, _)).Times (0); | ||
3854 | 253 | EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (_, _)).Times (0); | ||
3855 | 254 | |||
3856 | 255 | buffer->pushClientRequest (xwc, valueMask); | ||
3857 | 256 | buffer->pushWrapperRequest (xwc, 0); | ||
3858 | 257 | buffer->pushFrameRequest (xwc, 0); | ||
3859 | 258 | |||
3860 | 259 | InSequence s; | ||
3861 | 260 | |||
3862 | 261 | /* Always frame -> wrapper -> client */ | ||
3863 | 262 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
3864 | 263 | valueMask)); | ||
3865 | 264 | EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (MaskXWC (xwc, valueMask), | ||
3866 | 265 | valueMask)); | ||
3867 | 266 | EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (MaskXWC (xwc, valueMask), | ||
3868 | 267 | valueMask)); | ||
3869 | 268 | |||
3870 | 269 | lock->release (); | ||
3871 | 270 | } | ||
3872 | 271 | |||
3873 | 272 | TEST_F (ConfigureRequestBufferDispatch, UnlockBuffer) | ||
3874 | 273 | { | ||
3875 | 274 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
3876 | 275 | |||
3877 | 276 | unsigned int valueMask = CWX | CWY; | ||
3878 | 277 | |||
3879 | 278 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
3880 | 279 | |||
3881 | 280 | buffer->pushFrameRequest (xwc, valueMask); | ||
3882 | 281 | |||
3883 | 282 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
3884 | 283 | valueMask)); | ||
3885 | 284 | |||
3886 | 285 | lock->release (); | ||
3887 | 286 | } | ||
3888 | 287 | |||
3889 | 288 | TEST_F (ConfigureRequestBufferDispatch, ImplicitUnlockBuffer) | ||
3890 | 289 | { | ||
3891 | 290 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
3892 | 291 | |||
3893 | 292 | unsigned int valueMask = CWX | CWY; | ||
3894 | 293 | |||
3895 | 294 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
3896 | 295 | |||
3897 | 296 | buffer->pushFrameRequest (xwc, valueMask); | ||
3898 | 297 | |||
3899 | 298 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
3900 | 299 | valueMask)); | ||
3901 | 300 | } | ||
3902 | 301 | |||
3903 | 302 | TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnRestack) | ||
3904 | 303 | { | ||
3905 | 304 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
3906 | 305 | |||
3907 | 306 | unsigned int valueMask = CWStackMode | CWSibling; | ||
3908 | 307 | |||
3909 | 308 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
3910 | 309 | valueMask)); | ||
3911 | 310 | |||
3912 | 311 | buffer->pushFrameRequest (xwc, valueMask); | ||
3913 | 312 | } | ||
3914 | 313 | |||
3915 | 314 | TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnWindowSizeChange) | ||
3916 | 315 | { | ||
3917 | 316 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
3918 | 317 | |||
3919 | 318 | unsigned int valueMask = CWWidth | CWHeight | CWBorderWidth; | ||
3920 | 319 | |||
3921 | 320 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
3922 | 321 | valueMask)); | ||
3923 | 322 | |||
3924 | 323 | buffer->pushFrameRequest (xwc, valueMask); | ||
3925 | 324 | } | ||
3926 | 325 | |||
3927 | 326 | TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnClientReposition) | ||
3928 | 327 | { | ||
3929 | 328 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
3930 | 329 | |||
3931 | 330 | unsigned int valueMask = CWX | CWY; | ||
3932 | 331 | |||
3933 | 332 | EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (MaskXWC (xwc, valueMask), | ||
3934 | 333 | valueMask)); | ||
3935 | 334 | |||
3936 | 335 | buffer->pushClientRequest (xwc, valueMask); | ||
3937 | 336 | } | ||
3938 | 337 | |||
3939 | 338 | TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnWrapperReposition) | ||
3940 | 339 | { | ||
3941 | 340 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
3942 | 341 | |||
3943 | 342 | unsigned int valueMask = CWX | CWY; | ||
3944 | 343 | |||
3945 | 344 | EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (MaskXWC (xwc, valueMask), | ||
3946 | 345 | valueMask)); | ||
3947 | 346 | |||
3948 | 347 | buffer->pushWrapperRequest (xwc, valueMask); | ||
3949 | 348 | } | ||
3950 | 349 | |||
3951 | 350 | namespace | ||
3952 | 351 | { | ||
3953 | 352 | class MockLock : | ||
3954 | 353 | public crb::BufferLock | ||
3955 | 354 | { | ||
3956 | 355 | public: | ||
3957 | 356 | |||
3958 | 357 | /* We're currently importing the locks statefulness and coupling | ||
3959 | 358 | * the caller with that */ | ||
3960 | 359 | MockLock () : | ||
3961 | 360 | armed (false) | ||
3962 | 361 | { | ||
3963 | 362 | ON_CALL (*this, lock ()).WillByDefault ( | ||
3964 | 363 | Invoke (this, &MockLock::FreezeIfUnarmed)); | ||
3965 | 364 | ON_CALL (*this, release ()).WillByDefault ( | ||
3966 | 365 | Invoke (this, &MockLock::ReleaseIfArmed)); | ||
3967 | 366 | } | ||
3968 | 367 | |||
3969 | 368 | void OperateOver (crb::CountedFreeze *cf) | ||
3970 | 369 | { | ||
3971 | 370 | countedFreeze = cf; | ||
3972 | 371 | } | ||
3973 | 372 | |||
3974 | 373 | void FreezeIfUnarmed () | ||
3975 | 374 | { | ||
3976 | 375 | if (!armed) | ||
3977 | 376 | { | ||
3978 | 377 | countedFreeze->freeze (); | ||
3979 | 378 | armed = true; | ||
3980 | 379 | } | ||
3981 | 380 | } | ||
3982 | 381 | |||
3983 | 382 | void ReleaseIfArmed () | ||
3984 | 383 | { | ||
3985 | 384 | if (armed) | ||
3986 | 385 | { | ||
3987 | 386 | countedFreeze->release (); | ||
3988 | 387 | armed = false; | ||
3989 | 388 | } | ||
3990 | 389 | } | ||
3991 | 390 | |||
3992 | 391 | typedef boost::shared_ptr <MockLock> Ptr; | ||
3993 | 392 | |||
3994 | 393 | MOCK_METHOD0 (lock, void ()); | ||
3995 | 394 | MOCK_METHOD0 (release, void ()); | ||
3996 | 395 | |||
3997 | 396 | private: | ||
3998 | 397 | |||
3999 | 398 | crb::CountedFreeze *countedFreeze; | ||
4000 | 399 | bool armed; | ||
4001 | 400 | }; | ||
4002 | 401 | |||
4003 | 402 | class MockLockFactory | ||
4004 | 403 | { | ||
4005 | 404 | public: | ||
4006 | 405 | |||
4007 | 406 | crb::BufferLock::Ptr | ||
4008 | 407 | CreateMockLock (crb::CountedFreeze *cf) | ||
4009 | 408 | { | ||
4010 | 409 | MockLock::Ptr mockLock (locks.front ()); | ||
4011 | 410 | mockLock->OperateOver (cf); | ||
4012 | 411 | |||
4013 | 412 | locks.pop_front (); | ||
4014 | 413 | |||
4015 | 414 | return mockLock; | ||
4016 | 415 | } | ||
4017 | 416 | |||
4018 | 417 | void | ||
4019 | 418 | QueueLockForCreation (const MockLock::Ptr &lock) | ||
4020 | 419 | { | ||
4021 | 420 | locks.push_back (lock); | ||
4022 | 421 | } | ||
4023 | 422 | |||
4024 | 423 | private: | ||
4025 | 424 | |||
4026 | 425 | std::deque <MockLock::Ptr> locks; | ||
4027 | 426 | }; | ||
4028 | 427 | } | ||
4029 | 428 | |||
4030 | 429 | class ConfigureRequestBufferLockBehaviour : | ||
4031 | 430 | public ConfigureRequestBuffer | ||
4032 | 431 | { | ||
4033 | 432 | public: | ||
4034 | 433 | |||
4035 | 434 | ConfigureRequestBufferLockBehaviour () : | ||
4036 | 435 | ConfigureRequestBuffer (), | ||
4037 | 436 | lock (boost::make_shared <MockLock> ()), | ||
4038 | 437 | factory ( | ||
4039 | 438 | boost::bind (&MockLockFactory::CreateMockLock, | ||
4040 | 439 | &mockLockFactory, | ||
4041 | 440 | _1)), | ||
4042 | 441 | buffer ( | ||
4043 | 442 | crb::ConfigureRequestBuffer::Create ( | ||
4044 | 443 | &asyncServerWindow, | ||
4045 | 444 | &syncServerWindow, | ||
4046 | 445 | factory)) | ||
4047 | 446 | |||
4048 | 447 | { | ||
4049 | 448 | mockLockFactory.QueueLockForCreation (lock); | ||
4050 | 449 | } | ||
4051 | 450 | |||
4052 | 451 | protected: | ||
4053 | 452 | |||
4054 | 453 | typedef NiceMock <MockAsyncServerWindow> NiceServerWindow; | ||
4055 | 454 | typedef crb::ConfigureRequestBuffer::LockFactory LockFactory; | ||
4056 | 455 | |||
4057 | 456 | MockLock::Ptr lock; | ||
4058 | 457 | MockLockFactory mockLockFactory; | ||
4059 | 458 | |||
4060 | 459 | LockFactory factory; | ||
4061 | 460 | crb::Buffer::Ptr buffer; | ||
4062 | 461 | }; | ||
4063 | 462 | |||
4064 | 463 | TEST_F (ConfigureRequestBufferLockBehaviour, RearmBufferLockOnRelease) | ||
4065 | 464 | { | ||
4066 | 465 | EXPECT_CALL (*lock, lock ()); | ||
4067 | 466 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4068 | 467 | |||
4069 | 468 | unsigned int valueMask = CWX | CWY; | ||
4070 | 469 | |||
4071 | 470 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4072 | 471 | |||
4073 | 472 | buffer->pushFrameRequest (xwc, valueMask); | ||
4074 | 473 | |||
4075 | 474 | /* We are releasing this lock */ | ||
4076 | 475 | EXPECT_CALL (*lock, release ()); | ||
4077 | 476 | |||
4078 | 477 | /* Now the buffer will dispatch is configure request */ | ||
4079 | 478 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4080 | 479 | |||
4081 | 480 | /* Rearm locks on release */ | ||
4082 | 481 | EXPECT_CALL (*lock, lock ()); | ||
4083 | 482 | |||
4084 | 483 | /* Directly release the queue */ | ||
4085 | 484 | releasable->release (); | ||
4086 | 485 | } | ||
4087 | 486 | |||
4088 | 487 | TEST_F (ConfigureRequestBufferLockBehaviour, NoRearmBufferLockNoReleaseRequired) | ||
4089 | 488 | { | ||
4090 | 489 | /* Locks get armed on construction */ | ||
4091 | 490 | EXPECT_CALL (*lock, lock ()); | ||
4092 | 491 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4093 | 492 | |||
4094 | 493 | /* No call to requestConfigureOnFrame if there's nothing to be configured */ | ||
4095 | 494 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4096 | 495 | |||
4097 | 496 | /* We are releasing this lock */ | ||
4098 | 497 | EXPECT_CALL (*lock, release ()); | ||
4099 | 498 | |||
4100 | 499 | /* No rearm - we haven't released the whole buffer */ | ||
4101 | 500 | EXPECT_CALL (*lock, lock ()).Times (0); | ||
4102 | 501 | |||
4103 | 502 | /* Directly release the queue */ | ||
4104 | 503 | releasable->release (); | ||
4105 | 504 | } | ||
4106 | 505 | |||
4107 | 506 | TEST_F (ConfigureRequestBufferLockBehaviour, RearmWhenPushReady) | ||
4108 | 507 | { | ||
4109 | 508 | /* Locks get armed on construction */ | ||
4110 | 509 | EXPECT_CALL (*lock, lock ()); | ||
4111 | 510 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4112 | 511 | |||
4113 | 512 | /* We are releasing this lock */ | ||
4114 | 513 | EXPECT_CALL (*lock, release ()); | ||
4115 | 514 | |||
4116 | 515 | /* No call to requestConfigureOnFrame if there's nothing to be configured */ | ||
4117 | 516 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4118 | 517 | |||
4119 | 518 | /* No rearm - we haven't released it */ | ||
4120 | 519 | EXPECT_CALL (*lock, lock ()).Times (0); | ||
4121 | 520 | |||
4122 | 521 | /* Directly release the queue */ | ||
4123 | 522 | releasable->release (); | ||
4124 | 523 | |||
4125 | 524 | /* Since we're now going to push something to a queue | ||
4126 | 525 | * that's effectively not locked, the locks should now | ||
4127 | 526 | * be released */ | ||
4128 | 527 | unsigned int valueMask = CWX | CWY; | ||
4129 | 528 | |||
4130 | 529 | /* Now rearm it */ | ||
4131 | 530 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4132 | 531 | EXPECT_CALL (*lock, lock ()); | ||
4133 | 532 | |||
4134 | 533 | buffer->pushFrameRequest (xwc, valueMask); | ||
4135 | 534 | } | ||
4136 | 535 | |||
4137 | 536 | TEST_F (ConfigureRequestBufferLockBehaviour, NoRearmBufferLockOnNoRelease) | ||
4138 | 537 | { | ||
4139 | 538 | MockLock::Ptr second (boost::make_shared <MockLock> ()); | ||
4140 | 539 | mockLockFactory.QueueLockForCreation (second); | ||
4141 | 540 | |||
4142 | 541 | /* Locks get armed on construction */ | ||
4143 | 542 | EXPECT_CALL (*lock, lock ()); | ||
4144 | 543 | EXPECT_CALL (*second, lock ()); | ||
4145 | 544 | |||
4146 | 545 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4147 | 546 | crb::Releasable::Ptr otherReleasable (buffer->obtainLock ()); | ||
4148 | 547 | |||
4149 | 548 | /* We are releasing this lock */ | ||
4150 | 549 | EXPECT_CALL (*lock, release ()); | ||
4151 | 550 | |||
4152 | 551 | /* No call to requestConfigureOnFrame if there's nothing to be configured */ | ||
4153 | 552 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4154 | 553 | |||
4155 | 554 | /* No rearm - we haven't released it */ | ||
4156 | 555 | EXPECT_CALL (*lock, lock ()).Times (0); | ||
4157 | 556 | |||
4158 | 557 | releasable->release (); | ||
4159 | 558 | } | ||
4160 | 559 | |||
4161 | 560 | TEST_F (ConfigureRequestBufferLockBehaviour, QueryAttributesDispatchAndRearm) | ||
4162 | 561 | { | ||
4163 | 562 | /* Locks get armed on construction */ | ||
4164 | 563 | EXPECT_CALL (*lock, lock ()); | ||
4165 | 564 | |||
4166 | 565 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4167 | 566 | |||
4168 | 567 | unsigned int valueMask = CWX | CWY; | ||
4169 | 568 | |||
4170 | 569 | /* Queue locked */ | ||
4171 | 570 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4172 | 571 | |||
4173 | 572 | buffer->pushFrameRequest (xwc, valueMask); | ||
4174 | 573 | |||
4175 | 574 | /* Queue forceably unlocked, locks rearmed */ | ||
4176 | 575 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4177 | 576 | EXPECT_CALL (*lock, lock ()); | ||
4178 | 577 | |||
4179 | 578 | /* Expect a call to XGetWindowAttributes */ | ||
4180 | 579 | EXPECT_CALL (syncServerWindow, queryShapeRectangles (_, _, _)) | ||
4181 | 580 | .WillOnce ( | ||
4182 | 581 | ReturnNull ()); | ||
4183 | 582 | |||
4184 | 583 | int a, b; | ||
4185 | 584 | |||
4186 | 585 | EXPECT_THAT (buffer->queryShapeRectangles (0, &a, &b), IsNull ()); | ||
4187 | 586 | } | ||
4188 | 587 | |||
4189 | 588 | TEST_F (ConfigureRequestBufferLockBehaviour, QueryFrameAttributesDispatchAndRearm) | ||
4190 | 589 | { | ||
4191 | 590 | /* Locks get armed on construction */ | ||
4192 | 591 | EXPECT_CALL (*lock, lock ()); | ||
4193 | 592 | |||
4194 | 593 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4195 | 594 | |||
4196 | 595 | unsigned int valueMask = CWX | CWY; | ||
4197 | 596 | |||
4198 | 597 | /* Queue locked */ | ||
4199 | 598 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4200 | 599 | |||
4201 | 600 | buffer->pushFrameRequest (xwc, valueMask); | ||
4202 | 601 | |||
4203 | 602 | /* Queue forceably unlocked, locks rearmed */ | ||
4204 | 603 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4205 | 604 | EXPECT_CALL (*lock, lock ()); | ||
4206 | 605 | |||
4207 | 606 | /* Expect a call to XGetWindowAttributes */ | ||
4208 | 607 | XWindowAttributes xwa; | ||
4209 | 608 | EXPECT_CALL (syncServerWindow, queryFrameAttributes (_)) | ||
4210 | 609 | .WillOnce ( | ||
4211 | 610 | DoAll ( | ||
4212 | 611 | SetArgReferee <0> (xwa), | ||
4213 | 612 | Return (true))); | ||
4214 | 613 | |||
4215 | 614 | buffer->queryFrameAttributes (xwa); | ||
4216 | 615 | } | ||
4217 | 616 | |||
4218 | 617 | TEST_F (ConfigureRequestBufferLockBehaviour, QueryShapeRectanglesDispatchAndRearm) | ||
4219 | 618 | { | ||
4220 | 619 | /* Locks get armed on construction */ | ||
4221 | 620 | EXPECT_CALL (*lock, lock ()); | ||
4222 | 621 | |||
4223 | 622 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4224 | 623 | |||
4225 | 624 | unsigned int valueMask = CWX | CWY; | ||
4226 | 625 | |||
4227 | 626 | /* Queue locked */ | ||
4228 | 627 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4229 | 628 | |||
4230 | 629 | buffer->pushFrameRequest (xwc, valueMask); | ||
4231 | 630 | |||
4232 | 631 | /* Queue forceably unlocked, locks rearmed */ | ||
4233 | 632 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4234 | 633 | EXPECT_CALL (*lock, lock ()); | ||
4235 | 634 | |||
4236 | 635 | /* Expect a call to XGetWindowAttributes */ | ||
4237 | 636 | XWindowAttributes xwa; | ||
4238 | 637 | EXPECT_CALL (syncServerWindow, queryFrameAttributes (_)) | ||
4239 | 638 | .WillOnce ( | ||
4240 | 639 | DoAll ( | ||
4241 | 640 | SetArgReferee <0> (xwa), | ||
4242 | 641 | Return (true))); | ||
4243 | 642 | |||
4244 | 643 | buffer->queryFrameAttributes (xwa); | ||
4245 | 644 | } | ||
4246 | 645 | |||
4247 | 646 | TEST_F (ConfigureRequestBufferLockBehaviour, ForceReleaseDispatchAndRearm) | ||
4248 | 647 | { | ||
4249 | 648 | /* Locks get armed on construction */ | ||
4250 | 649 | EXPECT_CALL (*lock, lock ()); | ||
4251 | 650 | |||
4252 | 651 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4253 | 652 | |||
4254 | 653 | unsigned int valueMask = CWX | CWY; | ||
4255 | 654 | |||
4256 | 655 | /* Queue locked */ | ||
4257 | 656 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4258 | 657 | |||
4259 | 658 | buffer->pushFrameRequest (xwc, valueMask); | ||
4260 | 659 | |||
4261 | 660 | /* Queue forceably unlocked, locks rearmed */ | ||
4262 | 661 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4263 | 662 | EXPECT_CALL (*lock, lock ()); | ||
4264 | 663 | |||
4265 | 664 | /* Force release */ | ||
4266 | 665 | buffer->forceRelease (); | ||
4267 | 666 | } | ||
4268 | 667 | |||
4269 | 0 | 668 | ||
4270 | === removed file 'src/tests/test_configurerequestbuffer.cpp' | |||
4271 | --- src/tests/test_configurerequestbuffer.cpp 2012-12-13 14:07:01 +0000 | |||
4272 | +++ src/tests/test_configurerequestbuffer.cpp 1970-01-01 00:00:00 +0000 | |||
4273 | @@ -1,667 +0,0 @@ | |||
4274 | 1 | /* | ||
4275 | 2 | * Copyright © 2012 Sam Spilsbury | ||
4276 | 3 | * | ||
4277 | 4 | * Permission to use, copy, modify, distribute, and sell this software | ||
4278 | 5 | * and its documentation for any purpose is hereby granted without | ||
4279 | 6 | * fee, provided that the above copyright notice appear in all copies | ||
4280 | 7 | * and that both that copyright notice and this permission notice | ||
4281 | 8 | * appear in supporting documentation, and that the name of | ||
4282 | 9 | * Canonical Ltd. not be used in advertising or publicity pertaining to | ||
4283 | 10 | * distribution of the software without specific, written prior permission. | ||
4284 | 11 | * Canonical Ltd. makes no representations about the suitability of this | ||
4285 | 12 | * software for any purpose. It is provided "as is" without express or | ||
4286 | 13 | * implied warranty. | ||
4287 | 14 | * | ||
4288 | 15 | * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
4289 | 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN | ||
4290 | 17 | * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
4291 | 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
4292 | 19 | * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||
4293 | 20 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | ||
4294 | 21 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
4295 | 22 | * | ||
4296 | 23 | * Authored by: Sam Spilsbury <smspillaz@gmail.com> | ||
4297 | 24 | */ | ||
4298 | 25 | #include <deque> | ||
4299 | 26 | #include <boost/shared_ptr.hpp> | ||
4300 | 27 | #include <boost/make_shared.hpp> | ||
4301 | 28 | #include <boost/bind.hpp> | ||
4302 | 29 | #include <gmock/gmock.h> | ||
4303 | 30 | #include <gtest/gtest.h> | ||
4304 | 31 | #include <X11/Xlib.h> | ||
4305 | 32 | |||
4306 | 33 | #include "configurerequestbuffer-impl.h" | ||
4307 | 34 | #include "asyncserverwindow.h" | ||
4308 | 35 | |||
4309 | 36 | namespace crb = compiz::window::configure_buffers; | ||
4310 | 37 | namespace cw = compiz::window; | ||
4311 | 38 | |||
4312 | 39 | using testing::_; | ||
4313 | 40 | using testing::NiceMock; | ||
4314 | 41 | using testing::Return; | ||
4315 | 42 | using testing::Invoke; | ||
4316 | 43 | using testing::WithArgs; | ||
4317 | 44 | using testing::SetArgReferee; | ||
4318 | 45 | using testing::DoAll; | ||
4319 | 46 | using testing::InSequence; | ||
4320 | 47 | using testing::ReturnNull; | ||
4321 | 48 | using testing::IsNull; | ||
4322 | 49 | |||
4323 | 50 | class MockAsyncServerWindow : | ||
4324 | 51 | public cw::AsyncServerWindow | ||
4325 | 52 | { | ||
4326 | 53 | public: | ||
4327 | 54 | |||
4328 | 55 | MOCK_METHOD2 (requestConfigureOnClient, int (const XWindowChanges &, unsigned int)); | ||
4329 | 56 | MOCK_METHOD2 (requestConfigureOnFrame, int (const XWindowChanges &, unsigned int)); | ||
4330 | 57 | MOCK_METHOD2 (requestConfigureOnWrapper, int (const XWindowChanges &, unsigned int)); | ||
4331 | 58 | MOCK_METHOD0 (sendSyntheticConfigureNotify, void ()); | ||
4332 | 59 | MOCK_CONST_METHOD0 (hasCustomShape, bool ()); | ||
4333 | 60 | }; | ||
4334 | 61 | |||
4335 | 62 | class MockSyncServerWindow : | ||
4336 | 63 | public cw::SyncServerWindow | ||
4337 | 64 | { | ||
4338 | 65 | public: | ||
4339 | 66 | |||
4340 | 67 | MOCK_METHOD1 (queryAttributes, bool (XWindowAttributes &)); | ||
4341 | 68 | MOCK_METHOD1 (queryFrameAttributes, bool (XWindowAttributes &)); | ||
4342 | 69 | MOCK_METHOD3 (queryShapeRectangles, XRectangle * (int, int *, int *)); | ||
4343 | 70 | }; | ||
4344 | 71 | |||
4345 | 72 | namespace | ||
4346 | 73 | { | ||
4347 | 74 | int REQUEST_X = 1; | ||
4348 | 75 | int REQUEST_Y = 2; | ||
4349 | 76 | int REQUEST_WIDTH = 3; | ||
4350 | 77 | int REQUEST_HEIGHT = 4; | ||
4351 | 78 | int REQUEST_BORDER = 5; | ||
4352 | 79 | |||
4353 | 80 | Window REQUEST_ABOVE = 6; | ||
4354 | 81 | unsigned int REQUEST_MODE = 7; | ||
4355 | 82 | |||
4356 | 83 | crb::BufferLock::Ptr | ||
4357 | 84 | CreateNormalLock (crb::CountedFreeze *cf) | ||
4358 | 85 | { | ||
4359 | 86 | return boost::make_shared <crb::ConfigureBufferLock> (cf); | ||
4360 | 87 | } | ||
4361 | 88 | |||
4362 | 89 | } | ||
4363 | 90 | |||
4364 | 91 | MATCHER_P2 (MaskXWC, xwc, vm, "Matches XWindowChanges") | ||
4365 | 92 | { | ||
4366 | 93 | if (vm & CWX) | ||
4367 | 94 | if (xwc.x != arg.x) | ||
4368 | 95 | return false; | ||
4369 | 96 | |||
4370 | 97 | if (vm & CWY) | ||
4371 | 98 | if (xwc.y != arg.y) | ||
4372 | 99 | return false; | ||
4373 | 100 | |||
4374 | 101 | if (vm & CWWidth) | ||
4375 | 102 | if (xwc.width != arg.width) | ||
4376 | 103 | return false; | ||
4377 | 104 | |||
4378 | 105 | if (vm & CWHeight) | ||
4379 | 106 | if (xwc.height != arg.height) | ||
4380 | 107 | return false; | ||
4381 | 108 | |||
4382 | 109 | if (vm & CWBorderWidth) | ||
4383 | 110 | if (xwc.border_width != arg.border_width) | ||
4384 | 111 | return false; | ||
4385 | 112 | |||
4386 | 113 | if (vm & CWStackMode) | ||
4387 | 114 | if (xwc.stack_mode != arg.stack_mode) | ||
4388 | 115 | return false; | ||
4389 | 116 | |||
4390 | 117 | if (vm & CWSibling) | ||
4391 | 118 | if (xwc.sibling != arg.sibling) | ||
4392 | 119 | return false; | ||
4393 | 120 | |||
4394 | 121 | return true; | ||
4395 | 122 | } | ||
4396 | 123 | |||
4397 | 124 | class ConfigureRequestBuffer : | ||
4398 | 125 | public testing::Test | ||
4399 | 126 | { | ||
4400 | 127 | public: | ||
4401 | 128 | |||
4402 | 129 | ConfigureRequestBuffer () | ||
4403 | 130 | { | ||
4404 | 131 | /* Initialize xwc, we control it | ||
4405 | 132 | * through the value masks */ | ||
4406 | 133 | xwc.x = REQUEST_X; | ||
4407 | 134 | xwc.y = REQUEST_Y; | ||
4408 | 135 | xwc.width = REQUEST_WIDTH; | ||
4409 | 136 | xwc.height = REQUEST_HEIGHT; | ||
4410 | 137 | xwc.border_width = REQUEST_BORDER; | ||
4411 | 138 | xwc.sibling = REQUEST_ABOVE; | ||
4412 | 139 | xwc.stack_mode = REQUEST_MODE; | ||
4413 | 140 | } | ||
4414 | 141 | |||
4415 | 142 | protected: | ||
4416 | 143 | |||
4417 | 144 | XWindowChanges xwc; | ||
4418 | 145 | MockAsyncServerWindow asyncServerWindow; | ||
4419 | 146 | MockSyncServerWindow syncServerWindow; | ||
4420 | 147 | }; | ||
4421 | 148 | |||
4422 | 149 | class ConfigureRequestBufferDispatch : | ||
4423 | 150 | public ConfigureRequestBuffer | ||
4424 | 151 | { | ||
4425 | 152 | protected: | ||
4426 | 153 | |||
4427 | 154 | ConfigureRequestBufferDispatch () : | ||
4428 | 155 | ConfigureRequestBuffer (), | ||
4429 | 156 | factory (boost::bind (CreateNormalLock, _1)), | ||
4430 | 157 | buffer ( | ||
4431 | 158 | crb::ConfigureRequestBuffer::Create (&asyncServerWindow, | ||
4432 | 159 | &syncServerWindow, | ||
4433 | 160 | factory)) | ||
4434 | 161 | { | ||
4435 | 162 | } | ||
4436 | 163 | |||
4437 | 164 | crb::ConfigureRequestBuffer::LockFactory factory; | ||
4438 | 165 | crb::Buffer::Ptr buffer; | ||
4439 | 166 | }; | ||
4440 | 167 | |||
4441 | 168 | TEST_F (ConfigureRequestBufferDispatch, PushDirectSyntheticConfigureNotify) | ||
4442 | 169 | { | ||
4443 | 170 | EXPECT_CALL (asyncServerWindow, sendSyntheticConfigureNotify ()); | ||
4444 | 171 | |||
4445 | 172 | buffer->pushSyntheticConfigureNotify (); | ||
4446 | 173 | } | ||
4447 | 174 | |||
4448 | 175 | TEST_F (ConfigureRequestBufferDispatch, PushDirectClientUpdate) | ||
4449 | 176 | { | ||
4450 | 177 | unsigned int valueMask = CWX | CWY | CWBorderWidth | | ||
4451 | 178 | CWSibling | CWStackMode; | ||
4452 | 179 | |||
4453 | 180 | EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (MaskXWC (xwc, valueMask), | ||
4454 | 181 | valueMask)); | ||
4455 | 182 | |||
4456 | 183 | buffer->pushClientRequest (xwc, valueMask); | ||
4457 | 184 | } | ||
4458 | 185 | |||
4459 | 186 | TEST_F (ConfigureRequestBufferDispatch, PushDirectWrapperUpdate) | ||
4460 | 187 | { | ||
4461 | 188 | unsigned int valueMask = CWX | CWY | CWBorderWidth | | ||
4462 | 189 | CWSibling | CWStackMode; | ||
4463 | 190 | |||
4464 | 191 | EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (MaskXWC (xwc, valueMask), | ||
4465 | 192 | valueMask)); | ||
4466 | 193 | |||
4467 | 194 | buffer->pushWrapperRequest (xwc, valueMask); | ||
4468 | 195 | } | ||
4469 | 196 | |||
4470 | 197 | TEST_F (ConfigureRequestBufferDispatch, PushDirectFrameUpdate) | ||
4471 | 198 | { | ||
4472 | 199 | unsigned int valueMask = CWX | CWY | CWBorderWidth | | ||
4473 | 200 | CWSibling | CWStackMode; | ||
4474 | 201 | |||
4475 | 202 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
4476 | 203 | valueMask)); | ||
4477 | 204 | |||
4478 | 205 | buffer->pushFrameRequest (xwc, valueMask); | ||
4479 | 206 | } | ||
4480 | 207 | |||
4481 | 208 | TEST_F (ConfigureRequestBufferDispatch, PushUpdateLocked) | ||
4482 | 209 | { | ||
4483 | 210 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
4484 | 211 | |||
4485 | 212 | unsigned int valueMask = 0; | ||
4486 | 213 | |||
4487 | 214 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4488 | 215 | |||
4489 | 216 | buffer->pushFrameRequest (xwc, valueMask); | ||
4490 | 217 | } | ||
4491 | 218 | |||
4492 | 219 | TEST_F (ConfigureRequestBufferDispatch, PushCombinedUpdateLocked) | ||
4493 | 220 | { | ||
4494 | 221 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
4495 | 222 | |||
4496 | 223 | unsigned int valueMask = CWX; | ||
4497 | 224 | |||
4498 | 225 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4499 | 226 | |||
4500 | 227 | buffer->pushFrameRequest (xwc, valueMask); | ||
4501 | 228 | |||
4502 | 229 | valueMask |= CWY; | ||
4503 | 230 | |||
4504 | 231 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4505 | 232 | |||
4506 | 233 | buffer->pushFrameRequest (xwc, valueMask); | ||
4507 | 234 | |||
4508 | 235 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
4509 | 236 | valueMask)); | ||
4510 | 237 | |||
4511 | 238 | lock->release (); | ||
4512 | 239 | } | ||
4513 | 240 | |||
4514 | 241 | /* | ||
4515 | 242 | * This test is disabled until we can expose the QueryShapeRectangles API | ||
4516 | 243 | * to plugins | ||
4517 | 244 | */ | ||
4518 | 245 | TEST_F (ConfigureRequestBufferDispatch, DISABLED_PushUpdateLockedReleaseInOrder) | ||
4519 | 246 | { | ||
4520 | 247 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
4521 | 248 | |||
4522 | 249 | unsigned int valueMask = CWX | CWY; | ||
4523 | 250 | |||
4524 | 251 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4525 | 252 | EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (_, _)).Times (0); | ||
4526 | 253 | EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (_, _)).Times (0); | ||
4527 | 254 | |||
4528 | 255 | buffer->pushClientRequest (xwc, valueMask); | ||
4529 | 256 | buffer->pushWrapperRequest (xwc, 0); | ||
4530 | 257 | buffer->pushFrameRequest (xwc, 0); | ||
4531 | 258 | |||
4532 | 259 | InSequence s; | ||
4533 | 260 | |||
4534 | 261 | /* Always frame -> wrapper -> client */ | ||
4535 | 262 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
4536 | 263 | valueMask)); | ||
4537 | 264 | EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (MaskXWC (xwc, valueMask), | ||
4538 | 265 | valueMask)); | ||
4539 | 266 | EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (MaskXWC (xwc, valueMask), | ||
4540 | 267 | valueMask)); | ||
4541 | 268 | |||
4542 | 269 | lock->release (); | ||
4543 | 270 | } | ||
4544 | 271 | |||
4545 | 272 | TEST_F (ConfigureRequestBufferDispatch, UnlockBuffer) | ||
4546 | 273 | { | ||
4547 | 274 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
4548 | 275 | |||
4549 | 276 | unsigned int valueMask = CWX | CWY; | ||
4550 | 277 | |||
4551 | 278 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4552 | 279 | |||
4553 | 280 | buffer->pushFrameRequest (xwc, valueMask); | ||
4554 | 281 | |||
4555 | 282 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
4556 | 283 | valueMask)); | ||
4557 | 284 | |||
4558 | 285 | lock->release (); | ||
4559 | 286 | } | ||
4560 | 287 | |||
4561 | 288 | TEST_F (ConfigureRequestBufferDispatch, ImplicitUnlockBuffer) | ||
4562 | 289 | { | ||
4563 | 290 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
4564 | 291 | |||
4565 | 292 | unsigned int valueMask = CWX | CWY; | ||
4566 | 293 | |||
4567 | 294 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4568 | 295 | |||
4569 | 296 | buffer->pushFrameRequest (xwc, valueMask); | ||
4570 | 297 | |||
4571 | 298 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
4572 | 299 | valueMask)); | ||
4573 | 300 | } | ||
4574 | 301 | |||
4575 | 302 | TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnRestack) | ||
4576 | 303 | { | ||
4577 | 304 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
4578 | 305 | |||
4579 | 306 | unsigned int valueMask = CWStackMode | CWSibling; | ||
4580 | 307 | |||
4581 | 308 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
4582 | 309 | valueMask)); | ||
4583 | 310 | |||
4584 | 311 | buffer->pushFrameRequest (xwc, valueMask); | ||
4585 | 312 | } | ||
4586 | 313 | |||
4587 | 314 | TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnWindowSizeChange) | ||
4588 | 315 | { | ||
4589 | 316 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
4590 | 317 | |||
4591 | 318 | unsigned int valueMask = CWWidth | CWHeight | CWBorderWidth; | ||
4592 | 319 | |||
4593 | 320 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (MaskXWC (xwc, valueMask), | ||
4594 | 321 | valueMask)); | ||
4595 | 322 | |||
4596 | 323 | buffer->pushFrameRequest (xwc, valueMask); | ||
4597 | 324 | } | ||
4598 | 325 | |||
4599 | 326 | TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnClientReposition) | ||
4600 | 327 | { | ||
4601 | 328 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
4602 | 329 | |||
4603 | 330 | unsigned int valueMask = CWX | CWY; | ||
4604 | 331 | |||
4605 | 332 | EXPECT_CALL (asyncServerWindow, requestConfigureOnClient (MaskXWC (xwc, valueMask), | ||
4606 | 333 | valueMask)); | ||
4607 | 334 | |||
4608 | 335 | buffer->pushClientRequest (xwc, valueMask); | ||
4609 | 336 | } | ||
4610 | 337 | |||
4611 | 338 | TEST_F (ConfigureRequestBufferDispatch, ForceImmediateConfigureOnWrapperReposition) | ||
4612 | 339 | { | ||
4613 | 340 | crb::Releasable::Ptr lock (buffer->obtainLock ()); | ||
4614 | 341 | |||
4615 | 342 | unsigned int valueMask = CWX | CWY; | ||
4616 | 343 | |||
4617 | 344 | EXPECT_CALL (asyncServerWindow, requestConfigureOnWrapper (MaskXWC (xwc, valueMask), | ||
4618 | 345 | valueMask)); | ||
4619 | 346 | |||
4620 | 347 | buffer->pushWrapperRequest (xwc, valueMask); | ||
4621 | 348 | } | ||
4622 | 349 | |||
4623 | 350 | namespace | ||
4624 | 351 | { | ||
4625 | 352 | class MockLock : | ||
4626 | 353 | public crb::BufferLock | ||
4627 | 354 | { | ||
4628 | 355 | public: | ||
4629 | 356 | |||
4630 | 357 | /* We're currently importing the locks statefulness and coupling | ||
4631 | 358 | * the caller with that */ | ||
4632 | 359 | MockLock () : | ||
4633 | 360 | armed (false) | ||
4634 | 361 | { | ||
4635 | 362 | ON_CALL (*this, lock ()).WillByDefault ( | ||
4636 | 363 | Invoke (this, &MockLock::FreezeIfUnarmed)); | ||
4637 | 364 | ON_CALL (*this, release ()).WillByDefault ( | ||
4638 | 365 | Invoke (this, &MockLock::ReleaseIfArmed)); | ||
4639 | 366 | } | ||
4640 | 367 | |||
4641 | 368 | void OperateOver (crb::CountedFreeze *cf) | ||
4642 | 369 | { | ||
4643 | 370 | countedFreeze = cf; | ||
4644 | 371 | } | ||
4645 | 372 | |||
4646 | 373 | void FreezeIfUnarmed () | ||
4647 | 374 | { | ||
4648 | 375 | if (!armed) | ||
4649 | 376 | { | ||
4650 | 377 | countedFreeze->freeze (); | ||
4651 | 378 | armed = true; | ||
4652 | 379 | } | ||
4653 | 380 | } | ||
4654 | 381 | |||
4655 | 382 | void ReleaseIfArmed () | ||
4656 | 383 | { | ||
4657 | 384 | if (armed) | ||
4658 | 385 | { | ||
4659 | 386 | countedFreeze->release (); | ||
4660 | 387 | armed = false; | ||
4661 | 388 | } | ||
4662 | 389 | } | ||
4663 | 390 | |||
4664 | 391 | typedef boost::shared_ptr <MockLock> Ptr; | ||
4665 | 392 | |||
4666 | 393 | MOCK_METHOD0 (lock, void ()); | ||
4667 | 394 | MOCK_METHOD0 (release, void ()); | ||
4668 | 395 | |||
4669 | 396 | private: | ||
4670 | 397 | |||
4671 | 398 | crb::CountedFreeze *countedFreeze; | ||
4672 | 399 | bool armed; | ||
4673 | 400 | }; | ||
4674 | 401 | |||
4675 | 402 | class MockLockFactory | ||
4676 | 403 | { | ||
4677 | 404 | public: | ||
4678 | 405 | |||
4679 | 406 | crb::BufferLock::Ptr | ||
4680 | 407 | CreateMockLock (crb::CountedFreeze *cf) | ||
4681 | 408 | { | ||
4682 | 409 | MockLock::Ptr mockLock (locks.front ()); | ||
4683 | 410 | mockLock->OperateOver (cf); | ||
4684 | 411 | |||
4685 | 412 | locks.pop_front (); | ||
4686 | 413 | |||
4687 | 414 | return mockLock; | ||
4688 | 415 | } | ||
4689 | 416 | |||
4690 | 417 | void | ||
4691 | 418 | QueueLockForCreation (const MockLock::Ptr &lock) | ||
4692 | 419 | { | ||
4693 | 420 | locks.push_back (lock); | ||
4694 | 421 | } | ||
4695 | 422 | |||
4696 | 423 | private: | ||
4697 | 424 | |||
4698 | 425 | std::deque <MockLock::Ptr> locks; | ||
4699 | 426 | }; | ||
4700 | 427 | } | ||
4701 | 428 | |||
4702 | 429 | class ConfigureRequestBufferLockBehaviour : | ||
4703 | 430 | public ConfigureRequestBuffer | ||
4704 | 431 | { | ||
4705 | 432 | public: | ||
4706 | 433 | |||
4707 | 434 | ConfigureRequestBufferLockBehaviour () : | ||
4708 | 435 | ConfigureRequestBuffer (), | ||
4709 | 436 | lock (boost::make_shared <MockLock> ()), | ||
4710 | 437 | factory ( | ||
4711 | 438 | boost::bind (&MockLockFactory::CreateMockLock, | ||
4712 | 439 | &mockLockFactory, | ||
4713 | 440 | _1)), | ||
4714 | 441 | buffer ( | ||
4715 | 442 | crb::ConfigureRequestBuffer::Create ( | ||
4716 | 443 | &asyncServerWindow, | ||
4717 | 444 | &syncServerWindow, | ||
4718 | 445 | factory)) | ||
4719 | 446 | |||
4720 | 447 | { | ||
4721 | 448 | mockLockFactory.QueueLockForCreation (lock); | ||
4722 | 449 | } | ||
4723 | 450 | |||
4724 | 451 | protected: | ||
4725 | 452 | |||
4726 | 453 | typedef NiceMock <MockAsyncServerWindow> NiceServerWindow; | ||
4727 | 454 | typedef crb::ConfigureRequestBuffer::LockFactory LockFactory; | ||
4728 | 455 | |||
4729 | 456 | MockLock::Ptr lock; | ||
4730 | 457 | MockLockFactory mockLockFactory; | ||
4731 | 458 | |||
4732 | 459 | LockFactory factory; | ||
4733 | 460 | crb::Buffer::Ptr buffer; | ||
4734 | 461 | }; | ||
4735 | 462 | |||
4736 | 463 | TEST_F (ConfigureRequestBufferLockBehaviour, RearmBufferLockOnRelease) | ||
4737 | 464 | { | ||
4738 | 465 | EXPECT_CALL (*lock, lock ()); | ||
4739 | 466 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4740 | 467 | |||
4741 | 468 | unsigned int valueMask = CWX | CWY; | ||
4742 | 469 | |||
4743 | 470 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4744 | 471 | |||
4745 | 472 | buffer->pushFrameRequest (xwc, valueMask); | ||
4746 | 473 | |||
4747 | 474 | /* We are releasing this lock */ | ||
4748 | 475 | EXPECT_CALL (*lock, release ()); | ||
4749 | 476 | |||
4750 | 477 | /* Now the buffer will dispatch is configure request */ | ||
4751 | 478 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4752 | 479 | |||
4753 | 480 | /* Rearm locks on release */ | ||
4754 | 481 | EXPECT_CALL (*lock, lock ()); | ||
4755 | 482 | |||
4756 | 483 | /* Directly release the queue */ | ||
4757 | 484 | releasable->release (); | ||
4758 | 485 | } | ||
4759 | 486 | |||
4760 | 487 | TEST_F (ConfigureRequestBufferLockBehaviour, NoRearmBufferLockNoReleaseRequired) | ||
4761 | 488 | { | ||
4762 | 489 | /* Locks get armed on construction */ | ||
4763 | 490 | EXPECT_CALL (*lock, lock ()); | ||
4764 | 491 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4765 | 492 | |||
4766 | 493 | /* No call to requestConfigureOnFrame if there's nothing to be configured */ | ||
4767 | 494 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4768 | 495 | |||
4769 | 496 | /* We are releasing this lock */ | ||
4770 | 497 | EXPECT_CALL (*lock, release ()); | ||
4771 | 498 | |||
4772 | 499 | /* No rearm - we haven't released the whole buffer */ | ||
4773 | 500 | EXPECT_CALL (*lock, lock ()).Times (0); | ||
4774 | 501 | |||
4775 | 502 | /* Directly release the queue */ | ||
4776 | 503 | releasable->release (); | ||
4777 | 504 | } | ||
4778 | 505 | |||
4779 | 506 | TEST_F (ConfigureRequestBufferLockBehaviour, RearmWhenPushReady) | ||
4780 | 507 | { | ||
4781 | 508 | /* Locks get armed on construction */ | ||
4782 | 509 | EXPECT_CALL (*lock, lock ()); | ||
4783 | 510 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4784 | 511 | |||
4785 | 512 | /* We are releasing this lock */ | ||
4786 | 513 | EXPECT_CALL (*lock, release ()); | ||
4787 | 514 | |||
4788 | 515 | /* No call to requestConfigureOnFrame if there's nothing to be configured */ | ||
4789 | 516 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4790 | 517 | |||
4791 | 518 | /* No rearm - we haven't released it */ | ||
4792 | 519 | EXPECT_CALL (*lock, lock ()).Times (0); | ||
4793 | 520 | |||
4794 | 521 | /* Directly release the queue */ | ||
4795 | 522 | releasable->release (); | ||
4796 | 523 | |||
4797 | 524 | /* Since we're now going to push something to a queue | ||
4798 | 525 | * that's effectively not locked, the locks should now | ||
4799 | 526 | * be released */ | ||
4800 | 527 | unsigned int valueMask = CWX | CWY; | ||
4801 | 528 | |||
4802 | 529 | /* Now rearm it */ | ||
4803 | 530 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4804 | 531 | EXPECT_CALL (*lock, lock ()); | ||
4805 | 532 | |||
4806 | 533 | buffer->pushFrameRequest (xwc, valueMask); | ||
4807 | 534 | } | ||
4808 | 535 | |||
4809 | 536 | TEST_F (ConfigureRequestBufferLockBehaviour, NoRearmBufferLockOnNoRelease) | ||
4810 | 537 | { | ||
4811 | 538 | MockLock::Ptr second (boost::make_shared <MockLock> ()); | ||
4812 | 539 | mockLockFactory.QueueLockForCreation (second); | ||
4813 | 540 | |||
4814 | 541 | /* Locks get armed on construction */ | ||
4815 | 542 | EXPECT_CALL (*lock, lock ()); | ||
4816 | 543 | EXPECT_CALL (*second, lock ()); | ||
4817 | 544 | |||
4818 | 545 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4819 | 546 | crb::Releasable::Ptr otherReleasable (buffer->obtainLock ()); | ||
4820 | 547 | |||
4821 | 548 | /* We are releasing this lock */ | ||
4822 | 549 | EXPECT_CALL (*lock, release ()); | ||
4823 | 550 | |||
4824 | 551 | /* No call to requestConfigureOnFrame if there's nothing to be configured */ | ||
4825 | 552 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4826 | 553 | |||
4827 | 554 | /* No rearm - we haven't released it */ | ||
4828 | 555 | EXPECT_CALL (*lock, lock ()).Times (0); | ||
4829 | 556 | |||
4830 | 557 | releasable->release (); | ||
4831 | 558 | } | ||
4832 | 559 | |||
4833 | 560 | TEST_F (ConfigureRequestBufferLockBehaviour, QueryAttributesDispatchAndRearm) | ||
4834 | 561 | { | ||
4835 | 562 | /* Locks get armed on construction */ | ||
4836 | 563 | EXPECT_CALL (*lock, lock ()); | ||
4837 | 564 | |||
4838 | 565 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4839 | 566 | |||
4840 | 567 | unsigned int valueMask = CWX | CWY; | ||
4841 | 568 | |||
4842 | 569 | /* Queue locked */ | ||
4843 | 570 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4844 | 571 | |||
4845 | 572 | buffer->pushFrameRequest (xwc, valueMask); | ||
4846 | 573 | |||
4847 | 574 | /* Queue forceably unlocked, locks rearmed */ | ||
4848 | 575 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4849 | 576 | EXPECT_CALL (*lock, lock ()); | ||
4850 | 577 | |||
4851 | 578 | /* Expect a call to XGetWindowAttributes */ | ||
4852 | 579 | EXPECT_CALL (syncServerWindow, queryShapeRectangles (_, _, _)) | ||
4853 | 580 | .WillOnce ( | ||
4854 | 581 | ReturnNull ()); | ||
4855 | 582 | |||
4856 | 583 | int a, b; | ||
4857 | 584 | |||
4858 | 585 | EXPECT_THAT (buffer->queryShapeRectangles (0, &a, &b), IsNull ()); | ||
4859 | 586 | } | ||
4860 | 587 | |||
4861 | 588 | TEST_F (ConfigureRequestBufferLockBehaviour, QueryFrameAttributesDispatchAndRearm) | ||
4862 | 589 | { | ||
4863 | 590 | /* Locks get armed on construction */ | ||
4864 | 591 | EXPECT_CALL (*lock, lock ()); | ||
4865 | 592 | |||
4866 | 593 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4867 | 594 | |||
4868 | 595 | unsigned int valueMask = CWX | CWY; | ||
4869 | 596 | |||
4870 | 597 | /* Queue locked */ | ||
4871 | 598 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4872 | 599 | |||
4873 | 600 | buffer->pushFrameRequest (xwc, valueMask); | ||
4874 | 601 | |||
4875 | 602 | /* Queue forceably unlocked, locks rearmed */ | ||
4876 | 603 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4877 | 604 | EXPECT_CALL (*lock, lock ()); | ||
4878 | 605 | |||
4879 | 606 | /* Expect a call to XGetWindowAttributes */ | ||
4880 | 607 | XWindowAttributes xwa; | ||
4881 | 608 | EXPECT_CALL (syncServerWindow, queryFrameAttributes (_)) | ||
4882 | 609 | .WillOnce ( | ||
4883 | 610 | DoAll ( | ||
4884 | 611 | SetArgReferee <0> (xwa), | ||
4885 | 612 | Return (true))); | ||
4886 | 613 | |||
4887 | 614 | buffer->queryFrameAttributes (xwa); | ||
4888 | 615 | } | ||
4889 | 616 | |||
4890 | 617 | TEST_F (ConfigureRequestBufferLockBehaviour, QueryShapeRectanglesDispatchAndRearm) | ||
4891 | 618 | { | ||
4892 | 619 | /* Locks get armed on construction */ | ||
4893 | 620 | EXPECT_CALL (*lock, lock ()); | ||
4894 | 621 | |||
4895 | 622 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4896 | 623 | |||
4897 | 624 | unsigned int valueMask = CWX | CWY; | ||
4898 | 625 | |||
4899 | 626 | /* Queue locked */ | ||
4900 | 627 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4901 | 628 | |||
4902 | 629 | buffer->pushFrameRequest (xwc, valueMask); | ||
4903 | 630 | |||
4904 | 631 | /* Queue forceably unlocked, locks rearmed */ | ||
4905 | 632 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4906 | 633 | EXPECT_CALL (*lock, lock ()); | ||
4907 | 634 | |||
4908 | 635 | /* Expect a call to XGetWindowAttributes */ | ||
4909 | 636 | XWindowAttributes xwa; | ||
4910 | 637 | EXPECT_CALL (syncServerWindow, queryFrameAttributes (_)) | ||
4911 | 638 | .WillOnce ( | ||
4912 | 639 | DoAll ( | ||
4913 | 640 | SetArgReferee <0> (xwa), | ||
4914 | 641 | Return (true))); | ||
4915 | 642 | |||
4916 | 643 | buffer->queryFrameAttributes (xwa); | ||
4917 | 644 | } | ||
4918 | 645 | |||
4919 | 646 | TEST_F (ConfigureRequestBufferLockBehaviour, ForceReleaseDispatchAndRearm) | ||
4920 | 647 | { | ||
4921 | 648 | /* Locks get armed on construction */ | ||
4922 | 649 | EXPECT_CALL (*lock, lock ()); | ||
4923 | 650 | |||
4924 | 651 | crb::Releasable::Ptr releasable (buffer->obtainLock ()); | ||
4925 | 652 | |||
4926 | 653 | unsigned int valueMask = CWX | CWY; | ||
4927 | 654 | |||
4928 | 655 | /* Queue locked */ | ||
4929 | 656 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)).Times (0); | ||
4930 | 657 | |||
4931 | 658 | buffer->pushFrameRequest (xwc, valueMask); | ||
4932 | 659 | |||
4933 | 660 | /* Queue forceably unlocked, locks rearmed */ | ||
4934 | 661 | EXPECT_CALL (asyncServerWindow, requestConfigureOnFrame (_, _)); | ||
4935 | 662 | EXPECT_CALL (*lock, lock ()); | ||
4936 | 663 | |||
4937 | 664 | /* Force release */ | ||
4938 | 665 | buffer->forceRelease (); | ||
4939 | 666 | } | ||
4940 | 667 |
FAILED: Continuous integration, rev:3387 jenkins. qa.ubuntu. com/job/ compiz- ci/77/ jenkins. qa.ubuntu. com/job/ compiz- ci/./build= pbuilder, distribution= quantal, flavor= amd64/77/ console
http://
Executed test runs:
FAILURE: http://