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