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

Proposed by Sam Spilsbury
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 Needs Fixing
Sam Spilsbury Pending
jenkins continuous-integration Pending
Review via email: mp+147837@code.launchpad.net

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

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

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

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

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

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

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

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

Probably a good idea. Lets do that.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

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

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

OK, then. Bug 1051287 needs fixing here.

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

Lets look into this again post 0.9.9.0

review: Needs Resubmitting
Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

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

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

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

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

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

Thanks, I'll update it.

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

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

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

--
Sam Spilsbury

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

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

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

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

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

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

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

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

3412. By Sam Spilsbury

Merge lp:compiz

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
3413. By Sam Spilsbury

Fix merge errors

3414. By Sam Spilsbury

Merge lp:compiz

3415. By Sam Spilsbury

Revert more changes which should not have happened

3416. By Sam Spilsbury

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

3417. By Sam Spilsbury

Merge lp:compiz

3418. By Sam Spilsbury

Merge lp:compiz

3419. By Sam Spilsbury

Unrevert changes reverted by a merge

Unmerged revisions

3419. By Sam Spilsbury

Unrevert changes reverted by a merge

3418. By Sam Spilsbury

Merge lp:compiz

3417. By Sam Spilsbury

Merge lp:compiz

3416. By Sam Spilsbury

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

3415. By Sam Spilsbury

Revert more changes which should not have happened

3414. By Sam Spilsbury

Merge lp:compiz

3413. By Sam Spilsbury

Fix merge errors

3412. By Sam Spilsbury

Merge lp:compiz

3411. By Sam Spilsbury

Another botched merge

3410. By Sam Spilsbury

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
=== modified file 'include/core/window.h'
--- include/core/window.h 2013-01-03 16:06:41 +0000
+++ include/core/window.h 2013-02-13 11:45:25 +0000
@@ -43,12 +43,12 @@
43#include <core/region.h>43#include <core/region.h>
44#include <core/windowgeometry.h>44#include <core/windowgeometry.h>
45#include <core/windowextents.h>45#include <core/windowextents.h>
46#include <core/servergrab.h>
4746
48#include <core/wrapsystem.h>47#include <core/wrapsystem.h>
4948
50#include <map>49#include <map>
5150
51class ServerLock;
52class CompWindow;52class CompWindow;
53class CompIcon;53class CompIcon;
54class PrivateWindow;54class PrivateWindow;
@@ -434,7 +434,7 @@
434 void moveInputFocusToOtherWindow ();434 void moveInputFocusToOtherWindow ();
435435
436 /* wraps XConfigureWindow and updates serverGeometry */436 /* wraps XConfigureWindow and updates serverGeometry */
437 void configureXWindow (unsigned int valueMask,437 void configureXWindow (unsigned int valueMask,
438 XWindowChanges *xwc);438 XWindowChanges *xwc);
439439
440 void restackAndConfigureXWindow (unsigned int valueMask,440 void restackAndConfigureXWindow (unsigned int valueMask,
441441
=== modified file 'plugins/opengl/CMakeLists.txt'
--- plugins/opengl/CMakeLists.txt 2012-12-12 07:33:12 +0000
+++ plugins/opengl/CMakeLists.txt 2013-02-13 11:45:25 +0000
@@ -5,15 +5,21 @@
5set (INTERNAL_LIBRARIES5set (INTERNAL_LIBRARIES
6 compiz_opengl_double_buffer6 compiz_opengl_double_buffer
7 compiz_opengl_fsregion7 compiz_opengl_fsregion
8 compiz_opengl_framebuffer_direct_draw
8 compiz_opengl_blacklist9 compiz_opengl_blacklist
9 compiz_opengl_glx_tfp_bind10 compiz_opengl_glx_tfp_bind
10)11)
1112
13set (COMPIZ_OPENGL_PLUGIN_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
14set (COMPIZ_OPENGL_PLUGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
15
12add_subdirectory (src/doublebuffer)16add_subdirectory (src/doublebuffer)
13add_subdirectory (src/fsregion)17add_subdirectory (src/fsregion)
18add_subdirectory (src/fbdirectdraw)
14add_subdirectory (src/blacklist)19add_subdirectory (src/blacklist)
15add_subdirectory (src/glxtfpbind)20add_subdirectory (src/glxtfpbind)
1621
22include_directories (src/fbdirectdraw/include)
17include_directories (src/glxtfpbind/include)23include_directories (src/glxtfpbind/include)
1824
19if (USE_GLES)25if (USE_GLES)
2026
=== modified file 'plugins/opengl/include/opengl/framebufferobject.h'
--- plugins/opengl/include/opengl/framebufferobject.h 2012-08-09 02:19:26 +0000
+++ plugins/opengl/include/opengl/framebufferobject.h 2013-02-13 11:45:25 +0000
@@ -26,29 +26,175 @@
26#ifndef _COMPIZ_GLFRAMEBUFFEROBJECT_H26#ifndef _COMPIZ_GLFRAMEBUFFEROBJECT_H
27#define _COMPIZ_GLFRAMEBUFFEROBJECT_H27#define _COMPIZ_GLFRAMEBUFFEROBJECT_H
2828
29#include <opengl/opengl.h>29#include <list>
30#include <boost/function.hpp>
31#include <opengl/opengl-api.h>
32#include <core/size.h>
33#include <core/rect.h>
34
35class GLVertexBuffer;
36class GLTexture;
37
38namespace compiz
39{
40namespace opengl
41{
42typedef enum _BlitMask
43{
44 ColorData = (1 << 0),
45 StencilData = (1 << 1)
46} BlitMask;
47
48typedef enum _Filter
49{
50 Fast = 0,
51 Good = 1,
52} Filter;
53
54typedef enum _BindPoint
55{
56 Read = 0,
57 Draw = 1
58} BindPoint;
59
60class BindableFramebuffer
61{
62 public:
63
64 virtual ~BindableFramebuffer () {}
65
66 virtual GLuint getResourceId () const = 0;
67 virtual bool setBindStatus (GLenum) = 0;
68 virtual void updateAllocation (GLenum) = 0;
69};
70
71class BindLocation
72{
73 public:
74
75 virtual ~BindLocation () {}
76
77 /**
78 * Bind the specified BindableFramebuffer to this bind location
79 * usually either as the read target or the draw target
80 *
81 * The previous FBO is no longer bound. If it was bound to the
82 * draw target, it will be safe to use its texture.
83 *
84 * This returns the last-bound BindableFramebuffer object on
85 * success and NULL on failure (no change). Call this again
86 * in order to restore that framebuffer
87 */
88 virtual BindableFramebuffer * bind (BindableFramebuffer *) = 0;
89};
90
91typedef boost::function <bool (const CompRect &src,
92 const CompRect &dst,
93 GLbitfield mask,
94 GLenum filter)> RectangularDraw;
95typedef std::list <RectangularDraw> RectangularDrawList;
96
97class DirectDrawStrategies
98{
99 public:
100
101 typedef boost::shared_ptr <DirectDrawStrategies> Ptr;
102
103 virtual ~DirectDrawStrategies () {}
104 virtual void draw (const CompRect &src,
105 const CompRect &dst,
106 BlitMask mask,
107 Filter filter) = 0;
108};
109
110class FramebufferObject
111{
112 public:
113
114 virtual ~FramebufferObject () {}
115
116 /**
117 * Ensure the texture is of the given size, recreating it if needed,
118 * and replace the FBO color attachment with it. The texture contents
119 * become undefined, unless specified in the 'image' argument.
120 * When specifying 'image', it's also possible to pass-in the
121 * desired image's 'format' and 'type'.
122 *
123 * Returns true on success, and false on texture allocation failure.
124 */
125 virtual bool allocate (const CompSize &size,
126 const char *image = NULL,
127 GLenum format = GL_RGBA,
128 GLenum type = GL_UNSIGNED_BYTE) = 0;
129
130 /**
131 * Check the FBO completeness. Returns true on complete.
132 * Otherwise returns false and reports the error to log.
133 */
134 virtual bool checkStatus () = 0;
135
136 /**
137 * Return a pointer to the texture that is the color attachment.
138 * This will return NULL, if allocate () has not been called, or
139 * the last allocate () call failed.
140 */
141 virtual GLTexture * tex () = 0;
142};
143
144class DirectDrawObject :
145 virtual public compiz::opengl::FramebufferObject,
146 virtual public compiz::opengl::BindableFramebuffer
147{
148 public:
149
150 virtual ~DirectDrawObject () {};
151
152 /**
153 * Draws a region of the framebuffer object as specified in
154 * framebuffer-specified co-ordinates as @src co-ordinates in
155 * the buffer currently bound co-ordinates @dst . @mask indicates
156 * what kind of data should be propogated downwards. @filter indicates
157 * what kind of filter should be used when drawing this buffer
158 *
159 * This since this code only draws a rectangular region from one
160 * framebuffer to another, it will try and use the fastest codepath
161 * possible, falling back to a simple textured draw if
162 * glBlitFramebuffer is not available
163 *
164 */
165 virtual void directDraw (const CompRect &src,
166 const CompRect &dst,
167 compiz::opengl::BlitMask mask,
168 compiz::opengl::Filter filter) = 0;
169};
170
171namespace impl
172{
173namespace cgl = compiz::opengl;
30174
31struct PrivateGLFramebufferObject;175struct PrivateGLFramebufferObject;
32176
33/**177class FBOBindLocation :
34 * Class representing a framebuffer object in GL, supporting only one178 public cgl::BindLocation
35 * color attachment as per GLES 2 spec. The color attachment is referred179{
36 * to as the texture (of the FBO).180 public:
37 *181
38 * Usage:182 FBOBindLocation (GLenum binding, BindableFramebuffer *back);
39 * 1. create a GLFramebufferObject (requires a GL context)183 BindableFramebuffer * bind (BindableFramebuffer *);
40 * 2. call allocate (size), and check status ()184
41 * 3. old = bind ()185 private:
42 * 4. do your rendering186
43 * 5. rebind (old)187 class Private;
44 * 6. use the rendered texture via tex ()188 std::auto_ptr <Private> priv;
45 * 7. go to 2 or 3, or delete to quit (requires a GL context)189};
46 */190
47class GLFramebufferObject191class FramebufferObject :
48{192 public cgl::FramebufferObject,
49 public:193 public cgl::BindableFramebuffer
50 GLFramebufferObject ();194{
51 ~GLFramebufferObject ();195 public:
196 FramebufferObject ();
197 ~FramebufferObject ();
52198
53 /**199 /**
54 * Ensure the texture is of the given size, recreating it if needed,200 * Ensure the texture is of the given size, recreating it if needed,
@@ -65,26 +211,6 @@
65 GLenum type = GL_UNSIGNED_BYTE);211 GLenum type = GL_UNSIGNED_BYTE);
66212
67 /**213 /**
68 * Bind this as the current FBO, previous binding in GL context is
69 * undone. GL rendering is now targeted to this FBO.
70 * Returns a pointer to the previously bound FBO, or NULL if
71 * the previous binding was zero (the window system provided
72 * framebuffer).
73 *
74 * The previous FBO is no longer bound, so you can use its
75 * texture. To restore the previous FBO, call rebind (FBO) with
76 * the returned pointer as the argument.
77 */
78 GLFramebufferObject *bind ();
79
80 /**
81 * Bind the given FBO as the current FBO, without looking up the
82 * previous binding. The argument can be NULL, in which case the
83 * window system provided framebuffer gets bound (FBO is unbound).
84 */
85 static void rebind (GLFramebufferObject *fbo);
86
87 /**
88 * Check the FBO completeness. Returns true on complete.214 * Check the FBO completeness. Returns true on complete.
89 * Otherwise returns false and reports the error to log.215 * Otherwise returns false and reports the error to log.
90 */216 */
@@ -95,10 +221,23 @@
95 * This will return NULL, if allocate () has not been called, or221 * This will return NULL, if allocate () has not been called, or
96 * the last allocate () call failed.222 * the last allocate () call failed.
97 */223 */
98 GLTexture *tex ();224 GLTexture * tex ();
99225
100 private:226 private:
227
228 /**
229 * Returns the framebuffer identifier
230 */
231 GLuint getResourceId () const;
232 bool setBindStatus (GLenum);
233 void updateAllocation (GLenum bindingLocation);
234
101 PrivateGLFramebufferObject *priv;235 PrivateGLFramebufferObject *priv;
102};236};
237}
238}
239}
240
241typedef compiz::opengl::impl::FramebufferObject GLFramebufferObject;
103242
104#endif // _COMPIZ_GLFRAMEBUFFEROBJECT_H243#endif // _COMPIZ_GLFRAMEBUFFEROBJECT_H
105244
=== added file 'plugins/opengl/include/opengl/opengl-api.h'
--- plugins/opengl/include/opengl/opengl-api.h 1970-01-01 00:00:00 +0000
+++ plugins/opengl/include/opengl/opengl-api.h 2013-02-13 11:45:25 +0000
@@ -0,0 +1,42 @@
1/*
2 * Copyright © 2008 Dennis Kasprzyk
3 * Copyright © 2007 Novell, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without
7 * fee, provided that the above copyright notice appear in all copies
8 * and that both that copyright notice and this permission notice
9 * appear in supporting documentation, and that the name of
10 * Dennis Kasprzyk not be used in advertising or publicity pertaining to
11 * distribution of the software without specific, written prior permission.
12 * Dennis Kasprzyk makes no representations about the suitability of this
13 * software for any purpose. It is provided "as is" without express or
14 * implied warranty.
15 *
16 * DENNIS KASPRZYK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
18 * NO EVENT SHALL DENNIS KASPRZYK BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
20 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
21 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
22 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 *
24 * Authors: Dennis Kasprzyk <onestone@compiz-fusion.org>
25 * David Reveman <davidr@novell.com>
26 */
27
28#ifndef _COMPIZ_OPENGL_API_H
29#define _COMPIZ_OPENGL_API_H
30
31#ifdef USE_GLES
32#define SUPPORT_X11
33#include <GLES2/gl2.h>
34#include <GLES2/gl2ext.h>
35#include <EGL/egl.h>
36#include <EGL/eglext.h>
37#else
38#include <GL/gl.h>
39#include <GL/glx.h>
40#endif
41
42#endif
043
=== modified file 'plugins/opengl/include/opengl/opengl.h'
--- plugins/opengl/include/opengl/opengl.h 2013-01-10 09:23:24 +0000
+++ plugins/opengl/include/opengl/opengl.h 2013-02-13 11:45:25 +0000
@@ -28,29 +28,19 @@
28#ifndef _COMPIZ_OPENGL_H28#ifndef _COMPIZ_OPENGL_H
29#define _COMPIZ_OPENGL_H29#define _COMPIZ_OPENGL_H
3030
31#ifdef USE_GLES31#include <opengl/opengl-api.h>
32#define SUPPORT_X11
33#include <GLES2/gl2.h>
34#include <GLES2/gl2ext.h>
35#include <EGL/egl.h>
36#include <EGL/eglext.h>
37#else
38#include <GL/gl.h>
39#include <GL/glx.h>
40#endif
4132
42#include <core/size.h>33#include <core/size.h>
43#include <core/pluginclasshandler.h>34#include <core/pluginclasshandler.h>
4435
45#include <opengl/matrix.h>36#include <opengl/matrix.h>
46#include <opengl/texture.h>37#include <opengl/texture.h>
47#include <opengl/framebufferobject.h>
48#include <opengl/vertexbuffer.h>38#include <opengl/vertexbuffer.h>
49#include <opengl/program.h>39#include <opengl/program.h>
50#include <opengl/programcache.h>40#include <opengl/programcache.h>
51#include <opengl/shadercache.h>41#include <opengl/shadercache.h>
5242
53#define COMPIZ_OPENGL_ABI 643#define COMPIZ_OPENGL_ABI 7
5444
55/*45/*
56 * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but46 * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but
@@ -84,9 +74,38 @@
84extern const float GREEN_SATURATION_WEIGHT;74extern const float GREEN_SATURATION_WEIGHT;
85extern const float BLUE_SATURATION_WEIGHT;75extern const float BLUE_SATURATION_WEIGHT;
8676
77class GLScreen;
87class PrivateGLScreen;78class PrivateGLScreen;
88class PrivateGLWindow;79class PrivateGLWindow;
8980
81namespace compiz
82{
83namespace opengl
84{
85typedef boost::function <bool (const CompRect &src,
86 const CompRect &dst,
87 GLbitfield mask,
88 GLenum filter)> BlitFramebufferFunc;
89
90class DirectDrawObject;
91class FramebufferObject;
92class BindableFramebuffer;
93
94/**
95 * Convenience method to construct a framebuffer object that
96 * supports GLX_EXT_blit_framebuffer and a fallback path
97 */
98DirectDrawObject *createBlittableFramebufferObjectWithFallback(const CompSize &sz, GLScreen *gScreen);
99
100namespace impl
101{
102class FramebufferObject;
103}
104}
105}
106
107typedef compiz::opengl::impl::FramebufferObject GLFramebufferObject;
108
90extern GLushort defaultColor[4];109extern GLushort defaultColor[4];
91110
92#ifndef GLX_EXT_texture_from_pixmap111#ifndef GLX_EXT_texture_from_pixmap
@@ -313,6 +332,18 @@
313 GLsizei width,332 GLsizei width,
314 GLsizei height);333 GLsizei height);
315334
335 /* GLX_EXT_blit_framebuffer */
336 typedef void (*GLBlitFramebufferProc) (GLint srcX0,
337 GLint srcY0,
338 GLint srcX1,
339 GLint srcY1,
340 GLint dstX0,
341 GLint dstY0,
342 GLint dstX1,
343 GLint dstY1,
344 GLbitfield mask,
345 GLenum filter);
346
316347
317 /* GL_ARB_shader_objects */348 /* GL_ARB_shader_objects */
318 #ifndef USE_GLES349 #ifndef USE_GLES
@@ -413,11 +444,12 @@
413 extern GLDisableVertexAttribArrayProc disableVertexAttribArray;444 extern GLDisableVertexAttribArrayProc disableVertexAttribArray;
414 extern GLVertexAttribPointerProc vertexAttribPointer;445 extern GLVertexAttribPointerProc vertexAttribPointer;
415446
416 extern GLGenRenderbuffersProc genRenderbuffers;447 extern GLGenRenderbuffersProc genRenderbuffers;
417 extern GLDeleteRenderbuffersProc deleteRenderbuffers;448 extern GLDeleteRenderbuffersProc deleteRenderbuffers;
418 extern GLBindRenderbufferProc bindRenderbuffer;449 extern GLBindRenderbufferProc bindRenderbuffer;
419 extern GLFramebufferRenderbufferProc framebufferRenderbuffer;450 extern GLFramebufferRenderbufferProc framebufferRenderbuffer;
420 extern GLRenderbufferStorageProc renderbufferStorage;451 extern GLRenderbufferStorageProc renderbufferStorage;
452 extern GLBlitFramebufferProc blitFramebuffer;
421453
422 #ifndef USE_GLES454 #ifndef USE_GLES
423 extern GLCreateShaderObjectARBProc createShaderObjectARB;455 extern GLCreateShaderObjectARBProc createShaderObjectARB;
@@ -579,7 +611,6 @@
579extern GLScreenPaintAttrib defaultScreenPaintAttrib;611extern GLScreenPaintAttrib defaultScreenPaintAttrib;
580612
581class GLScreen;613class GLScreen;
582class GLFramebufferObject;
583class GLScreenInterface;614class GLScreenInterface;
584extern template class WrapableInterface<GLScreen, GLScreenInterface>;615extern template class WrapableInterface<GLScreen, GLScreenInterface>;
585616
@@ -658,9 +689,9 @@
658 * @param scratchFbo Describes the final composited FBO that is689 * @param scratchFbo Describes the final composited FBO that is
659 * to be rendered.690 * to be rendered.
660 */691 */
661 virtual void glPaintCompositedOutput (const CompRegion &region,692 virtual void glPaintCompositedOutput (const CompRegion &region,
662 GLFramebufferObject *fbo,693 compiz::opengl::DirectDrawObject *fbo,
663 unsigned int mask);694 unsigned int mask);
664695
665 /**696 /**
666 * Hookable function used by plugins to determine stenciling mask697 * Hookable function used by plugins to determine stenciling mask
@@ -759,13 +790,36 @@
759 /**790 /**
760 * Returns the FBO compiz is using for the screen791 * Returns the FBO compiz is using for the screen
761 */792 */
762 GLFramebufferObject *fbo ();793 compiz::opengl::FramebufferObject * fbo ();
794
795 /**
796 * Binds a framebuffer for drawing, returns the old bindable
797 */
798 compiz::opengl::BindableFramebuffer *
799 bindFramebufferForDrawing (compiz::opengl::BindableFramebuffer *);
800
801 /**
802 * Binds a framebuffer for reading, returns the old reading
803 */
804 compiz::opengl::BindableFramebuffer *
805 bindFramebufferForReading (compiz::opengl::BindableFramebuffer *);
806
807 /**
808 * Gets the backbuffer as a BindableFramebuffer
809 */
810 compiz::opengl::BindableFramebuffer *
811 backbuffer ();
763812
764 /**813 /**
765 * Returns a default icon texture814 * Returns a default icon texture
766 */815 */
767 GLTexture *defaultIcon ();816 GLTexture *defaultIcon ();
768817
818 /**
819 * Returns the current framebuffer function for blitting the framebuffer
820 */
821 const compiz::opengl::BlitFramebufferFunc & blitFramebufferFunc ();
822
769 void resetRasterPos ();823 void resetRasterPos ();
770824
771 bool glInitContext (XVisualInfo *);825 bool glInitContext (XVisualInfo *);
@@ -786,7 +840,7 @@
786840
787 WRAPABLE_HND (5, GLScreenInterface, GLMatrix *, projectionMatrix);841 WRAPABLE_HND (5, GLScreenInterface, GLMatrix *, projectionMatrix);
788 WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput,842 WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput,
789 const CompRegion &, GLFramebufferObject *, unsigned int);843 const CompRegion &, compiz::opengl::DirectDrawObject *, unsigned int);
790844
791 WRAPABLE_HND (7, GLScreenInterface, void, glBufferStencil, const GLMatrix &,845 WRAPABLE_HND (7, GLScreenInterface, void, glBufferStencil, const GLMatrix &,
792 GLVertexBuffer &,846 GLVertexBuffer &,
793847
=== added directory 'plugins/opengl/src/fbdirectdraw'
=== added file 'plugins/opengl/src/fbdirectdraw/CMakeLists.txt'
--- plugins/opengl/src/fbdirectdraw/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/fbdirectdraw/CMakeLists.txt 2013-02-13 11:45:25 +0000
@@ -0,0 +1,32 @@
1INCLUDE_DIRECTORIES (
2 ${COMPIZ_OPENGL_PLUGIN_SOURCE_DIR}
3 ${COMPIZ_OPENGL_PLUGIN_INCLUDE_DIR}
4 ${CMAKE_CURRENT_SOURCE_DIR}/include
5 ${CMAKE_CURRENT_SOURCE_DIR}/src
6
7 ${Boost_INCLUDE_DIRS}
8)
9
10LINK_DIRECTORIES (${COMPIZ_LIBRARY_DIRS})
11
12SET(
13 SRCS
14 ${CMAKE_CURRENT_SOURCE_DIR}/src/framebuffer-direct-draw.cpp
15)
16
17ADD_LIBRARY(
18 compiz_opengl_framebuffer_direct_draw STATIC
19
20 ${SRCS}
21)
22
23if (COMPIZ_BUILD_TESTING)
24ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
25endif (COMPIZ_BUILD_TESTING)
26
27TARGET_LINK_LIBRARIES(
28 compiz_opengl_framebuffer_direct_draw
29
30 compiz_region
31 compiz_logmessage
32)
033
=== added directory 'plugins/opengl/src/fbdirectdraw/include'
=== added file 'plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h'
--- plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h 2013-02-13 11:45:25 +0000
@@ -0,0 +1,111 @@
1/*
2 * Compiz, opengl plugin, FramebufferDirectDraw class
3 *
4 * Copyright (c) 2012 Canonical Ltd.
5 * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#ifndef _COMPIZ_OPENGL_FRAMEBUFFER_DIRECT_DRAW_H
26#define _COMPIZ_OPENGL_FRAMEBUFFER_DIRECT_DRAW_H
27
28#include <memory>
29#include <boost/shared_ptr.hpp>
30#include <core/rect.h>
31#include <opengl/framebufferobject.h>
32
33class GLVertexBuffer;
34
35namespace compiz
36{
37namespace opengl
38{
39namespace impl
40{
41namespace cglfb = compiz::opengl;
42
43class PrivateDirectDrawStrategies;
44
45class DirectDrawStrategies :
46 public cglfb::DirectDrawStrategies
47{
48 public:
49
50 typedef boost::shared_ptr <DirectDrawStrategies> Ptr;
51
52 DirectDrawStrategies (const RectangularDrawList &strategies);
53
54 void draw (const CompRect &src,
55 const CompRect &dst,
56 BlitMask mask,
57 Filter filter);
58
59 private:
60
61 std::auto_ptr <PrivateDirectDrawStrategies> priv;
62};
63
64class PrivateDirectDrawObject;
65
66class DirectDrawObject :
67 virtual public cglfb::FramebufferObject,
68 public cglfb::DirectDrawObject
69{
70 public:
71
72 DirectDrawObject (const boost::shared_ptr <cglfb::DirectDrawStrategies> &,
73 const boost::shared_ptr <cglfb::FramebufferObject> &,
74 const boost::shared_ptr <cglfb::BindableFramebuffer> &);
75
76 bool allocate (const CompSize &size,
77 const char *image = NULL,
78 GLenum format = GL_RGBA,
79 GLenum type = GL_UNSIGNED_BYTE);
80 bool checkStatus ();
81 GLTexture * tex ();
82
83 void directDraw (const CompRect &src,
84 const CompRect &dst,
85 cglfb::BlitMask mask,
86 cglfb::Filter filter);
87
88 private:
89
90 GLuint getResourceId () const;
91 bool setBindStatus (GLenum);
92 void updateAllocation (GLenum);
93
94 PrivateDirectDrawObject *priv;
95};
96
97typedef boost::function <cglfb::BindableFramebuffer * (cglfb::BindableFramebuffer *)>
98 BindReadBufferFunc;
99
100bool rectangleDrawFromReadBuffer (const CompRect &src,
101 const CompRect &dst,
102 GLbitfield mask,
103 GLenum filter,
104 cglfb::BindableFramebuffer *bindable,
105 const BindReadBufferFunc &func,
106 cglfb::RectangularDraw strategy);
107}
108}
109}
110
111#endif
0112
=== added directory 'plugins/opengl/src/fbdirectdraw/src'
=== added file 'plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp'
--- plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp 2013-02-13 11:45:25 +0000
@@ -0,0 +1,177 @@
1/*
2 * Compiz, opengl plugin, DirectDrawFramebufferStrategies class
3 *
4 * Copyright (c) 2012 Canonical Ltd.
5 * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#include "framebuffer-direct-draw.h"
26
27namespace cglfb = compiz::opengl;
28namespace cglfbi = compiz::opengl::impl;
29
30class GLTexture;
31class GLVertexBuffer;
32
33namespace compiz
34{
35namespace opengl
36{
37namespace impl
38{
39class PrivateDirectDrawStrategies
40{
41 public:
42
43 PrivateDirectDrawStrategies (const cglfb::RectangularDrawList &strategies) :
44 rectDrawList (strategies)
45 {
46 }
47
48 cglfb::RectangularDrawList rectDrawList;
49};
50
51class PrivateDirectDrawObject
52{
53 public:
54
55 PrivateDirectDrawObject (const boost::shared_ptr <cglfb::DirectDrawStrategies> &strategies,
56 const boost::shared_ptr <cglfb::FramebufferObject> &object,
57 const boost::shared_ptr <cglfb::BindableFramebuffer> &bindable) :
58 directDrawStrategies (strategies),
59 framebufferObject (object),
60 bindableFramebuffer (bindable)
61 {
62 };
63
64 boost::shared_ptr <cglfb::DirectDrawStrategies> directDrawStrategies;
65 boost::shared_ptr <cglfb::FramebufferObject> framebufferObject;
66 boost::shared_ptr <cglfb::BindableFramebuffer> bindableFramebuffer;
67};
68}
69}
70}
71
72cglfbi::DirectDrawObject::DirectDrawObject (const boost::shared_ptr <cglfb::DirectDrawStrategies> &strategies,
73 const boost::shared_ptr <cglfb::FramebufferObject> &object,
74 const boost::shared_ptr <cglfb::BindableFramebuffer> &bindable) :
75 priv (new cglfbi::PrivateDirectDrawObject (strategies, object, bindable))
76{
77}
78
79bool
80cglfbi::DirectDrawObject::allocate (const CompSize &size, const char *image,
81 GLenum format, GLenum type)
82{
83 return priv->framebufferObject->allocate (size, image, format, type);
84}
85
86bool
87cglfbi::DirectDrawObject::checkStatus ()
88{
89 return priv->framebufferObject->checkStatus ();
90}
91
92GLTexture *
93cglfbi::DirectDrawObject::tex ()
94{
95 return priv->framebufferObject->tex ();
96}
97
98GLuint
99cglfbi::DirectDrawObject::getResourceId () const
100{
101 return priv->bindableFramebuffer->getResourceId ();
102}
103
104bool
105cglfbi::DirectDrawObject::setBindStatus (GLenum status)
106{
107 return priv->bindableFramebuffer->setBindStatus (status);
108}
109
110void
111cglfbi::DirectDrawObject::updateAllocation (GLenum bindPoint)
112{
113 return priv->bindableFramebuffer->updateAllocation (bindPoint);
114}
115
116void
117cglfbi::DirectDrawObject::directDraw (const CompRect &src,
118 const CompRect &dst,
119 cglfb::BlitMask mask,
120 cglfb::Filter filter)
121{
122 if (!checkStatus ())
123 return;
124
125 priv->directDrawStrategies->draw (src, dst, mask, filter);
126}
127
128bool
129cglfbi::rectangleDrawFromReadBuffer (const CompRect &src,
130 const CompRect &dst,
131 GLbitfield mask,
132 GLenum filter,
133 cglfb::BindableFramebuffer *bindable,
134 const cglfbi::BindReadBufferFunc &bindReadBuffer,
135 cglfb::RectangularDraw strategy)
136{
137 bool status = false;
138 /* Bind to the read framebuffer first */
139 cglfb::BindableFramebuffer *old = bindReadBuffer (bindable);
140
141 if (old)
142 status = strategy (src, dst, mask, filter);
143
144 /* Intentionally not rebinding the old one */
145
146 return status;
147}
148
149cglfbi::DirectDrawStrategies::DirectDrawStrategies (const cglfb::RectangularDrawList &strategies) :
150 priv (new cglfbi::PrivateDirectDrawStrategies (strategies))
151{
152}
153
154void
155cglfbi::DirectDrawStrategies::draw (const CompRect &src,
156 const CompRect &dst,
157 cglfb::BlitMask mask,
158 cglfb::Filter filter)
159{
160 if (!mask)
161 return;
162
163 const GLbitfield glMask = (mask & cglfb::ColorData ? GL_COLOR_BUFFER_BIT : 0) |
164 (mask & cglfb::StencilData ? GL_STENCIL_BUFFER_BIT : 0);
165 const GLenum glFilter = (filter == cglfb::Fast ? GL_NEAREST : GL_LINEAR);
166
167 while (!priv->rectDrawList.empty ())
168 {
169 const cglfb::RectangularDraw &strategy = priv->rectDrawList.back ();
170
171 /* If one method fails, try the next */
172 if (!strategy (src, dst, glMask, glFilter))
173 priv->rectDrawList.pop_back ();
174 else
175 break;
176 }
177}
0178
=== added directory 'plugins/opengl/src/fbdirectdraw/tests'
=== added file 'plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt'
--- plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt 2013-02-13 11:45:25 +0000
@@ -0,0 +1,24 @@
1find_library (GMOCK_LIBRARY gmock)
2find_library (GMOCK_MAIN_LIBRARY gmock_main)
3
4if (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
5 message ("Google Mock and Google Test not found - cannot build tests!")
6 set (COMPIZ_BUILD_TESTING OFF)
7endif (NOT GMOCK_LIBRARY OR NOT GMOCK_MAIN_LIBRARY OR NOT GTEST_FOUND)
8
9include_directories (${GTEST_INCLUDE_DIRS})
10
11link_directories (${COMPIZ_LIBRARY_DIRS})
12
13add_executable (compiz_test_opengl_framebuffer_direct_draw
14 ${CMAKE_CURRENT_SOURCE_DIR}/test-opengl-framebuffer-direct-draw.cpp)
15
16target_link_libraries (compiz_test_opengl_framebuffer_direct_draw
17 compiz_opengl_framebuffer_direct_draw
18 ${GTEST_BOTH_LIBRARIES}
19 ${GMOCK_LIBRARY}
20 ${GMOCK_MAIN_LIBRARY}
21 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
22 )
23
24compiz_discover_tests (compiz_test_opengl_framebuffer_direct_draw COVERAGE compiz_opengl_framebuffer_direct_draw)
025
=== added file 'plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp'
--- plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp 1970-01-01 00:00:00 +0000
+++ plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp 2013-02-13 11:45:25 +0000
@@ -0,0 +1,236 @@
1/*
2 * Compiz, opengl plugin, DirectDrawFramebufferStrategies class
3 *
4 * Copyright (c) 2012 Canonical Ltd.
5 * Authors: Sam Spilsbury <sam.spilsbury@canonical.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25#include <memory>
26#include <boost/function.hpp>
27#include <boost/bind.hpp>
28#include <gtest/gtest.h>
29#include <gmock/gmock.h>
30#include <opengl/opengl-api.h>
31#include <opengl/framebufferobject.h>
32#include "framebuffer-direct-draw.h"
33
34using ::testing::Return;
35using ::testing::_;
36using ::testing::Expectation;
37using ::testing::StrictMock;
38using ::testing::NiceMock;
39using ::testing::ReturnNull;
40
41namespace cglfb = compiz::opengl;
42namespace cglfbi = compiz::opengl::impl;
43
44namespace
45{
46class MockDrawStrategy
47{
48 public:
49
50 MOCK_METHOD4 (draw, bool (const CompRect &,
51 const CompRect &,
52 GLbitfield,
53 GLenum));
54};
55
56class MockBindLocation :
57 public cglfb::BindLocation
58{
59 public:
60
61 MOCK_METHOD1 (bind, cglfb::BindableFramebuffer * (cglfb::BindableFramebuffer *));
62};
63
64class MockBindable :
65 public cglfb::BindableFramebuffer
66{
67 public:
68
69 MOCK_METHOD1 (updateAllocation, void (GLenum));
70 MOCK_METHOD1 (setBindStatus, bool (GLenum));
71 MOCK_CONST_METHOD0 (getResourceId, GLuint ());
72};
73
74}
75
76class FBDirectDrawStrategies :
77 public ::testing::Test
78{
79 public:
80
81 FBDirectDrawStrategies () :
82 blitFramebuffer (boost::bind (&MockDrawStrategy::draw, &mpfb, _1, _2, _3, _4)),
83 rtdraw (boost::bind (&MockDrawStrategy::draw, &mdr,
84 _1, _2, _3, _4))
85 {
86 }
87
88 void SetUpStrategyList (const cglfb::RectangularDraw &blit,
89 const cglfb::RectangularDraw &draw)
90 {
91 strategyList.clear ();
92 strategyList.push_back (draw);
93 strategyList.push_back (blit);
94 }
95
96 virtual void SetUp ()
97 {
98 boost::function <cglfb::BindableFramebuffer * (cglfb::BindableFramebuffer *)> readBind
99 (boost::bind (&MockBindLocation::bind, &mockBindLocation, _1));
100 blitFramebufferWithReadPushed = boost::bind (&cglfbi::rectangleDrawFromReadBuffer,
101 _1, _2, _3, _4,
102 &mockBindable,
103 readBind,
104 blitFramebuffer);
105
106 SetUpStrategyList (blitFramebuffer, rtdraw);
107 directDraw.reset (new cglfbi::DirectDrawStrategies (strategyList));
108 }
109
110 std::auto_ptr <cglfbi::DirectDrawStrategies> directDraw;
111 MockDrawStrategy mpfb;
112 cglfb::RectangularDraw blitFramebuffer;
113 cglfb::RectangularDraw blitFramebufferWithReadPushed;
114 MockDrawStrategy mdr;
115 StrictMock <MockBindable> mockBindable;
116 StrictMock <MockBindLocation> mockBindLocation;
117 cglfb::RectangularDraw rtdraw;
118 cglfb::RectangularDrawList strategyList;
119
120};
121
122TEST_F (FBDirectDrawStrategies, BufferBitsSet)
123{
124 CompRect srcAndDst (0, 0, 0, 0);
125
126 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, GL_COLOR_BUFFER_BIT |
127 GL_STENCIL_BUFFER_BIT,
128 _)).WillOnce (Return (true));
129
130 directDraw->draw (srcAndDst,
131 srcAndDst,
132 static_cast <cglfb::BlitMask> (cglfb::ColorData |
133 cglfb::StencilData),
134 cglfb::Good);
135}
136
137TEST_F (FBDirectDrawStrategies, BufferNoBitsSet)
138{
139 CompRect srcAndDst (0, 0, 0, 0);
140
141 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, 0,
142 _)).Times (0);
143
144 directDraw->draw (srcAndDst,
145 srcAndDst,
146 static_cast <cglfb::BlitMask> (0),
147 cglfb::Good);
148}
149
150TEST_F (FBDirectDrawStrategies, GoodToLinear)
151{
152 CompRect srcAndDst (0, 0, 0, 0);
153
154 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _,
155 GL_LINEAR)).WillOnce (Return (true));
156
157 directDraw->draw (srcAndDst,
158 srcAndDst,
159 cglfb::ColorData,
160 cglfb::Good);
161}
162
163TEST_F (FBDirectDrawStrategies, FastToNearest)
164{
165 CompRect srcAndDst (0, 0, 0, 0);
166
167 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _,
168 GL_NEAREST)).WillOnce (Return (true));
169
170 directDraw->draw (srcAndDst,
171 srcAndDst,
172 cglfb::ColorData,
173 cglfb::Fast);
174}
175
176TEST_F (FBDirectDrawStrategies, RevertToPaintWhenBlitUnavailable)
177{
178 CompRect srcAndDst (0, 0, 0, 0);
179
180 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _,
181 _)).WillOnce (Return (false));
182 EXPECT_CALL (mdr, draw (srcAndDst, srcAndDst, _, _));
183
184 directDraw->draw (srcAndDst,
185 srcAndDst,
186 cglfb::ColorData,
187 cglfb::Fast);
188}
189
190TEST_F (FBDirectDrawStrategies, RevertOnBlitUnavailablePermanent)
191{
192 StrictMock <MockDrawStrategy> strictMdr;
193 CompRect srcAndDst (0, 0, 0, 0);
194
195 rtdraw = boost::bind (&MockDrawStrategy::draw, &strictMdr, _1, _2, _3, _4);
196
197 SetUpStrategyList (blitFramebuffer, rtdraw);
198 directDraw.reset (new cglfbi::DirectDrawStrategies (strategyList));
199
200 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, _)).WillOnce (Return (false));
201 ON_CALL (strictMdr, draw (_, _, _, _)).WillByDefault (Return (true));
202 EXPECT_CALL (strictMdr, draw (srcAndDst, srcAndDst, _, _)).Times (2);
203
204 directDraw->draw (srcAndDst,
205 srcAndDst,
206 cglfb::ColorData,
207 cglfb::Fast);
208 directDraw->draw (srcAndDst,
209 srcAndDst,
210 cglfb::ColorData,
211 cglfb::Fast);
212}
213
214TEST_F (FBDirectDrawStrategies, BindReadFramebufferOnBlit)
215{
216 CompRect srcAndDst (0, 0, 0, 0);
217
218 SetUpStrategyList (blitFramebufferWithReadPushed, rtdraw);
219 directDraw.reset (new cglfbi::DirectDrawStrategies (strategyList));
220
221 MockBindable backBuffer;
222
223 EXPECT_CALL (mockBindLocation, bind (&mockBindable)).WillOnce (Return (&backBuffer));
224 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, _)).WillOnce (Return (false));
225 ON_CALL (mdr, draw (_, _, _, _)).WillByDefault (Return (true));
226 EXPECT_CALL (mdr, draw (srcAndDst, srcAndDst, _, _)).Times (2);
227
228 directDraw->draw (srcAndDst,
229 srcAndDst,
230 cglfb::ColorData,
231 cglfb::Fast);
232 directDraw->draw (srcAndDst,
233 srcAndDst,
234 cglfb::ColorData,
235 cglfb::Fast);
236}
0237
=== modified file 'plugins/opengl/src/framebufferobject.cpp'
--- plugins/opengl/src/framebufferobject.cpp 2012-08-06 09:44:49 +0000
+++ plugins/opengl/src/framebufferobject.cpp 2013-02-13 11:45:25 +0000
@@ -22,88 +22,96 @@
22 *22 *
23 * Authors: Pekka Paalanen <ppaalanen@gmail.com>23 * Authors: Pekka Paalanen <ppaalanen@gmail.com>
24 */24 */
2525#include <memory>
26#include <map>26#include <map>
27#include <opengl/opengl.h>
27#include <opengl/framebufferobject.h>28#include <opengl/framebufferobject.h>
28#include <opengl/texture.h>29#include <opengl/texture.h>
2930
31#include "framebuffer-direct-draw.h"
32
33namespace cglfb = compiz::opengl;
34namespace cglfbi = compiz::opengl::impl;
35
36namespace compiz
37{
38namespace opengl
39{
40namespace impl
41{
30struct PrivateGLFramebufferObject42struct PrivateGLFramebufferObject
31{43{
32 PrivateGLFramebufferObject () :44 PrivateGLFramebufferObject () :
33 fboId (0),45 fboId (0),
34 pushedId (0),
35 glTex (NULL),46 glTex (NULL),
36 status (-1)47 status (-1)
37 {48 {
38 }49 }
3950
40 void pushFBO ();
41 void popFBO ();
42
43 GLuint fboId;51 GLuint fboId;
44 GLuint pushedId;
45 GLuint rbStencilId;52 GLuint rbStencilId;
46 GLTexture *glTex;53 GLTexture *glTex;
4754
48 GLint status;55 GLint status;
4956
50 static GLuint boundId;57 std::auto_ptr <cglfb::DirectDrawStrategies> mDirectDraw;
51 static std::map<GLuint, GLFramebufferObject *> idMap;58 GLVertexBuffer *vertexBuffer;
52};59};
5360
54GLuint PrivateGLFramebufferObject::boundId = 0;61}
55std::map<GLuint, GLFramebufferObject *> PrivateGLFramebufferObject::idMap;62}
5663}
57void64
58PrivateGLFramebufferObject::pushFBO ()65GLuint
59{66cglfbi::FramebufferObject::getResourceId () const
60 pushedId = boundId;67{
61 if (boundId != fboId)68 return priv->fboId;
62 {69}
63 (*GL::bindFramebuffer) (GL::FRAMEBUFFER, fboId);70
64 boundId = fboId;71bool
65 }72cglfbi::FramebufferObject::setBindStatus (GLenum status)
66}73{
6774 priv->status = status;
68void75 return checkStatus ();
69PrivateGLFramebufferObject::popFBO ()76}
70{77
71 if (boundId != pushedId)78void
72 {79cglfbi::FramebufferObject::updateAllocation (GLenum bindingLocation)
73 (*GL::bindFramebuffer) (GL::FRAMEBUFFER, pushedId);80{
74 boundId = pushedId;81 if (priv->status == -1)
75 }82 {
76}83 (*GL::framebufferTexture2D) (bindingLocation, GL::COLOR_ATTACHMENT0,
7784 priv->glTex->target (),
78GLFramebufferObject::GLFramebufferObject () :85 priv->glTex->name (), 0);
79 priv (new PrivateGLFramebufferObject)86 (*GL::framebufferRenderbuffer) (bindingLocation, GL::DEPTH_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId);
87 (*GL::framebufferRenderbuffer) (bindingLocation, GL::STENCIL_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId);
88 }
89
90}
91
92cglfbi::FramebufferObject::FramebufferObject () :
93 priv (new cglfbi::PrivateGLFramebufferObject ())
80{94{
81 (*GL::genFramebuffers) (1, &priv->fboId);95 (*GL::genFramebuffers) (1, &priv->fboId);
82 (*GL::genRenderbuffers) (1, &priv->rbStencilId);96 (*GL::genRenderbuffers) (1, &priv->rbStencilId);
83
84 if (priv->fboId != 0)
85 PrivateGLFramebufferObject::idMap[priv->fboId] = this;
86}97}
8798
88GLFramebufferObject::~GLFramebufferObject ()99cglfbi::FramebufferObject::~FramebufferObject ()
89{100{
90 if (priv->glTex)101 if (priv->glTex)
91 GLTexture::decRef (priv->glTex);102 GLTexture::decRef (priv->glTex);
92103
93 PrivateGLFramebufferObject::idMap.erase (priv->fboId);
94 (*GL::deleteFramebuffers) (1, &priv->fboId);104 (*GL::deleteFramebuffers) (1, &priv->fboId);
95 (*GL::deleteRenderbuffers) (1, &priv->rbStencilId);105 (*GL::deleteRenderbuffers) (1, &priv->rbStencilId);
96106
97
98 delete priv;107 delete priv;
99}108}
100109
101bool110bool
102GLFramebufferObject::allocate (const CompSize &size, const char *image,111cglfbi::FramebufferObject::allocate (const CompSize &size,
103 GLenum format, GLenum type)112 const char *image,
113 GLenum format, GLenum type)
104{114{
105 priv->status = -1;
106
107 if (!priv->glTex ||115 if (!priv->glTex ||
108 size.width () != priv->glTex->width () ||116 size.width () != priv->glTex->width () ||
109 size.height () != priv->glTex->height ())117 size.height () != priv->glTex->height ())
@@ -125,86 +133,39 @@
125 (*GL::bindRenderbuffer) (GL::RENDERBUFFER, priv->rbStencilId);133 (*GL::bindRenderbuffer) (GL::RENDERBUFFER, priv->rbStencilId);
126 (*GL::renderbufferStorage) (GL::RENDERBUFFER, GL::DEPTH24_STENCIL8, size.width (), size.height ());134 (*GL::renderbufferStorage) (GL::RENDERBUFFER, GL::DEPTH24_STENCIL8, size.width (), size.height ());
127 }135 }
136
137 priv->status = -1;
128 }138 }
129139
130 priv->pushFBO ();
131
132 (*GL::framebufferTexture2D) (GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0,
133 priv->glTex->target (),
134 priv->glTex->name (), 0);
135
136 priv->status = (*GL::checkFramebufferStatus) (GL::DRAW_FRAMEBUFFER);
137
138 priv->popFBO ();
139 return true;140 return true;
140}141}
141142
142GLFramebufferObject *143namespace
143GLFramebufferObject::bind ()144{
144{145const char *
145 GLFramebufferObject *old = NULL;
146
147 if (priv->boundId != 0)
148 {
149 std::map<GLuint, GLFramebufferObject *>::iterator it;
150 it = PrivateGLFramebufferObject::idMap.find (priv->boundId);
151
152 if (it != PrivateGLFramebufferObject::idMap.end ())
153 old = it->second;
154 else
155 compLogMessage ("opengl", CompLogLevelError,
156 "An FBO without GLFramebufferObject cannot be restored");
157 }
158
159 (*GL::bindFramebuffer) (GL::FRAMEBUFFER, priv->fboId);
160 priv->boundId = priv->fboId;
161
162 (*GL::framebufferRenderbuffer) (GL::FRAMEBUFFER, GL::DEPTH_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId);
163 (*GL::framebufferRenderbuffer) (GL::FRAMEBUFFER, GL::STENCIL_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId);
164
165 return old;
166}
167
168// static
169void
170GLFramebufferObject::rebind (GLFramebufferObject *fbo)
171{
172 GLuint id = fbo ? fbo->priv->fboId : 0;
173
174 if (id != fbo->priv->boundId)
175 {
176 (*GL::bindFramebuffer) (GL::FRAMEBUFFER, id);
177 fbo->priv->boundId = id;
178 }
179}
180
181static const char *
182getFboErrorString (GLint status)146getFboErrorString (GLint status)
183{147{
184 switch (status)148 switch (status)
185 {149 {
186 case GL::FRAMEBUFFER_COMPLETE:150 case GL::FRAMEBUFFER_COMPLETE:
187 return "GL::FRAMEBUFFER_COMPLETE";151 return "GL::FRAMEBUFFER_COMPLETE";
188 case GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT:152 case GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
189 return "GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT";153 return "GL::FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
190 case GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:154 case GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
191 return "GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";155 return "GL::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
192 case GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS:156 case GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
193 return "GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS";157 return "GL::FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
194 case GL::FRAMEBUFFER_UNSUPPORTED:158 case GL::FRAMEBUFFER_UNSUPPORTED:
195 return "GL::FRAMEBUFFER_UNSUPPORTED";159 return "GL::FRAMEBUFFER_UNSUPPORTED";
196 default:160 default:
197 return "unexpected status";161 return "unexpected status";
198 }162 }
199}163}
164}
200165
201bool166bool
202GLFramebufferObject::checkStatus ()167cglfbi::FramebufferObject::checkStatus ()
203{168{
204 priv->pushFBO ();
205 priv-> status = (*GL::checkFramebufferStatus) (GL_FRAMEBUFFER);
206 priv->popFBO ();
207
208 if (priv->status == static_cast <GLint> (GL::FRAMEBUFFER_COMPLETE))169 if (priv->status == static_cast <GLint> (GL::FRAMEBUFFER_COMPLETE))
209 return true;170 return true;
210171
@@ -215,7 +176,47 @@
215}176}
216177
217GLTexture *178GLTexture *
218GLFramebufferObject::tex ()179cglfbi::FramebufferObject::tex ()
219{180{
220 return priv->glTex;181 return priv->glTex;
221}182}
183
184class cglfbi::FBOBindLocation::Private
185{
186 public:
187
188 Private (GLenum binding,
189 cglfb::BindableFramebuffer *back) :
190 mCurrentlyBound (back),
191 mBindPoint (binding)
192 {
193 }
194
195 cglfb::BindableFramebuffer *mCurrentlyBound;
196 GLenum mBindPoint;
197};
198
199cglfbi::FBOBindLocation::FBOBindLocation (GLenum binding,
200 cglfb::BindableFramebuffer *back) :
201 priv (new cglfbi::FBOBindLocation::Private (binding, back))
202{
203}
204
205cglfb::BindableFramebuffer *
206cglfbi::FBOBindLocation::bind (cglfb::BindableFramebuffer *next)
207{
208 if (priv->mCurrentlyBound == next)
209 return next;
210
211 (*GL::bindFramebuffer) (priv->mBindPoint, next->getResourceId ());
212 next->updateAllocation (priv->mBindPoint);
213 if (!next->setBindStatus ((*GL::checkFramebufferStatus) (priv->mBindPoint)))
214 {
215 (*GL::bindFramebuffer) (priv->mBindPoint, priv->mCurrentlyBound->getResourceId ());
216 return NULL;
217 }
218
219 cglfb::BindableFramebuffer *last = priv->mCurrentlyBound;
220 priv->mCurrentlyBound = next;
221 return last;
222}
222223
=== modified file 'plugins/opengl/src/paint.cpp'
--- plugins/opengl/src/paint.cpp 2013-01-01 10:04:50 +0000
+++ plugins/opengl/src/paint.cpp 2013-02-13 11:45:25 +0000
@@ -44,6 +44,7 @@
44#define DEG2RAD (M_PI / 180.0f)44#define DEG2RAD (M_PI / 180.0f)
4545
46using namespace compiz::opengl;46using namespace compiz::opengl;
47namespace cglfb = compiz::opengl;
4748
48GLScreenPaintAttrib defaultScreenPaintAttrib = {49GLScreenPaintAttrib defaultScreenPaintAttrib = {
49 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA50 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA
@@ -669,89 +670,16 @@
669}670}
670671
671void672void
672GLScreen::glPaintCompositedOutput (const CompRegion &region,673GLScreen::glPaintCompositedOutput (const CompRegion &region,
673 GLFramebufferObject *fbo,674 compiz::opengl::DirectDrawObject *fbo,
674 unsigned int mask)675 unsigned int mask)
675{676{
676 WRAPABLE_HND_FUNCTN (glPaintCompositedOutput, region, fbo, mask)677 WRAPABLE_HND_FUNCTN (glPaintCompositedOutput, region, fbo, mask)
677678
678 GLMatrix sTransform;679 /* Draw every rect individually, this could be a little slow
679 const GLTexture::Matrix & texmatrix = fbo->tex ()->matrix ();680 * for lots of rects, but the general usecase isn't that */
680 GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();681 foreach (const CompRect &r, region.rects ())
681682 fbo->directDraw (r, r, cglfb::ColorData, cglfb::Fast);
682 streamingBuffer->begin (GL_TRIANGLES);
683
684 if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
685 {
686 GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, 0.0f);
687 GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, screen->width ());
688 GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, 0.0f);
689 GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, screen->height ());
690
691 const GLfloat vertexData[] = {
692 0.0f, 0.0f, 0.0f,
693 0.0f, (float)screen->height (), 0.0f,
694 (float)screen->width (), 0.0f, 0.0f,
695
696 0.0f, (float)screen->height (), 0.0f,
697 (float)screen->width (), (float)screen->height (), 0.0f,
698 (float)screen->width (), 0.0f, 0.0f,
699 };
700
701 const GLfloat textureData[] = {
702 tx1, ty1,
703 tx1, ty2,
704 tx2, ty1,
705 tx1, ty2,
706 tx2, ty2,
707 tx2, ty1,
708 };
709
710 streamingBuffer->addVertices (6, &vertexData[0]);
711 streamingBuffer->addTexCoords (0, 6, &textureData[0]);
712 }
713 else
714 {
715 BoxPtr pBox = const_cast <Region> (region.handle ())->rects;
716 int nBox = const_cast <Region> (region.handle ())->numRects;
717
718 while (nBox--)
719 {
720 GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, pBox->x1);
721 GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, pBox->x2);
722 GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y1);
723 GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y2);
724
725 const GLfloat vertexData[] = {
726 (float)pBox->x1, (float)pBox->y1, 0.0f,
727 (float)pBox->x1, (float)pBox->y2, 0.0f,
728 (float)pBox->x2, (float)pBox->y1, 0.0f,
729
730 (float)pBox->x1, (float)pBox->y2, 0.0f,
731 (float)pBox->x2, (float)pBox->y2, 0.0f,
732 (float)pBox->x2, (float)pBox->y1, 0.0f,
733 };
734
735 const GLfloat textureData[] = {
736 tx1, ty1,
737 tx1, ty2,
738 tx2, ty1,
739 tx1, ty2,
740 tx2, ty2,
741 tx2, ty1,
742 };
743
744 streamingBuffer->addVertices (6, &vertexData[0]);
745 streamingBuffer->addTexCoords (0, 6, &textureData[0]);
746 pBox++;
747 }
748 }
749
750 streamingBuffer->end ();
751 fbo->tex ()->enable (GLTexture::Fast);
752 sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
753 streamingBuffer->render (sTransform);
754 fbo->tex ()->disable ();
755}683}
756684
757static void685static void
758686
=== modified file 'plugins/opengl/src/privates.h'
--- plugins/opengl/src/privates.h 2013-01-01 09:41:41 +0000
+++ plugins/opengl/src/privates.h 2013-02-13 11:45:25 +0000
@@ -29,21 +29,27 @@
29#define _OPENGL_PRIVATES_H29#define _OPENGL_PRIVATES_H
3030
31#include <memory>31#include <memory>
32
33#include <composite/composite.h>32#include <composite/composite.h>
34#include <opengl/opengl.h>33#include <opengl/opengl.h>
35#include <core/atoms.h>34#include <core/atoms.h>
36
37#ifdef USE_GLES
38#include <opengl/framebufferobject.h>35#include <opengl/framebufferobject.h>
39#endif
40
41#include <opengl/doublebuffer.h>36#include <opengl/doublebuffer.h>
4237
43#include "privatetexture.h"38#include "privatetexture.h"
44#include "privatevertexbuffer.h"39#include "privatevertexbuffer.h"
45#include "opengl_options.h"40#include "opengl_options.h"
4641
42namespace compiz
43{
44 namespace opengl
45 {
46 namespace impl
47 {
48 class DirectDrawObject;
49 }
50 }
51}
52
47extern CompOutput *targetOutput;53extern CompOutput *targetOutput;
4854
49class GLDoubleBuffer :55class GLDoubleBuffer :
@@ -85,6 +91,17 @@
85 Window mOutput;91 Window mOutput;
86};92};
8793
94namespace compiz
95{
96 namespace opengl
97 {
98 bool blitFramebufferGLX (const CompRect &src,
99 const CompRect &dst,
100 GLbitfield mask,
101 GLenum filter);
102 }
103}
104
88#else105#else
89106
90class EGLDoubleBuffer :107class EGLDoubleBuffer :
@@ -108,6 +125,17 @@
108 EGLSurface const & mSurface;125 EGLSurface const & mSurface;
109};126};
110127
128namespace compiz
129{
130 namespace opengl
131 {
132 bool blitFramebufferEGL (const CompRect &src,
133 const CompRect &dst,
134 GLbitfield mask,
135 GLenum filter);
136 }
137}
138
111#endif139#endif
112140
113class GLIcon141class GLIcon
@@ -119,6 +147,16 @@
119 GLTexture::List textures;147 GLTexture::List textures;
120};148};
121149
150class BindableBackbuffer :
151 public compiz::opengl::BindableFramebuffer
152{
153 public:
154
155 GLuint getResourceId () const;
156 bool setBindStatus (GLenum);
157 void updateAllocation (GLenum);
158};
159
122class PrivateGLScreen :160class PrivateGLScreen :
123 public ScreenInterface,161 public ScreenInterface,
124 public compiz::composite::PaintHandler,162 public compiz::composite::PaintHandler,
@@ -196,8 +234,9 @@
196 GLXDoubleBuffer doubleBuffer;234 GLXDoubleBuffer doubleBuffer;
197 #endif235 #endif
198236
199 GLFramebufferObject *scratchFbo;237 std::auto_ptr <compiz::opengl::DirectDrawObject> scratchFbo;
200 CompRegion outputRegion;238 compiz::opengl::BlitFramebufferFunc blitFramebuffer;
239 CompRegion outputRegion;
201240
202 XRectangle lastViewport;241 XRectangle lastViewport;
203 bool refreshSubBuffer;242 bool refreshSubBuffer;
@@ -221,6 +260,9 @@
221 Pixmap rootPixmapCopy;260 Pixmap rootPixmapCopy;
222 CompSize rootPixmapSize;261 CompSize rootPixmapSize;
223262
263 BindableBackbuffer backbuffer;
264 compiz::opengl::impl::FBOBindLocation drawFramebufferBinding;
265 compiz::opengl::impl::FBOBindLocation readFramebufferBinding;
224 const char *glVendor, *glRenderer, *glVersion;266 const char *glVendor, *glRenderer, *glVersion;
225267
226 mutable CompString prevRegex;268 mutable CompString prevRegex;
227269
=== modified file 'plugins/opengl/src/screen.cpp'
--- plugins/opengl/src/screen.cpp 2013-01-09 10:57:03 +0000
+++ plugins/opengl/src/screen.cpp 2013-02-13 11:45:25 +0000
@@ -36,6 +36,7 @@
36#include <boost/make_shared.hpp>36#include <boost/make_shared.hpp>
3737
38#include "privates.h"38#include "privates.h"
39#include "framebuffer-direct-draw.h"
39#include "blacklist/blacklist.h"40#include "blacklist/blacklist.h"
4041
41#include <dlfcn.h>42#include <dlfcn.h>
@@ -67,6 +68,26 @@
6768
6869
69using namespace compiz::opengl;70using namespace compiz::opengl;
71namespace cglfb = compiz::opengl;
72namespace cgli = compiz::opengl::impl;
73
74namespace compiz
75{
76 namespace opengl
77 {
78#ifndef USE_GLES
79 bool blitFramebufferGLX (const CompRect &src,
80 const CompRect &dst,
81 GLbitfield mask,
82 GLenum filter);
83#else
84 bool blitFramebufferEGL (const CompRect &src,
85 const CompRect &dst,
86 GLbitfield mask,
87 GLenum filter);
88#endif
89 }
90}
7091
71namespace GL {92namespace GL {
72 #ifdef USE_GLES93 #ifdef USE_GLES
@@ -164,11 +185,12 @@
164 GLDisableVertexAttribArrayProc disableVertexAttribArray = NULL;185 GLDisableVertexAttribArrayProc disableVertexAttribArray = NULL;
165 GLVertexAttribPointerProc vertexAttribPointer = NULL;186 GLVertexAttribPointerProc vertexAttribPointer = NULL;
166187
167 GLGenRenderbuffersProc genRenderbuffers = NULL;188 GLGenRenderbuffersProc genRenderbuffers = NULL;
168 GLDeleteRenderbuffersProc deleteRenderbuffers = NULL;189 GLDeleteRenderbuffersProc deleteRenderbuffers = NULL;
169 GLFramebufferRenderbufferProc framebufferRenderbuffer = NULL;190 GLFramebufferRenderbufferProc framebufferRenderbuffer = NULL;
170 GLBindRenderbufferProc bindRenderbuffer = NULL;191 GLBindRenderbufferProc bindRenderbuffer = NULL;
171 GLRenderbufferStorageProc renderbufferStorage = NULL;192 GLRenderbufferStorageProc renderbufferStorage = NULL;
193 GLBlitFramebufferProc blitFramebuffer = NULL;
172194
173 bool textureFromPixmap = true;195 bool textureFromPixmap = true;
174 bool textureRectangle = false;196 bool textureRectangle = false;
@@ -299,6 +321,115 @@
299 GLScreen *gScreen;321 GLScreen *gScreen;
300};322};
301323
324namespace
325{
326bool defaultRectangularFramebufferDraw (GLVertexBuffer *vertexBuffer,
327 GLFramebufferObject *fbo,
328 const CompRect &src,
329 const CompRect &dst,
330 GLbitfield mask,
331 GLenum filter)
332{
333 GLTexture *texture = fbo->tex ();
334 GLMatrix sTransform;
335 const GLTexture::Matrix & texmatrix = texture->matrix ();
336 const GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, src.x1 ());
337 const GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, src.x2 ());
338 const GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, src.y1 ());
339 const GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, src.y2 ());
340
341 const GLfloat vx1 = src.x1 ();
342 const GLfloat vx2 = src.x2 ();
343 const GLfloat vy1 = src.y1 ();
344 const GLfloat vy2 = src.y2 ();
345
346 const GLTexture::Filter texFilter =
347 (filter == GL_LINEAR) ? GLTexture::Good :
348 GLTexture::Fast;
349
350 GLfloat vertexData[] = {
351 vx1, vy1, 0.0f,
352 vx1, vy2, 0.0f,
353 vx2, vy1, 0.0f,
354
355 vx1, vy2, 0.0f,
356 vx2, vy2, 0.0f,
357 vx2, vy1, 0.0f,
358 };
359
360 GLfloat textureData[] = {
361 tx1, ty1,
362 tx1, ty2,
363 tx2, ty1,
364 tx1, ty2,
365 tx2, ty2,
366 tx2, ty1,
367 };
368
369 vertexBuffer->begin (GL_TRIANGLES);
370 vertexBuffer->addVertices (6, vertexData);
371 vertexBuffer->addTexCoords (0, 6, textureData);
372
373 if (vertexBuffer->end ())
374 {
375 texture->enable (texFilter);
376 sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
377 vertexBuffer->render (sTransform);
378 texture->disable ();
379 }
380
381 return true;
382}
383
384void initDirectDraw (cgli::DirectDrawStrategies::Ptr &directDraw,
385 const compiz::opengl::RectangularDraw &blitFramebuffer,
386 const compiz::opengl::RectangularDraw &rectangularTextureDraw,
387 const cgli::BindReadBufferFunc &func,
388 compiz::opengl::BindableFramebuffer *bindable)
389{
390 cglfb::RectangularDraw blitFramebufferBound (
391 boost::bind (
392 cgli::rectangleDrawFromReadBuffer,
393 _1, _2, _3, _4,
394 bindable,
395 func,
396 blitFramebuffer));
397
398 /* Tries each of these from back to front */
399 cglfb::RectangularDrawList strategies;
400
401 strategies.push_back (rectangularTextureDraw);
402 strategies.push_back (blitFramebufferBound);
403 directDraw.reset (new cgli::DirectDrawStrategies (strategies));
404}
405}
406
407namespace compiz
408{
409namespace opengl
410{
411DirectDrawObject *
412createBlittableFramebufferObjectWithFallback (const CompSize &sz,
413 GLScreen *gScreen)
414{
415 boost::shared_ptr <cgli::DirectDrawStrategies> directDraw;
416 boost::shared_ptr <cgli::FramebufferObject> fbo (boost::make_shared <cgli::FramebufferObject> ());
417 cglfb::RectangularDraw rectangularTextureDraw (boost::bind (defaultRectangularFramebufferDraw,
418 GLVertexBuffer::streamingBuffer (),
419 fbo.get (),
420 _1, _2, _3, _4));
421 initDirectDraw (directDraw,
422 gScreen->blitFramebufferFunc (),
423 rectangularTextureDraw,
424 boost::bind (&GLScreen::bindFramebufferForReading, gScreen, _1),
425 fbo.get ());
426 DirectDrawObject *dd (new cgli::DirectDrawObject (directDraw, fbo, fbo));
427 dd->allocate (*screen, NULL, GL_BGRA);
428 return dd;
429}
430}
431}
432
302#ifndef USE_GLES433#ifndef USE_GLES
303434
304namespace compiz435namespace compiz
@@ -591,6 +722,7 @@
591 if (GL::textureFromPixmap)722 if (GL::textureFromPixmap)
592 registerBindPixmap (EglTexture::bindPixmapToTexture);723 registerBindPixmap (EglTexture::bindPixmapToTexture);
593724
725 priv->blitFramebuffer = boost::bind (compiz::opengl::blitFramebufferEGL, _1, _2, _3, _4);
594 priv->incorrectRefreshRate = false;726 priv->incorrectRefreshRate = false;
595727
596 #else728 #else
@@ -779,6 +911,10 @@
779 GL::fboSupported = true;911 GL::fboSupported = true;
780 }912 }
781913
914 if (GL::fboSupported &&
915 strstr (glExtensions, "GL_EXT_framebuffer_blit"))
916 GL::blitFramebuffer = (GL::GLBlitFramebufferProc) getProcAddress ("glBlitFramebufferEXT");
917
782 GL::fboStencilSupported = GL::fboSupported &&918 GL::fboStencilSupported = GL::fboSupported &&
783 strstr (glExtensions, "GL_EXT_packed_depth_stencil");919 strstr (glExtensions, "GL_EXT_packed_depth_stencil");
784920
@@ -895,13 +1031,13 @@
8951031
896 if (GL::textureFromPixmap)1032 if (GL::textureFromPixmap)
897 registerBindPixmap (TfpTexture::bindPixmapToTexture);1033 registerBindPixmap (TfpTexture::bindPixmapToTexture);
1034
1035 priv->blitFramebuffer = boost::bind (compiz::opengl::blitFramebufferGLX, _1, _2, _3, _4);
898#endif1036#endif
8991037
900 if (GL::fboSupported)1038 if (GL::fboSupported)
901 {1039 priv->scratchFbo.reset (compiz::opengl::createBlittableFramebufferObjectWithFallback (*screen,
902 priv->scratchFbo = new GLFramebufferObject;1040 this));
903 priv->scratchFbo->allocate (*screen, NULL, GL_BGRA);
904 }
9051041
906 GLVertexBuffer::streamingBuffer ()->setAutoProgram (priv->autoProgram);1042 GLVertexBuffer::streamingBuffer ()->setAutoProgram (priv->autoProgram);
9071043
@@ -1209,9 +1345,6 @@
1209 glXDestroyContext (screen->dpy (), priv->ctx);1345 glXDestroyContext (screen->dpy (), priv->ctx);
1210 #endif1346 #endif
12111347
1212 if (priv->scratchFbo)
1213 delete priv->scratchFbo;
1214
1215 delete priv;1348 delete priv;
1216}1349}
12171350
@@ -1234,6 +1367,7 @@
1234 doubleBuffer (screen->dpy (), *screen, surface),1367 doubleBuffer (screen->dpy (), *screen, surface),
1235 #endif1368 #endif
1236 scratchFbo (NULL),1369 scratchFbo (NULL),
1370 blitFramebuffer (),
1237 outputRegion (),1371 outputRegion (),
1238 refreshSubBuffer (false),1372 refreshSubBuffer (false),
1239 lastMask (0),1373 lastMask (0),
@@ -1246,6 +1380,10 @@
1246 autoProgram (new GLScreenAutoProgram(gs)),1380 autoProgram (new GLScreenAutoProgram(gs)),
1247 rootPixmapCopy (None),1381 rootPixmapCopy (None),
1248 rootPixmapSize (),1382 rootPixmapSize (),
1383 drawFramebufferBinding (GL::DRAW_FRAMEBUFFER,
1384 &backbuffer),
1385 readFramebufferBinding (GL::READ_FRAMEBUFFER,
1386 &backbuffer),
1249 glVendor (NULL),1387 glVendor (NULL),
1250 glRenderer (NULL),1388 glRenderer (NULL),
1251 glVersion (NULL),1389 glVersion (NULL),
@@ -1441,11 +1579,19 @@
1441void1579void
1442PrivateGLScreen::outputChangeNotify ()1580PrivateGLScreen::outputChangeNotify ()
1443{1581{
1582 compiz::opengl::BindableFramebuffer *previousReadBuffer =
1583 readFramebufferBinding.bind (&backbuffer);
1584 compiz::opengl::BindableFramebuffer *previousDrawBuffer =
1585 drawFramebufferBinding.bind (&backbuffer);
1586
1444 screen->outputChangeNotify ();1587 screen->outputChangeNotify ();
14451588
1446 if (scratchFbo)1589 if (scratchFbo.get ())
1447 scratchFbo->allocate (*screen, NULL, GL_BGRA);1590 scratchFbo->allocate (*screen, NULL, GL_BGRA);
1448 updateView ();1591 updateView ();
1592
1593 readFramebufferBinding.bind (previousReadBuffer);
1594 drawFramebufferBinding.bind (previousDrawBuffer);
1449}1595}
14501596
1451#ifndef USE_GLES1597#ifndef USE_GLES
@@ -1670,9 +1816,9 @@
1670 WRAPABLE_DEF (projectionMatrix)1816 WRAPABLE_DEF (projectionMatrix)
16711817
1672void1818void
1673GLScreenInterface::glPaintCompositedOutput (const CompRegion &region,1819GLScreenInterface::glPaintCompositedOutput (const CompRegion &region,
1674 GLFramebufferObject *fbo,1820 compiz::opengl::DirectDrawObject *fbo,
1675 unsigned int mask)1821 unsigned int mask)
1676 WRAPABLE_DEF (glPaintCompositedOutput, region, fbo, mask)1822 WRAPABLE_DEF (glPaintCompositedOutput, region, fbo, mask)
16771823
1678void1824void
@@ -1899,6 +2045,30 @@
18992045
1900}2046}
19012047
2048bool
2049cglfb::blitFramebufferGLX (const CompRect &src,
2050 const CompRect &dst,
2051 GLbitfield mask,
2052 GLenum filter)
2053{
2054 /* Must have GL_EXT_blit_framebuffer */
2055 if (!GL::blitFramebuffer)
2056 return false;
2057
2058 /* Be sure to invert y-coords too */
2059 (*GL::blitFramebuffer) (src.x1 (), // sx0
2060 screen->height () - src.y2 (), // sy0
2061 src.x2 (), // sx1
2062 screen->height () - src.y1 (), // sy1
2063 dst.x1 (), // dx0
2064 screen->height () - dst.y2 (), // dy0
2065 dst.x2 (), // dx1,
2066 screen->height () - dst.y1 (), // dy1
2067 GL_COLOR_BUFFER_BIT,
2068 GL_LINEAR);
2069 return true;
2070}
2071
1902#else2072#else
19032073
1904EGLDoubleBuffer::EGLDoubleBuffer (Display *d,2074EGLDoubleBuffer::EGLDoubleBuffer (Display *d,
@@ -1957,6 +2127,16 @@
1957{2127{
1958}2128}
19592129
2130bool
2131cglfb::blitFramebufferEGL (const CompRect &src,
2132 const CompRect &dst,
2133 GLbitfield mask,
2134 GLenum filter)
2135{
2136 /* Not supported on OpenGL|ES2 */
2137 return false;
2138}
2139
1960#endif2140#endif
19612141
1962void2142void
@@ -1977,17 +2157,11 @@
1977 glDepthMask (GL_FALSE);2157 glDepthMask (GL_FALSE);
1978 glStencilMask (0);2158 glStencilMask (0);
19792159
1980 GLFramebufferObject *oldFbo = NULL;2160 compiz::opengl::BindableFramebuffer *oldFbo = NULL;
1981 bool useFbo = false;
19822161
1983 /* Clear the color buffer where appropriate */2162 /* Clear the color buffer where appropriate */
1984 if (GL::fboEnabled && scratchFbo)2163 if (GL::fboEnabled && scratchFbo.get ())
1985 {2164 oldFbo = drawFramebufferBinding.bind (scratchFbo.get ());
1986 oldFbo = scratchFbo->bind ();
1987 useFbo = scratchFbo->checkStatus () && scratchFbo->tex ();
1988 if (!useFbo)
1989 GLFramebufferObject::rebind (oldFbo);
1990 }
19912165
1992#ifdef UNSAFE_ARM_SGX_FIXME2166#ifdef UNSAFE_ARM_SGX_FIXME
1993 refreshSubBuffer = ((lastMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&2167 refreshSubBuffer = ((lastMask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
@@ -2080,13 +2254,10 @@
20802254
2081 glViewport (0, 0, screen->width (), screen->height ());2255 glViewport (0, 0, screen->width (), screen->height ());
20822256
2083 if (useFbo)2257 if (oldFbo)
2084 {2258 {
2085 GLFramebufferObject::rebind (oldFbo);2259 drawFramebufferBinding.bind (oldFbo);
20862260 gScreen->glPaintCompositedOutput (screen->region (), scratchFbo.get (), mask);
2087 // FIXME: does not work if screen dimensions exceed max texture size
2088 // We should try to use glBlitFramebuffer instead.
2089 gScreen->glPaintCompositedOutput (screen->region (), scratchFbo, mask);
2090 }2261 }
20912262
2092 if (cScreen->outputWindowChanged ())2263 if (cScreen->outputWindowChanged ())
@@ -2101,13 +2272,13 @@
2101 }2272 }
21022273
2103 bool alwaysSwap = optionGetAlwaysSwapBuffers ();2274 bool alwaysSwap = optionGetAlwaysSwapBuffers ();
2104 bool fullscreen = useFbo ||2275 bool fullscreen = oldFbo ||
2105 alwaysSwap ||2276 alwaysSwap ||
2106 ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&2277 ((mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK) &&
2107 commonFrontbuffer);2278 commonFrontbuffer);
21082279
2109 doubleBuffer.set (DoubleBuffer::VSYNC, optionGetSyncToVblank ());2280 doubleBuffer.set (DoubleBuffer::VSYNC, optionGetSyncToVblank ());
2110 doubleBuffer.set (DoubleBuffer::HAVE_PERSISTENT_BACK_BUFFER, useFbo);2281 doubleBuffer.set (DoubleBuffer::HAVE_PERSISTENT_BACK_BUFFER, oldFbo ? true : false);
2111 doubleBuffer.set (DoubleBuffer::NEED_PERSISTENT_BACK_BUFFER, alwaysSwap);2282 doubleBuffer.set (DoubleBuffer::NEED_PERSISTENT_BACK_BUFFER, alwaysSwap);
2112 doubleBuffer.render (tmpRegion, fullscreen);2283 doubleBuffer.render (tmpRegion, fullscreen);
21132284
@@ -2195,10 +2366,34 @@
2195 }2366 }
2196}2367}
21972368
2198GLFramebufferObject *2369compiz::opengl::FramebufferObject *
2199GLScreen::fbo ()2370GLScreen::fbo ()
2200{2371{
2201 return priv->scratchFbo;2372 return priv->scratchFbo.get ();
2373}
2374
2375compiz::opengl::BindableFramebuffer *
2376GLScreen::backbuffer ()
2377{
2378 return &priv->backbuffer;
2379}
2380
2381compiz::opengl::BindableFramebuffer *
2382GLScreen::bindFramebufferForDrawing (compiz::opengl::BindableFramebuffer *next)
2383{
2384 return priv->drawFramebufferBinding.bind (next);
2385}
2386
2387compiz::opengl::BindableFramebuffer *
2388GLScreen::bindFramebufferForReading (compiz::opengl::BindableFramebuffer *next)
2389{
2390 return priv->readFramebufferBinding.bind (next);
2391}
2392
2393const cglfb::BlitFramebufferFunc &
2394GLScreen::blitFramebufferFunc ()
2395{
2396 return priv->blitFramebuffer;
2202}2397}
22032398
2204GLTexture *2399GLTexture *
@@ -2240,3 +2435,19 @@
2240 priv->rasterPos.setY (0);2435 priv->rasterPos.setY (0);
2241}2436}
22422437
2438GLuint
2439BindableBackbuffer::getResourceId () const
2440{
2441 return 0;
2442}
2443
2444bool
2445BindableBackbuffer::setBindStatus (GLenum)
2446{
2447 return true;
2448}
2449
2450void
2451BindableBackbuffer::updateAllocation (GLenum)
2452{
2453}
22432454
=== modified file 'plugins/water/src/water.cpp'
--- plugins/water/src/water.cpp 2013-01-28 19:45:04 +0000
+++ plugins/water/src/water.cpp 2013-02-13 11:45:25 +0000
@@ -62,7 +62,11 @@
62 if (!useFbo)62 if (!useFbo)
63 return false;63 return false;
6464
65 oldFbo = waterFbo[fIndex]->bind ();65 oldFbo = gScreen->bindFramebufferForDrawing (waterFbo[fIndex]);
66
67 if (!oldFbo)
68 return false;
69
66 glGetIntegerv(GL_VIEWPORT, &oldViewport[0]);70 glGetIntegerv(GL_VIEWPORT, &oldViewport[0]);
67 glViewport (0, 0, texWidth, texHeight);71 glViewport (0, 0, texWidth, texHeight);
6872
@@ -72,7 +76,7 @@
72void76void
73WaterScreen::fboEpilogue ()77WaterScreen::fboEpilogue ()
74{78{
75 GLFramebufferObject::rebind (oldFbo);79 gScreen->bindFramebufferForDrawing (oldFbo);
76 glViewport (oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);80 glViewport (oldViewport[0], oldViewport[1], oldViewport[2], oldViewport[3]);
77}81}
7882
@@ -305,28 +309,32 @@
305 waterFbo[i]->allocate (size, (char *) t0,309 waterFbo[i]->allocate (size, (char *) t0,
306 GL_BGRA, GL_UNSIGNED_BYTE);310 GL_BGRA, GL_UNSIGNED_BYTE);
307 // check if FBOs are working. If not, fallback to software textures311 // check if FBOs are working. If not, fallback to software textures
308 oldFbo = waterFbo[i]->bind ();312 oldFbo = gScreen->bindFramebufferForDrawing (waterFbo[i]);
309 waterFbo[i]->rebind (oldFbo);313 if (!oldFbo)
310 if (!waterFbo[i]->checkStatus ())
311 {314 {
312 useFbo = false;315 useFbo = false;
313 delete waterFbo[i];316 delete waterFbo[i];
314 break;317 break;
315 }318 }
319 gScreen->bindFramebufferForDrawing (oldFbo);
316 }320 }
317 }321 }
318}322}
319323
320void324void
321WaterScreen::glPaintCompositedOutput (const CompRegion &region,325WaterScreen::glPaintCompositedOutput (const CompRegion &region,
322 GLFramebufferObject *fbo,326 compiz::opengl::DirectDrawObject *fbo,
323 unsigned int mask)327 unsigned int mask)
324{328{
325 if (count)329 if (count)
326 {330 {
327 if (GL::vboEnabled && GL::shaders)331 if (GL::vboEnabled && GL::shaders)
328 {332 {
329 GLFramebufferObject::rebind (oldFbo);333 /* This seems redundant to me */
334 gScreen->bindFramebufferForDrawing (oldFbo);
335
336 oldFbo = NULL;
337
330 glViewport (oldViewport[0], oldViewport[1],338 glViewport (oldViewport[0], oldViewport[1],
331 oldViewport[2], oldViewport[3]);339 oldViewport[2], oldViewport[3]);
332340
333341
=== modified file 'plugins/water/src/water.h'
--- plugins/water/src/water.h 2012-09-07 23:56:21 +0000
+++ plugins/water/src/water.h 2013-02-13 11:45:25 +0000
@@ -64,9 +64,9 @@
6464
65 void handleEvent (XEvent *);65 void handleEvent (XEvent *);
6666
67 void glPaintCompositedOutput (const CompRegion &region,67 void glPaintCompositedOutput (const CompRegion &region,
68 GLFramebufferObject *fbo,68 compiz::opengl::DirectDrawObject *fbo,
69 unsigned int mask);69 unsigned int mask);
70 void preparePaint (int);70 void preparePaint (int);
71 void donePaint ();71 void donePaint ();
7272
@@ -100,7 +100,7 @@
100100
101 GLFramebufferObject *waterFbo[TEXTURE_NUM];101 GLFramebufferObject *waterFbo[TEXTURE_NUM];
102102
103 GLFramebufferObject *oldFbo;103 compiz::opengl::BindableFramebuffer *oldFbo;
104 GLint oldViewport[4];104 GLint oldViewport[4];
105 int fboIndex;105 int fboIndex;
106 bool useFbo;106 bool useFbo;
107107
=== modified file 'src/event.cpp'
--- src/event.cpp 2013-01-03 16:06:41 +0000
+++ src/event.cpp 2013-02-13 11:45:25 +0000
@@ -1288,17 +1288,6 @@
1288 if (!XGetWindowAttributes (privateScreen.dpy, event->xcreatewindow.window, &wa))1288 if (!XGetWindowAttributes (privateScreen.dpy, event->xcreatewindow.window, &wa))
1289 privateScreen.setDefaultWindowAttributes (&wa);1289 privateScreen.setDefaultWindowAttributes (&wa);
12901290
1291 /* That being said, we should store as much information as possible
1292 * about it. There may be requests relative to this window that could
1293 * use the data in the XCreateWindowEvent structure, especially the
1294 * override redirect state */
1295 wa.x = event->xcreatewindow.x;
1296 wa.y = event->xcreatewindow.y;
1297 wa.width = event->xcreatewindow.width;
1298 wa.height = event->xcreatewindow.height;
1299 wa.border_width = event->xcreatewindow.border_width;
1300 wa.override_redirect = event->xcreatewindow.override_redirect;
1301
1302 foreach (CompWindow *w, screen->windows ())1291 foreach (CompWindow *w, screen->windows ())
1303 {1292 {
1304 if (w->priv->serverFrame == event->xcreatewindow.window)1293 if (w->priv->serverFrame == event->xcreatewindow.window)
@@ -1478,15 +1467,7 @@
1478 if (!XGetWindowAttributes (privateScreen.dpy, event->xcreatewindow.window, &wa))1467 if (!XGetWindowAttributes (privateScreen.dpy, event->xcreatewindow.window, &wa))
1479 privateScreen.setDefaultWindowAttributes (&wa);1468 privateScreen.setDefaultWindowAttributes (&wa);
14801469
1481 /* That being said, we should store as much information as possible1470 PrivateWindow::createCompWindow (getTopWindow ()->id (), getTopServerWindow ()->id (), wa, event->xcreatewindow.window);
1482 * about it. There may be requests relative to this window that could
1483 * use the data in the XCreateWindowEvent structure, especially the
1484 * override redirect state */
1485 wa.x = event->xreparent.x;
1486 wa.y = event->xreparent.y;
1487 wa.override_redirect = event->xreparent.override_redirect;
1488
1489 PrivateWindow::createCompWindow (getTopWindow ()->id (), getTopServerWindow ()->id (), wa, event->xreparent.window);
1490 break;1471 break;
1491 }1472 }
1492 else1473 else
@@ -2118,10 +2099,7 @@
2118 ServerLock lock (screen->serverGrabInterface ());2099 ServerLock lock (screen->serverGrabInterface ());
21192100
2120 /* This will be the window that we must lower relative to */2101 /* This will be the window that we must lower relative to */
2121 CompWindow *sibling =2102 CompWindow *sibling = PrivateWindow::findValidStackSiblingBelow (active, fsw, lock);
2122 PrivateWindow::findValidStackSiblingBelow (active,
2123 fsw,
2124 lock);
21252103
2126 if (sibling)2104 if (sibling)
2127 {2105 {
@@ -2199,11 +2177,7 @@
2199 if (w)2177 if (w)
2200 {2178 {
2201 ServerLock lock (screen->serverGrabInterface ());2179 ServerLock lock (screen->serverGrabInterface ());
2202 if (PrivateWindow::stackDocks (w,2180 if (PrivateWindow::stackDocks (w, dockWindows, &xwc, &mask, lock))
2203 dockWindows,
2204 &xwc,
2205 &mask,
2206 lock))
2207 {2181 {
2208 Window sibling = xwc.sibling;2182 Window sibling = xwc.sibling;
2209 xwc.stack_mode = Above;2183 xwc.stack_mode = Above;
22102184
=== modified file 'src/option/tests/CMakeLists.txt'
--- src/option/tests/CMakeLists.txt 2012-12-10 13:01:00 +0000
+++ src/option/tests/CMakeLists.txt 2013-02-13 11:45:25 +0000
@@ -10,7 +10,6 @@
10 ${compiz_SOURCE_DIR}/src/point/include10 ${compiz_SOURCE_DIR}/src/point/include
11 ${compiz_SOURCE_DIR}/src/window/geometry/include11 ${compiz_SOURCE_DIR}/src/window/geometry/include
12 ${compiz_SOURCE_DIR}/src/window/extents/include12 ${compiz_SOURCE_DIR}/src/window/extents/include
13 ${compiz_SOURCE_DIR}/src/servergrab/include
14 ${COMPIZ_INCLUDE_DIRS}13 ${COMPIZ_INCLUDE_DIRS}
15)14)
1615
1716
=== modified file 'src/option/tests/option.cpp'
--- src/option/tests/option.cpp 2012-12-10 13:01:00 +0000
+++ src/option/tests/option.cpp 2013-02-13 11:45:25 +0000
@@ -1,9 +1,5 @@
1#include <gtest/gtest.h>1#include <gtest/gtest.h>
22
3/* XXX: including core.h means that we pull in
4 * both window.h and screen.h which are cascading
5 * includes. We should eliminate this dependency
6 */
7#include "core/core.h"3#include "core/core.h"
8#include "core/action.h"4#include "core/action.h"
9#include "core/match.h"5#include "core/match.h"
106
=== modified file 'src/outputdevices.h'
--- src/outputdevices.h 2012-12-10 13:01:00 +0000
+++ src/outputdevices.h 2013-02-13 11:45:25 +0000
@@ -25,11 +25,6 @@
25#include <core/output.h>25#include <core/output.h>
26#include <core/rect.h>26#include <core/rect.h>
27#include <core/region.h>27#include <core/region.h>
28
29/* XXX: Including screen.h includes window.h and other unnecessary
30 * headers which cause cascading header dependencies. We should seek to
31 * eliminate this dependency
32 */
33#include <core/screen.h>28#include <core/screen.h>
3429
35namespace compiz30namespace compiz
3631
=== modified file 'src/privatewindow.h'
--- src/privatewindow.h 2013-01-03 16:06:41 +0000
+++ src/privatewindow.h 2013-02-13 11:45:25 +0000
@@ -33,6 +33,8 @@
33#include <core/point.h>33#include <core/point.h>
34#include <core/timer.h>34#include <core/timer.h>
3535
36class ServerLock;
37
36#include <boost/shared_ptr.hpp>38#include <boost/shared_ptr.hpp>
3739
38#define XWINDOWCHANGES_INIT {0, 0, 0, 0, 0, None, 0}40#define XWINDOWCHANGES_INIT {0, 0, 0, 0, 0, None, 0}
@@ -127,22 +129,23 @@
127129
128 bool isInvisible() const;130 bool isInvisible() const;
129131
130 static bool stackLayerCheck (CompWindow *w,132 static bool stackLayerCheck (CompWindow *w,
131 Window clientLeader,133 Window clientLeader,
132 CompWindow *below,134 CompWindow *below,
133 const ServerLock &lock);135 const ServerLock &lock);
134136
135 static bool avoidStackingRelativeTo (CompWindow *w, const ServerLock &lock);137 static bool avoidStackingRelativeTo (CompWindow *w,
138 const ServerLock &lock);
136139
137 static CompWindow * findSiblingBelow (CompWindow *w,140 static CompWindow * findSiblingBelow (CompWindow *w,
138 bool aboveFs,141 bool aboveFs,
139 const ServerLock &lock);142 const ServerLock &lock);
140143
141 static CompWindow * findLowestSiblingBelow (CompWindow *w,144 static CompWindow * findLowestSiblingBelow (CompWindow *w,
142 const ServerLock &lock);145 const ServerLock &lock);
143146
144 static bool validSiblingBelow (CompWindow *w,147 static bool validSiblingBelow (CompWindow *w,
145 CompWindow *sibling,148 CompWindow *sibling,
146 const ServerLock &lock);149 const ServerLock &lock);
147150
148 void saveGeometry (int mask);151 void saveGeometry (int mask);
@@ -152,21 +155,21 @@
152 void reconfigureXWindow (unsigned int valueMask,155 void reconfigureXWindow (unsigned int valueMask,
153 XWindowChanges *xwc);156 XWindowChanges *xwc);
154157
155 static bool stackDocks (CompWindow *w,158 static bool stackDocks (CompWindow *w,
156 CompWindowList &updateList,159 CompWindowList &updateList,
157 XWindowChanges *xwc,160 XWindowChanges *xwc,
158 unsigned int *mask,161 unsigned int *mask,
159 const ServerLock &lock);162 const ServerLock &lock);
160163
161 static bool stackTransients (CompWindow *w,164 static bool stackTransients (CompWindow *w,
162 CompWindow *avoid,165 CompWindow *avoid,
163 XWindowChanges *xwc,166 XWindowChanges *xwc,
164 CompWindowList &updateList,167 CompWindowList &updateList,
165 const ServerLock &lock);168 const ServerLock &lock);
166169
167 static void stackAncestors (CompWindow *w,170 static void stackAncestors (CompWindow *w,
168 XWindowChanges *xwc,171 XWindowChanges *xwc,
169 CompWindowList &updateList,172 CompWindowList &updateList,
170 const ServerLock &lock);173 const ServerLock &lock);
171174
172 static bool isAncestorTo (CompWindow *transient,175 static bool isAncestorTo (CompWindow *transient,
@@ -179,8 +182,8 @@
179 int addWindowSizeChanges (XWindowChanges *xwc,182 int addWindowSizeChanges (XWindowChanges *xwc,
180 CompWindow::Geometry old);183 CompWindow::Geometry old);
181184
182 int addWindowStackChanges (XWindowChanges *xwc,185 int addWindowStackChanges (XWindowChanges *xwc,
183 CompWindow *sibling,186 CompWindow *sibling,
184 const ServerLock &lock);187 const ServerLock &lock);
185188
186 static CompWindow * findValidStackSiblingBelow (CompWindow *w,189 static CompWindow * findValidStackSiblingBelow (CompWindow *w,
187190
=== modified file 'src/tests/CMakeLists.txt'
--- src/tests/CMakeLists.txt 2013-01-03 16:06:41 +0000
+++ src/tests/CMakeLists.txt 2013-02-13 11:45:25 +0000
@@ -10,7 +10,6 @@
10 ${COMPIZ_MAIN_SOURCE_DIR}/pluginclasshandler/include10 ${COMPIZ_MAIN_SOURCE_DIR}/pluginclasshandler/include
11 ${COMPIZ_MAIN_SOURCE_DIR}/window/geometry/include11 ${COMPIZ_MAIN_SOURCE_DIR}/window/geometry/include
12 ${COMPIZ_MAIN_SOURCE_DIR}/window/extents/include12 ${COMPIZ_MAIN_SOURCE_DIR}/window/extents/include
13 ${COMPIZ_MAIN_SOURCE_DIR}/servergrab/include
14 ${COMPIZ_INCLUDE_DIRS}13 ${COMPIZ_INCLUDE_DIRS}
15)14)
1615
1716
=== modified file 'src/window.cpp'
--- src/window.cpp 2013-02-12 22:02:10 +0000
+++ src/window.cpp 2013-02-13 11:45:25 +0000
@@ -41,6 +41,7 @@
41#include <core/icon.h>41#include <core/icon.h>
42#include <core/atoms.h>42#include <core/atoms.h>
43#include "core/windowconstrainment.h"43#include "core/windowconstrainment.h"
44#include <core/servergrab.h>
44#include "privatewindow.h"45#include "privatewindow.h"
45#include "privatescreen.h"46#include "privatescreen.h"
46#include "privatestackdebugger.h"47#include "privatestackdebugger.h"
4748
=== modified file 'tests/system/xorg-gtest/tests/compiz_xorg_gtest_test_window_stacking.cpp'
--- tests/system/xorg-gtest/tests/compiz_xorg_gtest_test_window_stacking.cpp 2012-12-10 12:38:48 +0000
+++ tests/system/xorg-gtest/tests/compiz_xorg_gtest_test_window_stacking.cpp 2013-02-13 11:45:25 +0000
@@ -293,83 +293,3 @@
293 EXPECT_EQ (*it++, w3);293 EXPECT_EQ (*it++, w3);
294 EXPECT_EQ (*it++, w2);294 EXPECT_EQ (*it++, w2);
295}295}
296
297TEST_F (CompizXorgSystemStackingTest, TestCreateRelativeToDestroyedWindowFindsAnotherAppropriatePosition)
298{
299 ::Display *dpy = Display ();
300 ct::PropertyNotifyXEventMatcher matcher (dpy, "_NET_CLIENT_LIST_STACKING");
301
302 Window dock = ct::CreateNormalWindow (dpy);
303
304 /* Make it a dock */
305 MakeDock (dpy, dock);
306
307 /* Immediately map the dock window and clear the event queue for it */
308 XMapRaised (dpy, dock);
309
310 ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, dock, ReparentNotify, -1, -1)));
311 ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, dock, MapNotify, -1, -1)));
312
313 /* Dock window needs to be in the client list */
314 ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
315 DefaultRootWindow (dpy),
316 PropertyNotify,
317 -1,
318 -1,
319 matcher)));
320 std::list <Window> clientList = ct::NET_CLIENT_LIST_STACKING (dpy);
321 ASSERT_EQ (clientList.size (), 1);
322
323 Window w1 = ct::CreateNormalWindow (dpy);
324 Window w2 = ct::CreateNormalWindow (dpy);
325
326 XMapRaised (dpy, w1);
327
328 /* All reparented and mapped */
329 ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy,w1, ReparentNotify, -1, -1)));
330 ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, w1, MapNotify, -1, -1)));
331
332 /* Grab the server so that we can guaruntee that all of these requests
333 * happen before compiz gets them */
334 XGrabServer (dpy);
335 XSync (dpy, false);
336
337 /* Map the second window, so it ideally goes above w1. Compiz will
338 * receive the MapRequest for this first */
339 XMapRaised (dpy, w2);
340
341 /* Create window that has w2 as its ideal above-candidate
342 * (compiz will receive the CreateNotify for this window
343 * after the MapRequest but before the subsequent MapNotify) */
344 Window w3 = ct::CreateNormalWindow (dpy);
345
346 XMapRaised (dpy, w3);
347
348 /* Destroy w2 */
349 XDestroyWindow (dpy, w2);
350
351 XUngrabServer (dpy);
352 XSync (dpy, false);
353
354 /* Reparented and mapped */
355 ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, w3, ReparentNotify, -1, -1)));
356 ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, w3, MapNotify, -1, -1)));
357
358 /* Update _NET_CLIENT_LIST_STACKING twice */
359 ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
360 DefaultRootWindow (dpy),
361 PropertyNotify,
362 -1,
363 -1,
364 matcher)));
365
366 /* Check the client list to see that dock > w3 > w1 */
367 clientList = ct::NET_CLIENT_LIST_STACKING (dpy);
368
369 std::list <Window>::iterator it = clientList.begin ();
370
371 EXPECT_EQ (3, clientList.size ());
372 EXPECT_EQ (w1, (*it++));
373 EXPECT_EQ (w3, (*it++));
374 EXPECT_EQ (dock, (*it++));
375}

Subscribers

People subscribed via source and target branches