Merge lp:~compiz-team/compiz/compiz.fix_1040478.1 into lp:compiz/0.9.10
- compiz.fix_1040478.1
- Merge into 0.9.10
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 |
Related bugs: |
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 FramebufferDire
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 FramebufferDire
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.
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal | # |
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3388
http://
Executed test runs:
SUCCESS: http://
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.
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3388
http://
Executed test runs:
FAILURE: http://
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3389
http://
Executed test runs:
FAILURE: http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Don't we want to fix bug 1051287 before merging this?
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.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3389
http://
Executed test runs:
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3394
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild:
http://
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
Lets look into this again post 0.9.9.0
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/
Is the fallthrough in plugins/
1323 switch (status)
1324 {
1325 - case GL::FRAMEBUFFER
1326 + case GL::FRAMEBUFFER
1327 return "GL::FRAMEBUFFE
1328 - case GL::FRAMEBUFFER
1329 + case GL::FRAMEBUFFER
1330 return "GL::FRAMEBUFFE
1331 - case GL::FRAMEBUFFER
1332 + case GL::FRAMEBUFFER
1333 return "GL::FRAMEBUFFE
1334 - case GL::FRAMEBUFFER
1335 + case GL::FRAMEBUFFER
1336 return "GL::FRAMEBUFFE
1337 - case GL::FRAMEBUFFER
1338 + case GL::FRAMEBUFFER
1339 return "GL::FRAMEBUFFE
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/
Thanks, I'll update it.
>
> Is the fallthrough in plugins/
> 1323 switch (status)
> 1324 {
> 1325 - case GL::FRAMEBUFFER
> 1326 + case GL::FRAMEBUFFER
> 1327 return "GL::FRAMEBUFFE
> 1328 - case GL::FRAMEBUFFER
> 1329 + case GL::FRAMEBUFFER
> 1330 return "GL::FRAMEBUFFE
> 1331 - case GL::FRAMEBUFFER
> 1332 + case GL::FRAMEBUFFER
> 1333 return "GL::FRAMEBUFFE
> 1334 - case GL::FRAMEBUFFER
> 1335 + case GL::FRAMEBUFFER
> 1336 return "GL::FRAMEBUFFE
> 1337 - case GL::FRAMEBUFFER
> 1338 + case GL::FRAMEBUFFER
> 1339 return "GL::FRAMEBUFFE
> 1340 default:
> 1341 return "unexpected status";
> 1342 }
>
No fall-through is possible, since we return directly.
> --
> https:/
> 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.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3405
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3409
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3410
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3411
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3413
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3413
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3414
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3415
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3416
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3417
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3417
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3418
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3419
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:3628
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:3629
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
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_
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:/
> 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_
We should land this in trunk and set up a Compiz-trunk-PPA, so more users could
test changes that are landed in trunk.
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:/
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:/
> 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
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3726
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
MC Return (mc-return) wrote : | # |
Sam, I've linked this MP with the related bug reports.
Unmerged revisions
Preview Diff
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 ®ion, |
586 | - GLFramebufferObject *fbo, |
587 | - unsigned int mask); |
588 | + virtual void glPaintCompositedOutput (const CompRegion ®ion, |
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 ®ion, |
1583 | - GLFramebufferObject *fbo, |
1584 | - unsigned int mask) |
1585 | +GLScreen::glPaintCompositedOutput (const CompRegion ®ion, |
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 ®ion, |
2052 | - GLFramebufferObject *fbo, |
2053 | - unsigned int mask) |
2054 | +GLScreenInterface::glPaintCompositedOutput (const CompRegion ®ion, |
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 ®ion, |
2272 | - GLFramebufferObject *fbo, |
2273 | - unsigned int mask) |
2274 | +WaterScreen::glPaintCompositedOutput (const CompRegion ®ion, |
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 ®ion, |
2300 | - GLFramebufferObject *fbo, |
2301 | - unsigned int mask); |
2302 | + void glPaintCompositedOutput (const CompRegion ®ion, |
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; |
FAILED: Continuous integration, rev:3387 jenkins. qa.ubuntu. com/job/ compiz- ci/77/ jenkins. qa.ubuntu. com/job/ compiz- ci/./build= pbuilder, distribution= quantal, flavor= amd64/77/ console
http://
Executed test runs:
FAILURE: http://