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

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~compiz-team/compiz/compiz.performance_1040478
Merge into: lp:compiz/0.9.8
Diff against target: 1923 lines (+1204/-269)
15 files modified
plugins/opengl/CMakeLists.txt (+7/-0)
plugins/opengl/include/opengl/framebufferobject.h (+219/-73)
plugins/opengl/include/opengl/opengl-api.h (+42/-0)
plugins/opengl/include/opengl/opengl.h (+50/-22)
plugins/opengl/src/fbdirectdraw/CMakeLists.txt (+32/-0)
plugins/opengl/src/fbdirectdraw/include/framebuffer-direct-draw.h (+103/-0)
plugins/opengl/src/fbdirectdraw/src/framebuffer-direct-draw.cpp (+159/-0)
plugins/opengl/src/fbdirectdraw/tests/CMakeLists.txt (+24/-0)
plugins/opengl/src/fbdirectdraw/tests/test-opengl-framebuffer-direct-draw.cpp (+219/-0)
plugins/opengl/src/framebufferobject.cpp (+119/-60)
plugins/opengl/src/paint.cpp (+8/-82)
plugins/opengl/src/privates.h (+37/-6)
plugins/opengl/src/screen.cpp (+179/-20)
plugins/water/src/water.cpp (+3/-3)
plugins/water/src/water.h (+3/-3)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.performance_1040478
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Resubmitting
jenkins (community) continuous-integration Approve
Review via email: mp+124543@code.launchpad.net

This proposal has been superseded by a proposal from 2012-09-28.

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. Distro says they're okay with this.

To post a comment you must log in.
Revision history for this message
jenkins (martin-mrazik+qa) wrote :
review: Needs Fixing (continuous-integration)
3388. By Sam Spilsbury

Merge lp:compiz

Revision history for this message
jenkins (martin-mrazik+qa) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

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
3389. By Sam Spilsbury

Merge lp:compiz

3390. By Sam Spilsbury

Merge e lp:compiz

3391. By Sam Spilsbury

Merge lp:compiz

3392. By Sam Spilsbury

Simplify lots of variable names, unindent namespaces

3393. By Sam Spilsbury

Set the stencil and depth attachments in allocate and not bind

3394. By Sam Spilsbury

Refactored large parts of the code, make binding the concern of BindLocation

3395. By Sam Spilsbury

Merge lp:compiz

3396. By Sam Spilsbury

Moved the creation of directly drawable fbo's into a convenience method
so that other plugins can create them

3397. By Sam Spilsbury

Fix compile error on tests

3398. By Sam Spilsbury

We don't need to provide a BindableFramebuffer to access the backbuffer

3399. By Sam Spilsbury

Unbind framebuffers before processing output change

3400. By Sam Spilsbury

Invert y-coords of glBlitFramebuffer operation

3401. By Sam Spilsbury

Reset framebuffer status on reallocation

3402. By Sam Spilsbury

Merge lp:compiz

3403. By Sam Spilsbury

Remove unused variable

3404. By Sam Spilsbury

Merge lp:compiz

3405. By Sam Spilsbury

Merge lp:compiz

3406. By Sam Spilsbury

Merge lp:compiz

3407. By Sam Spilsbury

Remove referenes to configure buffers

3408. By Sam Spilsbury

Revert trunk merge as it was broken

3409. By Sam Spilsbury

Merge lp:compiz

3410. By Sam Spilsbury

Unrevert changes which shouldn't have been reverted

3411. By Sam Spilsbury

Another botched merge

3412. By Sam Spilsbury

Merge lp:compiz

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 'plugins/opengl/CMakeLists.txt'
--- plugins/opengl/CMakeLists.txt 2012-09-04 10:19:19 +0000
+++ plugins/opengl/CMakeLists.txt 2012-09-15 15:18:21 +0000
@@ -5,10 +5,17 @@
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)9)
910
11set (COMPIZ_OPENGL_PLUGIN_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
12set (COMPIZ_OPENGL_PLUGIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
13
10add_subdirectory (src/doublebuffer)14add_subdirectory (src/doublebuffer)
11add_subdirectory (src/fsregion)15add_subdirectory (src/fsregion)
16add_subdirectory (src/fbdirectdraw)
17
18include_directories (src/fbdirectdraw/include)
1219
13if (USE_GLES)20if (USE_GLES)
14 compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR})21 compiz_plugin(opengl PLUGINDEPS composite CFLAGSADD "-DUSE_GLES -std=c++0x" LIBRARIES ${OPENGLES2_LIBRARIES} ${INTERNAL_LIBRARIES} dl INCDIRS ${OPENGLES2_INCLUDE_DIR})
1522
=== 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 2012-09-15 15:18:21 +0000
@@ -26,79 +26,225 @@
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 <boost/function.hpp>
3030#include <opengl/opengl-api.h>
31struct PrivateGLFramebufferObject;31#include <core/size.h>
3232#include <core/rect.h>
33/**33
34 * Class representing a framebuffer object in GL, supporting only one34class GLVertexBuffer;
35 * color attachment as per GLES 2 spec. The color attachment is referred35class GLTexture;
36 * to as the texture (of the FBO).36
37 *37namespace compiz
38 * Usage:
39 * 1. create a GLFramebufferObject (requires a GL context)
40 * 2. call allocate (size), and check status ()
41 * 3. old = bind ()
42 * 4. do your rendering
43 * 5. rebind (old)
44 * 6. use the rendered texture via tex ()
45 * 7. go to 2 or 3, or delete to quit (requires a GL context)
46 */
47class GLFramebufferObject
48{38{
49 public:39 namespace opengl
50 GLFramebufferObject ();40 {
51 ~GLFramebufferObject ();41 typedef enum _FramebufferBlitInformation
5242 {
53 /**43 ColorData = (1 << 0),
54 * Ensure the texture is of the given size, recreating it if needed,44 StencilData = (1 << 1)
55 * and replace the FBO color attachment with it. The texture contents45 } FramebufferBlitInformation;
56 * become undefined, unless specified in the 'image' argument.46
57 * When specifying 'image', it's also possible to pass-in the47 typedef enum _FramebufferFilter
58 * desired image's 'format' and 'type'.48 {
59 *49 Fast = 0,
60 * Returns true on success, and false on texture allocation failure.50 Good = 1,
61 */51 } FramebufferFilter;
62 bool allocate (const CompSize &size,52
63 const char *image = NULL,53 typedef enum _FramebufferBindPoint
64 GLenum format = GL_RGBA,54 {
65 GLenum type = GL_UNSIGNED_BYTE);55 Read = 0,
6656 Draw = 1
67 /**57 } FramebufferBindPoint;
68 * Bind this as the current FBO, previous binding in GL context is58
69 * undone. GL rendering is now targeted to this FBO.59 class PushableFramebuffer
70 * Returns a pointer to the previously bound FBO, or NULL if60 {
71 * the previous binding was zero (the window system provided61 public:
72 * framebuffer).62
73 *63 virtual ~PushableFramebuffer () {}
74 * The previous FBO is no longer bound, so you can use its64
75 * texture. To restore the previous FBO, call rebind (FBO) with65 /* Binds this framebuffer immediately */
76 * the returned pointer as the argument.66 virtual void pushFBO (FramebufferBindPoint bindPoint) = 0;
77 */67 /* Binds the last bound framebuffer immediately */
78 GLFramebufferObject *bind ();68 virtual void popFBO () = 0;
7969 };
80 /**70
81 * Bind the given FBO as the current FBO, without looking up the71 typedef boost::function <bool (const CompRect &src,
82 * previous binding. The argument can be NULL, in which case the72 const CompRect &dst,
83 * window system provided framebuffer gets bound (FBO is unbound).73 GLbitfield mask,
84 */74 GLenum filter)> FramebufferRectangularDrawStrategy;
85 static void rebind (GLFramebufferObject *fbo);75 typedef std::list <FramebufferRectangularDrawStrategy> FramebufferRectangularDrawStrategyList;
8676
87 /**77 class DirectDrawFramebufferStrategies
88 * Check the FBO completeness. Returns true on complete.78 {
89 * Otherwise returns false and reports the error to log.79 public:
90 */80
91 bool checkStatus ();81 virtual ~DirectDrawFramebufferStrategies () {}
9282 virtual void draw (const CompRect &src,
93 /**83 const CompRect &dst,
94 * Return a pointer to the texture that is the color attachment.84 FramebufferBlitInformation mask,
95 * This will return NULL, if allocate () has not been called, or85 FramebufferFilter filter) = 0;
96 * the last allocate () call failed.86 };
97 */87
98 GLTexture *tex ();88 class FramebufferObject
9989 {
100 private:90 public:
101 PrivateGLFramebufferObject *priv;91
102};92 virtual ~FramebufferObject () {}
93
94 /**
95 * Ensure the texture is of the given size, recreating it if needed,
96 * and replace the FBO color attachment with it. The texture contents
97 * become undefined, unless specified in the 'image' argument.
98 * When specifying 'image', it's also possible to pass-in the
99 * desired image's 'format' and 'type'.
100 *
101 * Returns true on success, and false on texture allocation failure.
102 */
103 virtual bool allocate (const CompSize &size,
104 const char *image = NULL,
105 GLenum format = GL_RGBA,
106 GLenum type = GL_UNSIGNED_BYTE) = 0;
107
108 /**
109 * Bind this as the current FBO, previous binding in GL context is
110 * undone. GL rendering is now targeted to this FBO.
111 * Returns a pointer to the previously bound FBO, or NULL if
112 * the previous binding was zero (the window system provided
113 * framebuffer).
114 *
115 * The previous FBO is no longer bound, so you can use its
116 * texture. To restore the previous FBO, call rebind (FBO) with
117 * the returned pointer as the argument.
118 */
119 virtual compiz::opengl::FramebufferObject * bind (compiz::opengl::FramebufferBindPoint bindPoint =
120 compiz::opengl::Draw) = 0;
121
122 /**
123 * Check the FBO completeness. Returns true on complete.
124 * Otherwise returns false and reports the error to log.
125 */
126 virtual bool checkStatus (compiz::opengl::FramebufferBindPoint bindPoint =
127 compiz::opengl::Draw) = 0;
128
129 /**
130 * Return a pointer to the texture that is the color attachment.
131 * This will return NULL, if allocate () has not been called, or
132 * the last allocate () call failed.
133 */
134 virtual GLTexture * tex () = 0;
135 };
136
137 class DirectDrawFramebufferObject :
138 virtual public compiz::opengl::FramebufferObject
139 {
140 public:
141
142 virtual ~DirectDrawFramebufferObject () {};
143
144 /**
145 * Draws a region of the framebuffer object as specified in
146 * framebuffer-specified co-ordinates as @src co-ordinates in
147 * the buffer currently bound co-ordinates @dst . @mask indicates
148 * what kind of data should be propogated downwards. @filter indicates
149 * what kind of filter should be used when drawing this buffer
150 *
151 * This since this code only draws a rectangular region from one
152 * framebuffer to another, it will try and use the fastest codepath
153 * possible, falling back to a simple textured draw if
154 * glBlitFramebuffer is not available
155 *
156 */
157 virtual void directDraw (const CompRect &src,
158 const CompRect &dst,
159 compiz::opengl::FramebufferBlitInformation mask,
160 compiz::opengl::FramebufferFilter filter) = 0;
161 };
162
163 namespace impl
164 {
165 namespace cgl = compiz::opengl;
166
167 struct PrivateGLFramebufferObject;
168
169 class PushableFramebuffer :
170 public cgl::FramebufferObject
171 {
172 public:
173
174 };
175
176 class FramebufferObject :
177 public cgl::FramebufferObject,
178 public cgl::PushableFramebuffer
179 {
180 public:
181 FramebufferObject ();
182 ~FramebufferObject ();
183
184 /**
185 * Ensure the texture is of the given size, recreating it if needed,
186 * and replace the FBO color attachment with it. The texture contents
187 * become undefined, unless specified in the 'image' argument.
188 * When specifying 'image', it's also possible to pass-in the
189 * desired image's 'format' and 'type'.
190 *
191 * Returns true on success, and false on texture allocation failure.
192 */
193 bool allocate (const CompSize &size,
194 const char *image = NULL,
195 GLenum format = GL_RGBA,
196 GLenum type = GL_UNSIGNED_BYTE);
197
198 /**
199 * Bind this as the current FBO, previous binding in GL context is
200 * undone. GL rendering is now targeted to this FBO.
201 * Returns a pointer to the previously bound FBO, or NULL if
202 * the previous binding was zero (the window system provided
203 * framebuffer).
204 *
205 * The previous FBO is no longer bound, so you can use its
206 * texture. To restore the previous FBO, call rebind (FBO) with
207 * the returned pointer as the argument.
208 */
209 FramebufferObject *bind (compiz::opengl::FramebufferBindPoint bindPoint =
210 compiz::opengl::Draw);
211
212 /**
213 * Bind the given FBO as the current FBO, without looking up the
214 * previous binding. The argument can be NULL, in which case the
215 * window system provided framebuffer gets bound (FBO is unbound).
216 */
217 static void rebind (FramebufferObject *fbo,
218 compiz::opengl::FramebufferBindPoint bindPoint =
219 compiz::opengl::Draw);
220
221 /**
222 * Check the FBO completeness. Returns true on complete.
223 * Otherwise returns false and reports the error to log.
224 */
225 bool checkStatus (compiz::opengl::FramebufferBindPoint bindPoint =
226 compiz::opengl::Draw);
227
228 /**
229 * Return a pointer to the texture that is the color attachment.
230 * This will return NULL, if allocate () has not been called, or
231 * the last allocate () call failed.
232 */
233 GLTexture * tex ();
234
235 private:
236
237 /* Binds this framebuffer immediately */
238 void pushFBO (FramebufferBindPoint bindPoint);
239 /* Binds the last bound framebuffer immediately */
240 void popFBO ();
241
242 PrivateGLFramebufferObject *priv;
243 };
244 }
245 }
246}
247
248typedef compiz::opengl::impl::FramebufferObject GLFramebufferObject;
103249
104#endif // _COMPIZ_GLFRAMEBUFFEROBJECT_H250#endif // _COMPIZ_GLFRAMEBUFFEROBJECT_H
105251
=== 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 2012-09-15 15:18:21 +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 2012-09-07 23:29:42 +0000
+++ plugins/opengl/include/opengl/opengl.h 2012-09-15 15:18:21 +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 543#define COMPIZ_OPENGL_ABI 6
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
@@ -87,6 +77,27 @@
87class PrivateGLScreen;77class PrivateGLScreen;
88class PrivateGLWindow;78class PrivateGLWindow;
8979
80namespace compiz
81{
82 namespace opengl
83 {
84 typedef boost::function <bool (const CompRect &src,
85 const CompRect &dst,
86 GLbitfield mask,
87 GLenum filter)> BlitFramebufferFunc;
88
89 class DirectDrawFramebufferObject;
90 class FramebufferObject;
91
92 namespace impl
93 {
94 class FramebufferObject;
95 }
96 }
97}
98
99typedef compiz::opengl::impl::FramebufferObject GLFramebufferObject;
100
90extern GLushort defaultColor[4];101extern GLushort defaultColor[4];
91102
92#ifndef GLX_EXT_texture_from_pixmap103#ifndef GLX_EXT_texture_from_pixmap
@@ -313,6 +324,18 @@
313 GLsizei width,324 GLsizei width,
314 GLsizei height);325 GLsizei height);
315326
327 /* GLX_EXT_blit_framebuffer */
328 typedef void (*GLBlitFramebufferProc) (GLint srcX0,
329 GLint srcY0,
330 GLint srcX1,
331 GLint srcY1,
332 GLint dstX0,
333 GLint dstY0,
334 GLint dstX1,
335 GLint dstY1,
336 GLbitfield mask,
337 GLenum filter);
338
316339
317 /* GL_ARB_shader_objects */340 /* GL_ARB_shader_objects */
318 #ifndef USE_GLES341 #ifndef USE_GLES
@@ -413,11 +436,12 @@
413 extern GLDisableVertexAttribArrayProc disableVertexAttribArray;436 extern GLDisableVertexAttribArrayProc disableVertexAttribArray;
414 extern GLVertexAttribPointerProc vertexAttribPointer;437 extern GLVertexAttribPointerProc vertexAttribPointer;
415438
416 extern GLGenRenderbuffersProc genRenderbuffers;439 extern GLGenRenderbuffersProc genRenderbuffers;
417 extern GLDeleteRenderbuffersProc deleteRenderbuffers;440 extern GLDeleteRenderbuffersProc deleteRenderbuffers;
418 extern GLBindRenderbufferProc bindRenderbuffer;441 extern GLBindRenderbufferProc bindRenderbuffer;
419 extern GLFramebufferRenderbufferProc framebufferRenderbuffer;442 extern GLFramebufferRenderbufferProc framebufferRenderbuffer;
420 extern GLRenderbufferStorageProc renderbufferStorage;443 extern GLRenderbufferStorageProc renderbufferStorage;
444 extern GLBlitFramebufferProc blitFramebuffer;
421445
422 #ifndef USE_GLES446 #ifndef USE_GLES
423 extern GLCreateShaderObjectARBProc createShaderObjectARB;447 extern GLCreateShaderObjectARBProc createShaderObjectARB;
@@ -579,7 +603,6 @@
579extern GLScreenPaintAttrib defaultScreenPaintAttrib;603extern GLScreenPaintAttrib defaultScreenPaintAttrib;
580604
581class GLScreen;605class GLScreen;
582class GLFramebufferObject;
583606
584class GLScreenInterface :607class GLScreenInterface :
585 public WrapableInterface<GLScreen, GLScreenInterface>608 public WrapableInterface<GLScreen, GLScreenInterface>
@@ -656,9 +679,9 @@
656 * @param scratchFbo Describes the final composited FBO that is679 * @param scratchFbo Describes the final composited FBO that is
657 * to be rendered.680 * to be rendered.
658 */681 */
659 virtual void glPaintCompositedOutput (const CompRegion &region,682 virtual void glPaintCompositedOutput (const CompRegion &region,
660 GLFramebufferObject *fbo,683 compiz::opengl::DirectDrawFramebufferObject *fbo,
661 unsigned int mask);684 unsigned int mask);
662685
663 /**686 /**
664 * Hookable function used by plugins to determine stenciling mask687 * Hookable function used by plugins to determine stenciling mask
@@ -756,13 +779,18 @@
756 /**779 /**
757 * Returns the FBO compiz is using for the screen780 * Returns the FBO compiz is using for the screen
758 */781 */
759 GLFramebufferObject *fbo ();782 compiz::opengl::FramebufferObject * fbo();
760783
761 /**784 /**
762 * Returns a default icon texture785 * Returns a default icon texture
763 */786 */
764 GLTexture *defaultIcon ();787 GLTexture *defaultIcon ();
765788
789 /**
790 * Returns the current framebuffer function for blitting the framebuffer
791 */
792 const compiz::opengl::BlitFramebufferFunc & blitFramebufferFunc ();
793
766 void resetRasterPos ();794 void resetRasterPos ();
767795
768 bool glInitContext (XVisualInfo *);796 bool glInitContext (XVisualInfo *);
@@ -783,7 +811,7 @@
783811
784 WRAPABLE_HND (5, GLScreenInterface, GLMatrix *, projectionMatrix);812 WRAPABLE_HND (5, GLScreenInterface, GLMatrix *, projectionMatrix);
785 WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput,813 WRAPABLE_HND (6, GLScreenInterface, void, glPaintCompositedOutput,
786 const CompRegion &, GLFramebufferObject *, unsigned int);814 const CompRegion &, compiz::opengl::DirectDrawFramebufferObject *, unsigned int);
787815
788 WRAPABLE_HND (7, GLScreenInterface, void, glBufferStencil, const GLMatrix &,816 WRAPABLE_HND (7, GLScreenInterface, void, glBufferStencil, const GLMatrix &,
789 GLVertexBuffer &,817 GLVertexBuffer &,
790818
=== 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 2012-09-15 15:18:21 +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 2012-09-15 15:18:21 +0000
@@ -0,0 +1,103 @@
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{
37 namespace opengl
38 {
39 namespace impl
40 {
41 namespace cglfb = compiz::opengl;
42
43 class PrivateDirectDrawFramebufferStrategies;
44
45 class DirectDrawFramebufferStrategies :
46 public cglfb::DirectDrawFramebufferStrategies
47 {
48 public:
49
50 DirectDrawFramebufferStrategies (const FramebufferRectangularDrawStrategyList &strategies);
51
52 void draw (const CompRect &src,
53 const CompRect &dst,
54 FramebufferBlitInformation mask,
55 FramebufferFilter filter);
56
57 private:
58
59 std::auto_ptr <PrivateDirectDrawFramebufferStrategies> priv;
60 };
61
62 class PrivateDirectDrawFramebufferObject;
63
64 class DirectDrawFramebufferObject :
65 virtual public cglfb::FramebufferObject,
66 public cglfb::DirectDrawFramebufferObject
67 {
68 public:
69
70 DirectDrawFramebufferObject (const boost::shared_ptr <cglfb::DirectDrawFramebufferStrategies> &,
71 const boost::shared_ptr <cglfb::FramebufferObject> &);
72
73 bool allocate (const CompSize &size,
74 const char *image = NULL,
75 GLenum format = GL_RGBA,
76 GLenum type = GL_UNSIGNED_BYTE);
77 FramebufferObject *bind (compiz::opengl::FramebufferBindPoint bindPoint =
78 compiz::opengl::Draw);
79 bool checkStatus (compiz::opengl::FramebufferBindPoint bindPoint =
80 compiz::opengl::Draw);
81 GLTexture * tex ();
82
83 void directDraw (const CompRect &src,
84 const CompRect &dst,
85 compiz::opengl::FramebufferBlitInformation mask,
86 compiz::opengl::FramebufferFilter filter);
87
88 private:
89
90 PrivateDirectDrawFramebufferObject *priv;
91 };
92
93 bool dispatchRectangleDrawStrategyWithPushedReadBuffer (const CompRect &src,
94 const CompRect &dst,
95 GLbitfield mask,
96 GLenum filter,
97 cglfb::PushableFramebuffer *pushableFramebuffer,
98 cglfb::FramebufferRectangularDrawStrategy strategy);
99 }
100 }
101}
102
103#endif
0104
=== 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 2012-09-15 15:18:21 +0000
@@ -0,0 +1,159 @@
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{
35 namespace opengl
36 {
37 namespace impl
38 {
39 class PrivateDirectDrawFramebufferStrategies
40 {
41 public:
42
43 PrivateDirectDrawFramebufferStrategies (const cglfb::FramebufferRectangularDrawStrategyList &strategies) :
44 rectangularDrawStrategies (strategies)
45 {
46 }
47
48 cglfb::FramebufferRectangularDrawStrategyList rectangularDrawStrategies;
49 };
50
51 class PrivateDirectDrawFramebufferObject
52 {
53 public:
54
55 PrivateDirectDrawFramebufferObject (const boost::shared_ptr <cglfb::DirectDrawFramebufferStrategies> &strategies,
56 const boost::shared_ptr <cglfb::FramebufferObject> &object) :
57 directDrawStrategies (strategies),
58 framebufferObject (object)
59 {
60 };
61
62 boost::shared_ptr <cglfb::DirectDrawFramebufferStrategies> directDrawStrategies;
63 boost::shared_ptr <cglfb::FramebufferObject> framebufferObject;
64 };
65 }
66 }
67}
68
69cglfbi::DirectDrawFramebufferObject::DirectDrawFramebufferObject (const boost::shared_ptr <cglfb::DirectDrawFramebufferStrategies> &strategies,
70 const boost::shared_ptr <cglfb::FramebufferObject> &object) :
71 priv (new PrivateDirectDrawFramebufferObject (strategies, object))
72{
73}
74
75bool
76cglfbi::DirectDrawFramebufferObject::allocate (const CompSize &size, const char *image,
77 GLenum format, GLenum type)
78{
79 return priv->framebufferObject->allocate (size, image, format, type);
80}
81
82cglfb::FramebufferObject *
83cglfbi::DirectDrawFramebufferObject::bind (cglfb::FramebufferBindPoint bindPoint)
84{
85 return priv->framebufferObject->bind (bindPoint);
86}
87
88bool
89cglfbi::DirectDrawFramebufferObject::checkStatus (cglfb::FramebufferBindPoint bindPoint)
90{
91 return priv->framebufferObject->checkStatus (bindPoint);
92}
93
94GLTexture *
95cglfbi::DirectDrawFramebufferObject::tex ()
96{
97 return priv->framebufferObject->tex ();
98}
99
100void
101cglfbi::DirectDrawFramebufferObject::directDraw (const CompRect &src,
102 const CompRect &dst,
103 cglfb::FramebufferBlitInformation mask,
104 cglfb::FramebufferFilter filter)
105{
106 if (!checkStatus ())
107 return;
108
109 priv->directDrawStrategies->draw (src, dst, mask, filter);
110}
111
112bool
113cglfbi::dispatchRectangleDrawStrategyWithPushedReadBuffer (const CompRect &src,
114 const CompRect &dst,
115 GLbitfield mask,
116 GLenum filter,
117 cglfb::PushableFramebuffer *pushableFramebuffer,
118 cglfb::FramebufferRectangularDrawStrategy strategy)
119{
120 bool status = false;
121 /* Bind to the read framebuffer first */
122 pushableFramebuffer->pushFBO (cglfb::Read);
123 status = strategy (src, dst, mask, filter);
124 pushableFramebuffer->popFBO ();
125 return status;
126}
127
128cglfbi::DirectDrawFramebufferStrategies::DirectDrawFramebufferStrategies (const cglfb::FramebufferRectangularDrawStrategyList &strategies) :
129 priv (new PrivateDirectDrawFramebufferStrategies (strategies))
130{
131}
132
133void
134cglfbi::DirectDrawFramebufferStrategies::draw (const CompRect &src,
135 const CompRect &dst,
136 cglfb::FramebufferBlitInformation mask,
137 cglfb::FramebufferFilter filter)
138{
139 if (!mask)
140 return;
141
142 const GLbitfield glMask = (mask & cglfb::ColorData ? GL_COLOR_BUFFER_BIT : 0) |
143 (mask & cglfb::StencilData ? GL_STENCIL_BUFFER_BIT : 0);
144 const GLenum glFilter = (filter == cglfb::Fast ? GL_NEAREST : GL_LINEAR);
145
146 cglfb::FramebufferRectangularDrawStrategyList::reverse_iterator rit =
147 priv->rectangularDrawStrategies.rbegin ();
148
149 while (!priv->rectangularDrawStrategies.empty ())
150 {
151 const cglfb::FramebufferRectangularDrawStrategy &strategy = priv->rectangularDrawStrategies.back ();
152
153 /* If one method fails, try the next */
154 if (!strategy (src, dst, glMask, glFilter))
155 priv->rectangularDrawStrategies.pop_back ();
156 else
157 break;
158 }
159}
0160
=== 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 2012-09-15 15:18:21 +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 2012-09-15 15:18:21 +0000
@@ -0,0 +1,219 @@
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;
39
40namespace cglfb = compiz::opengl;
41namespace cglfbi = compiz::opengl::impl;
42
43namespace
44{
45 class MockFramebufferRectangularDrawStrategy
46 {
47 public:
48
49 MOCK_METHOD4 (draw, bool (const CompRect &,
50 const CompRect &,
51 GLbitfield,
52 GLenum));
53 };
54
55 class MockPushableFramebuffer :
56 public cglfb::PushableFramebuffer
57 {
58 public:
59
60 MOCK_METHOD1 (pushFBO, void (cglfb::FramebufferBindPoint));
61 MOCK_METHOD0 (popFBO, void ());
62 };
63}
64
65class DirectDrawFramebufferStrategiesTest :
66 public ::testing::Test
67{
68 public:
69
70 DirectDrawFramebufferStrategiesTest () :
71 blitFramebuffer (boost::bind (&MockFramebufferRectangularDrawStrategy::draw, &mpfb, _1, _2, _3, _4)),
72 rtdraw (boost::bind (&MockFramebufferRectangularDrawStrategy::draw, &mdr,
73 _1, _2, _3, _4))
74 {
75 }
76
77 void SetUpStrategyList (const cglfb::FramebufferRectangularDrawStrategy &blit,
78 const cglfb::FramebufferRectangularDrawStrategy &draw)
79 {
80 strategyList.clear ();
81 strategyList.push_back (draw);
82 strategyList.push_back (blit);
83 }
84
85 virtual void SetUp ()
86 {
87 blitFramebufferWithReadPushed = boost::bind (&cglfbi::dispatchRectangleDrawStrategyWithPushedReadBuffer,
88 _1, _2, _3, _4,
89 &mpushable,
90 blitFramebuffer);
91
92 SetUpStrategyList (blitFramebuffer, rtdraw);
93 directDraw.reset (new cglfbi::DirectDrawFramebufferStrategies (strategyList));
94 }
95
96 std::auto_ptr <cglfbi::DirectDrawFramebufferStrategies> directDraw;
97 MockFramebufferRectangularDrawStrategy mpfb;
98 cglfb::FramebufferRectangularDrawStrategy blitFramebuffer;
99 cglfb::FramebufferRectangularDrawStrategy blitFramebufferWithReadPushed;
100 MockFramebufferRectangularDrawStrategy mdr;
101 StrictMock <MockPushableFramebuffer> mpushable;
102 cglfb::FramebufferRectangularDrawStrategy rtdraw;
103 cglfb::FramebufferRectangularDrawStrategyList strategyList;
104
105};
106
107TEST_F (DirectDrawFramebufferStrategiesTest, TestBufferBitsSet)
108{
109 CompRect srcAndDst (0, 0, 0, 0);
110
111 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, GL_COLOR_BUFFER_BIT |
112 GL_STENCIL_BUFFER_BIT,
113 _)).WillOnce (Return (true));
114
115 directDraw->draw (srcAndDst,
116 srcAndDst,
117 static_cast <cglfb::FramebufferBlitInformation> (cglfb::ColorData | cglfb::StencilData),
118 cglfb::Good);
119}
120
121TEST_F (DirectDrawFramebufferStrategiesTest, TestBufferNoBitsSet)
122{
123 CompRect srcAndDst (0, 0, 0, 0);
124
125 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, 0,
126 _)).Times (0);
127
128 directDraw->draw (srcAndDst,
129 srcAndDst,
130 static_cast <cglfb::FramebufferBlitInformation> (0),
131 cglfb::Good);
132}
133
134TEST_F (DirectDrawFramebufferStrategiesTest, TestGoodToLinear)
135{
136 CompRect srcAndDst (0, 0, 0, 0);
137
138 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _,
139 GL_LINEAR)).WillOnce (Return (true));
140
141 directDraw->draw (srcAndDst,
142 srcAndDst,
143 cglfb::ColorData,
144 cglfb::Good);
145}
146
147TEST_F (DirectDrawFramebufferStrategiesTest, TestFastToNearest)
148{
149 CompRect srcAndDst (0, 0, 0, 0);
150
151 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _,
152 GL_NEAREST)).WillOnce (Return (true));
153
154 directDraw->draw (srcAndDst,
155 srcAndDst,
156 cglfb::ColorData,
157 cglfb::Fast);
158}
159
160TEST_F (DirectDrawFramebufferStrategiesTest, TestRevertToPaintWhenBlitUnavailable)
161{
162 CompRect srcAndDst (0, 0, 0, 0);
163
164 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _,
165 _)).WillOnce (Return (false));
166 EXPECT_CALL (mdr, draw (srcAndDst, srcAndDst, _, _));
167
168 directDraw->draw (srcAndDst,
169 srcAndDst,
170 cglfb::ColorData,
171 cglfb::Fast);
172}
173
174TEST_F (DirectDrawFramebufferStrategiesTest, TestRevertOnBlitUnavailablePermanent)
175{
176 StrictMock <MockFramebufferRectangularDrawStrategy> strictMdr;
177 CompRect srcAndDst (0, 0, 0, 0);
178
179 rtdraw = boost::bind (&MockFramebufferRectangularDrawStrategy::draw, &strictMdr, _1, _2, _3, _4);
180
181 SetUpStrategyList (blitFramebuffer, rtdraw);
182 directDraw.reset (new cglfbi::DirectDrawFramebufferStrategies (strategyList));
183
184 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, _)).WillOnce (Return (false));
185 ON_CALL (strictMdr, draw (_, _, _, _)).WillByDefault (Return (true));
186 EXPECT_CALL (strictMdr, draw (srcAndDst, srcAndDst, _, _)).Times (2);
187
188 directDraw->draw (srcAndDst,
189 srcAndDst,
190 cglfb::ColorData,
191 cglfb::Fast);
192 directDraw->draw (srcAndDst,
193 srcAndDst,
194 cglfb::ColorData,
195 cglfb::Fast);
196}
197
198TEST_F (DirectDrawFramebufferStrategiesTest, TestPushAndPopReadFramebufferOnBlit)
199{
200 CompRect srcAndDst (0, 0, 0, 0);
201
202 SetUpStrategyList (blitFramebufferWithReadPushed, rtdraw);
203 directDraw.reset (new cglfbi::DirectDrawFramebufferStrategies (strategyList));
204
205 EXPECT_CALL (mpushable, pushFBO (cglfb::Read));
206 EXPECT_CALL (mpfb, draw (srcAndDst, srcAndDst, _, _)).WillOnce (Return (false));
207 EXPECT_CALL (mpushable, popFBO ());
208 ON_CALL (mdr, draw (_, _, _, _)).WillByDefault (Return (true));
209 EXPECT_CALL (mdr, draw (srcAndDst, srcAndDst, _, _)).Times (2);
210
211 directDraw->draw (srcAndDst,
212 srcAndDst,
213 cglfb::ColorData,
214 cglfb::Fast);
215 directDraw->draw (srcAndDst,
216 srcAndDst,
217 cglfb::ColorData,
218 cglfb::Fast);
219}
0220
=== modified file 'plugins/opengl/src/framebufferobject.cpp'
--- plugins/opengl/src/framebufferobject.cpp 2012-08-06 09:44:49 +0000
+++ plugins/opengl/src/framebufferobject.cpp 2012-09-15 15:18:21 +0000
@@ -22,87 +22,135 @@
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
30struct PrivateGLFramebufferObject31#include "framebuffer-direct-draw.h"
31{32
32 PrivateGLFramebufferObject () :33namespace cglfb = compiz::opengl;
33 fboId (0),34namespace cglfbi = compiz::opengl::impl;
34 pushedId (0),35
35 glTex (NULL),36namespace compiz
36 status (-1)37{
37 {38 namespace opengl
38 }39 {
3940 namespace impl
40 void pushFBO ();41 {
41 void popFBO ();42 struct PrivateGLFramebufferObject :
4243 public cglfb::PushableFramebuffer
43 GLuint fboId;44 {
44 GLuint pushedId;45 PrivateGLFramebufferObject () :
45 GLuint rbStencilId;46 fboId (0),
46 GLTexture *glTex;47 pushedId (0),
4748 glTex (NULL),
48 GLint status;49 status (-1)
4950 {
50 static GLuint boundId;51 }
51 static std::map<GLuint, GLFramebufferObject *> idMap;52
52};53 void pushFBO (cglfb::FramebufferBindPoint bindPoint);
5354 void popFBO ();
54GLuint PrivateGLFramebufferObject::boundId = 0;55
55std::map<GLuint, GLFramebufferObject *> PrivateGLFramebufferObject::idMap;56 GLuint fboId;
57 GLuint pushedId;
58 GLuint rbStencilId;
59 GLTexture *glTex;
60
61 GLint status;
62
63 std::auto_ptr <cglfb::DirectDrawFramebufferStrategies> mDirectDraw;
64 GLenum mBindPoint;
65 GLVertexBuffer *vertexBuffer;
66
67 static GLuint boundId;
68 static std::map<GLuint, cglfbi::FramebufferObject *> idMap;
69 };
70
71 GLuint PrivateGLFramebufferObject::boundId = 0;
72 std::map<GLuint, cglfbi::FramebufferObject *> PrivateGLFramebufferObject::idMap;
73 }
74 }
75}
76
77namespace
78{
79 inline GLenum framebufferBindPointToGLBinding (cglfb::FramebufferBindPoint bindPoint)
80 {
81 static const GLenum bindings[] =
82 {
83 GL::READ_FRAMEBUFFER,
84 GL::DRAW_FRAMEBUFFER
85 };
86
87 return bindings[static_cast <int> (bindPoint)];
88 }
89}
5690
57void91void
58PrivateGLFramebufferObject::pushFBO ()92cglfbi::PrivateGLFramebufferObject::pushFBO (cglfb::FramebufferBindPoint bindPoint)
59{93{
94 GLenum binding = framebufferBindPointToGLBinding (bindPoint);
95
60 pushedId = boundId;96 pushedId = boundId;
61 if (boundId != fboId)97 if (boundId != fboId)
62 {98 {
63 (*GL::bindFramebuffer) (GL::FRAMEBUFFER, fboId);99 mBindPoint = binding;
100 (*GL::bindFramebuffer) (mBindPoint, fboId);
64 boundId = fboId;101 boundId = fboId;
65 }102 }
66}103}
67104
68void105void
69PrivateGLFramebufferObject::popFBO ()106cglfbi::FramebufferObject::popFBO ()
107{
108 priv->popFBO ();
109}
110
111void
112cglfbi::FramebufferObject::pushFBO (cglfb::FramebufferBindPoint bindPoint)
113{
114 priv->pushFBO (bindPoint);
115}
116
117void
118cglfbi::PrivateGLFramebufferObject::popFBO ()
70{119{
71 if (boundId != pushedId)120 if (boundId != pushedId)
72 {121 {
73 (*GL::bindFramebuffer) (GL::FRAMEBUFFER, pushedId);122 (*GL::bindFramebuffer) (mBindPoint, pushedId);
74 boundId = pushedId;123 boundId = pushedId;
75 }124 }
76}125}
77126
78GLFramebufferObject::GLFramebufferObject () :127cglfbi::FramebufferObject::FramebufferObject () :
79 priv (new PrivateGLFramebufferObject)128 priv (new cglfbi::PrivateGLFramebufferObject ())
80{129{
81 (*GL::genFramebuffers) (1, &priv->fboId);130 (*GL::genFramebuffers) (1, &priv->fboId);
82 (*GL::genRenderbuffers) (1, &priv->rbStencilId);131 (*GL::genRenderbuffers) (1, &priv->rbStencilId);
83132
84 if (priv->fboId != 0)133 if (priv->fboId != 0)
85 PrivateGLFramebufferObject::idMap[priv->fboId] = this;134 cglfbi::PrivateGLFramebufferObject::idMap[priv->fboId] = this;
86}135}
87136
88GLFramebufferObject::~GLFramebufferObject ()137cglfbi::FramebufferObject::~FramebufferObject ()
89{138{
90 if (priv->glTex)139 if (priv->glTex)
91 GLTexture::decRef (priv->glTex);140 GLTexture::decRef (priv->glTex);
92141
93 PrivateGLFramebufferObject::idMap.erase (priv->fboId);142 cglfbi::PrivateGLFramebufferObject::idMap.erase (priv->fboId);
94 (*GL::deleteFramebuffers) (1, &priv->fboId);143 (*GL::deleteFramebuffers) (1, &priv->fboId);
95 (*GL::deleteRenderbuffers) (1, &priv->rbStencilId);144 (*GL::deleteRenderbuffers) (1, &priv->rbStencilId);
96145
97
98 delete priv;146 delete priv;
99}147}
100148
101bool149bool
102GLFramebufferObject::allocate (const CompSize &size, const char *image,150cglfbi::FramebufferObject::allocate (const CompSize &size, const char *image,
103 GLenum format, GLenum type)151 GLenum format, GLenum type)
104{152{
105 priv->status = -1;153 priv->status = 0;
106154
107 if (!priv->glTex ||155 if (!priv->glTex ||
108 size.width () != priv->glTex->width () ||156 size.width () != priv->glTex->width () ||
@@ -127,53 +175,59 @@
127 }175 }
128 }176 }
129177
130 priv->pushFBO ();178 priv->pushFBO (cglfb::Draw);
131179
132 (*GL::framebufferTexture2D) (GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0,180 (*GL::framebufferTexture2D) (priv->mBindPoint, GL::COLOR_ATTACHMENT0,
133 priv->glTex->target (),181 priv->glTex->target (),
134 priv->glTex->name (), 0);182 priv->glTex->name (), 0);
135183
136 priv->status = (*GL::checkFramebufferStatus) (GL::DRAW_FRAMEBUFFER);184 priv->status = (*GL::checkFramebufferStatus) (priv->mBindPoint);
137185
138 priv->popFBO ();186 priv->popFBO ();
139 return true;187 return true;
140}188}
141189
142GLFramebufferObject *190cglfbi::FramebufferObject *
143GLFramebufferObject::bind ()191cglfbi::FramebufferObject::bind (cglfb::FramebufferBindPoint bindPoint)
144{192{
145 GLFramebufferObject *old = NULL;193 const GLenum binding = framebufferBindPointToGLBinding (bindPoint);
194
195 cglfbi::FramebufferObject *old = NULL;
146196
147 if (priv->boundId != 0)197 if (priv->boundId != 0)
148 {198 {
149 std::map<GLuint, GLFramebufferObject *>::iterator it;199 std::map<GLuint, cglfbi::FramebufferObject *>::iterator it;
150 it = PrivateGLFramebufferObject::idMap.find (priv->boundId);200 it = cglfbi::PrivateGLFramebufferObject::idMap.find (priv->boundId);
151201
152 if (it != PrivateGLFramebufferObject::idMap.end ())202 if (it != cglfbi::PrivateGLFramebufferObject::idMap.end ())
153 old = it->second;203 old = it->second;
154 else204 else
155 compLogMessage ("opengl", CompLogLevelError,205 compLogMessage ("opengl", CompLogLevelError,
156 "An FBO without GLFramebufferObject cannot be restored");206 "An FBO without GLFramebufferObject cannot be restored");
157 }207 }
158208
159 (*GL::bindFramebuffer) (GL::FRAMEBUFFER, priv->fboId);209 priv->mBindPoint = binding;
210
211 (*GL::bindFramebuffer) (priv->mBindPoint, priv->fboId);
160 priv->boundId = priv->fboId;212 priv->boundId = priv->fboId;
161213
162 (*GL::framebufferRenderbuffer) (GL::FRAMEBUFFER, GL::DEPTH_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId);214 (*GL::framebufferRenderbuffer) (priv->mBindPoint, GL::DEPTH_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId);
163 (*GL::framebufferRenderbuffer) (GL::FRAMEBUFFER, GL::STENCIL_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId);215 (*GL::framebufferRenderbuffer) (priv->mBindPoint, GL::STENCIL_ATTACHMENT, GL::RENDERBUFFER, priv->rbStencilId);
164
165 return old;216 return old;
166}217}
167218
168// static219// static
169void220void
170GLFramebufferObject::rebind (GLFramebufferObject *fbo)221cglfbi::FramebufferObject::rebind (cglfbi::FramebufferObject *fbo,
222 cglfb::FramebufferBindPoint bindPoint)
171{223{
172 GLuint id = fbo ? fbo->priv->fboId : 0;224 GLuint id = fbo ? fbo->priv->fboId : 0;
225 const GLenum binding = fbo ? fbo->priv->mBindPoint :
226 framebufferBindPointToGLBinding (bindPoint);
173227
174 if (id != fbo->priv->boundId)228 if (id != fbo->priv->boundId)
175 {229 {
176 (*GL::bindFramebuffer) (GL::FRAMEBUFFER, id);230 (*GL::bindFramebuffer) (binding, id);
177 fbo->priv->boundId = id;231 fbo->priv->boundId = id;
178 }232 }
179}233}
@@ -199,11 +253,16 @@
199}253}
200254
201bool255bool
202GLFramebufferObject::checkStatus ()256cglfbi::FramebufferObject::checkStatus (cglfb::FramebufferBindPoint bindPoint)
203{257{
204 priv->pushFBO ();258 const GLenum binding = framebufferBindPointToGLBinding (bindPoint);
205 priv-> status = (*GL::checkFramebufferStatus) (GL_FRAMEBUFFER);259
206 priv->popFBO ();260 if (!priv->status)
261 {
262 priv->pushFBO (bindPoint);
263 priv->status = (*GL::checkFramebufferStatus) (binding);
264 priv->popFBO ();
265 }
207266
208 if (priv->status == static_cast <GLint> (GL::FRAMEBUFFER_COMPLETE))267 if (priv->status == static_cast <GLint> (GL::FRAMEBUFFER_COMPLETE))
209 return true;268 return true;
@@ -215,7 +274,7 @@
215}274}
216275
217GLTexture *276GLTexture *
218GLFramebufferObject::tex ()277cglfbi::FramebufferObject::tex ()
219{278{
220 return priv->glTex;279 return priv->glTex;
221}280}
222281
=== modified file 'plugins/opengl/src/paint.cpp'
--- plugins/opengl/src/paint.cpp 2012-09-06 09:55:05 +0000
+++ plugins/opengl/src/paint.cpp 2012-09-15 15:18:21 +0000
@@ -43,6 +43,7 @@
43#define DEG2RAD (M_PI / 180.0f)43#define DEG2RAD (M_PI / 180.0f)
4444
45using namespace compiz::opengl;45using namespace compiz::opengl;
46namespace cglfb = compiz::opengl;
4647
47GLScreenPaintAttrib defaultScreenPaintAttrib = {48GLScreenPaintAttrib defaultScreenPaintAttrib = {
48 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA49 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA
@@ -628,91 +629,16 @@
628}629}
629630
630void631void
631GLScreen::glPaintCompositedOutput (const CompRegion &region,632GLScreen::glPaintCompositedOutput (const CompRegion &region,
632 GLFramebufferObject *fbo,633 compiz::opengl::DirectDrawFramebufferObject *fbo,
633 unsigned int mask)634 unsigned int mask)
634{635{
635 WRAPABLE_HND_FUNCTN (glPaintCompositedOutput, region, fbo, mask)636 WRAPABLE_HND_FUNCTN (glPaintCompositedOutput, region, fbo, mask)
636637
637 GLMatrix sTransform;638 /* Draw every rect individually, this could be a little slow
638 std::vector<GLfloat> vertexData;639 * for lots of rects, but the general usecase isn't that */
639 std::vector<GLfloat> textureData;640 foreach (const CompRect &r, region.rects ())
640 const GLTexture::Matrix & texmatrix = fbo->tex ()->matrix ();641 fbo->directDraw (r, r, cglfb::ColorData, cglfb::Fast);
641 GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
642
643 streamingBuffer->begin (GL_TRIANGLES);
644
645 if (mask & COMPOSITE_SCREEN_DAMAGE_ALL_MASK)
646 {
647 GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, 0.0f);
648 GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, screen->width ());
649 GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, 0.0f);
650 GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, screen->height ());
651
652 vertexData = {
653 0.0f, 0.0f, 0.0f,
654 0.0f, (float)screen->height (), 0.0f,
655 (float)screen->width (), 0.0f, 0.0f,
656
657 0.0f, (float)screen->height (), 0.0f,
658 (float)screen->width (), (float)screen->height (), 0.0f,
659 (float)screen->width (), 0.0f, 0.0f,
660 };
661
662 textureData = {
663 tx1, ty1,
664 tx1, ty2,
665 tx2, ty1,
666 tx1, ty2,
667 tx2, ty2,
668 tx2, ty1,
669 };
670
671 streamingBuffer->addVertices (6, &vertexData[0]);
672 streamingBuffer->addTexCoords (0, 6, &textureData[0]);
673 }
674 else
675 {
676 BoxPtr pBox = const_cast <Region> (region.handle ())->rects;
677 int nBox = const_cast <Region> (region.handle ())->numRects;
678
679 while (nBox--)
680 {
681 GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, pBox->x1);
682 GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, pBox->x2);
683 GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y1);
684 GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, pBox->y2);
685
686 vertexData = {
687 (float)pBox->x1, (float)pBox->y1, 0.0f,
688 (float)pBox->x1, (float)pBox->y2, 0.0f,
689 (float)pBox->x2, (float)pBox->y1, 0.0f,
690
691 (float)pBox->x1, (float)pBox->y2, 0.0f,
692 (float)pBox->x2, (float)pBox->y2, 0.0f,
693 (float)pBox->x2, (float)pBox->y1, 0.0f,
694 };
695
696 textureData = {
697 tx1, ty1,
698 tx1, ty2,
699 tx2, ty1,
700 tx1, ty2,
701 tx2, ty2,
702 tx2, ty1,
703 };
704
705 streamingBuffer->addVertices (6, &vertexData[0]);
706 streamingBuffer->addTexCoords (0, 6, &textureData[0]);
707 pBox++;
708 }
709 }
710
711 streamingBuffer->end ();
712 fbo->tex ()->enable (GLTexture::Fast);
713 sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
714 streamingBuffer->render (sTransform);
715 fbo->tex ()->disable ();
716}642}
717643
718static void644static void
719645
=== modified file 'plugins/opengl/src/privates.h'
--- plugins/opengl/src/privates.h 2012-09-12 04:01:02 +0000
+++ plugins/opengl/src/privates.h 2012-09-15 15:18:21 +0000
@@ -28,20 +28,28 @@
28#ifndef _OPENGL_PRIVATES_H28#ifndef _OPENGL_PRIVATES_H
29#define _OPENGL_PRIVATES_H29#define _OPENGL_PRIVATES_H
3030
31#include <memory>
31#include <composite/composite.h>32#include <composite/composite.h>
32#include <opengl/opengl.h>33#include <opengl/opengl.h>
33#include <core/atoms.h>34#include <core/atoms.h>
34
35#ifdef USE_GLES
36#include <opengl/framebufferobject.h>35#include <opengl/framebufferobject.h>
37#endif
38
39#include <opengl/doublebuffer.h>36#include <opengl/doublebuffer.h>
4037
41#include "privatetexture.h"38#include "privatetexture.h"
42#include "privatevertexbuffer.h"39#include "privatevertexbuffer.h"
43#include "opengl_options.h"40#include "opengl_options.h"
4441
42namespace compiz
43{
44 namespace opengl
45 {
46 namespace impl
47 {
48 class DirectDrawFramebufferObject;
49 }
50 }
51}
52
45extern CompOutput *targetOutput;53extern CompOutput *targetOutput;
4654
47class GLDoubleBuffer :55class GLDoubleBuffer :
@@ -81,6 +89,17 @@
81 Window mOutput;89 Window mOutput;
82};90};
8391
92namespace compiz
93{
94 namespace opengl
95 {
96 bool blitFramebufferGLX (const CompRect &src,
97 const CompRect &dst,
98 GLbitfield mask,
99 GLenum filter);
100 }
101}
102
84#else103#else
85104
86class EGLDoubleBuffer :105class EGLDoubleBuffer :
@@ -104,6 +123,17 @@
104 EGLSurface const & mSurface;123 EGLSurface const & mSurface;
105};124};
106125
126namespace compiz
127{
128 namespace opengl
129 {
130 bool blitFramebufferEGL (const CompRect &src,
131 const CompRect &dst,
132 GLbitfield mask,
133 GLenum filter);
134 }
135}
136
107#endif137#endif
108138
109class GLIcon139class GLIcon
@@ -189,8 +219,9 @@
189 GLXDoubleBuffer doubleBuffer;219 GLXDoubleBuffer doubleBuffer;
190 #endif220 #endif
191221
192 GLFramebufferObject *scratchFbo;222 std::auto_ptr <compiz::opengl::impl::DirectDrawFramebufferObject> scratchFbo;
193 CompRegion outputRegion;223 compiz::opengl::BlitFramebufferFunc blitFramebuffer;
224 CompRegion outputRegion;
194225
195 XRectangle lastViewport;226 XRectangle lastViewport;
196 bool refreshSubBuffer;227 bool refreshSubBuffer;
197228
=== modified file 'plugins/opengl/src/screen.cpp'
--- plugins/opengl/src/screen.cpp 2012-09-13 08:35:17 +0000
+++ plugins/opengl/src/screen.cpp 2012-09-15 15:18:21 +0000
@@ -32,12 +32,35 @@
32#endif32#endif
33#include <errno.h>33#include <errno.h>
3434
35#include <boost/make_shared.hpp>
36
35#include "privates.h"37#include "privates.h"
38#include "framebuffer-direct-draw.h"
3639
37#include <dlfcn.h>40#include <dlfcn.h>
38#include <math.h>41#include <math.h>
3942
40using namespace compiz::opengl;43using namespace compiz::opengl;
44namespace cglfb = compiz::opengl;
45namespace cgli = compiz::opengl::impl;
46
47namespace compiz
48{
49 namespace opengl
50 {
51#ifndef USE_GLES
52 bool blitFramebufferGLX (const CompRect &src,
53 const CompRect &dst,
54 GLbitfield mask,
55 GLenum filter);
56#else
57 bool blitFramebufferEGL (const CompRect &src,
58 const CompRect &dst,
59 GLbitfield mask,
60 GLenum filter);
61#endif
62 }
63}
4164
42namespace GL {65namespace GL {
43 #ifdef USE_GLES66 #ifdef USE_GLES
@@ -135,11 +158,12 @@
135 GLDisableVertexAttribArrayProc disableVertexAttribArray = NULL;158 GLDisableVertexAttribArrayProc disableVertexAttribArray = NULL;
136 GLVertexAttribPointerProc vertexAttribPointer = NULL;159 GLVertexAttribPointerProc vertexAttribPointer = NULL;
137160
138 GLGenRenderbuffersProc genRenderbuffers = NULL;161 GLGenRenderbuffersProc genRenderbuffers = NULL;
139 GLDeleteRenderbuffersProc deleteRenderbuffers = NULL;162 GLDeleteRenderbuffersProc deleteRenderbuffers = NULL;
140 GLFramebufferRenderbufferProc framebufferRenderbuffer = NULL;163 GLFramebufferRenderbufferProc framebufferRenderbuffer = NULL;
141 GLBindRenderbufferProc bindRenderbuffer = NULL;164 GLBindRenderbufferProc bindRenderbuffer = NULL;
142 GLRenderbufferStorageProc renderbufferStorage = NULL;165 GLRenderbufferStorageProc renderbufferStorage = NULL;
166 GLBlitFramebufferProc blitFramebuffer = NULL;
143167
144 bool textureFromPixmap = true;168 bool textureFromPixmap = true;
145 bool textureRectangle = false;169 bool textureRectangle = false;
@@ -271,6 +295,89 @@
271 GLScreen *gScreen;295 GLScreen *gScreen;
272};296};
273297
298namespace
299{
300 bool defaultRectangularFramebufferDraw (GLVertexBuffer *vertexBuffer,
301 GLFramebufferObject *fbo,
302 const CompRect &src,
303 const CompRect &dst,
304 GLbitfield mask,
305 GLenum filter)
306 {
307 GLTexture *texture = fbo->tex ();
308 GLMatrix sTransform;
309 const GLTexture::Matrix & texmatrix = texture->matrix ();
310 const GLfloat tx1 = COMP_TEX_COORD_X (texmatrix, src.x1 ());
311 const GLfloat tx2 = COMP_TEX_COORD_X (texmatrix, src.x2 ());
312 const GLfloat ty1 = 1.0 - COMP_TEX_COORD_Y (texmatrix, src.y1 ());
313 const GLfloat ty2 = 1.0 - COMP_TEX_COORD_Y (texmatrix, src.y2 ());
314
315 const GLfloat vx1 = src.x1 ();
316 const GLfloat vx2 = src.x2 ();
317 const GLfloat vy1 = src.y1 ();
318 const GLfloat vy2 = src.y2 ();
319
320 const GLTexture::Filter texFilter =
321 (filter == GL_LINEAR) ? GLTexture::Good :
322 GLTexture::Fast;
323
324 std::vector<GLfloat> vertexData = {
325 vx1, vy1, 0.0f,
326 vx1, vy2, 0.0f,
327 vx2, vy1, 0.0f,
328
329 vx1, vy2, 0.0f,
330 vx2, vy2, 0.0f,
331 vx2, vy1, 0.0f,
332 };
333
334 std::vector<GLfloat> textureData = {
335 tx1, ty1,
336 tx1, ty2,
337 tx2, ty1,
338 tx1, ty2,
339 tx2, ty2,
340 tx2, ty1,
341 };
342
343 vertexBuffer->begin (GL_TRIANGLES);
344 vertexBuffer->addVertices (6, &vertexData[0]);
345 vertexBuffer->addTexCoords (0, 6, &textureData[0]);
346
347 if (vertexBuffer->end ())
348 {
349 texture->enable (texFilter);
350 sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
351 vertexBuffer->render (sTransform);
352 texture->disable ();
353 }
354
355 return true;
356 }
357
358 void initializeDirectDraw (boost::shared_ptr <cgli::DirectDrawFramebufferStrategies> &directDraw,
359 const compiz::opengl::FramebufferRectangularDrawStrategy &blitFramebuffer,
360 const compiz::opengl::FramebufferRectangularDrawStrategy &rectangularTextureDraw,
361 cglfb::PushableFramebuffer *pushable)
362 {
363 cglfb::FramebufferRectangularDrawStrategy blitFramebufferWithPush (
364 boost::bind (
365 cgli::dispatchRectangleDrawStrategyWithPushedReadBuffer,
366 _1, _2, _3, _4,
367 pushable,
368 blitFramebuffer));
369
370 /* Tries each of these from back to front */
371 cglfb::FramebufferRectangularDrawStrategyList strategies =
372 {
373 rectangularTextureDraw,
374 blitFramebufferWithPush
375 };
376
377 directDraw.reset (new cgli::DirectDrawFramebufferStrategies (strategies));
378 }
379}
380
274bool381bool
275GLScreen::glInitContext (XVisualInfo *visinfo)382GLScreen::glInitContext (XVisualInfo *visinfo)
276{383{
@@ -500,6 +607,7 @@
500 if (GL::textureFromPixmap)607 if (GL::textureFromPixmap)
501 registerBindPixmap (EglTexture::bindPixmapToTexture);608 registerBindPixmap (EglTexture::bindPixmapToTexture);
502609
610 priv->blitFramebuffer = boost::bind (compiz::opengl::blitFramebufferEGL, _1, _2, _3, _4);
503 #else611 #else
504612
505 Display *dpy = screen->dpy ();613 Display *dpy = screen->dpy ();
@@ -671,6 +779,10 @@
671 GL::fboSupported = true;779 GL::fboSupported = true;
672 }780 }
673781
782 if (GL::fboSupported &&
783 strstr (glExtensions, "GL_EXT_framebuffer_blit"))
784 GL::blitFramebuffer = (GL::GLBlitFramebufferProc) getProcAddress ("glBlitFramebufferEXT");
785
674 GL::fboStencilSupported = GL::fboSupported &&786 GL::fboStencilSupported = GL::fboSupported &&
675 strstr (glExtensions, "GL_EXT_packed_depth_stencil");787 strstr (glExtensions, "GL_EXT_packed_depth_stencil");
676788
@@ -796,11 +908,24 @@
796908
797 if (GL::textureFromPixmap)909 if (GL::textureFromPixmap)
798 registerBindPixmap (TfpTexture::bindPixmapToTexture);910 registerBindPixmap (TfpTexture::bindPixmapToTexture);
911
912 priv->blitFramebuffer = boost::bind (compiz::opengl::blitFramebufferGLX, _1, _2, _3, _4);
799#endif913#endif
800914
801 if (GL::fboSupported)915 if (GL::fboSupported)
802 {916 {
803 priv->scratchFbo = new GLFramebufferObject;917 boost::shared_ptr <cgli::DirectDrawFramebufferStrategies> directDraw;
918 boost::shared_ptr <cgli::FramebufferObject> fbo (boost::make_shared <cgli::FramebufferObject> ());
919 cglfb::FramebufferRectangularDrawStrategy rectangularTextureDraw (boost::bind (defaultRectangularFramebufferDraw,
920 GLVertexBuffer::streamingBuffer (),
921 fbo.get (),
922 _1, _2, _3, _4));
923 initializeDirectDraw (directDraw,
924 priv->blitFramebuffer,
925 rectangularTextureDraw,
926 fbo.get ());
927 priv->scratchFbo.reset (new cgli::DirectDrawFramebufferObject (directDraw,
928 fbo));
804 priv->scratchFbo->allocate (*screen, NULL, GL_BGRA);929 priv->scratchFbo->allocate (*screen, NULL, GL_BGRA);
805 }930 }
806931
@@ -1102,9 +1227,6 @@
1102 glXDestroyContext (screen->dpy (), priv->ctx);1227 glXDestroyContext (screen->dpy (), priv->ctx);
1103 #endif1228 #endif
11041229
1105 if (priv->scratchFbo)
1106 delete priv->scratchFbo;
1107
1108 delete priv;1230 delete priv;
1109}1231}
11101232
@@ -1125,6 +1247,7 @@
1125 doubleBuffer (screen->dpy (), *screen, surface),1247 doubleBuffer (screen->dpy (), *screen, surface),
1126 #endif1248 #endif
1127 scratchFbo (NULL),1249 scratchFbo (NULL),
1250 blitFramebuffer (),
1128 outputRegion (),1251 outputRegion (),
1129 lastMask (0),1252 lastMask (0),
1130 bindPixmap (),1253 bindPixmap (),
@@ -1326,7 +1449,7 @@
1326{1449{
1327 screen->outputChangeNotify ();1450 screen->outputChangeNotify ();
13281451
1329 if (scratchFbo)1452 if (scratchFbo.get ())
1330 scratchFbo->allocate (*screen, NULL, GL_BGRA);1453 scratchFbo->allocate (*screen, NULL, GL_BGRA);
1331 updateView ();1454 updateView ();
1332}1455}
@@ -1553,9 +1676,9 @@
1553 WRAPABLE_DEF (projectionMatrix)1676 WRAPABLE_DEF (projectionMatrix)
15541677
1555void1678void
1556GLScreenInterface::glPaintCompositedOutput (const CompRegion &region,1679GLScreenInterface::glPaintCompositedOutput (const CompRegion &region,
1557 GLFramebufferObject *fbo,1680 compiz::opengl::DirectDrawFramebufferObject *fbo,
1558 unsigned int mask)1681 unsigned int mask)
1559 WRAPABLE_DEF (glPaintCompositedOutput, region, fbo, mask)1682 WRAPABLE_DEF (glPaintCompositedOutput, region, fbo, mask)
15601683
1561void1684void
@@ -1838,6 +1961,29 @@
18381961
1839}1962}
18401963
1964bool
1965cglfb::blitFramebufferGLX (const CompRect &src,
1966 const CompRect &dst,
1967 GLbitfield mask,
1968 GLenum filter)
1969{
1970 /* Must have GL_EXT_blit_framebuffer */
1971 if (!GL::blitFramebuffer)
1972 return false;
1973
1974 (*GL::blitFramebuffer) (src.x1 (), // sx0
1975 src.y1 (), // sy0
1976 src.x2 (), // sx1
1977 src.y2 (), // sy1
1978 dst.x1 (), // dx0
1979 dst.y1 (), // dy0
1980 dst.x2 (), // dx1,
1981 dst.y2 (), // dy1
1982 GL_COLOR_BUFFER_BIT,
1983 GL_LINEAR);
1984 return true;
1985}
1986
1841#else1987#else
18421988
1843EGLDoubleBuffer::EGLDoubleBuffer (Display *d,1989EGLDoubleBuffer::EGLDoubleBuffer (Display *d,
@@ -1903,6 +2049,16 @@
1903{2049{
1904}2050}
19052051
2052bool
2053cglfb::blitFramebufferEGL (const CompRect &src,
2054 const CompRect &dst,
2055 GLbitfield mask,
2056 GLenum filter)
2057{
2058 /* Not supported on OpenGL|ES2 */
2059 return false;
2060}
2061
1906#endif2062#endif
19072063
1908void2064void
@@ -1927,9 +2083,9 @@
1927 bool useFbo = false;2083 bool useFbo = false;
19282084
1929 /* Clear the color buffer where appropriate */2085 /* Clear the color buffer where appropriate */
1930 if (GL::fboEnabled && scratchFbo)2086 if (GL::fboEnabled && scratchFbo.get ())
1931 {2087 {
1932 oldFbo = scratchFbo->bind ();2088 oldFbo = static_cast <GLFramebufferObject *> (scratchFbo->bind ());
1933 useFbo = scratchFbo->checkStatus () && scratchFbo->tex ();2089 useFbo = scratchFbo->checkStatus () && scratchFbo->tex ();
1934 if (!useFbo)2090 if (!useFbo)
1935 GLFramebufferObject::rebind (oldFbo);2091 GLFramebufferObject::rebind (oldFbo);
@@ -2029,10 +2185,7 @@
2029 if (useFbo)2185 if (useFbo)
2030 {2186 {
2031 GLFramebufferObject::rebind (oldFbo);2187 GLFramebufferObject::rebind (oldFbo);
20322188 gScreen->glPaintCompositedOutput (screen->region (), scratchFbo.get (), mask);
2033 // FIXME: does not work if screen dimensions exceed max texture size
2034 // We should try to use glBlitFramebuffer instead.
2035 gScreen->glPaintCompositedOutput (screen->region (), scratchFbo, mask);
2036 }2189 }
20372190
2038 bool alwaysSwap = optionGetAlwaysSwapBuffers ();2191 bool alwaysSwap = optionGetAlwaysSwapBuffers ();
@@ -2109,10 +2262,16 @@
2109 }2262 }
2110}2263}
21112264
2112GLFramebufferObject *2265compiz::opengl::FramebufferObject *
2113GLScreen::fbo ()2266GLScreen::fbo ()
2114{2267{
2115 return priv->scratchFbo;2268 return priv->scratchFbo.get ();
2269}
2270
2271const cglfb::BlitFramebufferFunc &
2272GLScreen::blitFramebufferFunc()
2273{
2274 return priv->blitFramebuffer;
2116}2275}
21172276
2118GLTexture *2277GLTexture *
21192278
=== modified file 'plugins/water/src/water.cpp'
--- plugins/water/src/water.cpp 2012-09-08 00:00:34 +0000
+++ plugins/water/src/water.cpp 2012-09-15 15:18:21 +0000
@@ -318,9 +318,9 @@
318}318}
319319
320void320void
321WaterScreen::glPaintCompositedOutput (const CompRegion &region,321WaterScreen::glPaintCompositedOutput (const CompRegion &region,
322 GLFramebufferObject *fbo,322 compiz::opengl::DirectDrawFramebufferObject *fbo,
323 unsigned int mask)323 unsigned int mask)
324{324{
325 if (count)325 if (count)
326 {326 {
327327
=== modified file 'plugins/water/src/water.h'
--- plugins/water/src/water.h 2012-09-07 23:56:21 +0000
+++ plugins/water/src/water.h 2012-09-15 15:18:21 +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::DirectDrawFramebufferObject *fbo,
69 unsigned int mask);69 unsigned int mask);
70 void preparePaint (int);70 void preparePaint (int);
71 void donePaint ();71 void donePaint ();
7272

Subscribers

People subscribed via source and target branches