Merge lp:~compiz-team/compiz/compiz.fix_1040478 into lp:compiz/0.9.10

Proposed by Sam Spilsbury on 2013-04-02
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1040478
Merge into: lp:compiz/0.9.10
Diff against target: 2312 lines (+1361/-326)
16 files modified
debian/patches/100_workaround_virtualbox_hang.patch (+25/-25)
plugins/opengl/CMakeLists.txt (+6/-0)
plugins/opengl/include/opengl/framebufferobject.h (+182/-41)
plugins/opengl/include/opengl/opengl-api.h (+42/-0)
plugins/opengl/include/opengl/opengl.h (+82/-22)
plugins/opengl/src/fbdirectdraw/CMakeLists.txt (+32/-0)
plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h (+111/-0)
plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp (+177/-0)
plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt (+24/-0)
plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp (+237/-0)
plugins/opengl/src/framebufferobject.cpp (+112/-104)
plugins/opengl/src/paint.cpp (+10/-80)
plugins/opengl/src/privates.h (+49/-7)
plugins/opengl/src/screen.cpp (+251/-34)
plugins/water/src/water.cpp (+17/-9)
plugins/water/src/water.h (+4/-4)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_1040478
Reviewer Review Type Date Requested Status
jenkins continuous-integration 2013-04-02 Pending
Sam Spilsbury Pending
PS Jenkins bot continuous-integration 2013-04-02 Pending
Daniel van Vugt 2013-04-02 Pending
MC Return 2013-04-02 Pending
Review via email: mp+156465@code.launchpad.net

This proposal supersedes a proposal from 2013-02-28.

This proposal has been superseded by a proposal from 2013-05-26.

Commit message

Implement support for glBlitFramebuffer. On some platforms this may speed up the final composite operation as we skip the fragment processor entirely.

The logic around this code is basically that if glBlitFramebuffer fails, then we don't use it again (the failure case is it not being available), and use the fallback textured draw code.

Tests added for the new module FramebufferDirectDraw.

(LP: #1040478) (LP: #1051287)

Description of the change

Rebased.

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.

Also added new concepts of framebuffer binding points. These are now responsible for binding framebuffers to the GL_DRAW_FRAMEBUFFER or GL_READ_FRAMEBUFFER rather than the object itself. This effectively means that we can optimize out multiple binds of the same object, or leave objects bound until they /actually/ need to change.

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

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

review: Needs Information
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Probably a good idea. Lets do that.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Though, I'm not entirely certain. In order to fix it properly I'll need to add a concept of framebuffer bindings points to opengl, that could inflate this change a little more (or at least introduce a dependency)

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

OK, then. Bug 1051287 needs fixing here.

review: Needs Fixing
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Lets look into this again post 0.9.9.0

review: Resubmit
MC Return (mc-return) wrote : Posted in a previous version of this proposal

165 + * This since this code only draws a rectangular region from one
should probably be:
165 + * Since this code only draws a rectangular region from one

The copyright in plugins/opengl/include/opengl/opengl-api.h seems to be incorrect.

Is the fallthrough in plugins/opengl/src/framebufferobject.cpp intentional ?
1323 switch (status)
1324 {
1325 - case GL::FRAMEBUFFER_COMPLETE:
1326 + case GL::FRAMEBUFFER_COMPLETE:
1327 return "GL::FRAMEBUFFER_COMPLETE";
1328 - case GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
1329 + case GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
1330 return "GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
1331 - case GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
1332 + case GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
1333 return "GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
1334 - case GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
1335 + case GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
1336 return "GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
1337 - case GL::FRAMEBUFFER_UNSUPPORTED:
1338 + case GL::FRAMEBUFFER_UNSUPPORTED:
1339 return "GL::FRAMEBUFFER_UNSUPPORTED";
1340 default:
1341 return "unexpected status";
1342 }

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

On Sun, Feb 10, 2013 at 8:28 PM, MC Return <email address hidden> wrote:
> 165 + * This since this code only draws a rectangular region from one
> should probably be:
> 165 + * Since this code only draws a rectangular region from one
>
> The copyright in plugins/opengl/include/opengl/opengl-api.h seems to be incorrect.

Thanks, I'll update it.

>
> Is the fallthrough in plugins/opengl/src/framebufferobject.cpp intentional ?
> 1323 switch (status)
> 1324 {
> 1325 - case GL::FRAMEBUFFER_COMPLETE:
> 1326 + case GL::FRAMEBUFFER_COMPLETE:
> 1327 return "GL::FRAMEBUFFER_COMPLETE";
> 1328 - case GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
> 1329 + case GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
> 1330 return "GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
> 1331 - case GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
> 1332 + case GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
> 1333 return "GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
> 1334 - case GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
> 1335 + case GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
> 1336 return "GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
> 1337 - case GL::FRAMEBUFFER_UNSUPPORTED:
> 1338 + case GL::FRAMEBUFFER_UNSUPPORTED:
> 1339 return "GL::FRAMEBUFFER_UNSUPPORTED";
> 1340 default:
> 1341 return "unexpected status";
> 1342 }
>

No fall-through is possible, since we return directly.

> --
> https://code.launchpad.net/~compiz-team/compiz/compiz.performance_1040478/+merge/147541
> You proposed lp:~compiz-team/compiz/compiz.performance_1040478 for merging.

--
Sam Spilsbury

MC Return (mc-return) wrote : Posted in a previous version of this proposal

>
> No fall-through is possible, since we return directly.
>
Ah, yeah - you are right ofc. - sorry 'bout that.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Checking the copyright again on opengl-api.h, I don't think there is any problem there. All I did for that code was cut-and-paste part of private.h, no actual modification on my part.

MC Return (mc-return) wrote : Posted in a previous version of this proposal

The change to debian/changelog seems to be unintended and should probably be removed here as well.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Thanks. I fixed that yesterday but seemed to forget to push it here.

MC Return (mc-return) wrote : Posted in a previous version of this proposal

Works for me (on ATI fglrx).

Btw, ATI fglrx supports GL_EXT_framebuffer_blit as well, reference: http://www.geeks3d.com/opengl-extensions/

review: Approve
Timo Jyrinki (timo-jyrinki) wrote : Posted in a previous version of this proposal

Since the 13.04 is happening, we are now past Feature Freeze with 0.9.9 :( The bug report would need be changed to a FFe if this would be wanted to be gotten in. The performance benefits should probably also need benchmarking to double-check there won't be any regressions? Especially Intel I'd guess, its OpenGL 3.0 support is quite new.

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

My understanding is that these branches will not be taken in
lp:compiz/raring. lp:compiz is now a separate project.

On Mon, Mar 11, 2013 at 1:17 PM, Timo Jyrinki
<email address hidden> wrote:
> Since the 13.04 is happening, we are now past Feature Freeze with 0.9.9 :( The bug report would need be changed to a FFe if this would be wanted to be gotten in. The performance benefits should probably also need benchmarking to double-check there won't be any regressions? Especially Intel I'd guess, its OpenGL 3.0 support is quite new.
> --
> https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1040478/+merge/150949
> You proposed lp:~compiz-team/compiz/compiz.fix_1040478 for merging.

--
Sam Spilsbury

Timo Jyrinki (timo-jyrinki) wrote : Posted in a previous version of this proposal

Yeah, you're correct.

MC Return (mc-return) wrote : Posted in a previous version of this proposal

> Since the 13.04 is happening, we are now past Feature Freeze with 0.9.9 :( The
> bug report would need be changed to a FFe if this would be wanted to be gotten
> in. The performance benefits should probably also need benchmarking to double-
> check there won't be any regressions? Especially Intel I'd guess, its OpenGL
> 3.0 support is quite new.

Intel should support GL_EXT_framebuffer_blit as well AFAIK.
We should land this in trunk and set up a Compiz-trunk-PPA, so more users could
test changes that are landed in trunk.

review: Approve
MC Return (mc-return) wrote : Posted in a previous version of this proposal

> My understanding is that these branches will not be taken in
> lp:compiz/raring. lp:compiz is now a separate project.
>

Sam, could you set up a PPA auto-building lp:compiz ?
It would be very useful to be able to have a solid user testing
base for changes landing in trunk==lp:compiz...

Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

 This is easy enough to do yourself, see "create packaging recipe"
here https://code.launchpad.net/~compiz-team/compiz/0.9.9 . The
default will work fine.

On Sun, Mar 24, 2013 at 6:11 PM, MC Return <email address hidden> wrote:
>> My understanding is that these branches will not be taken in
>> lp:compiz/raring. lp:compiz is now a separate project.
>>
>
> Sam, could you set up a PPA auto-building lp:compiz ?
> It would be very useful to be able to have a solid user testing
> base for changes landing in trunk==lp:compiz...
>
> --
> https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1040478/+merge/150949
> You proposed lp:~compiz-team/compiz/compiz.fix_1040478 for merging.

--
Sam Spilsbury

Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Please re-target this for lp:compiz/0.9.10

review: Resubmit

Unmerged revisions

3629. By Sam Spilsbury on 2013-02-28

Refresh patches

3628. By Sam Spilsbury on 2013-02-28

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.

(LP: #1040478) (LP: #1051287)

Preview Diff

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

Subscribers

People subscribed via source and target branches

to all changes: