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

Proposed by Sam Spilsbury
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
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.

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

[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-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 &region,
488- GLFramebufferObject *fbo,
489- unsigned int mask);
490+ virtual void glPaintCompositedOutput (const CompRegion &region,
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 &region,
1393- GLFramebufferObject *fbo,
1394- unsigned int mask)
1395+GLScreen::glPaintCompositedOutput (const CompRegion &region,
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 &region,
1801- GLFramebufferObject *fbo,
1802- unsigned int mask)
1803+GLScreenInterface::glPaintCompositedOutput (const CompRegion &region,
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 &region,
1908- GLFramebufferObject *fbo,
1909- unsigned int mask)
1910+WaterScreen::glPaintCompositedOutput (const CompRegion &region,
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 &region,
1925- GLFramebufferObject *fbo,
1926- unsigned int mask);
1927+ void glPaintCompositedOutput (const CompRegion &region,
1928+ compiz::opengl::DirectDrawFramebufferObject *fbo,
1929+ unsigned int mask);
1930 void preparePaint (int);
1931 void donePaint ();
1932

Subscribers

People subscribed via source and target branches