Merge lp:~compiz-team/compiz/compiz.performance_1040478 into lp:compiz/0.9.8
- compiz.performance_1040478
- Merge into 0.9.8
Status: | Superseded |
---|---|
Proposed branch: | lp:~compiz-team/compiz/compiz.performance_1040478 |
Merge into: | lp:compiz/0.9.8 |
Diff against target: |
1931 lines (+1212/-268) (has conflicts) 15 files modified
plugins/opengl/CMakeLists.txt (+13/-0) plugins/opengl/include/opengl/framebufferobject.h (+219/-73) plugins/opengl/include/opengl/opengl-api.h (+42/-0) plugins/opengl/include/opengl/opengl.h (+49/-21) plugins/opengl/src/fbdirectdraw/CMakeLists.txt (+32/-0) plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h (+103/-0) plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp (+159/-0) plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt (+24/-0) plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp (+219/-0) plugins/opengl/src/framebufferobject.cpp (+119/-60) plugins/opengl/src/paint.cpp (+8/-82) plugins/opengl/src/privates.h (+37/-6) plugins/opengl/src/screen.cpp (+182/-20) plugins/water/src/water.cpp (+3/-3) plugins/water/src/water.h (+3/-3) Text conflict in plugins/opengl/CMakeLists.txt Text conflict in plugins/opengl/src/screen.cpp |
To merge this branch: | bzr merge lp:~compiz-team/compiz/compiz.performance_1040478 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt | Pending | ||
jenkins | continuous-integration | Pending | |
Review via email: mp+126874@code.launchpad.net |
This proposal supersedes a proposal from 2012-09-28.
This proposal has been superseded by a proposal from 2012-09-28.
Commit message
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. Distro says they're okay with this.
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.
- 3389. By Sam Spilsbury
-
Merge lp:compiz
- 3390. By Sam Spilsbury
-
Merge e lp:compiz
- 3391. By Sam Spilsbury
-
Merge lp:compiz
- 3392. By Sam Spilsbury
-
Simplify lots of variable names, unindent namespaces
- 3393. By Sam Spilsbury
-
Set the stencil and depth attachments in allocate and not bind
- 3394. By Sam Spilsbury
-
Refactored large parts of the code, make binding the concern of BindLocation
- 3395. By Sam Spilsbury
-
Merge lp:compiz
- 3396. By Sam Spilsbury
-
Moved the creation of directly drawable fbo's into a convenience method
so that other plugins can create them - 3397. By Sam Spilsbury
-
Fix compile error on tests
- 3398. By Sam Spilsbury
-
We don't need to provide a BindableFramebuffer to access the backbuffer
- 3399. By Sam Spilsbury
-
Unbind framebuffers before processing output change
- 3400. By Sam Spilsbury
-
Invert y-coords of glBlitFramebuffer operation
- 3401. By Sam Spilsbury
-
Reset framebuffer status on reallocation
- 3402. By Sam Spilsbury
-
Merge lp:compiz
- 3403. By Sam Spilsbury
-
Remove unused variable
- 3404. By Sam Spilsbury
-
Merge lp:compiz
- 3405. By Sam Spilsbury
-
Merge lp:compiz
- 3406. By Sam Spilsbury
-
Merge lp:compiz
- 3407. By Sam Spilsbury
-
Remove referenes to configure buffers
- 3408. By Sam Spilsbury
-
Revert trunk merge as it was broken
- 3409. By Sam Spilsbury
-
Merge lp:compiz
- 3410. By Sam Spilsbury
-
Unrevert changes which shouldn't have been reverted
- 3411. By Sam Spilsbury
-
Another botched merge
- 3412. By Sam Spilsbury
-
Merge lp:compiz
- 3413. By Sam Spilsbury
-
Fix merge errors
- 3414. By Sam Spilsbury
-
Merge lp:compiz
- 3415. By Sam Spilsbury
-
Revert more changes which should not have happened
- 3416. By Sam Spilsbury
-
Make the currently bound drawbuffer available to plugins (as they might want
to do a read/draw swap) - 3417. By Sam Spilsbury
-
Merge lp:compiz
- 3418. By Sam Spilsbury
-
Merge lp:compiz
- 3419. By Sam Spilsbury
-
Unrevert changes reverted by a merge
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 | === modified file 'plugins/opengl/CMakeLists.txt' |
2 | --- plugins/opengl/CMakeLists.txt 2012-09-22 04:00:52 +0000 |
3 | +++ plugins/opengl/CMakeLists.txt 2012-09-28 07:42:53 +0000 |
4 | @@ -5,14 +5,27 @@ |
5 | set (INTERNAL_LIBRARIES |
6 | compiz_opengl_double_buffer |
7 | compiz_opengl_fsregion |
8 | +<<<<<<< TREE |
9 | compiz_opengl_glx_tfp_bind |
10 | +======= |
11 | + compiz_opengl_framebuffer_direct_draw |
12 | +>>>>>>> MERGE-SOURCE |
13 | ) |
14 | |
15 | +set (COMPIZ_OPENGL_PLUGIN_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) |
16 | +set (COMPIZ_OPENGL_PLUGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) |
17 | + |
18 | add_subdirectory (src/doublebuffer) |
19 | add_subdirectory (src/fsregion) |
20 | +<<<<<<< TREE |
21 | add_subdirectory (src/glxtfpbind) |
22 | |
23 | include_directories (src/glxtfpbind/include) |
24 | +======= |
25 | +add_subdirectory (src/fbdirectdraw) |
26 | + |
27 | +include_directories (src/fbdirectdraw/include) |
28 | +>>>>>>> MERGE-SOURCE |
29 | |
30 | if (USE_GLES) |
31 | compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR}) |
32 | |
33 | === modified file 'plugins/opengl/include/opengl/framebufferobject.h' |
34 | --- plugins/opengl/include/opengl/framebufferobject.h 2012-08-09 02:19:26 +0000 |
35 | +++ plugins/opengl/include/opengl/framebufferobject.h 2012-09-28 07:42:53 +0000 |
36 | @@ -26,79 +26,225 @@ |
37 | #ifndef _COMPIZ_GLFRAMEBUFFEROBJECT_H |
38 | #define _COMPIZ_GLFRAMEBUFFEROBJECT_H |
39 | |
40 | -#include <opengl/opengl.h> |
41 | - |
42 | -struct PrivateGLFramebufferObject; |
43 | - |
44 | -/** |
45 | - * Class representing a framebuffer object in GL, supporting only one |
46 | - * color attachment as per GLES 2 spec. The color attachment is referred |
47 | - * to as the texture (of the FBO). |
48 | - * |
49 | - * Usage: |
50 | - * 1. create a GLFramebufferObject (requires a GL context) |
51 | - * 2. call allocate (size), and check status () |
52 | - * 3. old = bind () |
53 | - * 4. do your rendering |
54 | - * 5. rebind (old) |
55 | - * 6. use the rendered texture via tex () |
56 | - * 7. go to 2 or 3, or delete to quit (requires a GL context) |
57 | - */ |
58 | -class GLFramebufferObject |
59 | +#include <boost/function.hpp> |
60 | +#include <opengl/opengl-api.h> |
61 | +#include <core/size.h> |
62 | +#include <core/rect.h> |
63 | + |
64 | +class GLVertexBuffer; |
65 | +class GLTexture; |
66 | + |
67 | +namespace compiz |
68 | { |
69 | - public: |
70 | - GLFramebufferObject (); |
71 | - ~GLFramebufferObject (); |
72 | - |
73 | - /** |
74 | - * Ensure the texture is of the given size, recreating it if needed, |
75 | - * and replace the FBO color attachment with it. The texture contents |
76 | - * become undefined, unless specified in the 'image' argument. |
77 | - * When specifying 'image', it's also possible to pass-in the |
78 | - * desired image's 'format' and 'type'. |
79 | - * |
80 | - * Returns true on success, and false on texture allocation failure. |
81 | - */ |
82 | - bool allocate (const CompSize &size, |
83 | - const char *image = NULL, |
84 | - GLenum format = GL_RGBA, |
85 | - GLenum type = GL_UNSIGNED_BYTE); |
86 | - |
87 | - /** |
88 | - * Bind this as the current FBO, previous binding in GL context is |
89 | - * undone. GL rendering is now targeted to this FBO. |
90 | - * Returns a pointer to the previously bound FBO, or NULL if |
91 | - * the previous binding was zero (the window system provided |
92 | - * framebuffer). |
93 | - * |
94 | - * The previous FBO is no longer bound, so you can use its |
95 | - * texture. To restore the previous FBO, call rebind (FBO) with |
96 | - * the returned pointer as the argument. |
97 | - */ |
98 | - GLFramebufferObject *bind (); |
99 | - |
100 | - /** |
101 | - * Bind the given FBO as the current FBO, without looking up the |
102 | - * previous binding. The argument can be NULL, in which case the |
103 | - * window system provided framebuffer gets bound (FBO is unbound). |
104 | - */ |
105 | - static void rebind (GLFramebufferObject *fbo); |
106 | - |
107 | - /** |
108 | - * Check the FBO completeness. Returns true on complete. |
109 | - * Otherwise returns false and reports the error to log. |
110 | - */ |
111 | - bool checkStatus (); |
112 | - |
113 | - /** |
114 | - * Return a pointer to the texture that is the color attachment. |
115 | - * This will return NULL, if allocate () has not been called, or |
116 | - * the last allocate () call failed. |
117 | - */ |
118 | - GLTexture *tex (); |
119 | - |
120 | - private: |
121 | - PrivateGLFramebufferObject *priv; |
122 | -}; |
123 | + namespace opengl |
124 | + { |
125 | + typedef enum _FramebufferBlitInformation |
126 | + { |
127 | + ColorData = (1 << 0), |
128 | + StencilData = (1 << 1) |
129 | + } FramebufferBlitInformation; |
130 | + |
131 | + typedef enum _FramebufferFilter |
132 | + { |
133 | + Fast = 0, |
134 | + Good = 1, |
135 | + } FramebufferFilter; |
136 | + |
137 | + typedef enum _FramebufferBindPoint |
138 | + { |
139 | + Read = 0, |
140 | + Draw = 1 |
141 | + } FramebufferBindPoint; |
142 | + |
143 | + class PushableFramebuffer |
144 | + { |
145 | + public: |
146 | + |
147 | + virtual ~PushableFramebuffer () {} |
148 | + |
149 | + /* Binds this framebuffer immediately */ |
150 | + virtual void pushFBO (FramebufferBindPoint bindPoint) = 0; |
151 | + /* Binds the last bound framebuffer immediately */ |
152 | + virtual void popFBO () = 0; |
153 | + }; |
154 | + |
155 | + typedef boost::function <bool (const CompRect &src, |
156 | + const CompRect &dst, |
157 | + GLbitfield mask, |
158 | + GLenum filter)> FramebufferRectangularDrawStrategy; |
159 | + typedef std::list <FramebufferRectangularDrawStrategy> FramebufferRectangularDrawStrategyList; |
160 | + |
161 | + class DirectDrawFramebufferStrategies |
162 | + { |
163 | + public: |
164 | + |
165 | + virtual ~DirectDrawFramebufferStrategies () {} |
166 | + virtual void draw (const CompRect &src, |
167 | + const CompRect &dst, |
168 | + FramebufferBlitInformation mask, |
169 | + FramebufferFilter filter) = 0; |
170 | + }; |
171 | + |
172 | + class FramebufferObject |
173 | + { |
174 | + public: |
175 | + |
176 | + virtual ~FramebufferObject () {} |
177 | + |
178 | + /** |
179 | + * Ensure the texture is of the given size, recreating it if needed, |
180 | + * and replace the FBO color attachment with it. The texture contents |
181 | + * become undefined, unless specified in the 'image' argument. |
182 | + * When specifying 'image', it's also possible to pass-in the |
183 | + * desired image's 'format' and 'type'. |
184 | + * |
185 | + * Returns true on success, and false on texture allocation failure. |
186 | + */ |
187 | + virtual bool allocate (const CompSize &size, |
188 | + const char *image = NULL, |
189 | + GLenum format = GL_RGBA, |
190 | + GLenum type = GL_UNSIGNED_BYTE) = 0; |
191 | + |
192 | + /** |
193 | + * Bind this as the current FBO, previous binding in GL context is |
194 | + * undone. GL rendering is now targeted to this FBO. |
195 | + * Returns a pointer to the previously bound FBO, or NULL if |
196 | + * the previous binding was zero (the window system provided |
197 | + * framebuffer). |
198 | + * |
199 | + * The previous FBO is no longer bound, so you can use its |
200 | + * texture. To restore the previous FBO, call rebind (FBO) with |
201 | + * the returned pointer as the argument. |
202 | + */ |
203 | + virtual compiz::opengl::FramebufferObject * bind (compiz::opengl::FramebufferBindPoint bindPoint = |
204 | + compiz::opengl::Draw) = 0; |
205 | + |
206 | + /** |
207 | + * Check the FBO completeness. Returns true on complete. |
208 | + * Otherwise returns false and reports the error to log. |
209 | + */ |
210 | + virtual bool checkStatus (compiz::opengl::FramebufferBindPoint bindPoint = |
211 | + compiz::opengl::Draw) = 0; |
212 | + |
213 | + /** |
214 | + * Return a pointer to the texture that is the color attachment. |
215 | + * This will return NULL, if allocate () has not been called, or |
216 | + * the last allocate () call failed. |
217 | + */ |
218 | + virtual GLTexture * tex () = 0; |
219 | + }; |
220 | + |
221 | + class DirectDrawFramebufferObject : |
222 | + virtual public compiz::opengl::FramebufferObject |
223 | + { |
224 | + public: |
225 | + |
226 | + virtual ~DirectDrawFramebufferObject () {}; |
227 | + |
228 | + /** |
229 | + * Draws a region of the framebuffer object as specified in |
230 | + * framebuffer-specified co-ordinates as @src co-ordinates in |
231 | + * the buffer currently bound co-ordinates @dst . @mask indicates |
232 | + * what kind of data should be propogated downwards. @filter indicates |
233 | + * what kind of filter should be used when drawing this buffer |
234 | + * |
235 | + * This since this code only draws a rectangular region from one |
236 | + * framebuffer to another, it will try and use the fastest codepath |
237 | + * possible, falling back to a simple textured draw if |
238 | + * glBlitFramebuffer is not available |
239 | + * |
240 | + */ |
241 | + virtual void directDraw (const CompRect &src, |
242 | + const CompRect &dst, |
243 | + compiz::opengl::FramebufferBlitInformation mask, |
244 | + compiz::opengl::FramebufferFilter filter) = 0; |
245 | + }; |
246 | + |
247 | + namespace impl |
248 | + { |
249 | + namespace cgl = compiz::opengl; |
250 | + |
251 | + struct PrivateGLFramebufferObject; |
252 | + |
253 | + class PushableFramebuffer : |
254 | + public cgl::FramebufferObject |
255 | + { |
256 | + public: |
257 | + |
258 | + }; |
259 | + |
260 | + class FramebufferObject : |
261 | + public cgl::FramebufferObject, |
262 | + public cgl::PushableFramebuffer |
263 | + { |
264 | + public: |
265 | + FramebufferObject (); |
266 | + ~FramebufferObject (); |
267 | + |
268 | + /** |
269 | + * Ensure the texture is of the given size, recreating it if needed, |
270 | + * and replace the FBO color attachment with it. The texture contents |
271 | + * become undefined, unless specified in the 'image' argument. |
272 | + * When specifying 'image', it's also possible to pass-in the |
273 | + * desired image's 'format' and 'type'. |
274 | + * |
275 | + * Returns true on success, and false on texture allocation failure. |
276 | + */ |
277 | + bool allocate (const CompSize &size, |
278 | + const char *image = NULL, |
279 | + GLenum format = GL_RGBA, |
280 | + GLenum type = GL_UNSIGNED_BYTE); |
281 | + |
282 | + /** |
283 | + * Bind this as the current FBO, previous binding in GL context is |
284 | + * undone. GL rendering is now targeted to this FBO. |
285 | + * Returns a pointer to the previously bound FBO, or NULL if |
286 | + * the previous binding was zero (the window system provided |
287 | + * framebuffer). |
288 | + * |
289 | + * The previous FBO is no longer bound, so you can use its |
290 | + * texture. To restore the previous FBO, call rebind (FBO) with |
291 | + * the returned pointer as the argument. |
292 | + */ |
293 | + FramebufferObject *bind (compiz::opengl::FramebufferBindPoint bindPoint = |
294 | + compiz::opengl::Draw); |
295 | + |
296 | + /** |
297 | + * Bind the given FBO as the current FBO, without looking up the |
298 | + * previous binding. The argument can be NULL, in which case the |
299 | + * window system provided framebuffer gets bound (FBO is unbound). |
300 | + */ |
301 | + static void rebind (FramebufferObject *fbo, |
302 | + compiz::opengl::FramebufferBindPoint bindPoint = |
303 | + compiz::opengl::Draw); |
304 | + |
305 | + /** |
306 | + * Check the FBO completeness. Returns true on complete. |
307 | + * Otherwise returns false and reports the error to log. |
308 | + */ |
309 | + bool checkStatus (compiz::opengl::FramebufferBindPoint bindPoint = |
310 | + compiz::opengl::Draw); |
311 | + |
312 | + /** |
313 | + * Return a pointer to the texture that is the color attachment. |
314 | + * This will return NULL, if allocate () has not been called, or |
315 | + * the last allocate () call failed. |
316 | + */ |
317 | + GLTexture * tex (); |
318 | + |
319 | + private: |
320 | + |
321 | + /* Binds this framebuffer immediately */ |
322 | + void pushFBO (FramebufferBindPoint bindPoint); |
323 | + /* Binds the last bound framebuffer immediately */ |
324 | + void popFBO (); |
325 | + |
326 | + PrivateGLFramebufferObject *priv; |
327 | + }; |
328 | + } |
329 | + } |
330 | +} |
331 | + |
332 | +typedef compiz::opengl::impl::FramebufferObject GLFramebufferObject; |
333 | |
334 | #endif // _COMPIZ_GLFRAMEBUFFEROBJECT_H |
335 | |
336 | === added file 'plugins/opengl/include/opengl/opengl-api.h' |
337 | --- plugins/opengl/include/opengl/opengl-api.h 1970-01-01 00:00:00 +0000 |
338 | +++ plugins/opengl/include/opengl/opengl-api.h 2012-09-28 07:42:53 +0000 |
339 | @@ -0,0 +1,42 @@ |
340 | +/* |
341 | + * Copyright © 2008 Dennis Kasprzyk |
342 | + * Copyright © 2007 Novell, Inc. |
343 | + * |
344 | + * Permission to use, copy, modify, distribute, and sell this software |
345 | + * and its documentation for any purpose is hereby granted without |
346 | + * fee, provided that the above copyright notice appear in all copies |
347 | + * and that both that copyright notice and this permission notice |
348 | + * appear in supporting documentation, and that the name of |
349 | + * Dennis Kasprzyk not be used in advertising or publicity pertaining to |
350 | + * distribution of the software without specific, written prior permission. |
351 | + * Dennis Kasprzyk makes no representations about the suitability of this |
352 | + * software for any purpose. It is provided "as is" without express or |
353 | + * implied warranty. |
354 | + * |
355 | + * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
356 | + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
357 | + * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
358 | + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
359 | + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
360 | + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
361 | + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
362 | + * |
363 | + * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org> |
364 | + * David Reveman <davidr@novell.com> |
365 | + */ |
366 | + |
367 | +#ifndef _COMPIZ_OPENGL_API_H |
368 | +#define _COMPIZ_OPENGL_API_H |
369 | + |
370 | +#ifdef USE_GLES |
371 | +#define SUPPORT_X11 |
372 | +#include <GLES2/gl2.h> |
373 | +#include <GLES2/gl2ext.h> |
374 | +#include <EGL/egl.h> |
375 | +#include <EGL/eglext.h> |
376 | +#else |
377 | +#include <GL/gl.h> |
378 | +#include <GL/glx.h> |
379 | +#endif |
380 | + |
381 | +#endif |
382 | |
383 | === modified file 'plugins/opengl/include/opengl/opengl.h' |
384 | --- plugins/opengl/include/opengl/opengl.h 2012-09-17 14:36:00 +0000 |
385 | +++ plugins/opengl/include/opengl/opengl.h 2012-09-28 07:42:53 +0000 |
386 | @@ -28,23 +28,13 @@ |
387 | #ifndef _COMPIZ_OPENGL_H |
388 | #define _COMPIZ_OPENGL_H |
389 | |
390 | -#ifdef USE_GLES |
391 | -#define SUPPORT_X11 |
392 | -#include <GLES2/gl2.h> |
393 | -#include <GLES2/gl2ext.h> |
394 | -#include <EGL/egl.h> |
395 | -#include <EGL/eglext.h> |
396 | -#else |
397 | -#include <GL/gl.h> |
398 | -#include <GL/glx.h> |
399 | -#endif |
400 | +#include <opengl/opengl-api.h> |
401 | |
402 | #include <core/size.h> |
403 | #include <core/pluginclasshandler.h> |
404 | |
405 | #include <opengl/matrix.h> |
406 | #include <opengl/texture.h> |
407 | -#include <opengl/framebufferobject.h> |
408 | #include <opengl/vertexbuffer.h> |
409 | #include <opengl/program.h> |
410 | #include <opengl/programcache.h> |
411 | @@ -87,6 +77,27 @@ |
412 | class PrivateGLScreen; |
413 | class PrivateGLWindow; |
414 | |
415 | +namespace compiz |
416 | +{ |
417 | + namespace opengl |
418 | + { |
419 | + typedef boost::function <bool (const CompRect &src, |
420 | + const CompRect &dst, |
421 | + GLbitfield mask, |
422 | + GLenum filter)> BlitFramebufferFunc; |
423 | + |
424 | + class DirectDrawFramebufferObject; |
425 | + class FramebufferObject; |
426 | + |
427 | + namespace impl |
428 | + { |
429 | + class FramebufferObject; |
430 | + } |
431 | + } |
432 | +} |
433 | + |
434 | +typedef compiz::opengl::impl::FramebufferObject GLFramebufferObject; |
435 | + |
436 | extern GLushort defaultColor[4]; |
437 | |
438 | #ifndef GLX_EXT_texture_from_pixmap |
439 | @@ -313,6 +324,18 @@ |
440 | GLsizei width, |
441 | GLsizei height); |
442 | |
443 | + /* GLX_EXT_blit_framebuffer */ |
444 | + typedef void (*GLBlitFramebufferProc) (GLint srcX0, |
445 | + GLint srcY0, |
446 | + GLint srcX1, |
447 | + GLint srcY1, |
448 | + GLint dstX0, |
449 | + GLint dstY0, |
450 | + GLint dstX1, |
451 | + GLint dstY1, |
452 | + GLbitfield mask, |
453 | + GLenum filter); |
454 | + |
455 | |
456 | /* GL_ARB_shader_objects */ |
457 | #ifndef USE_GLES |
458 | @@ -413,11 +436,12 @@ |
459 | extern GLDisableVertexAttribArrayProc disableVertexAttribArray; |
460 | extern GLVertexAttribPointerProc vertexAttribPointer; |
461 | |
462 | - extern GLGenRenderbuffersProc genRenderbuffers; |
463 | - extern GLDeleteRenderbuffersProc deleteRenderbuffers; |
464 | - extern GLBindRenderbufferProc bindRenderbuffer; |
465 | + extern GLGenRenderbuffersProc genRenderbuffers; |
466 | + extern GLDeleteRenderbuffersProc deleteRenderbuffers; |
467 | + extern GLBindRenderbufferProc bindRenderbuffer; |
468 | extern GLFramebufferRenderbufferProc framebufferRenderbuffer; |
469 | - extern GLRenderbufferStorageProc renderbufferStorage; |
470 | + extern GLRenderbufferStorageProc renderbufferStorage; |
471 | + extern GLBlitFramebufferProc blitFramebuffer; |
472 | |
473 | #ifndef USE_GLES |
474 | extern GLCreateShaderObjectARBProc createShaderObjectARB; |
475 | @@ -579,7 +603,6 @@ |
476 | extern GLScreenPaintAttrib defaultScreenPaintAttrib; |
477 | |
478 | class GLScreen; |
479 | -class GLFramebufferObject; |
480 | |
481 | class GLScreenInterface : |
482 | public WrapableInterface<GLScreen, GLScreenInterface> |
483 | @@ -656,9 +679,9 @@ |
484 | * @param scratchFbo Describes the final composited FBO that is |
485 | * to be rendered. |
486 | */ |
487 | - virtual void glPaintCompositedOutput (const CompRegion ®ion, |
488 | - GLFramebufferObject *fbo, |
489 | - unsigned int mask); |
490 | + virtual void glPaintCompositedOutput (const CompRegion ®ion, |
491 | + compiz::opengl::DirectDrawFramebufferObject *fbo, |
492 | + unsigned int mask); |
493 | |
494 | /** |
495 | * Hookable function used by plugins to determine stenciling mask |
496 | @@ -756,13 +779,18 @@ |
497 | /** |
498 | * Returns the FBO compiz is using for the screen |
499 | */ |
500 | - GLFramebufferObject *fbo (); |
501 | + compiz::opengl::FramebufferObject * fbo(); |
502 | |
503 | /** |
504 | * Returns a default icon texture |
505 | */ |
506 | GLTexture *defaultIcon (); |
507 | |
508 | + /** |
509 | + * Returns the current framebuffer function for blitting the framebuffer |
510 | + */ |
511 | + const compiz::opengl::BlitFramebufferFunc & blitFramebufferFunc (); |
512 | + |
513 | void resetRasterPos (); |
514 | |
515 | bool glInitContext (XVisualInfo *); |
516 | @@ -783,7 +811,7 @@ |
517 | |
518 | WRAPABLE_HND (5, GLScreenInterface, GLMatrix *, projectionMatrix); |
519 | WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput, |
520 | - const CompRegion &, GLFramebufferObject *, unsigned int); |
521 | + const CompRegion &, compiz::opengl::DirectDrawFramebufferObject *, unsigned int); |
522 | |
523 | WRAPABLE_HND (7, GLScreenInterface, void, glBufferStencil, const GLMatrix &, |
524 | GLVertexBuffer &, |
525 | |
526 | === added directory 'plugins/opengl/src/fbdirectdraw' |
527 | === added file 'plugins/opengl/src/fbdirectdraw/CMakeLists.txt' |
528 | --- plugins/opengl/src/fbdirectdraw/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
529 | +++ plugins/opengl/src/fbdirectdraw/CMakeLists.txt 2012-09-28 07:42:53 +0000 |
530 | @@ -0,0 +1,32 @@ |
531 | +INCLUDE_DIRECTORIES ( |
532 | + ${COMPIZ_OPENGL_PLUGIN_SOURCE_DIR} |
533 | + ${COMPIZ_OPENGL_PLUGIN_INCLUDE_DIR} |
534 | + ${CMAKE_CURRENT_SOURCE_DIR}/include |
535 | + ${CMAKE_CURRENT_SOURCE_DIR}/src |
536 | + |
537 | + ${Boost_INCLUDE_DIRS} |
538 | +) |
539 | + |
540 | +LINK_DIRECTORIES (${COMPIZ_LIBRARY_DIRS}) |
541 | + |
542 | +SET( |
543 | + SRCS |
544 | + ${CMAKE_CURRENT_SOURCE_DIR}/src/framebuffer-direct-draw.cpp |
545 | +) |
546 | + |
547 | +ADD_LIBRARY( |
548 | + compiz_opengl_framebuffer_direct_draw STATIC |
549 | + |
550 | + ${SRCS} |
551 | +) |
552 | + |
553 | +if (COMPIZ_BUILD_TESTING) |
554 | +ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests ) |
555 | +endif (COMPIZ_BUILD_TESTING) |
556 | + |
557 | +TARGET_LINK_LIBRARIES( |
558 | + compiz_opengl_framebuffer_direct_draw |
559 | + |
560 | + compiz_region |
561 | + compiz_logmessage |
562 | +) |
563 | |
564 | === added directory 'plugins/opengl/src/fbdirectdraw/include' |
565 | === added file 'plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h' |
566 | --- plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h 1970-01-01 00:00:00 +0000 |
567 | +++ plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h 2012-09-28 07:42:53 +0000 |
568 | @@ -0,0 +1,103 @@ |
569 | +/* |
570 | + * Compiz, opengl plugin, FramebufferDirectDraw class |
571 | + * |
572 | + * Copyright (c) 2012 Canonical Ltd. |
573 | + * Authors: Sam Spilsbury <sam.spilsbury@canonical.com> |
574 | + * |
575 | + * Permission is hereby granted, free of charge, to any person obtaining a |
576 | + * copy of this software and associated documentation files (the "Software"), |
577 | + * to deal in the Software without restriction, including without limitation |
578 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
579 | + * and/or sell copies of the Software, and to permit persons to whom the |
580 | + * Software is furnished to do so, subject to the following conditions: |
581 | + * |
582 | + * The above copyright notice and this permission notice shall be included in |
583 | + * all copies or substantial portions of the Software. |
584 | + * |
585 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
586 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
587 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
588 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
589 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
590 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
591 | + * DEALINGS IN THE SOFTWARE. |
592 | + */ |
593 | +#ifndef _COMPIZ_OPENGL_FRAMEBUFFER_DIRECT_DRAW_H |
594 | +#define _COMPIZ_OPENGL_FRAMEBUFFER_DIRECT_DRAW_H |
595 | + |
596 | +#include <memory> |
597 | +#include <boost/shared_ptr.hpp> |
598 | +#include <core/rect.h> |
599 | +#include <opengl/framebufferobject.h> |
600 | + |
601 | +class GLVertexBuffer; |
602 | + |
603 | +namespace compiz |
604 | +{ |
605 | + namespace opengl |
606 | + { |
607 | + namespace impl |
608 | + { |
609 | + namespace cglfb = compiz::opengl; |
610 | + |
611 | + class PrivateDirectDrawFramebufferStrategies; |
612 | + |
613 | + class DirectDrawFramebufferStrategies : |
614 | + public cglfb::DirectDrawFramebufferStrategies |
615 | + { |
616 | + public: |
617 | + |
618 | + DirectDrawFramebufferStrategies (const FramebufferRectangularDrawStrategyList &strategies); |
619 | + |
620 | + void draw (const CompRect &src, |
621 | + const CompRect &dst, |
622 | + FramebufferBlitInformation mask, |
623 | + FramebufferFilter filter); |
624 | + |
625 | + private: |
626 | + |
627 | + std::auto_ptr <PrivateDirectDrawFramebufferStrategies> priv; |
628 | + }; |
629 | + |
630 | + class PrivateDirectDrawFramebufferObject; |
631 | + |
632 | + class DirectDrawFramebufferObject : |
633 | + virtual public cglfb::FramebufferObject, |
634 | + public cglfb::DirectDrawFramebufferObject |
635 | + { |
636 | + public: |
637 | + |
638 | + DirectDrawFramebufferObject (const boost::shared_ptr <cglfb::DirectDrawFramebufferStrategies> &, |
639 | + const boost::shared_ptr <cglfb::FramebufferObject> &); |
640 | + |
641 | + bool allocate (const CompSize &size, |
642 | + const char *image = NULL, |
643 | + GLenum format = GL_RGBA, |
644 | + GLenum type = GL_UNSIGNED_BYTE); |
645 | + FramebufferObject *bind (compiz::opengl::FramebufferBindPoint bindPoint = |
646 | + compiz::opengl::Draw); |
647 | + bool checkStatus (compiz::opengl::FramebufferBindPoint bindPoint = |
648 | + compiz::opengl::Draw); |
649 | + GLTexture * tex (); |
650 | + |
651 | + void directDraw (const CompRect &src, |
652 | + const CompRect &dst, |
653 | + compiz::opengl::FramebufferBlitInformation mask, |
654 | + compiz::opengl::FramebufferFilter filter); |
655 | + |
656 | + private: |
657 | + |
658 | + PrivateDirectDrawFramebufferObject *priv; |
659 | + }; |
660 | + |
661 | + bool dispatchRectangleDrawStrategyWithPushedReadBuffer (const CompRect &src, |
662 | + const CompRect &dst, |
663 | + GLbitfield mask, |
664 | + GLenum filter, |
665 | + cglfb::PushableFramebuffer *pushableFramebuffer, |
666 | + cglfb::FramebufferRectangularDrawStrategy strategy); |
667 | + } |
668 | + } |
669 | +} |
670 | + |
671 | +#endif |
672 | |
673 | === added directory 'plugins/opengl/src/fbdirectdraw/src' |
674 | === added file 'plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp' |
675 | --- plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp 1970-01-01 00:00:00 +0000 |
676 | +++ plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp 2012-09-28 07:42:53 +0000 |
677 | @@ -0,0 +1,159 @@ |
678 | +/* |
679 | + * Compiz, opengl plugin, DirectDrawFramebufferStrategies class |
680 | + * |
681 | + * Copyright (c) 2012 Canonical Ltd. |
682 | + * Authors: Sam Spilsbury <sam.spilsbury@canonical.com> |
683 | + * |
684 | + * Permission is hereby granted, free of charge, to any person obtaining a |
685 | + * copy of this software and associated documentation files (the "Software"), |
686 | + * to deal in the Software without restriction, including without limitation |
687 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
688 | + * and/or sell copies of the Software, and to permit persons to whom the |
689 | + * Software is furnished to do so, subject to the following conditions: |
690 | + * |
691 | + * The above copyright notice and this permission notice shall be included in |
692 | + * all copies or substantial portions of the Software. |
693 | + * |
694 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
695 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
696 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
697 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
698 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
699 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
700 | + * DEALINGS IN THE SOFTWARE. |
701 | + */ |
702 | +#include "framebuffer-direct-draw.h" |
703 | + |
704 | +namespace cglfb = compiz::opengl; |
705 | +namespace cglfbi = compiz::opengl::impl; |
706 | + |
707 | +class GLTexture; |
708 | +class GLVertexBuffer; |
709 | + |
710 | +namespace compiz |
711 | +{ |
712 | + namespace opengl |
713 | + { |
714 | + namespace impl |
715 | + { |
716 | + class PrivateDirectDrawFramebufferStrategies |
717 | + { |
718 | + public: |
719 | + |
720 | + PrivateDirectDrawFramebufferStrategies (const cglfb::FramebufferRectangularDrawStrategyList &strategies) : |
721 | + rectangularDrawStrategies (strategies) |
722 | + { |
723 | + } |
724 | + |
725 | + cglfb::FramebufferRectangularDrawStrategyList rectangularDrawStrategies; |
726 | + }; |
727 | + |
728 | + class PrivateDirectDrawFramebufferObject |
729 | + { |
730 | + public: |
731 | + |
732 | + PrivateDirectDrawFramebufferObject (const boost::shared_ptr <cglfb::DirectDrawFramebufferStrategies> &strategies, |
733 | + const boost::shared_ptr <cglfb::FramebufferObject> &object) : |
734 | + directDrawStrategies (strategies), |
735 | + framebufferObject (object) |
736 | + { |
737 | + }; |
738 | + |
739 | + boost::shared_ptr <cglfb::DirectDrawFramebufferStrategies> directDrawStrategies; |
740 | + boost::shared_ptr <cglfb::FramebufferObject> framebufferObject; |
741 | + }; |
742 | + } |
743 | + } |
744 | +} |
745 | + |
746 | +cglfbi::DirectDrawFramebufferObject::DirectDrawFramebufferObject (const boost::shared_ptr <cglfb::DirectDrawFramebufferStrategies> &strategies, |
747 | + const boost::shared_ptr <cglfb::FramebufferObject> &object) : |
748 | + priv (new PrivateDirectDrawFramebufferObject (strategies, object)) |
749 | +{ |
750 | +} |
751 | + |
752 | +bool |
753 | +cglfbi::DirectDrawFramebufferObject::allocate (const CompSize &size, const char *image, |
754 | + GLenum format, GLenum type) |
755 | +{ |
756 | + return priv->framebufferObject->allocate (size, image, format, type); |
757 | +} |
758 | + |
759 | +cglfb::FramebufferObject * |
760 | +cglfbi::DirectDrawFramebufferObject::bind (cglfb::FramebufferBindPoint bindPoint) |
761 | +{ |
762 | + return priv->framebufferObject->bind (bindPoint); |
763 | +} |
764 | + |
765 | +bool |
766 | +cglfbi::DirectDrawFramebufferObject::checkStatus (cglfb::FramebufferBindPoint bindPoint) |
767 | +{ |
768 | + return priv->framebufferObject->checkStatus (bindPoint); |
769 | +} |
770 | + |
771 | +GLTexture * |
772 | +cglfbi::DirectDrawFramebufferObject::tex () |
773 | +{ |
774 | + return priv->framebufferObject->tex (); |
775 | +} |
776 | + |
777 | +void |
778 | +cglfbi::DirectDrawFramebufferObject::directDraw (const CompRect &src, |
779 | + const CompRect &dst, |
780 | + cglfb::FramebufferBlitInformation mask, |
781 | + cglfb::FramebufferFilter filter) |
782 | +{ |
783 | + if (!checkStatus ()) |
784 | + return; |
785 | + |
786 | + priv->directDrawStrategies->draw (src, dst, mask, filter); |
787 | +} |
788 | + |
789 | +bool |
790 | +cglfbi::dispatchRectangleDrawStrategyWithPushedReadBuffer (const CompRect &src, |
791 | + const CompRect &dst, |
792 | + GLbitfield mask, |
793 | + GLenum filter, |
794 | + cglfb::PushableFramebuffer *pushableFramebuffer, |
795 | + cglfb::FramebufferRectangularDrawStrategy strategy) |
796 | +{ |
797 | + bool status = false; |
798 | + /* Bind to the read framebuffer first */ |
799 | + pushableFramebuffer->pushFBO (cglfb::Read); |
800 | + status = strategy (src, dst, mask, filter); |
801 | + pushableFramebuffer->popFBO (); |
802 | + return status; |
803 | +} |
804 | + |
805 | +cglfbi::DirectDrawFramebufferStrategies::DirectDrawFramebufferStrategies (const cglfb::FramebufferRectangularDrawStrategyList &strategies) : |
806 | + priv (new PrivateDirectDrawFramebufferStrategies (strategies)) |
807 | +{ |
808 | +} |
809 | + |
810 | +void |
811 | +cglfbi::DirectDrawFramebufferStrategies::draw (const CompRect &src, |
812 | + const CompRect &dst, |
813 | + cglfb::FramebufferBlitInformation mask, |
814 | + cglfb::FramebufferFilter filter) |
815 | +{ |
816 | + if (!mask) |
817 | + return; |
818 | + |
819 | + const GLbitfield glMask = (mask & cglfb::ColorData ? GL_COLOR_BUFFER_BIT : 0) | |
820 | + (mask & cglfb::StencilData ? GL_STENCIL_BUFFER_BIT : 0); |
821 | + const GLenum glFilter = (filter == cglfb::Fast ? GL_NEAREST : GL_LINEAR); |
822 | + |
823 | + cglfb::FramebufferRectangularDrawStrategyList::reverse_iterator rit = |
824 | + priv->rectangularDrawStrategies.rbegin (); |
825 | + |
826 | + while (!priv->rectangularDrawStrategies.empty ()) |
827 | + { |
828 | + const cglfb::FramebufferRectangularDrawStrategy &strategy = priv->rectangularDrawStrategies.back (); |
829 | + |
830 | + /* If one method fails, try the next */ |
831 | + if (!strategy (src, dst, glMask, glFilter)) |
832 | + priv->rectangularDrawStrategies.pop_back (); |
833 | + else |
834 | + break; |
835 | + } |
836 | +} |
837 | |
838 | === added directory 'plugins/opengl/src/fbdirectdraw/tests' |
839 | === added file 'plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt' |
840 | --- plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
841 | +++ plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt 2012-09-28 07:42:53 +0000 |
842 | @@ -0,0 +1,24 @@ |
843 | +find_library (GMOCK_LIBRARY gmock) |
844 | +find_library (GMOCK_MAIN_LIBRARY gmock_main) |
845 | + |
846 | +if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND) |
847 | + message ("Google Mock and Google Test not found - cannot build tests!") |
848 | + set (COMPIZ_BUILD_TESTING OFF) |
849 | +endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND) |
850 | + |
851 | +include_directories (${GTEST_INCLUDE_DIRS}) |
852 | + |
853 | +link_directories (${COMPIZ_LIBRARY_DIRS}) |
854 | + |
855 | +add_executable (compiz_test_opengl_framebuffer_direct_draw |
856 | + ${CMAKE_CURRENT_SOURCE_DIR}/test-opengl-framebuffer-direct-draw.cpp) |
857 | + |
858 | +target_link_libraries (compiz_test_opengl_framebuffer_direct_draw |
859 | + compiz_opengl_framebuffer_direct_draw |
860 | + ${GTEST_BOTH_LIBRARIES} |
861 | + ${GMOCK_LIBRARY} |
862 | + ${GMOCK_MAIN_LIBRARY} |
863 | + ${CMAKE_THREAD_LIBS_INIT} # Link in pthread. |
864 | + ) |
865 | + |
866 | +compiz_discover_tests (compiz_test_opengl_framebuffer_direct_draw COVERAGE compiz_opengl_framebuffer_direct_draw) |
867 | |
868 | === added file 'plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp' |
869 | --- plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp 1970-01-01 00:00:00 +0000 |
870 | +++ plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp 2012-09-28 07:42:53 +0000 |
871 | @@ -0,0 +1,219 @@ |
872 | +/* |
873 | + * Compiz, opengl plugin, DirectDrawFramebufferStrategies class |
874 | + * |
875 | + * Copyright (c) 2012 Canonical Ltd. |
876 | + * Authors: Sam Spilsbury <sam.spilsbury@canonical.com> |
877 | + * |
878 | + * Permission is hereby granted, free of charge, to any person obtaining a |
879 | + * copy of this software and associated documentation files (the "Software"), |
880 | + * to deal in the Software without restriction, including without limitation |
881 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
882 | + * and/or sell copies of the Software, and to permit persons to whom the |
883 | + * Software is furnished to do so, subject to the following conditions: |
884 | + * |
885 | + * The above copyright notice and this permission notice shall be included in |
886 | + * all copies or substantial portions of the Software. |
887 | + * |
888 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
889 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
890 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
891 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
892 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
893 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
894 | + * DEALINGS IN THE SOFTWARE. |
895 | + */ |
896 | +#include <memory> |
897 | +#include <boost/function.hpp> |
898 | +#include <boost/bind.hpp> |
899 | +#include <gtest/gtest.h> |
900 | +#include <gmock/gmock.h> |
901 | +#include <opengl/opengl-api.h> |
902 | +#include <opengl/framebufferobject.h> |
903 | +#include "framebuffer-direct-draw.h" |
904 | + |
905 | +using ::testing::Return; |
906 | +using ::testing::_; |
907 | +using ::testing::Expectation; |
908 | +using ::testing::StrictMock; |
909 | +using ::testing::NiceMock; |
910 | + |
911 | +namespace cglfb = compiz::opengl; |
912 | +namespace cglfbi = compiz::opengl::impl; |
913 | + |
914 | +namespace |
915 | +{ |
916 | + class MockFramebufferRectangularDrawStrategy |
917 | + { |
918 | + public: |
919 | + |
920 | + MOCK_METHOD4 (draw, bool (const CompRect &, |
921 | + const CompRect &, |
922 | + GLbitfield, |
923 | + GLenum)); |
924 | + }; |
925 | + |
926 | + class MockPushableFramebuffer : |
927 | + public cglfb::PushableFramebuffer |
928 | + { |
929 | + public: |
930 | + |
931 | + MOCK_METHOD1 (pushFBO, void (cglfb::FramebufferBindPoint)); |
932 | + MOCK_METHOD0 (popFBO, void ()); |
933 | + }; |
934 | +} |
935 | + |
936 | +class DirectDrawFramebufferStrategiesTest : |
937 | + public ::testing::Test |
938 | +{ |
939 | + public: |
940 | + |
941 | + DirectDrawFramebufferStrategiesTest () : |
942 | + blitFramebuffer (boost::bind (&MockFramebufferRectangularDrawStrategy::draw, &mpfb, _1, _2, _3, _4)), |
943 | + rtdraw (boost::bind (&MockFramebufferRectangularDrawStrategy::draw, &mdr, |
944 | + _1, _2, _3, _4)) |
945 | + { |
946 | + } |
947 | + |
948 | + void SetUpStrategyList (const cglfb::FramebufferRectangularDrawStrategy &blit, |
949 | + const cglfb::FramebufferRectangularDrawStrategy &draw) |
950 | + { |
951 | + strategyList.clear (); |
952 | + strategyList.push_back (draw); |
953 | + strategyList.push_back (blit); |
954 | + } |
955 | + |
956 | + virtual void SetUp () |
957 | + { |
958 | + blitFramebufferWithReadPushed = boost::bind (&cglfbi::dispatchRectangleDrawStrategyWithPushedReadBuffer, |
959 | + _1, _2, _3, _4, |
960 | + &mpushable, |
961 | + blitFramebuffer); |
962 | + |
963 | + SetUpStrategyList (blitFramebuffer, rtdraw); |
964 | + directDraw.reset (new cglfbi::DirectDrawFramebufferStrategies (strategyList)); |
965 | + } |
966 | + |
967 | + std::auto_ptr <cglfbi::DirectDrawFramebufferStrategies> directDraw; |
968 | + MockFramebufferRectangularDrawStrategy mpfb; |
969 | + cglfb::FramebufferRectangularDrawStrategy blitFramebuffer; |
970 | + cglfb::FramebufferRectangularDrawStrategy blitFramebufferWithReadPushed; |
971 | + MockFramebufferRectangularDrawStrategy mdr; |
972 | + StrictMock <MockPushableFramebuffer> mpushable; |
973 | + cglfb::FramebufferRectangularDrawStrategy rtdraw; |
974 | + cglfb::FramebufferRectangularDrawStrategyList strategyList; |
975 | + |
976 | +}; |
977 | + |
978 | +TEST_F (DirectDrawFramebufferStrategiesTest, TestBufferBitsSet) |
979 | +{ |
980 | + CompRect srcAndDst (0, 0, 0, 0); |
981 | + |
982 | + EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, GL_COLOR_BUFFER_BIT | |
983 | + GL_STENCIL_BUFFER_BIT, |
984 | + _)).WillOnce (Return (true)); |
985 | + |
986 | + directDraw->draw (srcAndDst, |
987 | + srcAndDst, |
988 | + static_cast <cglfb::FramebufferBlitInformation> (cglfb::ColorData | cglfb::StencilData), |
989 | + cglfb::Good); |
990 | +} |
991 | + |
992 | +TEST_F (DirectDrawFramebufferStrategiesTest, TestBufferNoBitsSet) |
993 | +{ |
994 | + CompRect srcAndDst (0, 0, 0, 0); |
995 | + |
996 | + EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, 0, |
997 | + _)).Times (0); |
998 | + |
999 | + directDraw->draw (srcAndDst, |
1000 | + srcAndDst, |
1001 | + static_cast <cglfb::FramebufferBlitInformation> (0), |
1002 | + cglfb::Good); |
1003 | +} |
1004 | + |
1005 | +TEST_F (DirectDrawFramebufferStrategiesTest, TestGoodToLinear) |
1006 | +{ |
1007 | + CompRect srcAndDst (0, 0, 0, 0); |
1008 | + |
1009 | + EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, |
1010 | + GL_LINEAR)).WillOnce (Return (true)); |
1011 | + |
1012 | + directDraw->draw (srcAndDst, |
1013 | + srcAndDst, |
1014 | + cglfb::ColorData, |
1015 | + cglfb::Good); |
1016 | +} |
1017 | + |
1018 | +TEST_F (DirectDrawFramebufferStrategiesTest, TestFastToNearest) |
1019 | +{ |
1020 | + CompRect srcAndDst (0, 0, 0, 0); |
1021 | + |
1022 | + EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, |
1023 | + GL_NEAREST)).WillOnce (Return (true)); |
1024 | + |
1025 | + directDraw->draw (srcAndDst, |
1026 | + srcAndDst, |
1027 | + cglfb::ColorData, |
1028 | + cglfb::Fast); |
1029 | +} |
1030 | + |
1031 | +TEST_F (DirectDrawFramebufferStrategiesTest, TestRevertToPaintWhenBlitUnavailable) |
1032 | +{ |
1033 | + CompRect srcAndDst (0, 0, 0, 0); |
1034 | + |
1035 | + EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, |
1036 | + _)).WillOnce (Return (false)); |
1037 | + EXPECT_CALL (mdr, draw (srcAndDst, srcAndDst, _, _)); |
1038 | + |
1039 | + directDraw->draw (srcAndDst, |
1040 | + srcAndDst, |
1041 | + cglfb::ColorData, |
1042 | + cglfb::Fast); |
1043 | +} |
1044 | + |
1045 | +TEST_F (DirectDrawFramebufferStrategiesTest, TestRevertOnBlitUnavailablePermanent) |
1046 | +{ |
1047 | + StrictMock <MockFramebufferRectangularDrawStrategy> strictMdr; |
1048 | + CompRect srcAndDst (0, 0, 0, 0); |
1049 | + |
1050 | + rtdraw = boost::bind (&MockFramebufferRectangularDrawStrategy::draw, &strictMdr, _1, _2, _3, _4); |
1051 | + |
1052 | + SetUpStrategyList (blitFramebuffer, rtdraw); |
1053 | + directDraw.reset (new cglfbi::DirectDrawFramebufferStrategies (strategyList)); |
1054 | + |
1055 | + EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, _)).WillOnce (Return (false)); |
1056 | + ON_CALL (strictMdr, draw (_, _, _, _)).WillByDefault (Return (true)); |
1057 | + EXPECT_CALL (strictMdr, draw (srcAndDst, srcAndDst, _, _)).Times (2); |
1058 | + |
1059 | + directDraw->draw (srcAndDst, |
1060 | + srcAndDst, |
1061 | + cglfb::ColorData, |
1062 | + cglfb::Fast); |
1063 | + directDraw->draw (srcAndDst, |
1064 | + srcAndDst, |
1065 | + cglfb::ColorData, |
1066 | + cglfb::Fast); |
1067 | +} |
1068 | + |
1069 | +TEST_F (DirectDrawFramebufferStrategiesTest, TestPushAndPopReadFramebufferOnBlit) |
1070 | +{ |
1071 | + CompRect srcAndDst (0, 0, 0, 0); |
1072 | + |
1073 | + SetUpStrategyList (blitFramebufferWithReadPushed, rtdraw); |
1074 | + directDraw.reset (new cglfbi::DirectDrawFramebufferStrategies (strategyList)); |
1075 | + |
1076 | + EXPECT_CALL (mpushable, pushFBO (cglfb::Read)); |
1077 | + EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, _)).WillOnce (Return (false)); |
1078 | + EXPECT_CALL (mpushable, popFBO ()); |
1079 | + ON_CALL (mdr, draw (_, _, _, _)).WillByDefault (Return (true)); |
1080 | + EXPECT_CALL (mdr, draw (srcAndDst, srcAndDst, _, _)).Times (2); |
1081 | + |
1082 | + directDraw->draw (srcAndDst, |
1083 | + srcAndDst, |
1084 | + cglfb::ColorData, |
1085 | + cglfb::Fast); |
1086 | + directDraw->draw (srcAndDst, |
1087 | + srcAndDst, |
1088 | + cglfb::ColorData, |
1089 | + cglfb::Fast); |
1090 | +} |
1091 | |
1092 | === modified file 'plugins/opengl/src/framebufferobject.cpp' |
1093 | --- plugins/opengl/src/framebufferobject.cpp 2012-08-06 09:44:49 +0000 |
1094 | +++ plugins/opengl/src/framebufferobject.cpp 2012-09-28 07:42:53 +0000 |
1095 | @@ -22,87 +22,135 @@ |
1096 | * |
1097 | * Authors: Pekka Paalanen <ppaalanen@gmail.com> |
1098 | */ |
1099 | - |
1100 | +#include <memory> |
1101 | #include <map> |
1102 | +#include <opengl/opengl.h> |
1103 | #include <opengl/framebufferobject.h> |
1104 | #include <opengl/texture.h> |
1105 | |
1106 | -struct PrivateGLFramebufferObject |
1107 | -{ |
1108 | - PrivateGLFramebufferObject () : |
1109 | - fboId (0), |
1110 | - pushedId (0), |
1111 | - glTex (NULL), |
1112 | - status (-1) |
1113 | - { |
1114 | - } |
1115 | - |
1116 | - void pushFBO (); |
1117 | - void popFBO (); |
1118 | - |
1119 | - GLuint fboId; |
1120 | - GLuint pushedId; |
1121 | - GLuint rbStencilId; |
1122 | - GLTexture *glTex; |
1123 | - |
1124 | - GLint status; |
1125 | - |
1126 | - static GLuint boundId; |
1127 | - static std::map<GLuint, GLFramebufferObject *> idMap; |
1128 | -}; |
1129 | - |
1130 | -GLuint PrivateGLFramebufferObject::boundId = 0; |
1131 | -std::map<GLuint, GLFramebufferObject *> PrivateGLFramebufferObject::idMap; |
1132 | +#include "framebuffer-direct-draw.h" |
1133 | + |
1134 | +namespace cglfb = compiz::opengl; |
1135 | +namespace cglfbi = compiz::opengl::impl; |
1136 | + |
1137 | +namespace compiz |
1138 | +{ |
1139 | + namespace opengl |
1140 | + { |
1141 | + namespace impl |
1142 | + { |
1143 | + struct PrivateGLFramebufferObject : |
1144 | + public cglfb::PushableFramebuffer |
1145 | + { |
1146 | + PrivateGLFramebufferObject () : |
1147 | + fboId (0), |
1148 | + pushedId (0), |
1149 | + glTex (NULL), |
1150 | + status (-1) |
1151 | + { |
1152 | + } |
1153 | + |
1154 | + void pushFBO (cglfb::FramebufferBindPoint bindPoint); |
1155 | + void popFBO (); |
1156 | + |
1157 | + GLuint fboId; |
1158 | + GLuint pushedId; |
1159 | + GLuint rbStencilId; |
1160 | + GLTexture *glTex; |
1161 | + |
1162 | + GLint status; |
1163 | + |
1164 | + std::auto_ptr <cglfb::DirectDrawFramebufferStrategies> mDirectDraw; |
1165 | + GLenum mBindPoint; |
1166 | + GLVertexBuffer *vertexBuffer; |
1167 | + |
1168 | + static GLuint boundId; |
1169 | + static std::map<GLuint, cglfbi::FramebufferObject *> idMap; |
1170 | + }; |
1171 | + |
1172 | + GLuint PrivateGLFramebufferObject::boundId = 0; |
1173 | + std::map<GLuint, cglfbi::FramebufferObject *> PrivateGLFramebufferObject::idMap; |
1174 | + } |
1175 | + } |
1176 | +} |
1177 | + |
1178 | +namespace |
1179 | +{ |
1180 | + inline GLenum framebufferBindPointToGLBinding (cglfb::FramebufferBindPoint bindPoint) |
1181 | + { |
1182 | + static const GLenum bindings[] = |
1183 | + { |
1184 | + GL::READ_FRAMEBUFFER, |
1185 | + GL::DRAW_FRAMEBUFFER |
1186 | + }; |
1187 | + |
1188 | + return bindings[static_cast <int> (bindPoint)]; |
1189 | + } |
1190 | +} |
1191 | |
1192 | void |
1193 | -PrivateGLFramebufferObject::pushFBO () |
1194 | +cglfbi::PrivateGLFramebufferObject::pushFBO (cglfb::FramebufferBindPoint bindPoint) |
1195 | { |
1196 | + GLenum binding = framebufferBindPointToGLBinding (bindPoint); |
1197 | + |
1198 | pushedId = boundId; |
1199 | if (boundId != fboId) |
1200 | { |
1201 | - (*GL::bindFramebuffer) (GL::FRAMEBUFFER, fboId); |
1202 | + mBindPoint = binding; |
1203 | + (*GL::bindFramebuffer) (mBindPoint, fboId); |
1204 | boundId = fboId; |
1205 | } |
1206 | } |
1207 | |
1208 | void |
1209 | -PrivateGLFramebufferObject::popFBO () |
1210 | +cglfbi::FramebufferObject::popFBO () |
1211 | +{ |
1212 | + priv->popFBO (); |
1213 | +} |
1214 | + |
1215 | +void |
1216 | +cglfbi::FramebufferObject::pushFBO (cglfb::FramebufferBindPoint bindPoint) |
1217 | +{ |
1218 | + priv->pushFBO (bindPoint); |
1219 | +} |
1220 | + |
1221 | +void |
1222 | +cglfbi::PrivateGLFramebufferObject::popFBO () |
1223 | { |
1224 | if (boundId != pushedId) |
1225 | { |
1226 | - (*GL::bindFramebuffer) (GL::FRAMEBUFFER, pushedId); |
1227 | + (*GL::bindFramebuffer) (mBindPoint, pushedId); |
1228 | boundId = pushedId; |
1229 | } |
1230 | } |
1231 | |
1232 | -GLFramebufferObject::GLFramebufferObject () : |
1233 | - priv (new PrivateGLFramebufferObject) |
1234 | +cglfbi::FramebufferObject::FramebufferObject () : |
1235 | + priv (new cglfbi::PrivateGLFramebufferObject ()) |
1236 | { |
1237 | (*GL::genFramebuffers) (1, &priv->fboId); |
1238 | (*GL::genRenderbuffers) (1, &priv->rbStencilId); |
1239 | |
1240 | if (priv->fboId != 0) |
1241 | - PrivateGLFramebufferObject::idMap[priv->fboId] = this; |
1242 | + cglfbi::PrivateGLFramebufferObject::idMap[priv->fboId] = this; |
1243 | } |
1244 | |
1245 | -GLFramebufferObject::~GLFramebufferObject () |
1246 | +cglfbi::FramebufferObject::~FramebufferObject () |
1247 | { |
1248 | if (priv->glTex) |
1249 | GLTexture::decRef (priv->glTex); |
1250 | |
1251 | - PrivateGLFramebufferObject::idMap.erase (priv->fboId); |
1252 | + cglfbi::PrivateGLFramebufferObject::idMap.erase (priv->fboId); |
1253 | (*GL::deleteFramebuffers) (1, &priv->fboId); |
1254 | (*GL::deleteRenderbuffers) (1, &priv->rbStencilId); |
1255 | |
1256 | - |
1257 | delete priv; |
1258 | } |
1259 | |
1260 | bool |
1261 | -GLFramebufferObject::allocate (const CompSize &size, const char *image, |
1262 | - GLenum format, GLenum type) |
1263 | +cglfbi::FramebufferObject::allocate (const CompSize &size, const char *image, |
1264 | + GLenum format, GLenum type) |
1265 | { |
1266 | - priv->status = -1; |
1267 | + priv->status = 0; |
1268 | |
1269 | if (!priv->glTex || |
1270 | size.width () != priv->glTex->width () || |
1271 | @@ -127,53 +175,59 @@ |
1272 | } |
1273 | } |
1274 | |
1275 | - priv->pushFBO (); |
1276 | + priv->pushFBO (cglfb::Draw); |
1277 | |
1278 | - (*GL::framebufferTexture2D) (GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, |
1279 | + (*GL::framebufferTexture2D) (priv->mBindPoint, GL::COLOR_ATTACHMENT0, |
1280 | priv->glTex->target (), |
1281 | priv->glTex->name (), 0); |
1282 | |
1283 | - priv->status = (*GL::checkFramebufferStatus) (GL::DRAW_FRAMEBUFFER); |
1284 | + priv->status = (*GL::checkFramebufferStatus) (priv->mBindPoint); |
1285 | |
1286 | priv->popFBO (); |
1287 | return true; |
1288 | } |
1289 | |
1290 | -GLFramebufferObject * |
1291 | -GLFramebufferObject::bind () |
1292 | +cglfbi::FramebufferObject * |
1293 | +cglfbi::FramebufferObject::bind (cglfb::FramebufferBindPoint bindPoint) |
1294 | { |
1295 | - GLFramebufferObject *old = NULL; |
1296 | + const GLenum binding = framebufferBindPointToGLBinding (bindPoint); |
1297 | + |
1298 | + cglfbi::FramebufferObject *old = NULL; |
1299 | |
1300 | if (priv->boundId != 0) |
1301 | { |
1302 | - std::map<GLuint, GLFramebufferObject *>::iterator it; |
1303 | - it = PrivateGLFramebufferObject::idMap.find (priv->boundId); |
1304 | + std::map<GLuint, cglfbi::FramebufferObject *>::iterator it; |
1305 | + it = cglfbi::PrivateGLFramebufferObject::idMap.find (priv->boundId); |
1306 | |
1307 | - if (it != PrivateGLFramebufferObject::idMap.end ()) |
1308 | + if (it != cglfbi::PrivateGLFramebufferObject::idMap.end ()) |
1309 | old = it->second; |
1310 | else |
1311 | compLogMessage ("opengl", CompLogLevelError, |
1312 | "An FBO without GLFramebufferObject cannot be restored"); |
1313 | } |
1314 | |
1315 | - (*GL::bindFramebuffer) (GL::FRAMEBUFFER, priv->fboId); |
1316 | + priv->mBindPoint = binding; |
1317 | + |
1318 | + (*GL::bindFramebuffer) (priv->mBindPoint, priv->fboId); |
1319 | priv->boundId = priv->fboId; |
1320 | |
1321 | - (*GL::framebufferRenderbuffer) (GL::FRAMEBUFFER, GL::DEPTH_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId); |
1322 | - (*GL::framebufferRenderbuffer) (GL::FRAMEBUFFER, GL::STENCIL_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId); |
1323 | - |
1324 | + (*GL::framebufferRenderbuffer) (priv->mBindPoint, GL::DEPTH_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId); |
1325 | + (*GL::framebufferRenderbuffer) (priv->mBindPoint, GL::STENCIL_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId); |
1326 | return old; |
1327 | } |
1328 | |
1329 | // static |
1330 | void |
1331 | -GLFramebufferObject::rebind (GLFramebufferObject *fbo) |
1332 | +cglfbi::FramebufferObject::rebind (cglfbi::FramebufferObject *fbo, |
1333 | + cglfb::FramebufferBindPoint bindPoint) |
1334 | { |
1335 | GLuint id = fbo ? fbo->priv->fboId : 0; |
1336 | + const GLenum binding = fbo ? fbo->priv->mBindPoint : |
1337 | + framebufferBindPointToGLBinding (bindPoint); |
1338 | |
1339 | if (id != fbo->priv->boundId) |
1340 | { |
1341 | - (*GL::bindFramebuffer) (GL::FRAMEBUFFER, id); |
1342 | + (*GL::bindFramebuffer) (binding, id); |
1343 | fbo->priv->boundId = id; |
1344 | } |
1345 | } |
1346 | @@ -199,11 +253,16 @@ |
1347 | } |
1348 | |
1349 | bool |
1350 | -GLFramebufferObject::checkStatus () |
1351 | +cglfbi::FramebufferObject::checkStatus (cglfb::FramebufferBindPoint bindPoint) |
1352 | { |
1353 | - priv->pushFBO (); |
1354 | - priv-> status = (*GL::checkFramebufferStatus) (GL_FRAMEBUFFER); |
1355 | - priv->popFBO (); |
1356 | + const GLenum binding = framebufferBindPointToGLBinding (bindPoint); |
1357 | + |
1358 | + if (!priv->status) |
1359 | + { |
1360 | + priv->pushFBO (bindPoint); |
1361 | + priv->status = (*GL::checkFramebufferStatus) (binding); |
1362 | + priv->popFBO (); |
1363 | + } |
1364 | |
1365 | if (priv->status == static_cast <GLint> (GL::FRAMEBUFFER_COMPLETE)) |
1366 | return true; |
1367 | @@ -215,7 +274,7 @@ |
1368 | } |
1369 | |
1370 | GLTexture * |
1371 | -GLFramebufferObject::tex () |
1372 | +cglfbi::FramebufferObject::tex () |
1373 | { |
1374 | return priv->glTex; |
1375 | } |
1376 | |
1377 | === modified file 'plugins/opengl/src/paint.cpp' |
1378 | --- plugins/opengl/src/paint.cpp 2012-09-21 06:05:27 +0000 |
1379 | +++ plugins/opengl/src/paint.cpp 2012-09-28 07:42:53 +0000 |
1380 | @@ -44,6 +44,7 @@ |
1381 | #define DEG2RAD (M_PI / 180.0f) |
1382 | |
1383 | using namespace compiz::opengl; |
1384 | +namespace cglfb = compiz::opengl; |
1385 | |
1386 | GLScreenPaintAttrib defaultScreenPaintAttrib = { |
1387 | 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA |
1388 | @@ -650,91 +651,16 @@ |
1389 | } |
1390 | |
1391 | void |
1392 | -GLScreen::glPaintCompositedOutput (const CompRegion ®ion, |
1393 | - GLFramebufferObject *fbo, |
1394 | - unsigned int mask) |
1395 | +GLScreen::glPaintCompositedOutput (const CompRegion ®ion, |
1396 | + compiz::opengl::DirectDrawFramebufferObject *fbo, |
1397 | + unsigned int mask) |
1398 | { |
1399 | WRAPABLE_HND_FUNCTN (glPaintCompositedOutput, region, fbo, mask) |
1400 | |
1401 | - GLMatrix sTransform; |
1402 | - std::vector<GLfloat> vertexData; |
1403 | - std::vector<GLfloat> textureData; |
1404 | - const GLTexture::Matrix & texmatrix = fbo->tex ()->matrix (); |
1405 | - GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer (); |
1406 | - |
1407 | - streamingBuffer->begin (GL_TRIANGLES); |
1408 | - |
1409 | - if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) |
1410 | - { |
1411 | - GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, 0.0f); |
1412 | - GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, screen->width ()); |
1413 | - GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, 0.0f); |
1414 | - GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, screen->height ()); |
1415 | - |
1416 | - vertexData = { |
1417 | - 0.0f, 0.0f, 0.0f, |
1418 | - 0.0f, (float)screen->height (), 0.0f, |
1419 | - (float)screen->width (), 0.0f, 0.0f, |
1420 | - |
1421 | - 0.0f, (float)screen->height (), 0.0f, |
1422 | - (float)screen->width (), (float)screen->height (), 0.0f, |
1423 | - (float)screen->width (), 0.0f, 0.0f, |
1424 | - }; |
1425 | - |
1426 | - textureData = { |
1427 | - tx1, ty1, |
1428 | - tx1, ty2, |
1429 | - tx2, ty1, |
1430 | - tx1, ty2, |
1431 | - tx2, ty2, |
1432 | - tx2, ty1, |
1433 | - }; |
1434 | - |
1435 | - streamingBuffer->addVertices (6, &vertexData[0]); |
1436 | - streamingBuffer->addTexCoords (0, 6, &textureData[0]); |
1437 | - } |
1438 | - else |
1439 | - { |
1440 | - BoxPtr pBox = const_cast <Region> (region.handle ())->rects; |
1441 | - int nBox = const_cast <Region> (region.handle ())->numRects; |
1442 | - |
1443 | - while (nBox--) |
1444 | - { |
1445 | - GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, pBox->x1); |
1446 | - GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, pBox->x2); |
1447 | - GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y1); |
1448 | - GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y2); |
1449 | - |
1450 | - vertexData = { |
1451 | - (float)pBox->x1, (float)pBox->y1, 0.0f, |
1452 | - (float)pBox->x1, (float)pBox->y2, 0.0f, |
1453 | - (float)pBox->x2, (float)pBox->y1, 0.0f, |
1454 | - |
1455 | - (float)pBox->x1, (float)pBox->y2, 0.0f, |
1456 | - (float)pBox->x2, (float)pBox->y2, 0.0f, |
1457 | - (float)pBox->x2, (float)pBox->y1, 0.0f, |
1458 | - }; |
1459 | - |
1460 | - textureData = { |
1461 | - tx1, ty1, |
1462 | - tx1, ty2, |
1463 | - tx2, ty1, |
1464 | - tx1, ty2, |
1465 | - tx2, ty2, |
1466 | - tx2, ty1, |
1467 | - }; |
1468 | - |
1469 | - streamingBuffer->addVertices (6, &vertexData[0]); |
1470 | - streamingBuffer->addTexCoords (0, 6, &textureData[0]); |
1471 | - pBox++; |
1472 | - } |
1473 | - } |
1474 | - |
1475 | - streamingBuffer->end (); |
1476 | - fbo->tex ()->enable (GLTexture::Fast); |
1477 | - sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA); |
1478 | - streamingBuffer->render (sTransform); |
1479 | - fbo->tex ()->disable (); |
1480 | + /* Draw every rect individually, this could be a little slow |
1481 | + * for lots of rects, but the general usecase isn't that */ |
1482 | + foreach (const CompRect &r, region.rects ()) |
1483 | + fbo->directDraw (r, r, cglfb::ColorData, cglfb::Fast); |
1484 | } |
1485 | |
1486 | static void |
1487 | |
1488 | === modified file 'plugins/opengl/src/privates.h' |
1489 | --- plugins/opengl/src/privates.h 2012-09-25 10:47:39 +0000 |
1490 | +++ plugins/opengl/src/privates.h 2012-09-28 07:42:53 +0000 |
1491 | @@ -28,20 +28,28 @@ |
1492 | #ifndef _OPENGL_PRIVATES_H |
1493 | #define _OPENGL_PRIVATES_H |
1494 | |
1495 | +#include <memory> |
1496 | #include <composite/composite.h> |
1497 | #include <opengl/opengl.h> |
1498 | #include <core/atoms.h> |
1499 | - |
1500 | -#ifdef USE_GLES |
1501 | #include <opengl/framebufferobject.h> |
1502 | -#endif |
1503 | - |
1504 | #include <opengl/doublebuffer.h> |
1505 | |
1506 | #include "privatetexture.h" |
1507 | #include "privatevertexbuffer.h" |
1508 | #include "opengl_options.h" |
1509 | |
1510 | +namespace compiz |
1511 | +{ |
1512 | + namespace opengl |
1513 | + { |
1514 | + namespace impl |
1515 | + { |
1516 | + class DirectDrawFramebufferObject; |
1517 | + } |
1518 | + } |
1519 | +} |
1520 | + |
1521 | extern CompOutput *targetOutput; |
1522 | |
1523 | class GLDoubleBuffer : |
1524 | @@ -81,6 +89,17 @@ |
1525 | Window mOutput; |
1526 | }; |
1527 | |
1528 | +namespace compiz |
1529 | +{ |
1530 | + namespace opengl |
1531 | + { |
1532 | + bool blitFramebufferGLX (const CompRect &src, |
1533 | + const CompRect &dst, |
1534 | + GLbitfield mask, |
1535 | + GLenum filter); |
1536 | + } |
1537 | +} |
1538 | + |
1539 | #else |
1540 | |
1541 | class EGLDoubleBuffer : |
1542 | @@ -104,6 +123,17 @@ |
1543 | EGLSurface const & mSurface; |
1544 | }; |
1545 | |
1546 | +namespace compiz |
1547 | +{ |
1548 | + namespace opengl |
1549 | + { |
1550 | + bool blitFramebufferEGL (const CompRect &src, |
1551 | + const CompRect &dst, |
1552 | + GLbitfield mask, |
1553 | + GLenum filter); |
1554 | + } |
1555 | +} |
1556 | + |
1557 | #endif |
1558 | |
1559 | class GLIcon |
1560 | @@ -190,8 +220,9 @@ |
1561 | GLXDoubleBuffer doubleBuffer; |
1562 | #endif |
1563 | |
1564 | - GLFramebufferObject *scratchFbo; |
1565 | - CompRegion outputRegion; |
1566 | + std::auto_ptr <compiz::opengl::impl::DirectDrawFramebufferObject> scratchFbo; |
1567 | + compiz::opengl::BlitFramebufferFunc blitFramebuffer; |
1568 | + CompRegion outputRegion; |
1569 | |
1570 | XRectangle lastViewport; |
1571 | bool refreshSubBuffer; |
1572 | |
1573 | === modified file 'plugins/opengl/src/screen.cpp' |
1574 | --- plugins/opengl/src/screen.cpp 2012-09-26 07:58:17 +0000 |
1575 | +++ plugins/opengl/src/screen.cpp 2012-09-28 07:42:53 +0000 |
1576 | @@ -32,12 +32,35 @@ |
1577 | #endif |
1578 | #include <errno.h> |
1579 | |
1580 | +#include <boost/make_shared.hpp> |
1581 | + |
1582 | #include "privates.h" |
1583 | +#include "framebuffer-direct-draw.h" |
1584 | |
1585 | #include <dlfcn.h> |
1586 | #include <math.h> |
1587 | |
1588 | using namespace compiz::opengl; |
1589 | +namespace cglfb = compiz::opengl; |
1590 | +namespace cgli = compiz::opengl::impl; |
1591 | + |
1592 | +namespace compiz |
1593 | +{ |
1594 | + namespace opengl |
1595 | + { |
1596 | +#ifndef USE_GLES |
1597 | + bool blitFramebufferGLX (const CompRect &src, |
1598 | + const CompRect &dst, |
1599 | + GLbitfield mask, |
1600 | + GLenum filter); |
1601 | +#else |
1602 | + bool blitFramebufferEGL (const CompRect &src, |
1603 | + const CompRect &dst, |
1604 | + GLbitfield mask, |
1605 | + GLenum filter); |
1606 | +#endif |
1607 | + } |
1608 | +} |
1609 | |
1610 | namespace GL { |
1611 | #ifdef USE_GLES |
1612 | @@ -135,11 +158,12 @@ |
1613 | GLDisableVertexAttribArrayProc disableVertexAttribArray = NULL; |
1614 | GLVertexAttribPointerProc vertexAttribPointer = NULL; |
1615 | |
1616 | - GLGenRenderbuffersProc genRenderbuffers = NULL; |
1617 | - GLDeleteRenderbuffersProc deleteRenderbuffers = NULL; |
1618 | + GLGenRenderbuffersProc genRenderbuffers = NULL; |
1619 | + GLDeleteRenderbuffersProc deleteRenderbuffers = NULL; |
1620 | GLFramebufferRenderbufferProc framebufferRenderbuffer = NULL; |
1621 | - GLBindRenderbufferProc bindRenderbuffer = NULL; |
1622 | - GLRenderbufferStorageProc renderbufferStorage = NULL; |
1623 | + GLBindRenderbufferProc bindRenderbuffer = NULL; |
1624 | + GLRenderbufferStorageProc renderbufferStorage = NULL; |
1625 | + GLBlitFramebufferProc blitFramebuffer = NULL; |
1626 | |
1627 | bool textureFromPixmap = true; |
1628 | bool textureRectangle = false; |
1629 | @@ -271,6 +295,89 @@ |
1630 | GLScreen *gScreen; |
1631 | }; |
1632 | |
1633 | +namespace |
1634 | +{ |
1635 | + bool defaultRectangularFramebufferDraw (GLVertexBuffer *vertexBuffer, |
1636 | + GLFramebufferObject *fbo, |
1637 | + const CompRect &src, |
1638 | + const CompRect &dst, |
1639 | + GLbitfield mask, |
1640 | + GLenum filter) |
1641 | + { |
1642 | + GLTexture *texture = fbo->tex (); |
1643 | + GLMatrix sTransform; |
1644 | + const GLTexture::Matrix & texmatrix = texture->matrix (); |
1645 | + const GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, src.x1 ()); |
1646 | + const GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, src.x2 ()); |
1647 | + const GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, src.y1 ()); |
1648 | + const GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, src.y2 ()); |
1649 | + |
1650 | + const GLfloat vx1 = src.x1 (); |
1651 | + const GLfloat vx2 = src.x2 (); |
1652 | + const GLfloat vy1 = src.y1 (); |
1653 | + const GLfloat vy2 = src.y2 (); |
1654 | + |
1655 | + const GLTexture::Filter texFilter = |
1656 | + (filter == GL_LINEAR) ? GLTexture::Good : |
1657 | + GLTexture::Fast; |
1658 | + |
1659 | + std::vector<GLfloat> vertexData = { |
1660 | + vx1, vy1, 0.0f, |
1661 | + vx1, vy2, 0.0f, |
1662 | + vx2, vy1, 0.0f, |
1663 | + |
1664 | + vx1, vy2, 0.0f, |
1665 | + vx2, vy2, 0.0f, |
1666 | + vx2, vy1, 0.0f, |
1667 | + }; |
1668 | + |
1669 | + std::vector<GLfloat> textureData = { |
1670 | + tx1, ty1, |
1671 | + tx1, ty2, |
1672 | + tx2, ty1, |
1673 | + tx1, ty2, |
1674 | + tx2, ty2, |
1675 | + tx2, ty1, |
1676 | + }; |
1677 | + |
1678 | + vertexBuffer->begin (GL_TRIANGLES); |
1679 | + vertexBuffer->addVertices (6, &vertexData[0]); |
1680 | + vertexBuffer->addTexCoords (0, 6, &textureData[0]); |
1681 | + |
1682 | + if (vertexBuffer->end ()) |
1683 | + { |
1684 | + texture->enable (texFilter); |
1685 | + sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA); |
1686 | + vertexBuffer->render (sTransform); |
1687 | + texture->disable (); |
1688 | + } |
1689 | + |
1690 | + return true; |
1691 | + } |
1692 | + |
1693 | + void initializeDirectDraw (boost::shared_ptr <cgli::DirectDrawFramebufferStrategies> &directDraw, |
1694 | + const compiz::opengl::FramebufferRectangularDrawStrategy &blitFramebuffer, |
1695 | + const compiz::opengl::FramebufferRectangularDrawStrategy &rectangularTextureDraw, |
1696 | + cglfb::PushableFramebuffer *pushable) |
1697 | + { |
1698 | + cglfb::FramebufferRectangularDrawStrategy blitFramebufferWithPush ( |
1699 | + boost::bind ( |
1700 | + cgli::dispatchRectangleDrawStrategyWithPushedReadBuffer, |
1701 | + _1, _2, _3, _4, |
1702 | + pushable, |
1703 | + blitFramebuffer)); |
1704 | + |
1705 | + /* Tries each of these from back to front */ |
1706 | + cglfb::FramebufferRectangularDrawStrategyList strategies = |
1707 | + { |
1708 | + rectangularTextureDraw, |
1709 | + blitFramebufferWithPush |
1710 | + }; |
1711 | + |
1712 | + directDraw.reset (new cgli::DirectDrawFramebufferStrategies (strategies)); |
1713 | + } |
1714 | +} |
1715 | + |
1716 | bool |
1717 | GLScreen::glInitContext (XVisualInfo *visinfo) |
1718 | { |
1719 | @@ -500,8 +607,12 @@ |
1720 | if (GL::textureFromPixmap) |
1721 | registerBindPixmap (EglTexture::bindPixmapToTexture); |
1722 | |
1723 | +<<<<<<< TREE |
1724 | priv->incorrectRefreshRate = false; |
1725 | |
1726 | +======= |
1727 | + priv->blitFramebuffer = boost::bind (compiz::opengl::blitFramebufferEGL, _1, _2, _3, _4); |
1728 | +>>>>>>> MERGE-SOURCE |
1729 | #else |
1730 | |
1731 | Display *dpy = screen->dpy (); |
1732 | @@ -684,6 +795,10 @@ |
1733 | GL::fboSupported = true; |
1734 | } |
1735 | |
1736 | + if (GL::fboSupported && |
1737 | + strstr (glExtensions, "GL_EXT_framebuffer_blit")) |
1738 | + GL::blitFramebuffer = (GL::GLBlitFramebufferProc) getProcAddress ("glBlitFramebufferEXT"); |
1739 | + |
1740 | GL::fboStencilSupported = GL::fboSupported && |
1741 | strstr (glExtensions, "GL_EXT_packed_depth_stencil"); |
1742 | |
1743 | @@ -809,11 +924,24 @@ |
1744 | |
1745 | if (GL::textureFromPixmap) |
1746 | registerBindPixmap (TfpTexture::bindPixmapToTexture); |
1747 | + |
1748 | + priv->blitFramebuffer = boost::bind (compiz::opengl::blitFramebufferGLX, _1, _2, _3, _4); |
1749 | #endif |
1750 | |
1751 | if (GL::fboSupported) |
1752 | { |
1753 | - priv->scratchFbo = new GLFramebufferObject; |
1754 | + boost::shared_ptr <cgli::DirectDrawFramebufferStrategies> directDraw; |
1755 | + boost::shared_ptr <cgli::FramebufferObject> fbo (boost::make_shared <cgli::FramebufferObject> ()); |
1756 | + cglfb::FramebufferRectangularDrawStrategy rectangularTextureDraw (boost::bind (defaultRectangularFramebufferDraw, |
1757 | + GLVertexBuffer::streamingBuffer (), |
1758 | + fbo.get (), |
1759 | + _1, _2, _3, _4)); |
1760 | + initializeDirectDraw (directDraw, |
1761 | + priv->blitFramebuffer, |
1762 | + rectangularTextureDraw, |
1763 | + fbo.get ()); |
1764 | + priv->scratchFbo.reset (new cgli::DirectDrawFramebufferObject (directDraw, |
1765 | + fbo)); |
1766 | priv->scratchFbo->allocate (*screen, NULL, GL_BGRA); |
1767 | } |
1768 | |
1769 | @@ -1117,9 +1245,6 @@ |
1770 | glXDestroyContext (screen->dpy (), priv->ctx); |
1771 | #endif |
1772 | |
1773 | - if (priv->scratchFbo) |
1774 | - delete priv->scratchFbo; |
1775 | - |
1776 | delete priv; |
1777 | } |
1778 | |
1779 | @@ -1142,6 +1267,7 @@ |
1780 | doubleBuffer (screen->dpy (), *screen, surface), |
1781 | #endif |
1782 | scratchFbo (NULL), |
1783 | + blitFramebuffer (), |
1784 | outputRegion (), |
1785 | lastMask (0), |
1786 | bindPixmap (), |
1787 | @@ -1343,7 +1469,7 @@ |
1788 | { |
1789 | screen->outputChangeNotify (); |
1790 | |
1791 | - if (scratchFbo) |
1792 | + if (scratchFbo.get ()) |
1793 | scratchFbo->allocate (*screen, NULL, GL_BGRA); |
1794 | updateView (); |
1795 | } |
1796 | @@ -1570,9 +1696,9 @@ |
1797 | WRAPABLE_DEF (projectionMatrix) |
1798 | |
1799 | void |
1800 | -GLScreenInterface::glPaintCompositedOutput (const CompRegion ®ion, |
1801 | - GLFramebufferObject *fbo, |
1802 | - unsigned int mask) |
1803 | +GLScreenInterface::glPaintCompositedOutput (const CompRegion ®ion, |
1804 | + compiz::opengl::DirectDrawFramebufferObject *fbo, |
1805 | + unsigned int mask) |
1806 | WRAPABLE_DEF (glPaintCompositedOutput, region, fbo, mask) |
1807 | |
1808 | void |
1809 | @@ -1875,6 +2001,29 @@ |
1810 | |
1811 | } |
1812 | |
1813 | +bool |
1814 | +cglfb::blitFramebufferGLX (const CompRect &src, |
1815 | + const CompRect &dst, |
1816 | + GLbitfield mask, |
1817 | + GLenum filter) |
1818 | +{ |
1819 | + /* Must have GL_EXT_blit_framebuffer */ |
1820 | + if (!GL::blitFramebuffer) |
1821 | + return false; |
1822 | + |
1823 | + (*GL::blitFramebuffer) (src.x1 (), // sx0 |
1824 | + src.y1 (), // sy0 |
1825 | + src.x2 (), // sx1 |
1826 | + src.y2 (), // sy1 |
1827 | + dst.x1 (), // dx0 |
1828 | + dst.y1 (), // dy0 |
1829 | + dst.x2 (), // dx1, |
1830 | + dst.y2 (), // dy1 |
1831 | + GL_COLOR_BUFFER_BIT, |
1832 | + GL_LINEAR); |
1833 | + return true; |
1834 | +} |
1835 | + |
1836 | #else |
1837 | |
1838 | EGLDoubleBuffer::EGLDoubleBuffer (Display *d, |
1839 | @@ -1940,6 +2089,16 @@ |
1840 | { |
1841 | } |
1842 | |
1843 | +bool |
1844 | +cglfb::blitFramebufferEGL (const CompRect &src, |
1845 | + const CompRect &dst, |
1846 | + GLbitfield mask, |
1847 | + GLenum filter) |
1848 | +{ |
1849 | + /* Not supported on OpenGL|ES2 */ |
1850 | + return false; |
1851 | +} |
1852 | + |
1853 | #endif |
1854 | |
1855 | void |
1856 | @@ -1964,9 +2123,9 @@ |
1857 | bool useFbo = false; |
1858 | |
1859 | /* Clear the color buffer where appropriate */ |
1860 | - if (GL::fboEnabled && scratchFbo) |
1861 | + if (GL::fboEnabled && scratchFbo.get ()) |
1862 | { |
1863 | - oldFbo = scratchFbo->bind (); |
1864 | + oldFbo = static_cast <GLFramebufferObject *> (scratchFbo->bind ()); |
1865 | useFbo = scratchFbo->checkStatus () && scratchFbo->tex (); |
1866 | if (!useFbo) |
1867 | GLFramebufferObject::rebind (oldFbo); |
1868 | @@ -2066,10 +2225,7 @@ |
1869 | if (useFbo) |
1870 | { |
1871 | GLFramebufferObject::rebind (oldFbo); |
1872 | - |
1873 | - // FIXME: does not work if screen dimensions exceed max texture size |
1874 | - // We should try to use glBlitFramebuffer instead. |
1875 | - gScreen->glPaintCompositedOutput (screen->region (), scratchFbo, mask); |
1876 | + gScreen->glPaintCompositedOutput (screen->region (), scratchFbo.get (), mask); |
1877 | } |
1878 | |
1879 | if (cScreen->outputWindowChanged ()) |
1880 | @@ -2163,10 +2319,16 @@ |
1881 | } |
1882 | } |
1883 | |
1884 | -GLFramebufferObject * |
1885 | +compiz::opengl::FramebufferObject * |
1886 | GLScreen::fbo () |
1887 | { |
1888 | - return priv->scratchFbo; |
1889 | + return priv->scratchFbo.get (); |
1890 | +} |
1891 | + |
1892 | +const cglfb::BlitFramebufferFunc & |
1893 | +GLScreen::blitFramebufferFunc() |
1894 | +{ |
1895 | + return priv->blitFramebuffer; |
1896 | } |
1897 | |
1898 | GLTexture * |
1899 | |
1900 | === modified file 'plugins/water/src/water.cpp' |
1901 | --- plugins/water/src/water.cpp 2012-09-08 00:00:34 +0000 |
1902 | +++ plugins/water/src/water.cpp 2012-09-28 07:42:53 +0000 |
1903 | @@ -318,9 +318,9 @@ |
1904 | } |
1905 | |
1906 | void |
1907 | -WaterScreen::glPaintCompositedOutput (const CompRegion ®ion, |
1908 | - GLFramebufferObject *fbo, |
1909 | - unsigned int mask) |
1910 | +WaterScreen::glPaintCompositedOutput (const CompRegion ®ion, |
1911 | + compiz::opengl::DirectDrawFramebufferObject *fbo, |
1912 | + unsigned int mask) |
1913 | { |
1914 | if (count) |
1915 | { |
1916 | |
1917 | === modified file 'plugins/water/src/water.h' |
1918 | --- plugins/water/src/water.h 2012-09-07 23:56:21 +0000 |
1919 | +++ plugins/water/src/water.h 2012-09-28 07:42:53 +0000 |
1920 | @@ -64,9 +64,9 @@ |
1921 | |
1922 | void handleEvent (XEvent *); |
1923 | |
1924 | - void glPaintCompositedOutput (const CompRegion ®ion, |
1925 | - GLFramebufferObject *fbo, |
1926 | - unsigned int mask); |
1927 | + void glPaintCompositedOutput (const CompRegion ®ion, |
1928 | + compiz::opengl::DirectDrawFramebufferObject *fbo, |
1929 | + unsigned int mask); |
1930 | void preparePaint (int); |
1931 | void donePaint (); |
1932 |
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://