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