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

Proposed by Sam Spilsbury on 2012-09-15
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/compiz.performance_1040478
Merge into: lp:compiz/0.9.8
Diff against target: 1923 lines (+1204/-269)
15 files modified
plugins/opengl/CMakeLists.txt (+7/-0)
plugins/opengl/include/opengl/framebufferobject.h (+219/-73)
plugins/opengl/include/opengl/opengl-api.h (+42/-0)
plugins/opengl/include/opengl/opengl.h (+50/-22)
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 2012-09-15 Resubmit on 2012-09-20
jenkins (community) continuous-integration 2012-09-15 Approve on 2012-09-15
Review via email: mp+124543@code.launchpad.net

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.
jenkins (martin-mrazik+qa) wrote :
review: Needs Fixing (continuous-integration)
3388. By Sam Spilsbury on 2012-09-15

Merge lp:compiz

jenkins (martin-mrazik+qa) wrote :
review: Approve (continuous-integration)
Daniel van Vugt (vanvugt) wrote :

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: Resubmit
3389. By Sam Spilsbury on 2012-10-02

Merge lp:compiz

3390. By Sam Spilsbury on 2012-12-07

Merge e lp:compiz

3391. By Sam Spilsbury on 2012-12-07

Merge lp:compiz

3392. By Sam Spilsbury on 2012-12-07

Simplify lots of variable names, unindent namespaces

3393. By Sam Spilsbury on 2012-12-07

Set the stencil and depth attachments in allocate and not bind

3394. By Sam Spilsbury on 2012-12-07

Refactored large parts of the code, make binding the concern of BindLocation

3395. By Sam Spilsbury on 2012-12-13

Merge lp:compiz

3396. By Sam Spilsbury on 2012-12-21

Moved the creation of directly drawable fbo's into a convenience method
so that other plugins can create them

3397. By Sam Spilsbury on 2012-12-21

Fix compile error on tests

3398. By Sam Spilsbury on 2012-12-22

We don't need to provide a BindableFramebuffer to access the backbuffer

3399. By Sam Spilsbury on 2012-12-22

Unbind framebuffers before processing output change

3400. By Sam Spilsbury on 2012-12-22

Invert y-coords of glBlitFramebuffer operation

3401. By Sam Spilsbury on 2012-12-23

Reset framebuffer status on reallocation

3402. By Sam Spilsbury on 2013-01-03

Merge lp:compiz

3403. By Sam Spilsbury on 2013-01-04

Remove unused variable

3404. By Sam Spilsbury on 2013-01-30

Merge lp:compiz

3405. By Sam Spilsbury on 2013-02-10

Merge lp:compiz

3406. By Sam Spilsbury on 2013-02-12

Merge lp:compiz

3407. By Sam Spilsbury on 2013-02-12

Remove referenes to configure buffers

3408. By Sam Spilsbury on 2013-02-12

Revert trunk merge as it was broken

3409. By Sam Spilsbury on 2013-02-12

Merge lp:compiz

3410. By Sam Spilsbury on 2013-02-12

Unrevert changes which shouldn't have been reverted

3411. By Sam Spilsbury on 2013-02-12

Another botched merge

3412. By Sam Spilsbury on 2013-02-13

Merge lp:compiz

3413. By Sam Spilsbury on 2013-02-13

Fix merge errors

3414. By Sam Spilsbury on 2013-02-15

Merge lp:compiz

3415. By Sam Spilsbury on 2013-02-18

Revert more changes which should not have happened

3416. By Sam Spilsbury on 2013-02-18

Make the currently bound drawbuffer available to plugins (as they might want
to do a read/draw swap)

3417. By Sam Spilsbury on 2013-02-25

Merge lp:compiz

3418. By Sam Spilsbury on 2013-02-27

Merge lp:compiz

3419. By Sam Spilsbury on 2013-02-28

Unrevert changes reverted by a merge

Unmerged revisions

3419. By Sam Spilsbury on 2013-02-28

Unrevert changes reverted by a merge

3418. By Sam Spilsbury on 2013-02-27

Merge lp:compiz

3417. By Sam Spilsbury on 2013-02-25

Merge lp:compiz

3416. By Sam Spilsbury on 2013-02-18

Make the currently bound drawbuffer available to plugins (as they might want
to do a read/draw swap)

3415. By Sam Spilsbury on 2013-02-18

Revert more changes which should not have happened

3414. By Sam Spilsbury on 2013-02-15

Merge lp:compiz

3413. By Sam Spilsbury on 2013-02-13

Fix merge errors

3412. By Sam Spilsbury on 2013-02-13

Merge lp:compiz

3411. By Sam Spilsbury on 2013-02-12

Another botched merge

3410. By Sam Spilsbury on 2013-02-12

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

Subscribers

People subscribed via source and target branches