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

Proposed by Sam Spilsbury
Status: Work in progress
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1040478.1
Merge into: lp:compiz/0.9.10
Diff against target: 2316 lines (+1368/-324)
17 files modified
.bzrignore (+1/-0)
debian/patches/100_workaround_virtualbox_hang.patch (+31/-23)
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.1
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
MC Return Pending
Sam Spilsbury Pending
Daniel van Vugt Pending
jenkins continuous-integration Pending
Review via email: mp+165770@code.launchpad.net

This proposal supersedes 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.
Revision history for this message
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I have not seen any improvement yet myself. It would have to be quite significant to risk large changes to the 0.9.8 tree right now.

As far as I can tell, this is not required for quantal. So please repropose it after we've branched for 0.9.9.

review: Needs Resubmitting
Revision history for this message
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
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
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Probably a good idea. Lets do that.

Revision history for this message
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)

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

OK, then. Bug 1051287 needs fixing here.

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

Lets look into this again post 0.9.9.0

review: Needs Resubmitting
Revision history for this message
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 }

Revision history for this message
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

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
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
Revision history for this message
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.

Revision history for this message
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

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

Yeah, you're correct.

Revision history for this message
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
Revision history for this message
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...

Revision history for this message
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

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

Please re-target this for lp:compiz/0.9.10

review: Needs Resubmitting
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
MC Return (mc-return) wrote :

Sam, I've linked this MP with the related bug reports.

Unmerged revisions

3726. By Sam Spilsbury

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

Preview Diff

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

Subscribers

People subscribed via source and target branches

to all changes: