Merge lp:~smspillaz/unity/unity.fix_864784_868120_872625v2 into lp:unity
- unity.fix_864784_868120_872625v2
- Merge into trunk
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 |
Related bugs: |
|
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.
Commit message
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-
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 BackgroundEffec
Mirco Müller (macslow) wrote : Posted in a previous version of this proposal | # |
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.
Michal Hruby (mhr3) wrote : Posted in a previous version of this proposal | # |
Nvidia here and I can confirm MacSlow's findings.
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.
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.
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.
Jason Smith (jassmith) wrote : Posted in a previous version of this proposal | # |
+1
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
Can someone with fglrx test this ?
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
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.
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
*cough* *cough* someone test this on fglrx *cough*
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-
Saves a little typing (and it is more efficient in behaviour),
UnityFBO:
should be
UnityFBO:
Avoids an extra copy.
Jason Smith (jassmith) wrote : Posted in a previous version of this proposal | # |
This requires testing for merge
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.
Jason Smith (jassmith) wrote : | # |
Works like the other oem branch afaict, no merge conflicts after time. I say approve :)
Sam Spilsbury (smspillaz) wrote : | # |
standalone-
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
1 | === modified file 'plugins/unityshell/src/BackgroundEffectHelper.cpp' |
2 | --- plugins/unityshell/src/BackgroundEffectHelper.cpp 2011-09-28 05:19:39 +0000 |
3 | +++ plugins/unityshell/src/BackgroundEffectHelper.cpp 2012-01-05 02:50:45 +0000 |
4 | @@ -85,7 +85,20 @@ |
5 | bool BackgroundEffectHelper::HasEnabledHelpers() |
6 | { |
7 | for (BackgroundEffectHelper * bg_effect_helper : registered_list_) |
8 | + { |
9 | if (bg_effect_helper->enabled) |
10 | + { |
11 | + return true; |
12 | + } |
13 | + } |
14 | + |
15 | + return false; |
16 | +} |
17 | + |
18 | +bool BackgroundEffectHelper::HasDirtyHelpers() |
19 | +{ |
20 | + for (BackgroundEffectHelper * bg_effect_helper : registered_list_) |
21 | + if (bg_effect_helper->enabled && bg_effect_helper->cache_dirty) |
22 | return true; |
23 | |
24 | return false; |
25 | |
26 | === modified file 'plugins/unityshell/src/BackgroundEffectHelper.h' |
27 | --- plugins/unityshell/src/BackgroundEffectHelper.h 2011-10-19 22:13:57 +0000 |
28 | +++ plugins/unityshell/src/BackgroundEffectHelper.h 2012-01-05 02:50:45 +0000 |
29 | @@ -53,7 +53,7 @@ |
30 | void DirtyCache(); |
31 | |
32 | static void ProcessDamage(nux::Geometry geo); |
33 | - |
34 | + static bool HasDirtyHelpers(); |
35 | static bool HasEnabledHelpers(); |
36 | |
37 | static nux::Property<unity::BlurType> blur_type; |
38 | |
39 | === modified file 'plugins/unityshell/src/PanelView.cpp' |
40 | --- plugins/unityshell/src/PanelView.cpp 2011-12-19 20:20:22 +0000 |
41 | +++ plugins/unityshell/src/PanelView.cpp 2012-01-05 02:50:45 +0000 |
42 | @@ -616,8 +616,7 @@ |
43 | |
44 | _opacity = opacity; |
45 | |
46 | - if (_opacity < 1.0f && !_dash_is_open) |
47 | - bg_effect_helper_.enabled = false; |
48 | + bg_effect_helper_.enabled = (_opacity < 1.0f || _dash_is_open); |
49 | |
50 | ForceUpdateBackground(); |
51 | } |
52 | |
53 | === added file 'plugins/unityshell/src/ScreenEffectFramebufferObject.cpp' |
54 | --- plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 1970-01-01 00:00:00 +0000 |
55 | +++ plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-01-05 02:50:45 +0000 |
56 | @@ -0,0 +1,234 @@ |
57 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
58 | +/* Compiz unity plugin |
59 | + * unity.h |
60 | + * |
61 | + * Copyright (c) 2010-11 Canonical Ltd. |
62 | + * |
63 | + * This program is free software; you can redistribute it and/or |
64 | + * modify it under the terms of the GNU General Public License |
65 | + * as published by the Free Software Foundation; either version 3 |
66 | + * of the License, or (at your option) any later version. |
67 | + * |
68 | + * This program is distributed in the hope that it will be useful, |
69 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
70 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
71 | + * GNU General Public License for more details. |
72 | + * |
73 | + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> |
74 | + */ |
75 | + |
76 | +#include "ScreenEffectFramebufferObject.h" |
77 | +#include "BackgroundEffectHelper.h" |
78 | +#include <NuxCore/Logger.h> |
79 | +#include <dlfcn.h> |
80 | + |
81 | +namespace |
82 | +{ |
83 | + nux::logging::Logger logger ("unity.screeneffectframebufferobject"); |
84 | +} |
85 | + |
86 | +void unity::ScreenEffectFramebufferObject::paint (const nux::Geometry &output) |
87 | +{ |
88 | + /* Draw the bit of the relevant framebuffer for each output */ |
89 | + |
90 | + glPushAttrib (GL_VIEWPORT_BIT); |
91 | + glViewport (0, mScreenSize.height - (output.y + output.height), mScreenSize.width, mScreenSize.height); |
92 | + |
93 | + if (mFBTexture) |
94 | + { |
95 | + glEnable (GL_TEXTURE_2D); |
96 | + activeTexture (GL_TEXTURE0_ARB); |
97 | + glBindTexture (GL_TEXTURE_2D, mFBTexture); |
98 | + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
99 | + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
100 | + |
101 | + glPushAttrib (GL_SCISSOR_BIT); |
102 | + glEnable (GL_SCISSOR_TEST); |
103 | + |
104 | + glScissor (output.x, mScreenSize.height - (output.y + output.height), |
105 | + output.width, output.height); |
106 | + |
107 | + /* FIXME: This needs to be GL_TRIANGLE_STRIP */ |
108 | + glBegin (GL_QUADS); |
109 | + glTexCoord2f (0, 1); |
110 | + glVertex2i (mGeometry.x, mGeometry.y); |
111 | + glTexCoord2f (0, 0); |
112 | + glVertex2i (mGeometry.x, mGeometry.y + mGeometry.height); |
113 | + glTexCoord2f (1, 0); |
114 | + glVertex2i (mGeometry.x + mGeometry.width, mGeometry.y + mGeometry.height); |
115 | + glTexCoord2f (1, 1); |
116 | + glVertex2i (mGeometry.x + mGeometry.width, mGeometry.y); |
117 | + glEnd (); |
118 | + |
119 | + activeTexture (GL_TEXTURE0_ARB); |
120 | + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
121 | + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
122 | + glBindTexture (GL_TEXTURE_2D, 0); |
123 | + glDisable (GL_TEXTURE_2D); |
124 | + glPopAttrib (); |
125 | + } |
126 | + glPopAttrib (); |
127 | +} |
128 | + |
129 | +void unity::ScreenEffectFramebufferObject::onScreenSizeChanged(const nux::Geometry& screenSize) |
130 | +{ |
131 | + mScreenSize = screenSize; |
132 | +} |
133 | + |
134 | + |
135 | +void unity::ScreenEffectFramebufferObject::unbind () |
136 | +{ |
137 | + if (!mBoundCnt) |
138 | + return; |
139 | + |
140 | + mBoundCnt--; |
141 | + |
142 | + (*bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0); |
143 | + |
144 | + glDrawBuffer (GL_BACK); |
145 | + glReadBuffer (GL_BACK); |
146 | + |
147 | + /* Matches the viewport set we did in ::bind () */ |
148 | + glPopAttrib (); |
149 | + |
150 | +} |
151 | + |
152 | +bool unity::ScreenEffectFramebufferObject::status () |
153 | +{ |
154 | + return mFboStatus; |
155 | +} |
156 | + |
157 | +void unity::ScreenEffectFramebufferObject::bind (const nux::Geometry &output) |
158 | +{ |
159 | + if (!BackgroundEffectHelper::HasDirtyHelpers()) |
160 | + return; |
161 | + |
162 | + /* Clear the error bit */ |
163 | + glGetError (); |
164 | + |
165 | + if (!mFBTexture) |
166 | + { |
167 | + glGenTextures (1, &mFBTexture); |
168 | + |
169 | + glBindTexture (GL_TEXTURE_2D, mFBTexture); |
170 | + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
171 | + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
172 | + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
173 | + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
174 | + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, mGeometry.width, mGeometry.height, 0, GL_BGRA, |
175 | +#if IMAGE_BYTE_ORDER == MSBFirst |
176 | + GL_UNSIGNED_INT_8_8_8_8_REV, |
177 | +#else |
178 | + GL_UNSIGNED_BYTE, |
179 | +#endif |
180 | + NULL); |
181 | + |
182 | + glBindTexture (GL_TEXTURE_2D, 0); |
183 | + |
184 | + if (glGetError () != GL_NO_ERROR) |
185 | + { |
186 | + mFboHandle = 0; |
187 | + mFboStatus = false; |
188 | + return; |
189 | + } |
190 | + } |
191 | + |
192 | + (*bindFramebuffer) (GL_FRAMEBUFFER_EXT, mFboHandle); |
193 | + |
194 | + (*framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
195 | + GL_TEXTURE_2D, mFBTexture, 0); |
196 | + |
197 | + (*framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, |
198 | + GL_TEXTURE_2D, 0, 0); |
199 | + |
200 | + /* Ensure that a framebuffer is actually available */ |
201 | + if (!mFboStatus) |
202 | + { |
203 | + GLint status = (*checkFramebufferStatus) (GL_DRAW_FRAMEBUFFER); |
204 | + |
205 | + if (status != GL_FRAMEBUFFER_COMPLETE) |
206 | + { |
207 | + switch (status) |
208 | + { |
209 | + case GL_FRAMEBUFFER_UNDEFINED: |
210 | + LOG_WARN (logger) << "no window"; |
211 | + break; |
212 | + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: |
213 | + LOG_WARN (logger) << "attachment incomplete"; |
214 | + break; |
215 | + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: |
216 | + LOG_WARN (logger) << "no buffers attached to fbo"; |
217 | + break; |
218 | + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: |
219 | + LOG_WARN (logger) << "some attachment in glDrawBuffers doesn't exist in FBO"; |
220 | + break; |
221 | + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: |
222 | + LOG_WARN (logger) << "some attachment in glReadBuffers doesn't exist in FBO"; |
223 | + break; |
224 | + case GL_FRAMEBUFFER_UNSUPPORTED: |
225 | + LOG_WARN (logger) << "unsupported internal format"; |
226 | + break; |
227 | + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: |
228 | + LOG_WARN (logger) << "different levels of sampling for each attachment"; |
229 | + break; |
230 | + case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: |
231 | + LOG_WARN (logger) << "number of layers is different"; |
232 | + break; |
233 | + default: |
234 | + LOG_WARN (logger) << "unable to bind the framebuffer for an unknown reason"; |
235 | + break; |
236 | + } |
237 | + |
238 | + bindFramebuffer (GL_FRAMEBUFFER_EXT, 0); |
239 | + deleteFramebuffers (1, &mFboHandle); |
240 | + |
241 | + glDrawBuffer (GL_BACK); |
242 | + glReadBuffer (GL_BACK); |
243 | + |
244 | + mFboHandle = 0; |
245 | + |
246 | + mFboStatus = false; |
247 | + } |
248 | + else |
249 | + mFboStatus = true; |
250 | + } |
251 | + |
252 | + if (mFboStatus) |
253 | + { |
254 | + glPushAttrib (GL_VIEWPORT_BIT); |
255 | + |
256 | + glViewport (output.x, |
257 | + mScreenSize.height - (output.y + output.height), |
258 | + output.width, |
259 | + output.height); |
260 | + } |
261 | + |
262 | + mBoundCnt++; |
263 | +} |
264 | + |
265 | + |
266 | +unity::ScreenEffectFramebufferObject::ScreenEffectFramebufferObject (GLXGetProcAddressProc p, const nux::Geometry &geom) |
267 | + : getProcAddressGLX (p) |
268 | + , mFboStatus (false) |
269 | + , mFBTexture (0) |
270 | + , mGeometry (geom) |
271 | + , mBoundCnt (0) |
272 | + , mScreenSize (geom) |
273 | +{ |
274 | + activeTexture = (GLActiveTextureProc) (*getProcAddressGLX) ((GLubyte *) "glActiveTexture"); |
275 | + genFramebuffers = (GLGenFramebuffersProc) (*getProcAddressGLX) ((GLubyte *)"glGenFramebuffersEXT"); |
276 | + deleteFramebuffers = (GLDeleteFramebuffersProc) (*getProcAddressGLX) ((GLubyte *)"glDeleteFramebuffersEXT"); |
277 | + bindFramebuffer = (GLBindFramebufferProc) (*getProcAddressGLX) ((GLubyte *)"glBindFramebufferEXT"); |
278 | + checkFramebufferStatus = (GLCheckFramebufferStatusProc) (*getProcAddressGLX) ((GLubyte *) "glCheckFramebufferStatusEXT"); |
279 | + framebufferTexture2D = (GLFramebufferTexture2DProc) (*getProcAddressGLX) ((GLubyte *) "glFramebufferTexture2DEXT"); |
280 | + |
281 | + (*genFramebuffers) (1, &mFboHandle); |
282 | +} |
283 | + |
284 | +unity::ScreenEffectFramebufferObject::~ScreenEffectFramebufferObject () |
285 | +{ |
286 | + (*deleteFramebuffers) (1, &mFboHandle); |
287 | + |
288 | + if (mFBTexture) |
289 | + glDeleteTextures (1, &mFBTexture); |
290 | +} |
291 | |
292 | === added file 'plugins/unityshell/src/ScreenEffectFramebufferObject.h' |
293 | --- plugins/unityshell/src/ScreenEffectFramebufferObject.h 1970-01-01 00:00:00 +0000 |
294 | +++ plugins/unityshell/src/ScreenEffectFramebufferObject.h 2012-01-05 02:50:45 +0000 |
295 | @@ -0,0 +1,87 @@ |
296 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
297 | +/* Compiz unity plugin |
298 | + * unity.h |
299 | + * |
300 | + * Copyright (c) 2010-11 Canonical Ltd. |
301 | + * |
302 | + * This program is free software; you can redistribute it and/or |
303 | + * modify it under the terms of the GNU General Public License |
304 | + * as published by the Free Software Foundation; either version 3 |
305 | + * of the License, or (at your option) any later version. |
306 | + * |
307 | + * This program is distributed in the hope that it will be useful, |
308 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
309 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
310 | + * GNU General Public License for more details. |
311 | + * |
312 | + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> |
313 | + */ |
314 | + |
315 | +#ifndef UNITY_SCREENEFFECT_FRAMEBUFFER_H |
316 | +#define UNITY_SCREENEFFECT_FRAMEBUFFER_H |
317 | + |
318 | +#include <Nux/Nux.h> |
319 | + |
320 | +namespace unity |
321 | +{ |
322 | +class ScreenEffectFramebufferObject |
323 | +{ |
324 | +public: |
325 | + |
326 | + typedef boost::shared_ptr <ScreenEffectFramebufferObject> Ptr; |
327 | + typedef void (*FuncPtr) (void); |
328 | + typedef FuncPtr (*GLXGetProcAddressProc) (const GLubyte *procName); |
329 | + |
330 | + ScreenEffectFramebufferObject (GLXGetProcAddressProc, const nux::Geometry &geom); |
331 | + ~ScreenEffectFramebufferObject (); |
332 | + |
333 | +public: |
334 | + |
335 | + void bind (const nux::Geometry &geom); |
336 | + void unbind (); |
337 | + |
338 | + bool status (); |
339 | + void paint (const nux::Geometry &geom); |
340 | + bool bound () { return mBoundCnt > 0; } |
341 | + |
342 | + GLuint texture () { return mFBTexture; } |
343 | + |
344 | + void onScreenSizeChanged (const nux::Geometry &screenSize); |
345 | + |
346 | +private: |
347 | + |
348 | + FuncPtr getProcAddr (const std::string &); |
349 | + |
350 | + typedef void (*GLActiveTextureProc) (GLenum texture); |
351 | + typedef void (*GLGenFramebuffersProc) (GLsizei n, |
352 | + GLuint *framebuffers); |
353 | + typedef void (*GLDeleteFramebuffersProc) (GLsizei n, |
354 | + GLuint *framebuffers); |
355 | + typedef void (*GLBindFramebufferProc) (GLenum target, |
356 | + GLuint framebuffer); |
357 | + typedef GLenum (*GLCheckFramebufferStatusProc) (GLenum target); |
358 | + typedef void (*GLFramebufferTexture2DProc) (GLenum target, |
359 | + GLenum attachment, |
360 | + GLenum textarget, |
361 | + GLuint texture, |
362 | + GLint level); |
363 | + |
364 | + GLXGetProcAddressProc getProcAddressGLX; |
365 | + GLActiveTextureProc activeTexture; |
366 | + GLGenFramebuffersProc genFramebuffers; |
367 | + GLDeleteFramebuffersProc deleteFramebuffers; |
368 | + GLBindFramebufferProc bindFramebuffer; |
369 | + GLCheckFramebufferStatusProc checkFramebufferStatus; |
370 | + GLFramebufferTexture2DProc framebufferTexture2D; |
371 | + /* compiz fbo handle that goes through to nux */ |
372 | + GLuint mFboHandle; // actual handle to the framebuffer_ext |
373 | + bool mFboStatus; // did the framebuffer texture bind succeed |
374 | + GLuint mFBTexture; |
375 | + nux::Geometry mGeometry; |
376 | + unsigned int mBoundCnt; |
377 | + |
378 | + nux::Geometry mScreenSize; |
379 | +}; |
380 | +} // namespace unity |
381 | + |
382 | +#endif |
383 | |
384 | === modified file 'plugins/unityshell/src/unityshell.cpp' |
385 | --- plugins/unityshell/src/unityshell.cpp 2012-01-02 20:51:09 +0000 |
386 | +++ plugins/unityshell/src/unityshell.cpp 2012-01-05 02:50:45 +0000 |
387 | @@ -65,7 +65,6 @@ |
388 | /* Set up vtable symbols */ |
389 | COMPIZ_PLUGIN_20090315(unityshell, unity::UnityPluginVTable); |
390 | |
391 | - |
392 | namespace unity |
393 | { |
394 | using launcher::AbstractLauncherIcon; |
395 | @@ -114,7 +113,7 @@ |
396 | , damaged(false) |
397 | , _key_nav_mode_requested(false) |
398 | , _last_output(nullptr) |
399 | - , mActiveFbo (0) |
400 | + , _active_fbo (0) |
401 | , dash_is_open_ (false) |
402 | , grab_index_ (0) |
403 | , painting_tray_ (false) |
404 | @@ -227,12 +226,21 @@ |
405 | _edge_timeout = optionGetLauncherRevealEdgeTimeout (); |
406 | _in_paint = false; |
407 | |
408 | + void *dlhand = dlopen ("libunityshell.so", RTLD_LAZY); |
409 | + |
410 | + if (dlhand) |
411 | + { |
412 | + dlerror (); |
413 | + glXGetProcAddressP = (ScreenEffectFramebufferObject::GLXGetProcAddressProc) dlsym (dlhand, "glXGetProcAddress"); |
414 | + if (dlerror () != NULL) |
415 | + glXGetProcAddressP = NULL; |
416 | + } |
417 | + |
418 | if (GL::fbo) |
419 | { |
420 | - foreach (CompOutput & o, screen->outputDevs()) |
421 | - uScreen->mFbos[&o] = UnityFBO::Ptr (new UnityFBO(&o)); |
422 | - |
423 | - uScreen->mFbos[&(screen->fullscreenOutput ())] = UnityFBO::Ptr (new UnityFBO(&(screen->fullscreenOutput ()))); |
424 | + nux::Geometry geometry (0, 0, screen->width (), screen->height ()); |
425 | + uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry)); |
426 | + uScreen->_fbo->onScreenSizeChanged (geometry); |
427 | } |
428 | |
429 | optionSetBackgroundColorNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2)); |
430 | @@ -451,7 +459,7 @@ |
431 | |
432 | void UnityScreen::nuxEpilogue() |
433 | { |
434 | - (*GL::bindFramebuffer)(GL_FRAMEBUFFER_EXT, mActiveFbo); |
435 | + (*GL::bindFramebuffer)(GL_FRAMEBUFFER_EXT, _active_fbo); |
436 | |
437 | glMatrixMode(GL_PROJECTION); |
438 | glLoadIdentity(); |
439 | @@ -492,8 +500,6 @@ |
440 | if (PluginAdapter::Default()->IsExpoActive()) |
441 | return; |
442 | |
443 | - nuxPrologue(); |
444 | - |
445 | CompOutput* output = _last_output; |
446 | float vc[4]; |
447 | float h = 20.0f; |
448 | @@ -504,6 +510,9 @@ |
449 | float y1 = output->y() + panel_h; |
450 | float x2 = x1 + output->width(); |
451 | float y2 = y1 + h; |
452 | + GLMatrix sTransform = GLMatrix (); |
453 | + |
454 | + sTransform.toScreenSpace(output, -DEFAULT_Z_CAMERA); |
455 | |
456 | vc[0] = x1; |
457 | vc[1] = x2; |
458 | @@ -543,7 +552,6 @@ |
459 | glDisable(GL_BLEND); |
460 | } |
461 | } |
462 | - nuxEpilogue(); |
463 | } |
464 | |
465 | void |
466 | @@ -562,30 +570,35 @@ |
467 | { |
468 | CompOutput *output = _last_output; |
469 | Window tray_xid = panel_controller_->GetTrayXid (); |
470 | - bool bound = mFbos[output]->bound (); |
471 | - |
472 | - |
473 | - if (bound) |
474 | + |
475 | + bool was_bound = _fbo->bound (); |
476 | + _fbo->unbind (); |
477 | + |
478 | + /* Draw the bit of the relevant framebuffer for each output */ |
479 | + |
480 | + if (was_bound) |
481 | { |
482 | - mFbos[output]->unbind (); |
483 | - |
484 | - /* Draw the bit of the relevant framebuffer for each output */ |
485 | - mFbos[output]->paint (); |
486 | + GLMatrix sTransform; |
487 | + sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA); |
488 | + glPushMatrix (); |
489 | + glLoadMatrixf (sTransform.getMatrix ()); |
490 | + _fbo->paint (nux::Geometry (output->x (), output->y (), output->width (), output->height ())); |
491 | + glPopMatrix (); |
492 | } |
493 | |
494 | - nuxPrologue(); |
495 | - |
496 | nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture = |
497 | - nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(mFbos[output]->texture(), |
498 | - output->width(), output->height(), 1, nux::BITFMT_R8G8B8A8); |
499 | + nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(_fbo->texture(), |
500 | + screen->width (), screen->height(), 1, nux::BITFMT_R8G8B8A8); |
501 | |
502 | nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture; |
503 | |
504 | - nux::Geometry geo = nux::Geometry (output->x (), output->y (), output->width (), output->height ()); |
505 | + nux::Geometry geo = nux::Geometry (0, 0, screen->width (), screen->height ()); |
506 | + nux::Geometry oGeo = nux::Geometry (output->x (), output->y (), output->width (), output->height ()); |
507 | BackgroundEffectHelper::monitor_rect_ = geo; |
508 | |
509 | + nuxPrologue(); |
510 | _in_paint = true; |
511 | - wt->RenderInterfaceFromForeignCmd (&geo); |
512 | + wt->RenderInterfaceFromForeignCmd (&oGeo); |
513 | _in_paint = false; |
514 | nuxEpilogue(); |
515 | |
516 | @@ -985,6 +998,10 @@ |
517 | { |
518 | bool ret; |
519 | |
520 | + doShellRepaint = true; |
521 | + allowWindowPaint = true; |
522 | + _last_output = output; |
523 | + |
524 | /* bind the framebuffer here |
525 | * - it will be unbound and flushed |
526 | * to the backbuffer when some |
527 | @@ -995,11 +1012,7 @@ |
528 | * attempts to bind it will only increment |
529 | * its bind reference so make sure that |
530 | * you always unbind as much as you bind */ |
531 | - mFbos[output]->bind (); |
532 | - |
533 | - doShellRepaint = true; |
534 | - allowWindowPaint = true; |
535 | - _last_output = output; |
536 | + _fbo->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ())); |
537 | |
538 | /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */ |
539 | ret = gScreen->glPaintOutput(attrib, transform, region, output, mask); |
540 | @@ -1160,16 +1173,37 @@ |
541 | { |
542 | XDamageNotifyEvent *de = (XDamageNotifyEvent *) event; |
543 | CompWindow* w = screen->findWindow (de->drawable); |
544 | + std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList(); |
545 | + CompWindow* lastNWindow = screen->findWindow (xwns.back ()); |
546 | + bool processDamage = true; |
547 | |
548 | - if (w and !(w->wmType() & CompWindowTypeDndMask)) |
549 | + if (w) |
550 | { |
551 | - nux::Geometry damage (de->area.x, de->area.y, de->area.width, de->area.height); |
552 | - |
553 | - CompWindow::Geometry geom = w->geometry (); |
554 | - damage.x += geom.x () + geom.border (); |
555 | - damage.y += geom.y () + geom.border (); |
556 | - |
557 | - BackgroundEffectHelper::ProcessDamage(damage); |
558 | + if (!w->overrideRedirect () && |
559 | + w->isViewable () && |
560 | + !w->invisible ()) |
561 | + { |
562 | + |
563 | + for (; lastNWindow != NULL; lastNWindow = lastNWindow->next) |
564 | + { |
565 | + if (lastNWindow == w) |
566 | + { |
567 | + processDamage = false; |
568 | + break; |
569 | + } |
570 | + } |
571 | + |
572 | + if (processDamage) |
573 | + { |
574 | + nux::Geometry damage (de->area.x, de->area.y, de->area.width, de->area.height); |
575 | + |
576 | + const CompWindow::Geometry &geom = w->geometry (); |
577 | + damage.x += geom.x () + geom.border (); |
578 | + damage.y += geom.y () + geom.border (); |
579 | + |
580 | + BackgroundEffectHelper::ProcessDamage(damage); |
581 | + } |
582 | + } |
583 | } |
584 | } |
585 | } |
586 | @@ -2164,15 +2198,15 @@ |
587 | |
588 | void UnityScreen::Relayout() |
589 | { |
590 | + nux::Geometry geometry (0, 0, screen->width (), screen->height ()); |
591 | + |
592 | if (!needsRelayout) |
593 | return; |
594 | |
595 | if (GL::fbo) |
596 | { |
597 | - foreach (CompOutput &o, screen->outputDevs ()) |
598 | - uScreen->mFbos[&o] = UnityFBO::Ptr (new UnityFBO (&o)); |
599 | - |
600 | - uScreen->mFbos[&(screen->fullscreenOutput ())] = UnityFBO::Ptr (new UnityFBO (&(screen->fullscreenOutput ()))); |
601 | + uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry)); |
602 | + uScreen->_fbo->onScreenSizeChanged (geometry); |
603 | } |
604 | |
605 | UScreen *uscreen = UScreen::GetDefault(); |
606 | @@ -2195,8 +2229,6 @@ |
607 | { |
608 | UnityScreen* uScr = reinterpret_cast<UnityScreen*>(data); |
609 | |
610 | - uScreen->mFbos.clear (); |
611 | - |
612 | uScr->NeedsRelayout (); |
613 | uScr->Relayout(); |
614 | uScr->relayoutSourceId = 0; |
615 | @@ -2229,220 +2261,6 @@ |
616 | ScheduleRelayout(500); |
617 | } |
618 | |
619 | -void UnityFBO::paint () |
620 | -{ |
621 | - //CompositeScreen *cScreen = CompositeScreen::get (screen); |
622 | - //unsigned int mask = cScreen->damageMask (); |
623 | - float texx, texy, texwidth, texheight; |
624 | - |
625 | - /* Must be completely unbound before painting */ |
626 | - if (mBoundCnt) |
627 | - return; |
628 | - |
629 | - /* Draw the bit of the relevant framebuffer for each output */ |
630 | - GLMatrix transform; |
631 | - |
632 | - glViewport (output->x (), screen->height () - output->y2 (), output->width (), output->height ()); |
633 | - GLScreen::get (screen)->clearOutput (output, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
634 | - |
635 | - transform.toScreenSpace (output, -DEFAULT_Z_CAMERA); |
636 | - glPushMatrix (); |
637 | - glLoadMatrixf (transform.getMatrix ()); |
638 | - |
639 | - /* Note that texcoords here are normalized, so it's just (0,0)-(1,1) */ |
640 | - texx = 0.0; |
641 | - texy = 0.0; |
642 | - texwidth = 1.0f; |
643 | - texheight = 1.0f; |
644 | - |
645 | - if (mFBTexture) |
646 | - { |
647 | - glEnable (GL_TEXTURE_2D); |
648 | - GL::activeTexture (GL_TEXTURE0_ARB); |
649 | - glBindTexture (GL_TEXTURE_2D, mFBTexture); |
650 | - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
651 | - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
652 | - |
653 | - glPushAttrib (GL_SCISSOR_BIT); |
654 | - glEnable (GL_SCISSOR_TEST); |
655 | - |
656 | - glScissor (output->x1 (), screen->height () - output->y2 (), |
657 | - output->width (), output->height ()); |
658 | - |
659 | - /* FIXME: This needs to be GL_TRIANGLE_STRIP */ |
660 | - glBegin (GL_QUADS); |
661 | - glTexCoord2f (texx, texy + texheight); |
662 | - glVertex2i (output->x1 (), output->y1 ()); |
663 | - glTexCoord2f (texx, texy); |
664 | - glVertex2i (output->x1 (), output->y2 ()); |
665 | - glTexCoord2f (texx + texwidth, texy); |
666 | - glVertex2i (output->x2 (), output->y2 ()); |
667 | - glTexCoord2f (texx + texwidth, texy + texheight); |
668 | - glVertex2i (output->x2 (), output->y1 ()); |
669 | - glEnd (); |
670 | - |
671 | - GL::activeTexture (GL_TEXTURE0_ARB); |
672 | - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
673 | - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
674 | - glBindTexture (GL_TEXTURE_2D, 0); |
675 | - glEnable (GL_TEXTURE_2D); |
676 | - |
677 | - glDisable (GL_SCISSOR_TEST); |
678 | - glPopAttrib (); |
679 | - } |
680 | - |
681 | - glPopMatrix(); |
682 | -} |
683 | - |
684 | -void UnityFBO::unbind () |
685 | -{ |
686 | - mBoundCnt--; |
687 | - |
688 | - if (mBoundCnt) |
689 | - return; |
690 | - |
691 | - uScreen->setActiveFbo (0); |
692 | - (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0); |
693 | - |
694 | - glDrawBuffer (GL_BACK); |
695 | - glReadBuffer (GL_BACK); |
696 | - |
697 | -} |
698 | - |
699 | -bool UnityFBO::bound () |
700 | -{ |
701 | - return mBoundCnt > 0; |
702 | -} |
703 | - |
704 | -bool UnityFBO::status () |
705 | -{ |
706 | - return mFboStatus; |
707 | -} |
708 | - |
709 | -void UnityFBO::bind () |
710 | -{ |
711 | - if (mBoundCnt) |
712 | - { |
713 | - mBoundCnt++; |
714 | - return; |
715 | - } |
716 | - |
717 | - if (!mFBTexture) |
718 | - { |
719 | - glGenTextures (1, &mFBTexture); |
720 | - |
721 | - glBindTexture (GL_TEXTURE_2D, mFBTexture); |
722 | - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
723 | - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
724 | - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
725 | - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
726 | - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, output->width(), output->height(), 0, GL_BGRA, |
727 | -#if IMAGE_BYTE_ORDER == MSBFirst |
728 | - GL_UNSIGNED_INT_8_8_8_8_REV, |
729 | -#else |
730 | - GL_UNSIGNED_BYTE, |
731 | -#endif |
732 | - NULL); |
733 | - |
734 | - glBindTexture (GL_TEXTURE_2D, 0); |
735 | - } |
736 | - |
737 | - glGetError (); |
738 | - |
739 | - (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, mFboHandle); |
740 | - |
741 | - (*GL::framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
742 | - GL_TEXTURE_2D, mFBTexture, 0); |
743 | - |
744 | - (*GL::framebufferTexture2D) (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, |
745 | - GL_TEXTURE_2D, 0, 0); |
746 | - |
747 | - /* Ensure that a framebuffer is actually available */ |
748 | - if (!mFboStatus) |
749 | - { |
750 | - GLint status = (*GL::checkFramebufferStatus) (GL_DRAW_FRAMEBUFFER); |
751 | - |
752 | - if (status != GL_FRAMEBUFFER_COMPLETE) |
753 | - { |
754 | - switch (status) |
755 | - { |
756 | - case GL_FRAMEBUFFER_UNDEFINED: |
757 | - compLogMessage ("unity", CompLogLevelWarn, "no window"); |
758 | - break; |
759 | - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: |
760 | - compLogMessage ("unity", CompLogLevelWarn, "attachment incomplete"); |
761 | - break; |
762 | - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: |
763 | - compLogMessage ("unity", CompLogLevelWarn, "no buffers attached to fbo"); |
764 | - break; |
765 | - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: |
766 | - compLogMessage ("unity", CompLogLevelWarn, "some attachment in glDrawBuffers doesn't exist in FBO"); |
767 | - break; |
768 | - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: |
769 | - compLogMessage ("unity", CompLogLevelWarn, "some attachment in glReadBuffers doesn't exist in FBO"); |
770 | - break; |
771 | - case GL_FRAMEBUFFER_UNSUPPORTED: |
772 | - compLogMessage ("unity", CompLogLevelWarn, "unsupported internal format"); |
773 | - break; |
774 | - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: |
775 | - compLogMessage ("unity", CompLogLevelWarn, "different levels of sampling for each attachment"); |
776 | - break; |
777 | - case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: |
778 | - compLogMessage ("unity", CompLogLevelWarn, "number of layers is different"); |
779 | - break; |
780 | - default: |
781 | - compLogMessage ("unity", CompLogLevelWarn, "unable to bind the framebuffer for an unknown reason"); |
782 | - break; |
783 | - } |
784 | - |
785 | - GL::bindFramebuffer (GL_FRAMEBUFFER_EXT, 0); |
786 | - GL::deleteFramebuffers (1, &mFboHandle); |
787 | - |
788 | - glDrawBuffer (GL_BACK); |
789 | - glReadBuffer (GL_BACK); |
790 | - |
791 | - mFboHandle = 0; |
792 | - |
793 | - mFboStatus = false; |
794 | - uScreen->setActiveFbo (0); |
795 | - } |
796 | - else |
797 | - mFboStatus = true; |
798 | - } |
799 | - |
800 | - if (mFboStatus) |
801 | - { |
802 | - uScreen->setActiveFbo (mFboHandle); |
803 | - |
804 | - glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); |
805 | - glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); |
806 | - |
807 | - glViewport (0, |
808 | - 0, |
809 | - output->width(), |
810 | - output->height()); |
811 | - |
812 | - mBoundCnt++; |
813 | - } |
814 | -} |
815 | - |
816 | -UnityFBO::UnityFBO (CompOutput *o) |
817 | - : mFboStatus (false) |
818 | - , mFBTexture (0) |
819 | - , output (o) |
820 | - , mBoundCnt (0) |
821 | -{ |
822 | - (*GL::genFramebuffers) (1, &mFboHandle); |
823 | -} |
824 | - |
825 | -UnityFBO::~UnityFBO () |
826 | -{ |
827 | - (*GL::deleteFramebuffers) (1, &mFboHandle); |
828 | - |
829 | - if (mFBTexture) |
830 | - glDeleteTextures (1, &mFBTexture); |
831 | -} |
832 | - |
833 | void UnityScreen::OnDashRealized () |
834 | { |
835 | /* stack any windows named "onboard" above us */ |
836 | |
837 | === modified file 'plugins/unityshell/src/unityshell.h' |
838 | --- plugins/unityshell/src/unityshell.h 2011-12-15 07:08:41 +0000 |
839 | +++ plugins/unityshell/src/unityshell.h 2012-01-05 02:50:45 +0000 |
840 | @@ -47,47 +47,19 @@ |
841 | #include "DebugDBusInterface.h" |
842 | #include "SwitcherController.h" |
843 | #include "UBusWrapper.h" |
844 | +#include "ScreenEffectFramebufferObject.h" |
845 | |
846 | #include "compizminimizedwindowhandler.h" |
847 | #include "BGHash.h" |
848 | #include <compiztoolbox/compiztoolbox.h> |
849 | +#include <dlfcn.h> |
850 | |
851 | namespace unity |
852 | { |
853 | |
854 | -class UnityFBO |
855 | -{ |
856 | -public: |
857 | - |
858 | - typedef boost::shared_ptr <UnityFBO> Ptr; |
859 | - |
860 | - UnityFBO (CompOutput *o); |
861 | - ~UnityFBO (); |
862 | - |
863 | -public: |
864 | - |
865 | - void bind (); |
866 | - void unbind (); |
867 | - |
868 | - bool status (); |
869 | - bool bound (); |
870 | - void paint (); |
871 | - |
872 | - GLuint texture () { return mFBTexture; } |
873 | - |
874 | -private: |
875 | - |
876 | - /* compiz fbo handle that goes through to nux */ |
877 | - GLuint mFboHandle; // actual handle to the framebuffer_ext |
878 | - bool mFboStatus; // did the framebuffer texture bind succeed |
879 | - GLuint mFBTexture; |
880 | - CompOutput *output; |
881 | - unsigned int mBoundCnt; |
882 | -}; |
883 | - |
884 | class UnityShowdesktopHandler |
885 | { |
886 | -public: |
887 | + public: |
888 | |
889 | UnityShowdesktopHandler (CompWindow *w); |
890 | ~UnityShowdesktopHandler (); |
891 | @@ -234,8 +206,6 @@ |
892 | void NeedsRelayout(); |
893 | void ScheduleRelayout(guint timeout); |
894 | |
895 | - void setActiveFbo (GLuint fbo) { mActiveFbo = fbo; } |
896 | - |
897 | bool forcePaintOnTop (); |
898 | |
899 | protected: |
900 | @@ -320,8 +290,8 @@ |
901 | |
902 | unity::BGHash _bghash; |
903 | |
904 | - std::map <CompOutput *, UnityFBO::Ptr> mFbos; |
905 | - GLuint mActiveFbo; |
906 | + ScreenEffectFramebufferObject::Ptr _fbo; |
907 | + GLuint _active_fbo; |
908 | |
909 | bool queryForShader (); |
910 | |
911 | @@ -332,6 +302,8 @@ |
912 | bool painting_tray_; |
913 | unsigned int tray_paint_mask_; |
914 | |
915 | + ScreenEffectFramebufferObject::GLXGetProcAddressProc glXGetProcAddressP; |
916 | + |
917 | friend class UnityWindow; |
918 | }; |
919 | |
920 | |
921 | === modified file 'standalone-clients/CMakeLists.txt' |
922 | --- standalone-clients/CMakeLists.txt 2011-12-14 01:47:53 +0000 |
923 | +++ standalone-clients/CMakeLists.txt 2012-01-05 02:50:45 +0000 |
924 | @@ -26,13 +26,13 @@ |
925 | ) |
926 | add_definitions (${CFLAGS}) |
927 | |
928 | -set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm") |
929 | +set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm -lGL -lGLU") |
930 | link_libraries (${LIBS}) |
931 | |
932 | set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS}) |
933 | link_directories (${CMAKE_BINARY_DIR}/UnityCore ${LIB_PATHS}) |
934 | |
935 | -include_directories (. .. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR}) |
936 | +include_directories (. .. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) |
937 | |
938 | # We can't have convenience libs so we need to rebuild with what we need |
939 | # Please keep actual test files alphabetically at top and then files |
940 | @@ -452,6 +452,20 @@ |
941 | ) |
942 | add_dependencies (bg-hash unity-core-${UNITY_API_VERSION}) |
943 | |
944 | +find_package (OpenGL) |
945 | + |
946 | +include_directories (${OPENGL_gl_INCDIRS}) |
947 | +add_library (glfuncloader SHARED |
948 | + ${CMAKE_CURRENT_SOURCE_DIR}/GLFuncLoader.cpp) |
949 | +target_link_libraries (glfuncloader dl ${OPENGL_gl_LIBRARY}) |
950 | +add_executable (screen-effect-fbo |
951 | + TestScreenEffectFramebufferObject.cpp |
952 | + ${UNITY_SRC}/ScreenEffectFramebufferObject.cpp |
953 | + ${UNITY_SRC}/BackgroundEffectHelper.cpp) |
954 | + |
955 | +target_link_libraries (screen-effect-fbo glfuncloader ${OPENGL_gl_LIBRARY}) |
956 | +add_dependencies (screen-effect-fbo ${UNITY_API_VERSION}) |
957 | + |
958 | |
959 | # Custom target to make all the other targets here, add your test to this list |
960 | add_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) |
961 | |
962 | === added file 'standalone-clients/GLFuncLoader.cpp' |
963 | --- standalone-clients/GLFuncLoader.cpp 1970-01-01 00:00:00 +0000 |
964 | +++ standalone-clients/GLFuncLoader.cpp 2012-01-05 02:50:45 +0000 |
965 | @@ -0,0 +1,51 @@ |
966 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
967 | +/* Compiz unity plugin |
968 | + * unity.h |
969 | + * |
970 | + * Copyright (c) 2010-11 Canonical Ltd. |
971 | + * |
972 | + * This program is free software; you can redistribute it and/or |
973 | + * modify it under the terms of the GNU General Public License |
974 | + * as published by the Free Software Foundation; either version 3 |
975 | + * of the License, or (at your option) any later version. |
976 | + * |
977 | + * This program is distributed in the hope that it will be useful, |
978 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
979 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
980 | + * GNU General Public License for more details. |
981 | + * |
982 | + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> |
983 | + */ |
984 | + |
985 | +#include "GLFuncLoader.h" |
986 | +#include <dlfcn.h> |
987 | + |
988 | +unity::GLLoader::FuncPtr unity::GLLoader::getProcAddr(const std::string &name) |
989 | +{ |
990 | + static void *dlhand = NULL; |
991 | + FuncPtr funcPtr = NULL; |
992 | + |
993 | + glGetError (); |
994 | + |
995 | + if (!funcPtr) |
996 | + { |
997 | + if (!dlhand) |
998 | + dlhand = dlopen ("libglfuncloader.so", RTLD_LAZY); |
999 | + |
1000 | + char *error = dlerror (); |
1001 | + |
1002 | + if (dlhand) |
1003 | + { |
1004 | + dlerror (); |
1005 | + funcPtr = (FuncPtr) dlsym (dlhand, name.c_str ()); |
1006 | + |
1007 | + error = dlerror (); |
1008 | + if (error != NULL) |
1009 | + funcPtr = NULL; |
1010 | + } |
1011 | + } |
1012 | + |
1013 | + return funcPtr; |
1014 | +} |
1015 | + |
1016 | + |
1017 | |
1018 | === added file 'standalone-clients/GLFuncLoader.h' |
1019 | --- standalone-clients/GLFuncLoader.h 1970-01-01 00:00:00 +0000 |
1020 | +++ standalone-clients/GLFuncLoader.h 2012-01-05 02:50:45 +0000 |
1021 | @@ -0,0 +1,33 @@ |
1022 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
1023 | +/* Compiz unity plugin |
1024 | + * unity.h |
1025 | + * |
1026 | + * Copyright (c) 2010-11 Canonical Ltd. |
1027 | + * |
1028 | + * This program is free software; you can redistribute it and/or |
1029 | + * modify it under the terms of the GNU General Public License |
1030 | + * as published by the Free Software Foundation; either version 3 |
1031 | + * of the License, or (at your option) any later version. |
1032 | + * |
1033 | + * This program is distributed in the hope that it will be useful, |
1034 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1035 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1036 | + * GNU General Public License for more details. |
1037 | + * |
1038 | + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> |
1039 | + */ |
1040 | + |
1041 | +#include <string> |
1042 | +#include <GL/gl.h> |
1043 | +#include <GL/glx.h> |
1044 | + |
1045 | +namespace unity |
1046 | +{ |
1047 | +namespace GLLoader |
1048 | +{ |
1049 | +typedef void (*FuncPtr) (void); |
1050 | +typedef FuncPtr (*GLXGetProcAddressProc) (const GLubyte *procName); |
1051 | + |
1052 | +FuncPtr getProcAddr(const std::string &name); |
1053 | +} |
1054 | +} |
1055 | |
1056 | === added file 'standalone-clients/TestScreenEffectFramebufferObject.cpp' |
1057 | --- standalone-clients/TestScreenEffectFramebufferObject.cpp 1970-01-01 00:00:00 +0000 |
1058 | +++ standalone-clients/TestScreenEffectFramebufferObject.cpp 2012-01-05 02:50:45 +0000 |
1059 | @@ -0,0 +1,670 @@ |
1060 | +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
1061 | +/* Compiz unity plugin |
1062 | + * unity.h |
1063 | + * |
1064 | + * Copyright (c) 2010-11 Canonical Ltd. |
1065 | + * |
1066 | + * This program is free software; you can redistribute it and/or |
1067 | + * modify it under the terms of the GNU General Public License |
1068 | + * as published by the Free Software Foundation; either version 3 |
1069 | + * of the License, or (at your option) any later version. |
1070 | + * |
1071 | + * This program is distributed in the hope that it will be useful, |
1072 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1073 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1074 | + * GNU General Public License for more details. |
1075 | + * |
1076 | + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> |
1077 | + */ |
1078 | + |
1079 | +#include "ScreenEffectFramebufferObject.h" |
1080 | +#include "BackgroundEffectHelper.h" |
1081 | +#include "GLFuncLoader.h" |
1082 | +#include <Nux/Nux.h> |
1083 | +#include <Nux/VLayout.h> |
1084 | +#include <Nux/View.h> |
1085 | +#include <Nux/BaseWindow.h> |
1086 | +#include <Nux/WindowCompositor.h> |
1087 | +#include <NuxCore/Logger.h> |
1088 | +#include <NuxCore/Object.h> |
1089 | +#include <X11/Xlib.h> |
1090 | +#include <X11/Xutil.h> |
1091 | +#include <GL/glx.h> |
1092 | +#include <GL/gl.h> |
1093 | +#include <dlfcn.h> |
1094 | +#include <sys/poll.h> |
1095 | +#include <unistd.h> |
1096 | +#include <glib.h> |
1097 | +#include <gtk/gtk.h> |
1098 | +#include <cmath> |
1099 | + |
1100 | +using namespace unity::GLLoader; |
1101 | + |
1102 | +namespace |
1103 | +{ |
1104 | + nux::logging::Logger logger ("unity.test-screeneffectframebufferobject"); |
1105 | + |
1106 | + const static int attributes[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, |
1107 | + GLX_X_RENDERABLE, True, |
1108 | + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, |
1109 | + GLX_DOUBLEBUFFER, True, |
1110 | + GLX_RED_SIZE, 8, |
1111 | + GLX_GREEN_SIZE, 8, |
1112 | + GLX_BLUE_SIZE, 8, 0}; |
1113 | +} |
1114 | + |
1115 | +namespace GLFuncs |
1116 | +{ |
1117 | + GLXGetProcAddressProc glXGetProcAddressP; |
1118 | + PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfigP; |
1119 | + PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfigP; |
1120 | + PFNGLXCREATEWINDOWPROC glXCreateWindowP; |
1121 | + PFNGLXDESTROYWINDOWPROC glXDestroyWindowP; |
1122 | + PFNGLXMAKECONTEXTCURRENTPROC glXMakeContextCurrentP; |
1123 | + |
1124 | + void init () |
1125 | + { |
1126 | + glXGetProcAddressP = (GLXGetProcAddressProc) getProcAddr ("glXGetProcAddress"); |
1127 | + glXChooseFBConfigP = (PFNGLXCHOOSEFBCONFIGPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXChooseFBConfig"); |
1128 | + glXGetVisualFromFBConfigP = (PFNGLXGETVISUALFROMFBCONFIGPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXGetVisualFromFBConfig"); |
1129 | + glXCreateWindowP = (PFNGLXCREATEWINDOWPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXCreateWindow"); |
1130 | + glXMakeContextCurrentP = (PFNGLXMAKECONTEXTCURRENTPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXMakeContextCurrent"); |
1131 | + glXDestroyWindowP = (PFNGLXDESTROYWINDOWPROC) (*glXGetProcAddressP) ((const GLubyte *) "glXDestroyWindow"); |
1132 | + } |
1133 | +} |
1134 | + |
1135 | +class EffectView : |
1136 | + public nux::View |
1137 | +{ |
1138 | +public: |
1139 | + EffectView (NUX_FILE_LINE_PROTO); |
1140 | + virtual ~EffectView (); |
1141 | + |
1142 | + void Draw (nux::GraphicsEngine &context, bool force) { return; }; |
1143 | + void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); |
1144 | +private: |
1145 | + BackgroundEffectHelper bg_effect_helper_; |
1146 | +}; |
1147 | + |
1148 | +class Shape |
1149 | +{ |
1150 | + public: |
1151 | + |
1152 | + typedef boost::shared_ptr <Shape> Ptr; |
1153 | + |
1154 | + Shape (); |
1155 | + virtual ~Shape (); |
1156 | + |
1157 | + float rotation () { return mRotation; } |
1158 | + |
1159 | + void draw (unsigned int width, unsigned int height) { glDraw (width, height); } |
1160 | + void rotate () { applyRotation (); } |
1161 | + |
1162 | + protected: |
1163 | + |
1164 | + float mRotation; |
1165 | + |
1166 | + virtual void glDraw (unsigned int width, unsigned int height) = 0; |
1167 | + virtual void applyRotation () = 0; |
1168 | + virtual void getRotationAxes (float &x, float &y, float &z) = 0; |
1169 | +}; |
1170 | + |
1171 | +Shape::Shape () : |
1172 | + mRotation (0.0f) |
1173 | +{ |
1174 | +} |
1175 | + |
1176 | +Shape::~Shape () |
1177 | +{ |
1178 | +} |
1179 | + |
1180 | +class Triangle : |
1181 | + public Shape |
1182 | +{ |
1183 | + public: |
1184 | + |
1185 | + typedef boost::shared_ptr <Triangle> Ptr; |
1186 | + |
1187 | + protected: |
1188 | + |
1189 | + void glDraw (unsigned int width, unsigned int height); |
1190 | + void applyRotation () { mRotation += 5.0f; } |
1191 | + void getRotationAxes (float &x, float &y, float &z) { x = 0.0f; y = 1.0f; z = 0.0f; } |
1192 | +}; |
1193 | + |
1194 | +void |
1195 | +Triangle::glDraw (unsigned int width, unsigned int height) |
1196 | +{ |
1197 | + glBegin(GL_TRIANGLES); |
1198 | + glColor3f(1.0f, 0.0f, 0.0f); |
1199 | + glVertex3f(width / 4, height, 0.0f); |
1200 | + glColor3f(0.0f, 1.0f, 0.0f); |
1201 | + glVertex3f(0.0f, 0.0f, 0.0f); |
1202 | + glColor3f(0.0f, 0.0f, 1.0f); |
1203 | + glVertex3f(width / 2, 0.0f, 0.0f); |
1204 | + glEnd(); |
1205 | +} |
1206 | + |
1207 | +class Square : |
1208 | + public Shape |
1209 | +{ |
1210 | + public: |
1211 | + |
1212 | + typedef boost::shared_ptr <Square> Ptr; |
1213 | + |
1214 | + protected: |
1215 | + |
1216 | + void glDraw (unsigned int width, unsigned int height); |
1217 | + void applyRotation () { mRotation -= 2.5f; } |
1218 | + void getRotationAxes (float &x, float &y, float &z) { x = 1.0f; y = 0.0f; z = 0.0f; } |
1219 | + |
1220 | +}; |
1221 | + |
1222 | +void |
1223 | +Square::glDraw (unsigned int width, unsigned int height) |
1224 | +{ |
1225 | + glBegin(GL_QUADS); |
1226 | + glColor3f(sin (rotation () / 100.0f), -sin (rotation () / 100.0f), cos (rotation () / 100.0f)); |
1227 | + glVertex3f(width / 2, height, 0.0f); |
1228 | + glColor3f(-sin (rotation () / 100.0f), sin (rotation () / 100.0f), cos (rotation () / 100.0f)); |
1229 | + glVertex3f(width, height, 0.0f); |
1230 | + glColor3f(sin (rotation () / 100.0f), sin (rotation () / 100.0f), sin (rotation () / 100.0f)); |
1231 | + glVertex3f(width, 0.0f, 0.0f); |
1232 | + glColor3f(-sin (rotation () / 100.0f), cos (rotation () / 100.0f), cos (rotation () / 100.0f)); |
1233 | + glVertex3f(width / 2, 0.0f, 0.0f); |
1234 | + glEnd(); |
1235 | +} |
1236 | + |
1237 | +class BaseContext |
1238 | +{ |
1239 | + public: |
1240 | + |
1241 | + BaseContext (Display *); |
1242 | + ~BaseContext (); |
1243 | + |
1244 | + void run (); |
1245 | + |
1246 | + protected: |
1247 | + |
1248 | + bool eventHandler (); |
1249 | + bool paintDispatch (); |
1250 | + |
1251 | + enum class ModifierApplication |
1252 | + { |
1253 | + Square, |
1254 | + Triangle, |
1255 | + Both |
1256 | + }; |
1257 | + |
1258 | + void nextWindowPosition (); |
1259 | + void nextShapeRotation (); |
1260 | + void setupContextForSize (unsigned int width, |
1261 | + unsigned int height); |
1262 | + void drawShape (const Shape::Ptr &) {}; |
1263 | + |
1264 | + private: |
1265 | + |
1266 | + static gboolean onNewEvents (GIOChannel *channel, |
1267 | + GIOCondition condition, |
1268 | + gpointer data); |
1269 | + |
1270 | + static gboolean onPaintTimeout (gpointer data); |
1271 | + |
1272 | + static void onWindowThreadCreation (nux::NThread *thread, void *d); |
1273 | + |
1274 | + Display *mDisplay; |
1275 | + Window mWindow; |
1276 | + Colormap mColormap; |
1277 | + nux::WindowThread *mWindowThread; |
1278 | + nux::View *mRootView; |
1279 | + unity::ScreenEffectFramebufferObject::Ptr mFbo; |
1280 | + GLXWindow mGlxWindow; |
1281 | + GLXContext mContext; |
1282 | + ModifierApplication mRotating; |
1283 | + ModifierApplication mBlur; |
1284 | + unsigned int mWidth; |
1285 | + unsigned int mHeight; |
1286 | + bool mNuxReady; |
1287 | + Shape::Ptr mTriangle; |
1288 | + Shape::Ptr mSquare; |
1289 | +}; |
1290 | + |
1291 | +BaseContext::BaseContext (Display *display) : |
1292 | + mDisplay (display), |
1293 | + mWindowThread (NULL), |
1294 | + mRotating (ModifierApplication::Both), |
1295 | + mBlur (ModifierApplication::Both), |
1296 | + mWidth (640), |
1297 | + mHeight (480), |
1298 | + mNuxReady (false), |
1299 | + mTriangle (new Triangle ()), |
1300 | + mSquare (new Square ()) |
1301 | +{ |
1302 | + int numFBConfig = 0; |
1303 | + GLXFBConfig *fbConfigs = (*GLFuncs::glXChooseFBConfigP) (mDisplay, |
1304 | + DefaultScreen (mDisplay), |
1305 | + attributes, |
1306 | + &numFBConfig); |
1307 | + XVisualInfo *visinfo = (*GLFuncs::glXGetVisualFromFBConfigP) (mDisplay, |
1308 | + fbConfigs[0]); |
1309 | + |
1310 | + mContext = glXCreateContext (mDisplay, visinfo, 0, GL_TRUE); |
1311 | + mColormap = XCreateColormap (mDisplay, |
1312 | + DefaultRootWindow (mDisplay), |
1313 | + visinfo->visual, |
1314 | + AllocNone); |
1315 | + |
1316 | + XSetWindowAttributes wa; |
1317 | + |
1318 | + wa.colormap = mColormap; |
1319 | + wa.border_pixel = 0; |
1320 | + wa.event_mask = StructureNotifyMask | KeyPressMask | ExposureMask; |
1321 | + |
1322 | + mWindow = XCreateWindow (mDisplay, DefaultRootWindow (mDisplay), |
1323 | + 0, 0, mWidth, mHeight, 0, visinfo->depth, InputOutput, |
1324 | + visinfo->visual, CWColormap | CWEventMask | CWBorderPixel, |
1325 | + &wa); |
1326 | + |
1327 | + mGlxWindow = (*GLFuncs::glXCreateWindowP) (mDisplay, fbConfigs[0], mWindow, NULL); |
1328 | + |
1329 | + XStoreName (mDisplay, mWindow, "F1: Toggle Effect, F2: Rotation, F3: Effect"); |
1330 | + XMapWindow (mDisplay, mWindow); |
1331 | + |
1332 | + bool ready = false; |
1333 | + |
1334 | + do |
1335 | + { |
1336 | + XEvent ev; |
1337 | + XNextEvent (mDisplay, &ev); |
1338 | + switch (ev.type) |
1339 | + { |
1340 | + case MapNotify: |
1341 | + case ConfigureNotify: |
1342 | + case Expose: |
1343 | + ready = true; |
1344 | + break; |
1345 | + default: |
1346 | + break; |
1347 | + } |
1348 | + |
1349 | + } while (!ready); |
1350 | + |
1351 | + (*GLFuncs::glXMakeContextCurrentP) (mDisplay, mGlxWindow, mGlxWindow, mContext); |
1352 | + |
1353 | + setupContextForSize (mWidth, mHeight); |
1354 | +} |
1355 | + |
1356 | +void |
1357 | +BaseContext::run () |
1358 | +{ |
1359 | + GIOChannel *channel; |
1360 | + mWindowThread = nux::CreateFromForeignWindow (mWindow, |
1361 | + mContext, |
1362 | + &BaseContext::onWindowThreadCreation, |
1363 | + (void *) this); |
1364 | + |
1365 | + mWindowThread->Run(NULL); |
1366 | + |
1367 | + while (!mNuxReady); |
1368 | + g_timeout_add (128, &BaseContext::onPaintTimeout, (gpointer) this); |
1369 | + |
1370 | + channel = g_io_channel_unix_new (ConnectionNumber (mDisplay)); |
1371 | + |
1372 | + g_io_add_watch (channel, (GIOCondition) (G_IO_IN | G_IO_HUP | G_IO_ERR), |
1373 | + &BaseContext::onNewEvents, (gpointer) this); |
1374 | + gtk_main (); |
1375 | +} |
1376 | + |
1377 | +BaseContext::~BaseContext () |
1378 | +{ |
1379 | + delete mWindowThread; |
1380 | + |
1381 | + (*GLFuncs::glXMakeContextCurrentP) (mDisplay, None, None, mContext); |
1382 | + glXDestroyContext (mDisplay, mContext); |
1383 | + (*GLFuncs::glXDestroyWindowP) (mDisplay, mGlxWindow); |
1384 | + |
1385 | + XFreeColormap (mDisplay, mColormap); |
1386 | + XDestroyWindow (mDisplay, mWindow); |
1387 | +} |
1388 | + |
1389 | +void |
1390 | +BaseContext::setupContextForSize (unsigned int width, |
1391 | + unsigned int height) |
1392 | +{ |
1393 | + mWidth = width; |
1394 | + mHeight = height; |
1395 | + |
1396 | + glViewport(0, 0, width, height); |
1397 | + glDrawBuffer (GL_BACK); |
1398 | + glReadBuffer (GL_BACK); |
1399 | + glMatrixMode(GL_PROJECTION); |
1400 | + glLoadIdentity(); |
1401 | + gluPerspective(60.0f, 1.0f, 0.1f, 100.0f); |
1402 | + glMatrixMode(GL_MODELVIEW); |
1403 | + glLoadIdentity (); |
1404 | + glClearColor (1, 1, 1, 1); |
1405 | + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
1406 | + glXSwapBuffers (mDisplay, mGlxWindow); |
1407 | + |
1408 | + if (mFbo) |
1409 | + mFbo.reset (new unity::ScreenEffectFramebufferObject (GLFuncs::glXGetProcAddressP, nux::Geometry (0, 0, mWidth, mHeight))); |
1410 | + |
1411 | + if (mRootView && mNuxReady) |
1412 | + { |
1413 | + switch (mBlur) |
1414 | + { |
1415 | + case ModifierApplication::Both: |
1416 | + mRootView->SetGeometry (nux::Geometry (0, 0, mWidth / 2, mHeight)); |
1417 | + break; |
1418 | + case ModifierApplication::Triangle: |
1419 | + mRootView->SetGeometry (nux::Geometry (mWidth / 2, 0, mWidth / 2, mHeight)); |
1420 | + break; |
1421 | + case ModifierApplication::Square: |
1422 | + mRootView->SetGeometry (nux::Geometry (0, 0, mWidth, mHeight)); |
1423 | + break; |
1424 | + default: |
1425 | + break; |
1426 | + } |
1427 | + } |
1428 | +} |
1429 | + |
1430 | +bool |
1431 | +BaseContext::eventHandler () |
1432 | +{ |
1433 | + XEvent event; |
1434 | + XEvent *ev = &event; |
1435 | + |
1436 | + XNextEvent (mDisplay, &event); |
1437 | + |
1438 | + switch (ev->type) |
1439 | + { |
1440 | + case KeyPress: |
1441 | + if (XLookupKeysym (&ev->xkey, 0) == XK_Escape) |
1442 | + return false; |
1443 | + else if (XLookupKeysym (&ev->xkey, 0) == XK_F1) |
1444 | + { |
1445 | + if (!mFbo) |
1446 | + { |
1447 | + BackgroundEffectHelper::blur_type = unity::BLUR_ACTIVE; |
1448 | + mFbo.reset (new unity::ScreenEffectFramebufferObject (GLFuncs::glXGetProcAddressP, nux::Geometry (0, 0, mWidth, mHeight))); |
1449 | + } |
1450 | + else |
1451 | + { |
1452 | + BackgroundEffectHelper::blur_type = unity::BLUR_NONE; |
1453 | + mFbo.reset (); |
1454 | + } |
1455 | + } |
1456 | + else if (XLookupKeysym (&ev->xkey, 0) == XK_F2) |
1457 | + nextShapeRotation (); |
1458 | + else if (XLookupKeysym (&ev->xkey, 0) == XK_F3) |
1459 | + nextWindowPosition (); |
1460 | + break; |
1461 | + case ConfigureNotify: |
1462 | + setupContextForSize (ev->xconfigure.width, ev->xconfigure.height); |
1463 | + default: |
1464 | + break; |
1465 | + } |
1466 | + |
1467 | + return true; |
1468 | +} |
1469 | + |
1470 | +gboolean |
1471 | +BaseContext::onNewEvents (GIOChannel *channel, |
1472 | + GIOCondition condition, |
1473 | + gpointer data) |
1474 | +{ |
1475 | + BaseContext *self = static_cast <BaseContext *> (data); |
1476 | + gboolean keep_going = TRUE; |
1477 | + |
1478 | + if (condition & G_IO_IN) |
1479 | + { |
1480 | + if (self->eventHandler ()) |
1481 | + return TRUE; |
1482 | + else |
1483 | + return FALSE; |
1484 | + } |
1485 | + |
1486 | + return TRUE; |
1487 | +} |
1488 | + |
1489 | +gboolean |
1490 | +BaseContext::onPaintTimeout (gpointer data) |
1491 | +{ |
1492 | + BaseContext *self = static_cast <BaseContext *> (data); |
1493 | + |
1494 | + if (self->paintDispatch ()) |
1495 | + return TRUE; |
1496 | + |
1497 | + return FALSE; |
1498 | +} |
1499 | + |
1500 | +void |
1501 | +BaseContext::nextShapeRotation () |
1502 | +{ |
1503 | + switch (mRotating) |
1504 | + { |
1505 | + case ModifierApplication::Both: |
1506 | + mRotating = ModifierApplication::Triangle; |
1507 | + break; |
1508 | + case ModifierApplication::Triangle: |
1509 | + mRotating = ModifierApplication::Square; |
1510 | + break; |
1511 | + case ModifierApplication::Square: |
1512 | + mRotating = ModifierApplication::Both; |
1513 | + break; |
1514 | + default: |
1515 | + break; |
1516 | + } |
1517 | +} |
1518 | + |
1519 | +void |
1520 | +BaseContext::nextWindowPosition () |
1521 | +{ |
1522 | + switch (mBlur) |
1523 | + { |
1524 | + case ModifierApplication::Both: |
1525 | + mBlur = ModifierApplication::Triangle; |
1526 | + mRootView->SetGeometry (nux::Geometry (0, 0, mWidth / 2, mHeight)); |
1527 | + break; |
1528 | + case ModifierApplication::Triangle: |
1529 | + mBlur = ModifierApplication::Square; |
1530 | + mRootView->SetGeometry (nux::Geometry (mWidth / 2, 0, mWidth / 2, mHeight)); |
1531 | + break; |
1532 | + case ModifierApplication::Square: |
1533 | + mBlur = ModifierApplication::Both; |
1534 | + mRootView->SetGeometry (nux::Geometry (0, 0, mWidth, mHeight)); |
1535 | + break; |
1536 | + default: |
1537 | + break; |
1538 | + } |
1539 | +} |
1540 | + |
1541 | +EffectView::EffectView (NUX_FILE_LINE_DECL) |
1542 | + : View (NUX_FILE_LINE_PARAM) |
1543 | +{ |
1544 | + bg_effect_helper_.owner = this; |
1545 | +} |
1546 | + |
1547 | +EffectView::~EffectView () |
1548 | +{ |
1549 | +} |
1550 | + |
1551 | +void EffectView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) |
1552 | +{ |
1553 | + nux::Geometry base = GetGeometry(); |
1554 | + GfxContext.PushClippingRectangle(base); |
1555 | + nux::Geometry blur_geo (base.x, base.y, base.width, base.height); |
1556 | + |
1557 | + if (BackgroundEffectHelper::blur_type == unity::BLUR_ACTIVE) |
1558 | + { |
1559 | + bg_effect_helper_.enabled = true; |
1560 | + |
1561 | + auto blur_texture = bg_effect_helper_.GetBlurRegion(blur_geo); |
1562 | + |
1563 | + if (blur_texture.IsValid ()) |
1564 | + { |
1565 | + nux::TexCoordXForm texxform_blur_bg; |
1566 | + texxform_blur_bg.flip_v_coord = true; |
1567 | + texxform_blur_bg.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD); |
1568 | + texxform_blur_bg.uoffset = ((float) base.x) / (base.width); |
1569 | + texxform_blur_bg.voffset = ((float) base.y) / (base.height); |
1570 | + |
1571 | + nux::ROPConfig rop; |
1572 | + rop.Blend = false; |
1573 | + rop.SrcBlend = GL_ONE; |
1574 | + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; |
1575 | + |
1576 | + gPainter.PushDrawTextureLayer(GfxContext, base, |
1577 | + blur_texture, |
1578 | + texxform_blur_bg, |
1579 | + nux::color::White, |
1580 | + true, |
1581 | + rop); |
1582 | + } |
1583 | + } |
1584 | + else |
1585 | + bg_effect_helper_.enabled = false; |
1586 | + GfxContext.PopClippingRectangle(); |
1587 | +} |
1588 | + |
1589 | +bool |
1590 | +BaseContext::paintDispatch () |
1591 | +{ |
1592 | + if (mFbo) |
1593 | + { |
1594 | + switch (mRotating) |
1595 | + { |
1596 | + case ModifierApplication::Both: |
1597 | + BackgroundEffectHelper::ProcessDamage (nux::Geometry (0, 0, mWidth, mHeight)); |
1598 | + break; |
1599 | + case ModifierApplication::Triangle: |
1600 | + BackgroundEffectHelper::ProcessDamage (nux::Geometry (0, 0, mWidth / 2, mHeight)); |
1601 | + break; |
1602 | + case ModifierApplication::Square: |
1603 | + BackgroundEffectHelper::ProcessDamage (nux::Geometry (mWidth / 2, 0, mWidth / 2, mHeight)); |
1604 | + break; |
1605 | + } |
1606 | + |
1607 | + mFbo->bind (nux::Geometry (0, 0, mWidth, mHeight)); |
1608 | + |
1609 | + if (!mFbo->status ()) |
1610 | + LOG_INFO (logger) << "FBO not ok!"; |
1611 | + } |
1612 | + |
1613 | + glClearColor (1, 1, 1, 1); |
1614 | + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
1615 | + glPushMatrix (); |
1616 | + glLoadIdentity(); |
1617 | + glTranslatef(-0.5f, -0.5f, -0.866025404f); |
1618 | + glScalef (1.0f / mWidth, 1.0f / mHeight, 0.0f); |
1619 | + glTranslatef(mWidth * 0.25, 0, 0); |
1620 | + glRotatef(mTriangle->rotation (), 0.0f, 1.0f, 0.0f); |
1621 | + glTranslatef(-(mWidth * 0.25), 0, 0); |
1622 | + |
1623 | + mTriangle->draw (mWidth, mHeight); |
1624 | + |
1625 | + glLoadIdentity(); |
1626 | + glTranslatef(-0.5f, -0.5f, -0.866025404f); |
1627 | + glScalef (1.0f / mWidth, 1.0f / mHeight, 0.0f); |
1628 | + glTranslatef(mWidth * 0.75, 0, 0); |
1629 | + glRotatef(mSquare->rotation (), 0.0f, 1.0f, 0.0f); |
1630 | + glTranslatef(-(mWidth * 0.75), 0, 0); |
1631 | + |
1632 | + mSquare->draw (mWidth, mHeight); |
1633 | + |
1634 | + glColor4f (1.0f, 1.0f, 1.0f, 5.0f); |
1635 | + glPopMatrix (); |
1636 | + |
1637 | + if (mFbo) |
1638 | + mFbo->unbind (); |
1639 | + |
1640 | + if (mFbo && mFbo->status ()) |
1641 | + { |
1642 | + glClearColor (1, 1, 1, 1); |
1643 | + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
1644 | + glPushMatrix (); |
1645 | + glLoadIdentity(); |
1646 | + glTranslatef(-0.5f, 0.5f, -0.866025404f); |
1647 | + glScalef (1.0f / mWidth, -(1.0f / mHeight), 0.0f); |
1648 | + mFbo->paint (nux::Geometry (0, 0, mWidth, mHeight)); |
1649 | + glPopMatrix (); |
1650 | + |
1651 | + nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture = |
1652 | + nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID (mFbo->texture(), |
1653 | + mWidth, mHeight, 1, nux::BITFMT_R8G8B8A8); |
1654 | + |
1655 | + nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture; |
1656 | + |
1657 | + nux::Geometry geo = nux::Geometry (0, 0, mWidth, mHeight); |
1658 | + BackgroundEffectHelper::monitor_rect_ = geo; |
1659 | + } |
1660 | + |
1661 | + glMatrixMode(GL_PROJECTION); |
1662 | + glPushMatrix(); |
1663 | + |
1664 | + glMatrixMode(GL_MODELVIEW); |
1665 | + glPushMatrix(); |
1666 | + glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT | |
1667 | + GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT | GL_SCISSOR_BIT); |
1668 | + mRootView->ProcessDraw (mWindowThread->GetGraphicsEngine (), true); |
1669 | + glMatrixMode(GL_PROJECTION); |
1670 | + glPopMatrix(); |
1671 | + glMatrixMode(GL_MODELVIEW); |
1672 | + glPopMatrix(); |
1673 | + |
1674 | + glDrawBuffer(GL_BACK); |
1675 | + glReadBuffer(GL_BACK); |
1676 | + |
1677 | + glPopAttrib(); |
1678 | + |
1679 | + glXSwapBuffers (mDisplay, mGlxWindow); |
1680 | + |
1681 | + switch (mRotating) |
1682 | + { |
1683 | + case ModifierApplication::Both: |
1684 | + mTriangle->rotate (); |
1685 | + mSquare->rotate (); |
1686 | + break; |
1687 | + case ModifierApplication::Triangle: |
1688 | + mTriangle->rotate (); |
1689 | + break; |
1690 | + case ModifierApplication::Square: |
1691 | + mSquare->rotate (); |
1692 | + break; |
1693 | + } |
1694 | + |
1695 | + return true; |
1696 | +} |
1697 | + |
1698 | +void |
1699 | +BaseContext::onWindowThreadCreation (nux::NThread *thread, void *data) |
1700 | +{ |
1701 | + BaseContext *bc = static_cast <BaseContext *> (data); |
1702 | + |
1703 | + bc->mRootView = new EffectView (); |
1704 | + bc->mRootView->SetGeometry (nux::Geometry (0, 0, 640, 480)); |
1705 | + bc->mNuxReady = true; |
1706 | + BackgroundEffectHelper::blur_type = unity::BLUR_ACTIVE; |
1707 | +} |
1708 | + |
1709 | +int main (int argc, char **argv) |
1710 | +{ |
1711 | + Display *display = XOpenDisplay (NULL); |
1712 | + nux::NuxInitialize (0); |
1713 | + GLFuncs::init (); |
1714 | + g_type_init (); |
1715 | + g_thread_init (NULL); |
1716 | + gtk_init(&argc, &argv); |
1717 | + |
1718 | + BaseContext *bc = new BaseContext (display); |
1719 | + |
1720 | + bc->run (); |
1721 | + |
1722 | + delete bc; |
1723 | + |
1724 | + XCloseDisplay (display); |
1725 | + |
1726 | + return 0; |
1727 | +} |
1728 | + |
1729 | + |
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.