Merge lp:~compiz-team/compiz/compiz.performance_1040478 into lp:compiz/0.9.9

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/compiz.performance_1040478
Merge into: lp:compiz/0.9.9
Diff against target: 1918 lines (+1202/-268)
15 files modified
plugins/opengl/CMakeLists.txt (+6/-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 (+179/-20)
plugins/water/src/water.cpp (+3/-3)
plugins/water/src/water.h (+3/-3)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.performance_1040478
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Fixing
jenkins (community) continuous-integration Needs Fixing
Review via email: mp+126875@code.launchpad.net

This proposal supersedes a proposal from 2012-09-28.

This proposal has been superseded by a proposal from 2012-12-07.

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 FramebufferDirectDraw.

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 FramebufferDirectDraw.

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.

To post a comment you must log in.
Revision history for this message
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
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.

review: Needs Resubmitting
Revision history for this message
jenkins (martin-mrazik+qa) wrote :
review: Needs Fixing (continuous-integration)
3389. By Sam Spilsbury

Merge lp:compiz

Revision history for this message
jenkins (martin-mrazik+qa) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Don't we want to fix bug 1051287 before merging this?

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

Probably a good idea. Lets do that.

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

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)

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

OK, then. Bug 1051287 needs fixing here.

review: Needs Fixing
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

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

Subscribers

People subscribed via source and target branches