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

Proposed by Sam Spilsbury on 2013-02-13
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/compiz.performance_1040478
Merge into: lp:compiz/0.9.9
Diff against target: 2484 lines (+1343/-445)
24 files modified
include/core/window.h (+2/-2)
plugins/opengl/CMakeLists.txt (+6/-0)
plugins/opengl/include/opengl/framebufferobject.h (+180/-41)
plugins/opengl/include/opengl/opengl-api.h (+42/-0)
plugins/opengl/include/opengl/opengl.h (+76/-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 (+236/-0)
plugins/opengl/src/framebufferobject.cpp (+105/-104)
plugins/opengl/src/paint.cpp (+8/-80)
plugins/opengl/src/privates.h (+49/-7)
plugins/opengl/src/screen.cpp (+245/-34)
plugins/water/src/water.cpp (+17/-9)
plugins/water/src/water.h (+4/-4)
src/event.cpp (+3/-29)
src/option/tests/CMakeLists.txt (+0/-1)
src/option/tests/option.cpp (+0/-4)
src/outputdevices.h (+0/-5)
src/privatewindow.h (+25/-22)
src/tests/CMakeLists.txt (+0/-1)
src/window.cpp (+1/-0)
tests/system/xorg-gtest/tests/compiz_xorg_gtest_test_window_stacking.cpp (+0/-80)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.performance_1040478
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration 2013-02-13 Needs Fixing on 2013-02-13
jenkins continuous-integration 2013-02-13 Pending
Sam Spilsbury Pending
Review via email: mp+148158@code.launchpad.net

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

This proposal has been superseded by a proposal from 2013-02-15.

Commit message

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

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

Tests added for the new module FramebufferDirectDraw.

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

Description of the change

Proposing this now so I can get some early feedback.

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

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

Tests added for the new module FramebufferDirectDraw.

The API and ABI of GLFramebufferObject were broken too so that we could specify which buffer we actually wanted to bind.

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

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

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

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

review: Resubmit
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
jenkins (martin-mrazik+qa) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

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

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

Probably a good idea. Lets do that.

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

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

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

OK, then. Bug 1051287 needs fixing here.

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

Lets look into this again post 0.9.9.0

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

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

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

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

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

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

Thanks, I'll update it.

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

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

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

--
Sam Spilsbury

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

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

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

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

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

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

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

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

3414. By Sam Spilsbury on 2013-02-15

Merge lp:compiz

3415. By Sam Spilsbury on 2013-02-18

Revert more changes which should not have happened

3416. By Sam Spilsbury on 2013-02-18

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

3417. By Sam Spilsbury on 2013-02-25

Merge lp:compiz

3418. By Sam Spilsbury on 2013-02-27

Merge lp:compiz

3419. By Sam Spilsbury on 2013-02-28

Unrevert changes reverted by a merge

Unmerged revisions

3419. By Sam Spilsbury on 2013-02-28

Unrevert changes reverted by a merge

3418. By Sam Spilsbury on 2013-02-27

Merge lp:compiz

3417. By Sam Spilsbury on 2013-02-25

Merge lp:compiz

3416. By Sam Spilsbury on 2013-02-18

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

3415. By Sam Spilsbury on 2013-02-18

Revert more changes which should not have happened

3414. By Sam Spilsbury on 2013-02-15

Merge lp:compiz

3413. By Sam Spilsbury on 2013-02-13

Fix merge errors

3412. By Sam Spilsbury on 2013-02-13

Merge lp:compiz

3411. By Sam Spilsbury on 2013-02-12

Another botched merge

3410. By Sam Spilsbury on 2013-02-12

Unrevert changes which shouldn't have been reverted

Preview Diff

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

Subscribers

People subscribed via source and target branches