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

Proposed by Sam Spilsbury on 2013-05-26
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1040478
Merge into: lp:compiz/0.9.10
Diff against target: 2332 lines (+1389/-307) (has conflicts)
16 files modified
debian/patches/100_workaround_virtualbox_hang.patch (+53/-6)
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)
Text conflict in debian/patches/100_workaround_virtualbox_hang.patch
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_1040478
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration 2013-05-26 Pending
jenkins continuous-integration 2013-05-26 Pending
Sam Spilsbury Pending
Daniel van Vugt 2013-05-26 Pending
MC Return 2013-05-26 Pending
Review via email: mp+165769@code.launchpad.net

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

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

Subscribers

People subscribed via source and target branches

to all changes: