Merge lp:~smspillaz/unity/unity.fix_864784_868120_872625v2 into lp:unity

Proposed by Sam Spilsbury
Status: Merged
Approved by: Tim Penhey
Approved revision: no longer in the source branch.
Merged at revision: 1816
Proposed branch: lp:~smspillaz/unity/unity.fix_864784_868120_872625v2
Merge into: lp:unity
Diff against target: 1729 lines (+1188/-297)
11 files modified
plugins/unityshell/src/BackgroundEffectHelper.cpp (+13/-0)
plugins/unityshell/src/BackgroundEffectHelper.h (+1/-1)
plugins/unityshell/src/PanelView.cpp (+1/-2)
plugins/unityshell/src/ScreenEffectFramebufferObject.cpp (+234/-0)
plugins/unityshell/src/ScreenEffectFramebufferObject.h (+87/-0)
plugins/unityshell/src/unityshell.cpp (+75/-257)
plugins/unityshell/src/unityshell.h (+7/-35)
standalone-clients/CMakeLists.txt (+16/-2)
standalone-clients/GLFuncLoader.cpp (+51/-0)
standalone-clients/GLFuncLoader.h (+33/-0)
standalone-clients/TestScreenEffectFramebufferObject.cpp (+670/-0)
To merge this branch: bzr merge lp:~smspillaz/unity/unity.fix_864784_868120_872625v2
Reviewer Review Type Date Requested Status
Jason Smith (community) Approve
Mirco Müller Pending
Neil J. Patel Pending
Review via email: mp+86064@code.launchpad.net

This proposal supersedes a proposal from 2011-11-14.

Description of the change

Fix bug 868120 and bug 872625

We should use one framebuffer object per screen rather than one per monitor. Using one per monitor leads to all kinds of interesting rendering glitches because the plugins expect that paint is clipped to the entire backbuffer rather than paint being contained in one buffer.

This should also fix crashes on changing resolutions, as we don't have the race condition where a monitor paints and an fbo hasn't been created for it yet.

Also adds a testcase now, its in standalone-tests/TestScreenEffectFramebufferObject.cpp .

The testcase is a little quirky because we're trying to simulate what's going on when unity is actually running embedded in another opengl application, which means that we have to use nux's embedded mode rather than testing BackgroundEffectHelper directly. The testcase shows what happens in cases where parts of the scene are blurred and other parts aren't as well as what happens when some parts need updating and others don't (eg, the framebuffer should unbind). There's no automated test yet, but I imagine we could make one.

To post a comment you must log in.
Revision history for this message
Mirco Müller (macslow) wrote : Posted in a previous version of this proposal

This branch does break the repaint-cycle. While it compiles/works/runs screen-updates only happen when a window is moved. From the diff I currently don't see what you're missing.

review: Needs Fixing
Revision history for this message
Mirco Müller (macslow) wrote : Posted in a previous version of this proposal

I tried this on my laptop (intel graphics, mesa) and it worked ok. So something odd is happening with nvidia (binary driver). Might need to see how ATI/fglrx behaves with this.

Revision history for this message
Michal Hruby (mhr3) wrote : Posted in a previous version of this proposal

Nvidia here and I can confirm MacSlow's findings.

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

> Nvidia here and I can confirm MacSlow's findings.

Damn, ok. Their driver is broken :( I will have to work around it.

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

Noted: the driver is not carrying over attributes when set using glPushAttrib (GL_CURRENT_BIT), Jay says that they should be, and this is what the mesa drivers do, so NVIDIA should know about this.

Revision history for this message
Michal Hruby (mhr3) wrote : Posted in a previous version of this proposal

I can confirm that it properly repaints now, can't test multiple monitors though.

Revision history for this message
Jason Smith (jassmith) wrote : Posted in a previous version of this proposal

+1

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

Can someone with fglrx test this ?

Revision history for this message
Gord Allott (gordallott) wrote : Posted in a previous version of this proposal

On 11/10/11 12:18, Sam Spilsbury wrote:
> Noted: the driver is not carrying over attributes when set using glPushAttrib (GL_CURRENT_BIT), Jay says that they should be, and this is what the mesa drivers do, so NVIDIA should know about this.

merge approved

--
Gordon Allott
Canonical Ltd.
27 Floor, Millbank Tower
London SW1P 4QP
www.canonical.com

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

Testcase is to make sure that the screen actually redraws the way you'd expect it to. Bonus points if you can

 1) Test with multiple monitors to make sure the blur is correct on both
 2) No blur offsets
 3) No "flickering" when switching workspaces using expo
 4) No crashes when you hotplug a monitor on intel.

There is no unit test.

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

*cough* *cough* someone test this on fglrx *cough*

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

Instead of
  uScreen->_fbo = UnityFBO::Ptr (new UnityFBO (geometry));
you can go
  uScreen->_fbo.reset(new UnityFBO(geometry));

Saves a little typing (and it is more efficient in behaviour),

  UnityFBO::UnityFBO (CompRect geometry)
should be
  UnityFBO::UnityFBO(CompRect const& geometry)

Avoids an extra copy.

Revision history for this message
Jason Smith (jassmith) wrote : Posted in a previous version of this proposal

This requires testing for merge

review: Needs Fixing
Revision history for this message
Mirco Müller (macslow) wrote :

I checked this again. It works on nvidia (binary driver) now. Still unable to test it on any ATI-gfx-card, due to lack of hardware.

Regarding the missing unit-test... you could at least add a manual-test derived from your bullet-point list you posted in the comments. Than I'd be ok to give it a +1 when we found someone to test it successfully in a ATI-gfx-card.

Revision history for this message
Jason Smith (jassmith) wrote :

Works like the other oem branch afaict, no merge conflicts after time. I say approve :)

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

standalone-clients/TestScreenEffectFramebufferObject is a unit test in this case. It isn't automated, but it should how how the code works and you can test every possible case it hits.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

For the record, this proposal also contains the fixes for bug 861061 and bug 880707. This is because Sam's branches copied the fix from lp:~vanvugt/unity/fix-861061-trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/unityshell/src/BackgroundEffectHelper.cpp'
--- plugins/unityshell/src/BackgroundEffectHelper.cpp 2011-09-28 05:19:39 +0000
+++ plugins/unityshell/src/BackgroundEffectHelper.cpp 2012-01-05 02:50:45 +0000
@@ -85,7 +85,20 @@
85bool BackgroundEffectHelper::HasEnabledHelpers()85bool BackgroundEffectHelper::HasEnabledHelpers()
86{86{
87 for (BackgroundEffectHelper * bg_effect_helper : registered_list_)87 for (BackgroundEffectHelper * bg_effect_helper : registered_list_)
88 {
88 if (bg_effect_helper->enabled)89 if (bg_effect_helper->enabled)
90 {
91 return true;
92 }
93 }
94
95 return false;
96}
97
98bool BackgroundEffectHelper::HasDirtyHelpers()
99{
100 for (BackgroundEffectHelper * bg_effect_helper : registered_list_)
101 if (bg_effect_helper->enabled && bg_effect_helper->cache_dirty)
89 return true;102 return true;
90103
91 return false;104 return false;
92105
=== modified file 'plugins/unityshell/src/BackgroundEffectHelper.h'
--- plugins/unityshell/src/BackgroundEffectHelper.h 2011-10-19 22:13:57 +0000
+++ plugins/unityshell/src/BackgroundEffectHelper.h 2012-01-05 02:50:45 +0000
@@ -53,7 +53,7 @@
53 void DirtyCache();53 void DirtyCache();
5454
55 static void ProcessDamage(nux::Geometry geo);55 static void ProcessDamage(nux::Geometry geo);
5656 static bool HasDirtyHelpers();
57 static bool HasEnabledHelpers();57 static bool HasEnabledHelpers();
5858
59 static nux::Property<unity::BlurType> blur_type;59 static nux::Property<unity::BlurType> blur_type;
6060
=== modified file 'plugins/unityshell/src/PanelView.cpp'
--- plugins/unityshell/src/PanelView.cpp 2011-12-19 20:20:22 +0000
+++ plugins/unityshell/src/PanelView.cpp 2012-01-05 02:50:45 +0000
@@ -616,8 +616,7 @@
616616
617 _opacity = opacity;617 _opacity = opacity;
618618
619 if (_opacity < 1.0f && !_dash_is_open)619 bg_effect_helper_.enabled = (_opacity < 1.0f || _dash_is_open);
620 bg_effect_helper_.enabled = false;
621620
622 ForceUpdateBackground();621 ForceUpdateBackground();
623}622}
624623
=== added file 'plugins/unityshell/src/ScreenEffectFramebufferObject.cpp'
--- plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 1970-01-01 00:00:00 +0000
+++ plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-01-05 02:50:45 +0000
@@ -0,0 +1,234 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/* Compiz unity plugin
3 * unity.h
4 *
5 * Copyright (c) 2010-11 Canonical Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
18 */
19
20#include "ScreenEffectFramebufferObject.h"
21#include "BackgroundEffectHelper.h"
22#include <NuxCore/Logger.h>
23#include <dlfcn.h>
24
25namespace
26{
27 nux::logging::Logger logger ("unity.screeneffectframebufferobject");
28}
29
30void unity::ScreenEffectFramebufferObject::paint (const nux::Geometry &output)
31{
32 /* Draw the bit of the relevant framebuffer for each output */
33
34 glPushAttrib (GL_VIEWPORT_BIT);
35 glViewport (0, mScreenSize.height - (output.y + output.height), mScreenSize.width, mScreenSize.height);
36
37 if (mFBTexture)
38 {
39 glEnable (GL_TEXTURE_2D);
40 activeTexture (GL_TEXTURE0_ARB);
41 glBindTexture (GL_TEXTURE_2D, mFBTexture);
42 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
43 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
44
45 glPushAttrib (GL_SCISSOR_BIT);
46 glEnable (GL_SCISSOR_TEST);
47
48 glScissor (output.x, mScreenSize.height - (output.y + output.height),
49 output.width, output.height);
50
51 /* FIXME: This needs to be GL_TRIANGLE_STRIP */
52 glBegin (GL_QUADS);
53 glTexCoord2f (0, 1);
54 glVertex2i (mGeometry.x, mGeometry.y);
55 glTexCoord2f (0, 0);
56 glVertex2i (mGeometry.x, mGeometry.y + mGeometry.height);
57 glTexCoord2f (1, 0);
58 glVertex2i (mGeometry.x + mGeometry.width, mGeometry.y + mGeometry.height);
59 glTexCoord2f (1, 1);
60 glVertex2i (mGeometry.x + mGeometry.width, mGeometry.y);
61 glEnd ();
62
63 activeTexture (GL_TEXTURE0_ARB);
64 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
65 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
66 glBindTexture (GL_TEXTURE_2D, 0);
67 glDisable (GL_TEXTURE_2D);
68 glPopAttrib ();
69 }
70 glPopAttrib ();
71}
72
73void unity::ScreenEffectFramebufferObject::onScreenSizeChanged(const nux::Geometry& screenSize)
74{
75 mScreenSize = screenSize;
76}
77
78
79void unity::ScreenEffectFramebufferObject::unbind ()
80{
81 if (!mBoundCnt)
82 return;
83
84 mBoundCnt--;
85
86 (*bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0);
87
88 glDrawBuffer (GL_BACK);
89 glReadBuffer (GL_BACK);
90
91 /* Matches the viewport set we did in ::bind () */
92 glPopAttrib ();
93
94}
95
96bool unity::ScreenEffectFramebufferObject::status ()
97{
98 return mFboStatus;
99}
100
101void unity::ScreenEffectFramebufferObject::bind (const nux::Geometry &output)
102{
103 if (!BackgroundEffectHelper::HasDirtyHelpers())
104 return;
105
106 /* Clear the error bit */
107 glGetError ();
108
109 if (!mFBTexture)
110 {
111 glGenTextures (1, &mFBTexture);
112
113 glBindTexture (GL_TEXTURE_2D, mFBTexture);
114 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
115 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
116 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
117 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
118 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, mGeometry.width, mGeometry.height, 0, GL_BGRA,
119#if IMAGE_BYTE_ORDER == MSBFirst
120 GL_UNSIGNED_INT_8_8_8_8_REV,
121#else
122 GL_UNSIGNED_BYTE,
123#endif
124 NULL);
125
126 glBindTexture (GL_TEXTURE_2D, 0);
127
128 if (glGetError () != GL_NO_ERROR)
129 {
130 mFboHandle = 0;
131 mFboStatus = false;
132 return;
133 }
134 }
135
136 (*bindFramebuffer) (GL_FRAMEBUFFER_EXT, mFboHandle);
137
138 (*framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
139 GL_TEXTURE_2D, mFBTexture, 0);
140
141 (*framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
142 GL_TEXTURE_2D, 0, 0);
143
144 /* Ensure that a framebuffer is actually available */
145 if (!mFboStatus)
146 {
147 GLint status = (*checkFramebufferStatus) (GL_DRAW_FRAMEBUFFER);
148
149 if (status != GL_FRAMEBUFFER_COMPLETE)
150 {
151 switch (status)
152 {
153 case GL_FRAMEBUFFER_UNDEFINED:
154 LOG_WARN (logger) << "no window";
155 break;
156 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
157 LOG_WARN (logger) << "attachment incomplete";
158 break;
159 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
160 LOG_WARN (logger) << "no buffers attached to fbo";
161 break;
162 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
163 LOG_WARN (logger) << "some attachment in glDrawBuffers doesn't exist in FBO";
164 break;
165 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
166 LOG_WARN (logger) << "some attachment in glReadBuffers doesn't exist in FBO";
167 break;
168 case GL_FRAMEBUFFER_UNSUPPORTED:
169 LOG_WARN (logger) << "unsupported internal format";
170 break;
171 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
172 LOG_WARN (logger) << "different levels of sampling for each attachment";
173 break;
174 case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
175 LOG_WARN (logger) << "number of layers is different";
176 break;
177 default:
178 LOG_WARN (logger) << "unable to bind the framebuffer for an unknown reason";
179 break;
180 }
181
182 bindFramebuffer (GL_FRAMEBUFFER_EXT, 0);
183 deleteFramebuffers (1, &mFboHandle);
184
185 glDrawBuffer (GL_BACK);
186 glReadBuffer (GL_BACK);
187
188 mFboHandle = 0;
189
190 mFboStatus = false;
191 }
192 else
193 mFboStatus = true;
194 }
195
196 if (mFboStatus)
197 {
198 glPushAttrib (GL_VIEWPORT_BIT);
199
200 glViewport (output.x,
201 mScreenSize.height - (output.y + output.height),
202 output.width,
203 output.height);
204 }
205
206 mBoundCnt++;
207}
208
209
210unity::ScreenEffectFramebufferObject::ScreenEffectFramebufferObject (GLXGetProcAddressProc p, const nux::Geometry &geom)
211 : getProcAddressGLX (p)
212 , mFboStatus (false)
213 , mFBTexture (0)
214 , mGeometry (geom)
215 , mBoundCnt (0)
216 , mScreenSize (geom)
217{
218 activeTexture = (GLActiveTextureProc) (*getProcAddressGLX) ((GLubyte *) "glActiveTexture");
219 genFramebuffers = (GLGenFramebuffersProc) (*getProcAddressGLX) ((GLubyte *)"glGenFramebuffersEXT");
220 deleteFramebuffers = (GLDeleteFramebuffersProc) (*getProcAddressGLX) ((GLubyte *)"glDeleteFramebuffersEXT");
221 bindFramebuffer = (GLBindFramebufferProc) (*getProcAddressGLX) ((GLubyte *)"glBindFramebufferEXT");
222 checkFramebufferStatus = (GLCheckFramebufferStatusProc) (*getProcAddressGLX) ((GLubyte *) "glCheckFramebufferStatusEXT");
223 framebufferTexture2D = (GLFramebufferTexture2DProc) (*getProcAddressGLX) ((GLubyte *) "glFramebufferTexture2DEXT");
224
225 (*genFramebuffers) (1, &mFboHandle);
226}
227
228unity::ScreenEffectFramebufferObject::~ScreenEffectFramebufferObject ()
229{
230 (*deleteFramebuffers) (1, &mFboHandle);
231
232 if (mFBTexture)
233 glDeleteTextures (1, &mFBTexture);
234}
0235
=== added file 'plugins/unityshell/src/ScreenEffectFramebufferObject.h'
--- plugins/unityshell/src/ScreenEffectFramebufferObject.h 1970-01-01 00:00:00 +0000
+++ plugins/unityshell/src/ScreenEffectFramebufferObject.h 2012-01-05 02:50:45 +0000
@@ -0,0 +1,87 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/* Compiz unity plugin
3 * unity.h
4 *
5 * Copyright (c) 2010-11 Canonical Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
18 */
19
20#ifndef UNITY_SCREENEFFECT_FRAMEBUFFER_H
21#define UNITY_SCREENEFFECT_FRAMEBUFFER_H
22
23#include <Nux/Nux.h>
24
25namespace unity
26{
27class ScreenEffectFramebufferObject
28{
29public:
30
31 typedef boost::shared_ptr <ScreenEffectFramebufferObject> Ptr;
32 typedef void (*FuncPtr) (void);
33 typedef FuncPtr (*GLXGetProcAddressProc) (const GLubyte *procName);
34
35 ScreenEffectFramebufferObject (GLXGetProcAddressProc, const nux::Geometry &geom);
36 ~ScreenEffectFramebufferObject ();
37
38public:
39
40 void bind (const nux::Geometry &geom);
41 void unbind ();
42
43 bool status ();
44 void paint (const nux::Geometry &geom);
45 bool bound () { return mBoundCnt > 0; }
46
47 GLuint texture () { return mFBTexture; }
48
49 void onScreenSizeChanged (const nux::Geometry &screenSize);
50
51private:
52
53 FuncPtr getProcAddr (const std::string &);
54
55 typedef void (*GLActiveTextureProc) (GLenum texture);
56 typedef void (*GLGenFramebuffersProc) (GLsizei n,
57 GLuint *framebuffers);
58 typedef void (*GLDeleteFramebuffersProc) (GLsizei n,
59 GLuint *framebuffers);
60 typedef void (*GLBindFramebufferProc) (GLenum target,
61 GLuint framebuffer);
62 typedef GLenum (*GLCheckFramebufferStatusProc) (GLenum target);
63 typedef void (*GLFramebufferTexture2DProc) (GLenum target,
64 GLenum attachment,
65 GLenum textarget,
66 GLuint texture,
67 GLint level);
68
69 GLXGetProcAddressProc getProcAddressGLX;
70 GLActiveTextureProc activeTexture;
71 GLGenFramebuffersProc genFramebuffers;
72 GLDeleteFramebuffersProc deleteFramebuffers;
73 GLBindFramebufferProc bindFramebuffer;
74 GLCheckFramebufferStatusProc checkFramebufferStatus;
75 GLFramebufferTexture2DProc framebufferTexture2D;
76 /* compiz fbo handle that goes through to nux */
77 GLuint mFboHandle; // actual handle to the framebuffer_ext
78 bool mFboStatus; // did the framebuffer texture bind succeed
79 GLuint mFBTexture;
80 nux::Geometry mGeometry;
81 unsigned int mBoundCnt;
82
83 nux::Geometry mScreenSize;
84};
85} // namespace unity
86
87#endif
088
=== modified file 'plugins/unityshell/src/unityshell.cpp'
--- plugins/unityshell/src/unityshell.cpp 2012-01-02 20:51:09 +0000
+++ plugins/unityshell/src/unityshell.cpp 2012-01-05 02:50:45 +0000
@@ -65,7 +65,6 @@
65/* Set up vtable symbols */65/* Set up vtable symbols */
66COMPIZ_PLUGIN_20090315(unityshell, unity::UnityPluginVTable);66COMPIZ_PLUGIN_20090315(unityshell, unity::UnityPluginVTable);
6767
68
69namespace unity68namespace unity
70{69{
71using launcher::AbstractLauncherIcon;70using launcher::AbstractLauncherIcon;
@@ -114,7 +113,7 @@
114 , damaged(false)113 , damaged(false)
115 , _key_nav_mode_requested(false)114 , _key_nav_mode_requested(false)
116 , _last_output(nullptr)115 , _last_output(nullptr)
117 , mActiveFbo (0)116 , _active_fbo (0)
118 , dash_is_open_ (false)117 , dash_is_open_ (false)
119 , grab_index_ (0)118 , grab_index_ (0)
120 , painting_tray_ (false)119 , painting_tray_ (false)
@@ -227,12 +226,21 @@
227 _edge_timeout = optionGetLauncherRevealEdgeTimeout ();226 _edge_timeout = optionGetLauncherRevealEdgeTimeout ();
228 _in_paint = false;227 _in_paint = false;
229228
229 void *dlhand = dlopen ("libunityshell.so", RTLD_LAZY);
230
231 if (dlhand)
232 {
233 dlerror ();
234 glXGetProcAddressP = (ScreenEffectFramebufferObject::GLXGetProcAddressProc) dlsym (dlhand, "glXGetProcAddress");
235 if (dlerror () != NULL)
236 glXGetProcAddressP = NULL;
237 }
238
230 if (GL::fbo)239 if (GL::fbo)
231 {240 {
232 foreach (CompOutput & o, screen->outputDevs())241 nux::Geometry geometry (0, 0, screen->width (), screen->height ());
233 uScreen->mFbos[&o] = UnityFBO::Ptr (new UnityFBO(&o));242 uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
234243 uScreen->_fbo->onScreenSizeChanged (geometry);
235 uScreen->mFbos[&(screen->fullscreenOutput ())] = UnityFBO::Ptr (new UnityFBO(&(screen->fullscreenOutput ())));
236 }244 }
237245
238 optionSetBackgroundColorNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));246 optionSetBackgroundColorNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
@@ -451,7 +459,7 @@
451459
452void UnityScreen::nuxEpilogue()460void UnityScreen::nuxEpilogue()
453{461{
454 (*GL::bindFramebuffer)(GL_FRAMEBUFFER_EXT, mActiveFbo);462 (*GL::bindFramebuffer)(GL_FRAMEBUFFER_EXT, _active_fbo);
455463
456 glMatrixMode(GL_PROJECTION);464 glMatrixMode(GL_PROJECTION);
457 glLoadIdentity();465 glLoadIdentity();
@@ -492,8 +500,6 @@
492 if (PluginAdapter::Default()->IsExpoActive())500 if (PluginAdapter::Default()->IsExpoActive())
493 return;501 return;
494502
495 nuxPrologue();
496
497 CompOutput* output = _last_output;503 CompOutput* output = _last_output;
498 float vc[4];504 float vc[4];
499 float h = 20.0f;505 float h = 20.0f;
@@ -504,6 +510,9 @@
504 float y1 = output->y() + panel_h;510 float y1 = output->y() + panel_h;
505 float x2 = x1 + output->width();511 float x2 = x1 + output->width();
506 float y2 = y1 + h;512 float y2 = y1 + h;
513 GLMatrix sTransform = GLMatrix ();
514
515 sTransform.toScreenSpace(output, -DEFAULT_Z_CAMERA);
507516
508 vc[0] = x1;517 vc[0] = x1;
509 vc[1] = x2;518 vc[1] = x2;
@@ -543,7 +552,6 @@
543 glDisable(GL_BLEND);552 glDisable(GL_BLEND);
544 }553 }
545 }554 }
546 nuxEpilogue();
547}555}
548556
549void557void
@@ -562,30 +570,35 @@
562{570{
563 CompOutput *output = _last_output;571 CompOutput *output = _last_output;
564 Window tray_xid = panel_controller_->GetTrayXid ();572 Window tray_xid = panel_controller_->GetTrayXid ();
565 bool bound = mFbos[output]->bound ();573
566574 bool was_bound = _fbo->bound ();
567575 _fbo->unbind ();
568 if (bound)576
577 /* Draw the bit of the relevant framebuffer for each output */
578
579 if (was_bound)
569 {580 {
570 mFbos[output]->unbind ();581 GLMatrix sTransform;
571582 sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
572 /* Draw the bit of the relevant framebuffer for each output */583 glPushMatrix ();
573 mFbos[output]->paint ();584 glLoadMatrixf (sTransform.getMatrix ());
585 _fbo->paint (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
586 glPopMatrix ();
574 }587 }
575588
576 nuxPrologue();
577
578 nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture =589 nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture =
579 nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(mFbos[output]->texture(),590 nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(_fbo->texture(),
580 output->width(), output->height(), 1, nux::BITFMT_R8G8B8A8);591 screen->width (), screen->height(), 1, nux::BITFMT_R8G8B8A8);
581592
582 nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture;593 nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture;
583594
584 nux::Geometry geo = nux::Geometry (output->x (), output->y (), output->width (), output->height ());595 nux::Geometry geo = nux::Geometry (0, 0, screen->width (), screen->height ());
596 nux::Geometry oGeo = nux::Geometry (output->x (), output->y (), output->width (), output->height ());
585 BackgroundEffectHelper::monitor_rect_ = geo;597 BackgroundEffectHelper::monitor_rect_ = geo;
586598
599 nuxPrologue();
587 _in_paint = true;600 _in_paint = true;
588 wt->RenderInterfaceFromForeignCmd (&geo);601 wt->RenderInterfaceFromForeignCmd (&oGeo);
589 _in_paint = false;602 _in_paint = false;
590 nuxEpilogue();603 nuxEpilogue();
591604
@@ -985,6 +998,10 @@
985{998{
986 bool ret;999 bool ret;
9871000
1001 doShellRepaint = true;
1002 allowWindowPaint = true;
1003 _last_output = output;
1004
988 /* bind the framebuffer here1005 /* bind the framebuffer here
989 * - it will be unbound and flushed1006 * - it will be unbound and flushed
990 * to the backbuffer when some1007 * to the backbuffer when some
@@ -995,11 +1012,7 @@
995 * attempts to bind it will only increment1012 * attempts to bind it will only increment
996 * its bind reference so make sure that1013 * its bind reference so make sure that
997 * you always unbind as much as you bind */1014 * you always unbind as much as you bind */
998 mFbos[output]->bind ();1015 _fbo->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
999
1000 doShellRepaint = true;
1001 allowWindowPaint = true;
1002 _last_output = output;
10031016
1004 /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */1017 /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
1005 ret = gScreen->glPaintOutput(attrib, transform, region, output, mask);1018 ret = gScreen->glPaintOutput(attrib, transform, region, output, mask);
@@ -1160,16 +1173,37 @@
1160 {1173 {
1161 XDamageNotifyEvent *de = (XDamageNotifyEvent *) event;1174 XDamageNotifyEvent *de = (XDamageNotifyEvent *) event;
1162 CompWindow* w = screen->findWindow (de->drawable);1175 CompWindow* w = screen->findWindow (de->drawable);
1176 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
1177 CompWindow* lastNWindow = screen->findWindow (xwns.back ());
1178 bool processDamage = true;
11631179
1164 if (w and !(w->wmType() & CompWindowTypeDndMask))1180 if (w)
1165 {1181 {
1166 nux::Geometry damage (de->area.x, de->area.y, de->area.width, de->area.height);1182 if (!w->overrideRedirect () &&
11671183 w->isViewable () &&
1168 CompWindow::Geometry geom = w->geometry ();1184 !w->invisible ())
1169 damage.x += geom.x () + geom.border ();1185 {
1170 damage.y += geom.y () + geom.border ();1186
11711187 for (; lastNWindow != NULL; lastNWindow = lastNWindow->next)
1172 BackgroundEffectHelper::ProcessDamage(damage);1188 {
1189 if (lastNWindow == w)
1190 {
1191 processDamage = false;
1192 break;
1193 }
1194 }
1195
1196 if (processDamage)
1197 {
1198 nux::Geometry damage (de->area.x, de->area.y, de->area.width, de->area.height);
1199
1200 const CompWindow::Geometry &geom = w->geometry ();
1201 damage.x += geom.x () + geom.border ();
1202 damage.y += geom.y () + geom.border ();
1203
1204 BackgroundEffectHelper::ProcessDamage(damage);
1205 }
1206 }
1173 }1207 }
1174 }1208 }
1175}1209}
@@ -2164,15 +2198,15 @@
21642198
2165void UnityScreen::Relayout()2199void UnityScreen::Relayout()
2166{2200{
2201 nux::Geometry geometry (0, 0, screen->width (), screen->height ());
2202
2167 if (!needsRelayout)2203 if (!needsRelayout)
2168 return;2204 return;
21692205
2170 if (GL::fbo)2206 if (GL::fbo)
2171 {2207 {
2172 foreach (CompOutput &o, screen->outputDevs ())2208 uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
2173 uScreen->mFbos[&o] = UnityFBO::Ptr (new UnityFBO (&o));2209 uScreen->_fbo->onScreenSizeChanged (geometry);
2174
2175 uScreen->mFbos[&(screen->fullscreenOutput ())] = UnityFBO::Ptr (new UnityFBO (&(screen->fullscreenOutput ())));
2176 }2210 }
21772211
2178 UScreen *uscreen = UScreen::GetDefault();2212 UScreen *uscreen = UScreen::GetDefault();
@@ -2195,8 +2229,6 @@
2195{2229{
2196 UnityScreen* uScr = reinterpret_cast<UnityScreen*>(data);2230 UnityScreen* uScr = reinterpret_cast<UnityScreen*>(data);
21972231
2198 uScreen->mFbos.clear ();
2199
2200 uScr->NeedsRelayout ();2232 uScr->NeedsRelayout ();
2201 uScr->Relayout();2233 uScr->Relayout();
2202 uScr->relayoutSourceId = 0;2234 uScr->relayoutSourceId = 0;
@@ -2229,220 +2261,6 @@
2229 ScheduleRelayout(500);2261 ScheduleRelayout(500);
2230}2262}
22312263
2232void UnityFBO::paint ()
2233{
2234 //CompositeScreen *cScreen = CompositeScreen::get (screen);
2235 //unsigned int mask = cScreen->damageMask ();
2236 float texx, texy, texwidth, texheight;
2237
2238 /* Must be completely unbound before painting */
2239 if (mBoundCnt)
2240 return;
2241
2242 /* Draw the bit of the relevant framebuffer for each output */
2243 GLMatrix transform;
2244
2245 glViewport (output->x (), screen->height () - output->y2 (), output->width (), output->height ());
2246 GLScreen::get (screen)->clearOutput (output, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2247
2248 transform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
2249 glPushMatrix ();
2250 glLoadMatrixf (transform.getMatrix ());
2251
2252 /* Note that texcoords here are normalized, so it's just (0,0)-(1,1) */
2253 texx = 0.0;
2254 texy = 0.0;
2255 texwidth = 1.0f;
2256 texheight = 1.0f;
2257
2258 if (mFBTexture)
2259 {
2260 glEnable (GL_TEXTURE_2D);
2261 GL::activeTexture (GL_TEXTURE0_ARB);
2262 glBindTexture (GL_TEXTURE_2D, mFBTexture);
2263 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2264 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2265
2266 glPushAttrib (GL_SCISSOR_BIT);
2267 glEnable (GL_SCISSOR_TEST);
2268
2269 glScissor (output->x1 (), screen->height () - output->y2 (),
2270 output->width (), output->height ());
2271
2272 /* FIXME: This needs to be GL_TRIANGLE_STRIP */
2273 glBegin (GL_QUADS);
2274 glTexCoord2f (texx, texy + texheight);
2275 glVertex2i (output->x1 (), output->y1 ());
2276 glTexCoord2f (texx, texy);
2277 glVertex2i (output->x1 (), output->y2 ());
2278 glTexCoord2f (texx + texwidth, texy);
2279 glVertex2i (output->x2 (), output->y2 ());
2280 glTexCoord2f (texx + texwidth, texy + texheight);
2281 glVertex2i (output->x2 (), output->y1 ());
2282 glEnd ();
2283
2284 GL::activeTexture (GL_TEXTURE0_ARB);
2285 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2286 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2287 glBindTexture (GL_TEXTURE_2D, 0);
2288 glEnable (GL_TEXTURE_2D);
2289
2290 glDisable (GL_SCISSOR_TEST);
2291 glPopAttrib ();
2292 }
2293
2294 glPopMatrix();
2295}
2296
2297void UnityFBO::unbind ()
2298{
2299 mBoundCnt--;
2300
2301 if (mBoundCnt)
2302 return;
2303
2304 uScreen->setActiveFbo (0);
2305 (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0);
2306
2307 glDrawBuffer (GL_BACK);
2308 glReadBuffer (GL_BACK);
2309
2310}
2311
2312bool UnityFBO::bound ()
2313{
2314 return mBoundCnt > 0;
2315}
2316
2317bool UnityFBO::status ()
2318{
2319 return mFboStatus;
2320}
2321
2322void UnityFBO::bind ()
2323{
2324 if (mBoundCnt)
2325 {
2326 mBoundCnt++;
2327 return;
2328 }
2329
2330 if (!mFBTexture)
2331 {
2332 glGenTextures (1, &mFBTexture);
2333
2334 glBindTexture (GL_TEXTURE_2D, mFBTexture);
2335 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2336 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2337 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2338 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2339 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, output->width(), output->height(), 0, GL_BGRA,
2340#if IMAGE_BYTE_ORDER == MSBFirst
2341 GL_UNSIGNED_INT_8_8_8_8_REV,
2342#else
2343 GL_UNSIGNED_BYTE,
2344#endif
2345 NULL);
2346
2347 glBindTexture (GL_TEXTURE_2D, 0);
2348 }
2349
2350 glGetError ();
2351
2352 (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, mFboHandle);
2353
2354 (*GL::framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
2355 GL_TEXTURE_2D, mFBTexture, 0);
2356
2357 (*GL::framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
2358 GL_TEXTURE_2D, 0, 0);
2359
2360 /* Ensure that a framebuffer is actually available */
2361 if (!mFboStatus)
2362 {
2363 GLint status = (*GL::checkFramebufferStatus) (GL_DRAW_FRAMEBUFFER);
2364
2365 if (status != GL_FRAMEBUFFER_COMPLETE)
2366 {
2367 switch (status)
2368 {
2369 case GL_FRAMEBUFFER_UNDEFINED:
2370 compLogMessage ("unity", CompLogLevelWarn, "no window");
2371 break;
2372 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
2373 compLogMessage ("unity", CompLogLevelWarn, "attachment incomplete");
2374 break;
2375 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
2376 compLogMessage ("unity", CompLogLevelWarn, "no buffers attached to fbo");
2377 break;
2378 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
2379 compLogMessage ("unity", CompLogLevelWarn, "some attachment in glDrawBuffers doesn't exist in FBO");
2380 break;
2381 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
2382 compLogMessage ("unity", CompLogLevelWarn, "some attachment in glReadBuffers doesn't exist in FBO");
2383 break;
2384 case GL_FRAMEBUFFER_UNSUPPORTED:
2385 compLogMessage ("unity", CompLogLevelWarn, "unsupported internal format");
2386 break;
2387 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
2388 compLogMessage ("unity", CompLogLevelWarn, "different levels of sampling for each attachment");
2389 break;
2390 case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
2391 compLogMessage ("unity", CompLogLevelWarn, "number of layers is different");
2392 break;
2393 default:
2394 compLogMessage ("unity", CompLogLevelWarn, "unable to bind the framebuffer for an unknown reason");
2395 break;
2396 }
2397
2398 GL::bindFramebuffer (GL_FRAMEBUFFER_EXT, 0);
2399 GL::deleteFramebuffers (1, &mFboHandle);
2400
2401 glDrawBuffer (GL_BACK);
2402 glReadBuffer (GL_BACK);
2403
2404 mFboHandle = 0;
2405
2406 mFboStatus = false;
2407 uScreen->setActiveFbo (0);
2408 }
2409 else
2410 mFboStatus = true;
2411 }
2412
2413 if (mFboStatus)
2414 {
2415 uScreen->setActiveFbo (mFboHandle);
2416
2417 glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
2418 glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
2419
2420 glViewport (0,
2421 0,
2422 output->width(),
2423 output->height());
2424
2425 mBoundCnt++;
2426 }
2427}
2428
2429UnityFBO::UnityFBO (CompOutput *o)
2430 : mFboStatus (false)
2431 , mFBTexture (0)
2432 , output (o)
2433 , mBoundCnt (0)
2434{
2435 (*GL::genFramebuffers) (1, &mFboHandle);
2436}
2437
2438UnityFBO::~UnityFBO ()
2439{
2440 (*GL::deleteFramebuffers) (1, &mFboHandle);
2441
2442 if (mFBTexture)
2443 glDeleteTextures (1, &mFBTexture);
2444}
2445
2446void UnityScreen::OnDashRealized ()2264void UnityScreen::OnDashRealized ()
2447{2265{
2448 /* stack any windows named "onboard" above us */2266 /* stack any windows named "onboard" above us */
24492267
=== modified file 'plugins/unityshell/src/unityshell.h'
--- plugins/unityshell/src/unityshell.h 2011-12-15 07:08:41 +0000
+++ plugins/unityshell/src/unityshell.h 2012-01-05 02:50:45 +0000
@@ -47,47 +47,19 @@
47#include "DebugDBusInterface.h"47#include "DebugDBusInterface.h"
48#include "SwitcherController.h"48#include "SwitcherController.h"
49#include "UBusWrapper.h"49#include "UBusWrapper.h"
50#include "ScreenEffectFramebufferObject.h"
5051
51#include "compizminimizedwindowhandler.h"52#include "compizminimizedwindowhandler.h"
52#include "BGHash.h"53#include "BGHash.h"
53#include <compiztoolbox/compiztoolbox.h>54#include <compiztoolbox/compiztoolbox.h>
55#include <dlfcn.h>
5456
55namespace unity57namespace unity
56{58{
5759
58class UnityFBO
59{
60public:
61
62 typedef boost::shared_ptr <UnityFBO> Ptr;
63
64 UnityFBO (CompOutput *o);
65 ~UnityFBO ();
66
67public:
68
69 void bind ();
70 void unbind ();
71
72 bool status ();
73 bool bound ();
74 void paint ();
75
76 GLuint texture () { return mFBTexture; }
77
78private:
79
80 /* compiz fbo handle that goes through to nux */
81 GLuint mFboHandle; // actual handle to the framebuffer_ext
82 bool mFboStatus; // did the framebuffer texture bind succeed
83 GLuint mFBTexture;
84 CompOutput *output;
85 unsigned int mBoundCnt;
86};
87
88class UnityShowdesktopHandler60class UnityShowdesktopHandler
89{61{
90public:62 public:
9163
92 UnityShowdesktopHandler (CompWindow *w);64 UnityShowdesktopHandler (CompWindow *w);
93 ~UnityShowdesktopHandler ();65 ~UnityShowdesktopHandler ();
@@ -234,8 +206,6 @@
234 void NeedsRelayout();206 void NeedsRelayout();
235 void ScheduleRelayout(guint timeout);207 void ScheduleRelayout(guint timeout);
236208
237 void setActiveFbo (GLuint fbo) { mActiveFbo = fbo; }
238
239 bool forcePaintOnTop ();209 bool forcePaintOnTop ();
240210
241protected:211protected:
@@ -320,8 +290,8 @@
320290
321 unity::BGHash _bghash;291 unity::BGHash _bghash;
322292
323 std::map <CompOutput *, UnityFBO::Ptr> mFbos;293 ScreenEffectFramebufferObject::Ptr _fbo;
324 GLuint mActiveFbo;294 GLuint _active_fbo;
325295
326 bool queryForShader ();296 bool queryForShader ();
327297
@@ -332,6 +302,8 @@
332 bool painting_tray_;302 bool painting_tray_;
333 unsigned int tray_paint_mask_;303 unsigned int tray_paint_mask_;
334304
305 ScreenEffectFramebufferObject::GLXGetProcAddressProc glXGetProcAddressP;
306
335 friend class UnityWindow;307 friend class UnityWindow;
336};308};
337309
338310
=== modified file 'standalone-clients/CMakeLists.txt'
--- standalone-clients/CMakeLists.txt 2011-12-14 01:47:53 +0000
+++ standalone-clients/CMakeLists.txt 2012-01-05 02:50:45 +0000
@@ -26,13 +26,13 @@
26 )26 )
27add_definitions (${CFLAGS})27add_definitions (${CFLAGS})
2828
29set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm")29set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm -lGL -lGLU")
30link_libraries (${LIBS})30link_libraries (${LIBS})
3131
32set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS})32set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS})
33link_directories (${CMAKE_BINARY_DIR}/UnityCore ${LIB_PATHS})33link_directories (${CMAKE_BINARY_DIR}/UnityCore ${LIB_PATHS})
3434
35include_directories (. .. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR})35include_directories (. .. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
3636
37# We can't have convenience libs so we need to rebuild with what we need37# We can't have convenience libs so we need to rebuild with what we need
38# Please keep actual test files alphabetically at top and then files38# Please keep actual test files alphabetically at top and then files
@@ -452,6 +452,20 @@
452 )452 )
453add_dependencies (bg-hash unity-core-${UNITY_API_VERSION})453add_dependencies (bg-hash unity-core-${UNITY_API_VERSION})
454454
455find_package (OpenGL)
456
457include_directories (${OPENGL_gl_INCDIRS})
458add_library (glfuncloader SHARED
459 ${CMAKE_CURRENT_SOURCE_DIR}/GLFuncLoader.cpp)
460target_link_libraries (glfuncloader dl ${OPENGL_gl_LIBRARY})
461add_executable (screen-effect-fbo
462 TestScreenEffectFramebufferObject.cpp
463 ${UNITY_SRC}/ScreenEffectFramebufferObject.cpp
464 ${UNITY_SRC}/BackgroundEffectHelper.cpp)
465
466target_link_libraries (screen-effect-fbo glfuncloader ${OPENGL_gl_LIBRARY})
467add_dependencies (screen-effect-fbo ${UNITY_API_VERSION})
468
455469
456# Custom target to make all the other targets here, add your test to this list470# Custom target to make all the other targets here, add your test to this list
457add_custom_target(standalone-clients DEPENDS dash panel launcher switcher keyutil quicklist quicklist-visuals filters filter-bar preview-applicaiton preview-generic preview-music result-view dash-style bg-hash)471add_custom_target(standalone-clients DEPENDS dash panel launcher switcher keyutil quicklist quicklist-visuals filters filter-bar preview-applicaiton preview-generic preview-music result-view dash-style bg-hash)
458472
=== added file 'standalone-clients/GLFuncLoader.cpp'
--- standalone-clients/GLFuncLoader.cpp 1970-01-01 00:00:00 +0000
+++ standalone-clients/GLFuncLoader.cpp 2012-01-05 02:50:45 +0000
@@ -0,0 +1,51 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/* Compiz unity plugin
3 * unity.h
4 *
5 * Copyright (c) 2010-11 Canonical Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
18 */
19
20#include "GLFuncLoader.h"
21#include <dlfcn.h>
22
23unity::GLLoader::FuncPtr unity::GLLoader::getProcAddr(const std::string &name)
24{
25 static void *dlhand = NULL;
26 FuncPtr funcPtr = NULL;
27
28 glGetError ();
29
30 if (!funcPtr)
31 {
32 if (!dlhand)
33 dlhand = dlopen ("libglfuncloader.so", RTLD_LAZY);
34
35 char *error = dlerror ();
36
37 if (dlhand)
38 {
39 dlerror ();
40 funcPtr = (FuncPtr) dlsym (dlhand, name.c_str ());
41
42 error = dlerror ();
43 if (error != NULL)
44 funcPtr = NULL;
45 }
46 }
47
48 return funcPtr;
49}
50
51
052
=== added file 'standalone-clients/GLFuncLoader.h'
--- standalone-clients/GLFuncLoader.h 1970-01-01 00:00:00 +0000
+++ standalone-clients/GLFuncLoader.h 2012-01-05 02:50:45 +0000
@@ -0,0 +1,33 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/* Compiz unity plugin
3 * unity.h
4 *
5 * Copyright (c) 2010-11 Canonical Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
18 */
19
20#include <string>
21#include <GL/gl.h>
22#include <GL/glx.h>
23
24namespace unity
25{
26namespace GLLoader
27{
28typedef void (*FuncPtr) (void);
29typedef FuncPtr (*GLXGetProcAddressProc) (const GLubyte *procName);
30
31FuncPtr getProcAddr(const std::string &name);
32}
33}
034
=== added file 'standalone-clients/TestScreenEffectFramebufferObject.cpp'
--- standalone-clients/TestScreenEffectFramebufferObject.cpp 1970-01-01 00:00:00 +0000
+++ standalone-clients/TestScreenEffectFramebufferObject.cpp 2012-01-05 02:50:45 +0000
@@ -0,0 +1,670 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/* Compiz unity plugin
3 * unity.h
4 *
5 * Copyright (c) 2010-11 Canonical Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
18 */
19
20#include "ScreenEffectFramebufferObject.h"
21#include "BackgroundEffectHelper.h"
22#include "GLFuncLoader.h"
23#include <Nux/Nux.h>
24#include <Nux/VLayout.h>
25#include <Nux/View.h>
26#include <Nux/BaseWindow.h>
27#include <Nux/WindowCompositor.h>
28#include <NuxCore/Logger.h>
29#include <NuxCore/Object.h>
30#include <X11/Xlib.h>
31#include <X11/Xutil.h>
32#include <GL/glx.h>
33#include <GL/gl.h>
34#include <dlfcn.h>
35#include <sys/poll.h>
36#include <unistd.h>
37#include <glib.h>
38#include <gtk/gtk.h>
39#include <cmath>
40
41using namespace unity::GLLoader;
42
43namespace
44{
45 nux::logging::Logger logger ("unity.test-screeneffectframebufferobject");
46
47 const static int attributes[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT,
48 GLX_X_RENDERABLE, True,
49 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
50 GLX_DOUBLEBUFFER, True,
51 GLX_RED_SIZE, 8,
52 GLX_GREEN_SIZE, 8,
53 GLX_BLUE_SIZE, 8, 0};
54}
55
56namespace GLFuncs
57{
58 GLXGetProcAddressProc glXGetProcAddressP;
59 PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfigP;
60 PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfigP;
61 PFNGLXCREATEWINDOWPROC glXCreateWindowP;
62 PFNGLXDESTROYWINDOWPROC glXDestroyWindowP;
63 PFNGLXMAKECONTEXTCURRENTPROC glXMakeContextCurrentP;
64
65 void init ()
66 {
67 glXGetProcAddressP = (GLXGetProcAddressProc) getProcAddr ("glXGetProcAddress");
68 glXChooseFBConfigP = (PFNGLXCHOOSEFBCONFIGPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXChooseFBConfig");
69 glXGetVisualFromFBConfigP = (PFNGLXGETVISUALFROMFBCONFIGPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXGetVisualFromFBConfig");
70 glXCreateWindowP = (PFNGLXCREATEWINDOWPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXCreateWindow");
71 glXMakeContextCurrentP = (PFNGLXMAKECONTEXTCURRENTPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXMakeContextCurrent");
72 glXDestroyWindowP = (PFNGLXDESTROYWINDOWPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXDestroyWindow");
73 }
74}
75
76class EffectView :
77 public nux::View
78{
79public:
80 EffectView (NUX_FILE_LINE_PROTO);
81 virtual ~EffectView ();
82
83 void Draw (nux::GraphicsEngine &context, bool force) { return; };
84 void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
85private:
86 BackgroundEffectHelper bg_effect_helper_;
87};
88
89class Shape
90{
91 public:
92
93 typedef boost::shared_ptr <Shape> Ptr;
94
95 Shape ();
96 virtual ~Shape ();
97
98 float rotation () { return mRotation; }
99
100 void draw (unsigned int width, unsigned int height) { glDraw (width, height); }
101 void rotate () { applyRotation (); }
102
103 protected:
104
105 float mRotation;
106
107 virtual void glDraw (unsigned int width, unsigned int height) = 0;
108 virtual void applyRotation () = 0;
109 virtual void getRotationAxes (float &x, float &y, float &z) = 0;
110};
111
112Shape::Shape () :
113 mRotation (0.0f)
114{
115}
116
117Shape::~Shape ()
118{
119}
120
121class Triangle :
122 public Shape
123{
124 public:
125
126 typedef boost::shared_ptr <Triangle> Ptr;
127
128 protected:
129
130 void glDraw (unsigned int width, unsigned int height);
131 void applyRotation () { mRotation += 5.0f; }
132 void getRotationAxes (float &x, float &y, float &z) { x = 0.0f; y = 1.0f; z = 0.0f; }
133};
134
135void
136Triangle::glDraw (unsigned int width, unsigned int height)
137{
138 glBegin(GL_TRIANGLES);
139 glColor3f(1.0f, 0.0f, 0.0f);
140 glVertex3f(width / 4, height, 0.0f);
141 glColor3f(0.0f, 1.0f, 0.0f);
142 glVertex3f(0.0f, 0.0f, 0.0f);
143 glColor3f(0.0f, 0.0f, 1.0f);
144 glVertex3f(width / 2, 0.0f, 0.0f);
145 glEnd();
146}
147
148class Square :
149 public Shape
150{
151 public:
152
153 typedef boost::shared_ptr <Square> Ptr;
154
155 protected:
156
157 void glDraw (unsigned int width, unsigned int height);
158 void applyRotation () { mRotation -= 2.5f; }
159 void getRotationAxes (float &x, float &y, float &z) { x = 1.0f; y = 0.0f; z = 0.0f; }
160
161};
162
163void
164Square::glDraw (unsigned int width, unsigned int height)
165{
166 glBegin(GL_QUADS);
167 glColor3f(sin (rotation () / 100.0f), -sin (rotation () / 100.0f), cos (rotation () / 100.0f));
168 glVertex3f(width / 2, height, 0.0f);
169 glColor3f(-sin (rotation () / 100.0f), sin (rotation () / 100.0f), cos (rotation () / 100.0f));
170 glVertex3f(width, height, 0.0f);
171 glColor3f(sin (rotation () / 100.0f), sin (rotation () / 100.0f), sin (rotation () / 100.0f));
172 glVertex3f(width, 0.0f, 0.0f);
173 glColor3f(-sin (rotation () / 100.0f), cos (rotation () / 100.0f), cos (rotation () / 100.0f));
174 glVertex3f(width / 2, 0.0f, 0.0f);
175 glEnd();
176}
177
178class BaseContext
179{
180 public:
181
182 BaseContext (Display *);
183 ~BaseContext ();
184
185 void run ();
186
187 protected:
188
189 bool eventHandler ();
190 bool paintDispatch ();
191
192 enum class ModifierApplication
193 {
194 Square,
195 Triangle,
196 Both
197 };
198
199 void nextWindowPosition ();
200 void nextShapeRotation ();
201 void setupContextForSize (unsigned int width,
202 unsigned int height);
203 void drawShape (const Shape::Ptr &) {};
204
205 private:
206
207 static gboolean onNewEvents (GIOChannel *channel,
208 GIOCondition condition,
209 gpointer data);
210
211 static gboolean onPaintTimeout (gpointer data);
212
213 static void onWindowThreadCreation (nux::NThread *thread, void *d);
214
215 Display *mDisplay;
216 Window mWindow;
217 Colormap mColormap;
218 nux::WindowThread *mWindowThread;
219 nux::View *mRootView;
220 unity::ScreenEffectFramebufferObject::Ptr mFbo;
221 GLXWindow mGlxWindow;
222 GLXContext mContext;
223 ModifierApplication mRotating;
224 ModifierApplication mBlur;
225 unsigned int mWidth;
226 unsigned int mHeight;
227 bool mNuxReady;
228 Shape::Ptr mTriangle;
229 Shape::Ptr mSquare;
230};
231
232BaseContext::BaseContext (Display *display) :
233 mDisplay (display),
234 mWindowThread (NULL),
235 mRotating (ModifierApplication::Both),
236 mBlur (ModifierApplication::Both),
237 mWidth (640),
238 mHeight (480),
239 mNuxReady (false),
240 mTriangle (new Triangle ()),
241 mSquare (new Square ())
242{
243 int numFBConfig = 0;
244 GLXFBConfig *fbConfigs = (*GLFuncs::glXChooseFBConfigP) (mDisplay,
245 DefaultScreen (mDisplay),
246 attributes,
247 &numFBConfig);
248 XVisualInfo *visinfo = (*GLFuncs::glXGetVisualFromFBConfigP) (mDisplay,
249 fbConfigs[0]);
250
251 mContext = glXCreateContext (mDisplay, visinfo, 0, GL_TRUE);
252 mColormap = XCreateColormap (mDisplay,
253 DefaultRootWindow (mDisplay),
254 visinfo->visual,
255 AllocNone);
256
257 XSetWindowAttributes wa;
258
259 wa.colormap = mColormap;
260 wa.border_pixel = 0;
261 wa.event_mask = StructureNotifyMask | KeyPressMask | ExposureMask;
262
263 mWindow = XCreateWindow (mDisplay, DefaultRootWindow (mDisplay),
264 0, 0, mWidth, mHeight, 0, visinfo->depth, InputOutput,
265 visinfo->visual, CWColormap | CWEventMask | CWBorderPixel,
266 &wa);
267
268 mGlxWindow = (*GLFuncs::glXCreateWindowP) (mDisplay, fbConfigs[0], mWindow, NULL);
269
270 XStoreName (mDisplay, mWindow, "F1: Toggle Effect, F2: Rotation, F3: Effect");
271 XMapWindow (mDisplay, mWindow);
272
273 bool ready = false;
274
275 do
276 {
277 XEvent ev;
278 XNextEvent (mDisplay, &ev);
279 switch (ev.type)
280 {
281 case MapNotify:
282 case ConfigureNotify:
283 case Expose:
284 ready = true;
285 break;
286 default:
287 break;
288 }
289
290 } while (!ready);
291
292 (*GLFuncs::glXMakeContextCurrentP) (mDisplay, mGlxWindow, mGlxWindow, mContext);
293
294 setupContextForSize (mWidth, mHeight);
295}
296
297void
298BaseContext::run ()
299{
300 GIOChannel *channel;
301 mWindowThread = nux::CreateFromForeignWindow (mWindow,
302 mContext,
303 &BaseContext::onWindowThreadCreation,
304 (void *) this);
305
306 mWindowThread->Run(NULL);
307
308 while (!mNuxReady);
309 g_timeout_add (128, &BaseContext::onPaintTimeout, (gpointer) this);
310
311 channel = g_io_channel_unix_new (ConnectionNumber (mDisplay));
312
313 g_io_add_watch (channel, (GIOCondition) (G_IO_IN | G_IO_HUP | G_IO_ERR),
314 &BaseContext::onNewEvents, (gpointer) this);
315 gtk_main ();
316}
317
318BaseContext::~BaseContext ()
319{
320 delete mWindowThread;
321
322 (*GLFuncs::glXMakeContextCurrentP) (mDisplay, None, None, mContext);
323 glXDestroyContext (mDisplay, mContext);
324 (*GLFuncs::glXDestroyWindowP) (mDisplay, mGlxWindow);
325
326 XFreeColormap (mDisplay, mColormap);
327 XDestroyWindow (mDisplay, mWindow);
328}
329
330void
331BaseContext::setupContextForSize (unsigned int width,
332 unsigned int height)
333{
334 mWidth = width;
335 mHeight = height;
336
337 glViewport(0, 0, width, height);
338 glDrawBuffer (GL_BACK);
339 glReadBuffer (GL_BACK);
340 glMatrixMode(GL_PROJECTION);
341 glLoadIdentity();
342 gluPerspective(60.0f, 1.0f, 0.1f, 100.0f);
343 glMatrixMode(GL_MODELVIEW);
344 glLoadIdentity ();
345 glClearColor (1, 1, 1, 1);
346 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
347 glXSwapBuffers (mDisplay, mGlxWindow);
348
349 if (mFbo)
350 mFbo.reset (new unity::ScreenEffectFramebufferObject (GLFuncs::glXGetProcAddressP, nux::Geometry (0, 0, mWidth, mHeight)));
351
352 if (mRootView && mNuxReady)
353 {
354 switch (mBlur)
355 {
356 case ModifierApplication::Both:
357 mRootView->SetGeometry (nux::Geometry (0, 0, mWidth / 2, mHeight));
358 break;
359 case ModifierApplication::Triangle:
360 mRootView->SetGeometry (nux::Geometry (mWidth / 2, 0, mWidth / 2, mHeight));
361 break;
362 case ModifierApplication::Square:
363 mRootView->SetGeometry (nux::Geometry (0, 0, mWidth, mHeight));
364 break;
365 default:
366 break;
367 }
368 }
369}
370
371bool
372BaseContext::eventHandler ()
373{
374 XEvent event;
375 XEvent *ev = &event;
376
377 XNextEvent (mDisplay, &event);
378
379 switch (ev->type)
380 {
381 case KeyPress:
382 if (XLookupKeysym (&ev->xkey, 0) == XK_Escape)
383 return false;
384 else if (XLookupKeysym (&ev->xkey, 0) == XK_F1)
385 {
386 if (!mFbo)
387 {
388 BackgroundEffectHelper::blur_type = unity::BLUR_ACTIVE;
389 mFbo.reset (new unity::ScreenEffectFramebufferObject (GLFuncs::glXGetProcAddressP, nux::Geometry (0, 0, mWidth, mHeight)));
390 }
391 else
392 {
393 BackgroundEffectHelper::blur_type = unity::BLUR_NONE;
394 mFbo.reset ();
395 }
396 }
397 else if (XLookupKeysym (&ev->xkey, 0) == XK_F2)
398 nextShapeRotation ();
399 else if (XLookupKeysym (&ev->xkey, 0) == XK_F3)
400 nextWindowPosition ();
401 break;
402 case ConfigureNotify:
403 setupContextForSize (ev->xconfigure.width, ev->xconfigure.height);
404 default:
405 break;
406 }
407
408 return true;
409}
410
411gboolean
412BaseContext::onNewEvents (GIOChannel *channel,
413 GIOCondition condition,
414 gpointer data)
415{
416 BaseContext *self = static_cast <BaseContext *> (data);
417 gboolean keep_going = TRUE;
418
419 if (condition & G_IO_IN)
420 {
421 if (self->eventHandler ())
422 return TRUE;
423 else
424 return FALSE;
425 }
426
427 return TRUE;
428}
429
430gboolean
431BaseContext::onPaintTimeout (gpointer data)
432{
433 BaseContext *self = static_cast <BaseContext *> (data);
434
435 if (self->paintDispatch ())
436 return TRUE;
437
438 return FALSE;
439}
440
441void
442BaseContext::nextShapeRotation ()
443{
444 switch (mRotating)
445 {
446 case ModifierApplication::Both:
447 mRotating = ModifierApplication::Triangle;
448 break;
449 case ModifierApplication::Triangle:
450 mRotating = ModifierApplication::Square;
451 break;
452 case ModifierApplication::Square:
453 mRotating = ModifierApplication::Both;
454 break;
455 default:
456 break;
457 }
458}
459
460void
461BaseContext::nextWindowPosition ()
462{
463 switch (mBlur)
464 {
465 case ModifierApplication::Both:
466 mBlur = ModifierApplication::Triangle;
467 mRootView->SetGeometry (nux::Geometry (0, 0, mWidth / 2, mHeight));
468 break;
469 case ModifierApplication::Triangle:
470 mBlur = ModifierApplication::Square;
471 mRootView->SetGeometry (nux::Geometry (mWidth / 2, 0, mWidth / 2, mHeight));
472 break;
473 case ModifierApplication::Square:
474 mBlur = ModifierApplication::Both;
475 mRootView->SetGeometry (nux::Geometry (0, 0, mWidth, mHeight));
476 break;
477 default:
478 break;
479 }
480}
481
482EffectView::EffectView (NUX_FILE_LINE_DECL)
483 : View (NUX_FILE_LINE_PARAM)
484{
485 bg_effect_helper_.owner = this;
486}
487
488EffectView::~EffectView ()
489{
490}
491
492void EffectView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw)
493{
494 nux::Geometry base = GetGeometry();
495 GfxContext.PushClippingRectangle(base);
496 nux::Geometry blur_geo (base.x, base.y, base.width, base.height);
497
498 if (BackgroundEffectHelper::blur_type == unity::BLUR_ACTIVE)
499 {
500 bg_effect_helper_.enabled = true;
501
502 auto blur_texture = bg_effect_helper_.GetBlurRegion(blur_geo);
503
504 if (blur_texture.IsValid ())
505 {
506 nux::TexCoordXForm texxform_blur_bg;
507 texxform_blur_bg.flip_v_coord = true;
508 texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
509 texxform_blur_bg.uoffset = ((float) base.x) / (base.width);
510 texxform_blur_bg.voffset = ((float) base.y) / (base.height);
511
512 nux::ROPConfig rop;
513 rop.Blend = false;
514 rop.SrcBlend = GL_ONE;
515 rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA;
516
517 gPainter.PushDrawTextureLayer(GfxContext, base,
518 blur_texture,
519 texxform_blur_bg,
520 nux::color::White,
521 true,
522 rop);
523 }
524 }
525 else
526 bg_effect_helper_.enabled = false;
527 GfxContext.PopClippingRectangle();
528}
529
530bool
531BaseContext::paintDispatch ()
532{
533 if (mFbo)
534 {
535 switch (mRotating)
536 {
537 case ModifierApplication::Both:
538 BackgroundEffectHelper::ProcessDamage (nux::Geometry (0, 0, mWidth, mHeight));
539 break;
540 case ModifierApplication::Triangle:
541 BackgroundEffectHelper::ProcessDamage (nux::Geometry (0, 0, mWidth / 2, mHeight));
542 break;
543 case ModifierApplication::Square:
544 BackgroundEffectHelper::ProcessDamage (nux::Geometry (mWidth / 2, 0, mWidth / 2, mHeight));
545 break;
546 }
547
548 mFbo->bind (nux::Geometry (0, 0, mWidth, mHeight));
549
550 if (!mFbo->status ())
551 LOG_INFO (logger) << "FBO not ok!";
552 }
553
554 glClearColor (1, 1, 1, 1);
555 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
556 glPushMatrix ();
557 glLoadIdentity();
558 glTranslatef(-0.5f, -0.5f, -0.866025404f);
559 glScalef (1.0f / mWidth, 1.0f / mHeight, 0.0f);
560 glTranslatef(mWidth * 0.25, 0, 0);
561 glRotatef(mTriangle->rotation (), 0.0f, 1.0f, 0.0f);
562 glTranslatef(-(mWidth * 0.25), 0, 0);
563
564 mTriangle->draw (mWidth, mHeight);
565
566 glLoadIdentity();
567 glTranslatef(-0.5f, -0.5f, -0.866025404f);
568 glScalef (1.0f / mWidth, 1.0f / mHeight, 0.0f);
569 glTranslatef(mWidth * 0.75, 0, 0);
570 glRotatef(mSquare->rotation (), 0.0f, 1.0f, 0.0f);
571 glTranslatef(-(mWidth * 0.75), 0, 0);
572
573 mSquare->draw (mWidth, mHeight);
574
575 glColor4f (1.0f, 1.0f, 1.0f, 5.0f);
576 glPopMatrix ();
577
578 if (mFbo)
579 mFbo->unbind ();
580
581 if (mFbo && mFbo->status ())
582 {
583 glClearColor (1, 1, 1, 1);
584 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
585 glPushMatrix ();
586 glLoadIdentity();
587 glTranslatef(-0.5f, 0.5f, -0.866025404f);
588 glScalef (1.0f / mWidth, -(1.0f / mHeight), 0.0f);
589 mFbo->paint (nux::Geometry (0, 0, mWidth, mHeight));
590 glPopMatrix ();
591
592 nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture =
593 nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID (mFbo->texture(),
594 mWidth, mHeight, 1, nux::BITFMT_R8G8B8A8);
595
596 nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture;
597
598 nux::Geometry geo = nux::Geometry (0, 0, mWidth, mHeight);
599 BackgroundEffectHelper::monitor_rect_ = geo;
600 }
601
602 glMatrixMode(GL_PROJECTION);
603 glPushMatrix();
604
605 glMatrixMode(GL_MODELVIEW);
606 glPushMatrix();
607 glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT |
608 GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT | GL_SCISSOR_BIT);
609 mRootView->ProcessDraw (mWindowThread->GetGraphicsEngine (), true);
610 glMatrixMode(GL_PROJECTION);
611 glPopMatrix();
612 glMatrixMode(GL_MODELVIEW);
613 glPopMatrix();
614
615 glDrawBuffer(GL_BACK);
616 glReadBuffer(GL_BACK);
617
618 glPopAttrib();
619
620 glXSwapBuffers (mDisplay, mGlxWindow);
621
622 switch (mRotating)
623 {
624 case ModifierApplication::Both:
625 mTriangle->rotate ();
626 mSquare->rotate ();
627 break;
628 case ModifierApplication::Triangle:
629 mTriangle->rotate ();
630 break;
631 case ModifierApplication::Square:
632 mSquare->rotate ();
633 break;
634 }
635
636 return true;
637}
638
639void
640BaseContext::onWindowThreadCreation (nux::NThread *thread, void *data)
641{
642 BaseContext *bc = static_cast <BaseContext *> (data);
643
644 bc->mRootView = new EffectView ();
645 bc->mRootView->SetGeometry (nux::Geometry (0, 0, 640, 480));
646 bc->mNuxReady = true;
647 BackgroundEffectHelper::blur_type = unity::BLUR_ACTIVE;
648}
649
650int main (int argc, char **argv)
651{
652 Display *display = XOpenDisplay (NULL);
653 nux::NuxInitialize (0);
654 GLFuncs::init ();
655 g_type_init ();
656 g_thread_init (NULL);
657 gtk_init(&argc, &argv);
658
659 BaseContext *bc = new BaseContext (display);
660
661 bc->run ();
662
663 delete bc;
664
665 XCloseDisplay (display);
666
667 return 0;
668}
669
670