Merge lp:~smspillaz/compiz/compiz.revenge-of-the-blur-plugin into lp:compiz/0.9.12
- compiz.revenge-of-the-blur-plugin
- Merge into 0.9.12
| Status: | Merged |
|---|---|
| Approved by: | Marco Trevisan (Treviño) |
| Approved revision: | 4020 |
| Merged at revision: | 4020 |
| Proposed branch: | lp:~smspillaz/compiz/compiz.revenge-of-the-blur-plugin |
| Merge into: | lp:compiz/0.9.12 |
| Diff against target: |
3208 lines (+1260/-1141) 16 files modified
debian/compiz-plugins.install (+2/-0) plugins/CMakeLists.txt (+0/-1) plugins/blur/CMakeLists.txt (+12/-12) plugins/blur/src/blur.cpp (+1086/-1077) plugins/blur/src/blur.h (+59/-38) plugins/opengl/DRIVERS (+10/-0) plugins/opengl/include/opengl/opengl.h (+14/-2) plugins/opengl/include/opengl/program.h (+1/-1) plugins/opengl/include/opengl/vertexbuffer.h (+1/-0) plugins/opengl/src/paint.cpp (+10/-0) plugins/opengl/src/privates.h (+3/-0) plugins/opengl/src/program.cpp (+2/-2) plugins/opengl/src/screen.cpp (+44/-4) plugins/opengl/src/shadercache.cpp (+5/-4) plugins/opengl/src/vertexbuffer.cpp (+5/-0) plugins/opengl/src/window.cpp (+6/-0) |
| To merge this branch: | bzr merge lp:~smspillaz/compiz/compiz.revenge-of-the-blur-plugin |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Marco Trevisan (Treviño) | Approve | ||
| PS Jenkins bot (community) | continuous-integration | Approve | |
|
Review via email:
|
|||
Commit message
Blur: port the plugin to modern OpenGL
Description of the change
Port the blur plugin to modern OpenGL
Note: An ABI break was necessary to add glTransformatio
| PS Jenkins bot (ps-jenkins) wrote : | # |
- 4019. By Sam Spilsbury <email address hidden>
-
debian: Install the blur plugin as part of compiz-plugins
| PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:4019
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 4020. By Sam Spilsbury <email address hidden>
-
opengl: Don't invalidate the scratch buffer frame age every time it is queried
We only want to do this when we query the scratch buffer age and then
use it - as it is only on use when the age resets back to an invalidated
state.Previously, the age would re-set every time it is queried, which would
cause it to appear invalidated the next time damageCutoff was reached.
| PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:4020
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
| Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Nice cleanup, thanks a lot.
ABI changes are in fact not relevant for other parts.
Preview Diff
| 1 | === modified file 'debian/compiz-plugins.install' |
| 2 | --- debian/compiz-plugins.install 2015-07-24 16:28:37 +0000 |
| 3 | +++ debian/compiz-plugins.install 2016-05-14 02:33:05 +0000 |
| 4 | @@ -4,6 +4,8 @@ |
| 5 | usr/share/compiz/*annotate.* |
| 6 | usr/lib/*/compiz/*bench.* |
| 7 | usr/share/compiz/*bench.* |
| 8 | +usr/lib/*/compiz/*blur.* |
| 9 | +usr/share/compiz/*blur.* |
| 10 | usr/lib/*/compiz/*clone.* |
| 11 | usr/share/compiz/*clone.* |
| 12 | usr/lib/*/compiz/*crashhandler.* |
| 13 | |
| 14 | === modified file 'plugins/CMakeLists.txt' |
| 15 | --- plugins/CMakeLists.txt 2016-03-03 14:23:38 +0000 |
| 16 | +++ plugins/CMakeLists.txt 2016-05-14 02:33:05 +0000 |
| 17 | @@ -12,7 +12,6 @@ |
| 18 | # temporarily disable plugins that aren't ported yet |
| 19 | set (COMPIZ_DISABLE_PLUGIN_ANIMATIONADDON ON) |
| 20 | set (COMPIZ_DISABLE_PLUGIN_BICUBIC ON) |
| 21 | -set (COMPIZ_DISABLE_PLUGIN_BLUR ON) |
| 22 | set (COMPIZ_DISABLE_PLUGIN_COLORFILTER ON) |
| 23 | set (COMPIZ_DISABLE_PLUGIN_GROUP ON) |
| 24 | set (COMPIZ_DISABLE_PLUGIN_LOGINOUT ON) |
| 25 | |
| 26 | === modified file 'plugins/blur/CMakeLists.txt' |
| 27 | --- plugins/blur/CMakeLists.txt 2012-05-17 10:41:21 +0000 |
| 28 | +++ plugins/blur/CMakeLists.txt 2016-05-14 02:33:05 +0000 |
| 29 | @@ -2,15 +2,15 @@ |
| 30 | |
| 31 | include (CompizPlugin) |
| 32 | |
| 33 | -#find_package (OpenGL) |
| 34 | - |
| 35 | -#if (OPENGL_GLU_FOUND) |
| 36 | -# compiz_plugin(blur PLUGINDEPS composite opengl LIBRARIES decoration ${OPENGL_glu_LIBRARY} INCDIRS ${OPENGL_INCLUDE_DIR}) |
| 37 | - |
| 38 | -# if (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_BLUR) |
| 39 | -# set_target_properties ( |
| 40 | -# blur PROPERTIES |
| 41 | -# INSTALL_RPATH "${COMPIZ_LIBDIR}" |
| 42 | -# ) |
| 43 | -# endif (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_BLUR) |
| 44 | -#endif () |
| 45 | +find_package (OpenGL) |
| 46 | + |
| 47 | +if (OPENGL_GLU_FOUND) |
| 48 | + compiz_plugin(blur PLUGINDEPS composite opengl LIBRARIES decoration ${OPENGL_glu_LIBRARY} INCDIRS ${OPENGL_INCLUDE_DIR}) |
| 49 | + |
| 50 | + if (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_BLUR) |
| 51 | + set_target_properties ( |
| 52 | + blur PROPERTIES |
| 53 | + INSTALL_RPATH "${COMPIZ_LIBDIR}" |
| 54 | + ) |
| 55 | + endif (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_BLUR) |
| 56 | +endif () |
| 57 | |
| 58 | === modified file 'plugins/blur/src/blur.cpp' |
| 59 | --- plugins/blur/src/blur.cpp 2013-05-09 13:43:07 +0000 |
| 60 | +++ plugins/blur/src/blur.cpp 2016-05-14 02:33:05 +0000 |
| 61 | @@ -22,19 +22,22 @@ |
| 62 | * |
| 63 | * Author: David Reveman <davidr@novell.com> |
| 64 | */ |
| 65 | - |
| 66 | #include <blur.h> |
| 67 | +#include <sstream> |
| 68 | +#include <opengl/framebufferobject.h> |
| 69 | + |
| 70 | +/* Supporting independent texture fetch operations will require |
| 71 | + * GLVertexBuffer to support per-plugin attributes as texture co-ordinates |
| 72 | + * are two-component and not four-component |
| 73 | + */ |
| 74 | +#define INDEPENDENT_TEX_SUPPORTED 0 |
| 75 | |
| 76 | COMPIZ_PLUGIN_20090315 (blur, BlurPluginVTable) |
| 77 | |
| 78 | -const unsigned short BLUR_GAUSSIAN_RADIUS_MAX = 15; |
| 79 | - |
| 80 | -const unsigned short BLUR_STATE_CLIENT = 0; |
| 81 | -const unsigned short BLUR_STATE_DECOR = 1; |
| 82 | -const unsigned short BLUR_STATE_NUM = 2; |
| 83 | - |
| 84 | /* pascal triangle based kernel generator */ |
| 85 | -static int |
| 86 | +namespace |
| 87 | +{ |
| 88 | +int |
| 89 | blurCreateGaussianLinearKernel (int radius, |
| 90 | float strength, |
| 91 | float *amp, |
| 92 | @@ -106,6 +109,7 @@ |
| 93 | |
| 94 | return radius; |
| 95 | } |
| 96 | +} |
| 97 | |
| 98 | void |
| 99 | BlurScreen::updateFilterRadius () |
| 100 | @@ -137,20 +141,11 @@ |
| 101 | { |
| 102 | updateFilterRadius (); |
| 103 | |
| 104 | - foreach (BlurFunction &bf, srcBlurFunctions) |
| 105 | - GLFragment::destroyFragmentFunction (bf.id); |
| 106 | srcBlurFunctions.clear (); |
| 107 | - foreach (BlurFunction &bf, dstBlurFunctions) |
| 108 | - GLFragment::destroyFragmentFunction (bf.id); |
| 109 | dstBlurFunctions.clear (); |
| 110 | |
| 111 | - width = height = 0; |
| 112 | - |
| 113 | - if (program) |
| 114 | - { |
| 115 | - GL::deletePrograms (1, &program); |
| 116 | - program = 0; |
| 117 | - } |
| 118 | + program.reset (); |
| 119 | + texture.clear (); |
| 120 | } |
| 121 | |
| 122 | static CompRegion |
| 123 | @@ -249,7 +244,6 @@ |
| 124 | int threshold, |
| 125 | std::vector<BlurBox> box) |
| 126 | { |
| 127 | - |
| 128 | this->state[state].threshold = threshold; |
| 129 | this->state[state].box = box; |
| 130 | |
| 131 | @@ -289,7 +283,7 @@ |
| 132 | |
| 133 | match = &bScreen->optionGetFocusBlurMatch (); |
| 134 | |
| 135 | - focus = GL::fragmentProgram && match->evaluate (window); |
| 136 | + focus = GL::shaders && match->evaluate (window); |
| 137 | if (focus != focusBlur) |
| 138 | { |
| 139 | focusBlur = focus; |
| 140 | @@ -421,49 +415,75 @@ |
| 141 | } |
| 142 | |
| 143 | cScreen->preparePaint (msSinceLastPaint); |
| 144 | - |
| 145 | - if (cScreen->damageMask () & COMPOSITE_SCREEN_DAMAGE_REGION_MASK) |
| 146 | +} |
| 147 | + |
| 148 | +bool |
| 149 | +BlurScreen::markAreaDirty (const CompRegion &r) |
| 150 | +{ |
| 151 | + return allowAreaDirtyOnOwnDamageBuffer; |
| 152 | +} |
| 153 | + |
| 154 | +void |
| 155 | +BlurScreen::damageCutoff () |
| 156 | +{ |
| 157 | + if (alphaBlur) |
| 158 | { |
| 159 | - /* walk from bottom to top and expand damage */ |
| 160 | - if (alphaBlur) |
| 161 | + this->output = &screen->fullscreenOutput (); |
| 162 | + |
| 163 | + /* We need to do a primary pass here with glPaint to check which |
| 164 | + * regions of the backbuffer need to be updated. |
| 165 | + * |
| 166 | + * Because the backbuffer is effectively partially undefined, we are completely |
| 167 | + * reliant on what core is telling us the repair regions of the |
| 168 | + * backbuffer need to be - but obviously we can't completely rely |
| 169 | + * on it because of a feedback effect, as we need to expand |
| 170 | + * the repair region slightly so that the texture sampler |
| 171 | + * doesn't go out of range of the damage region. If we were to |
| 172 | + * simply expand the damage region, then that would feedback to us |
| 173 | + * on the next frame, until the damage region eventually became infinite. |
| 174 | + * |
| 175 | + * As such, we have a tracker in core to track all damage except the effect |
| 176 | + * of expanding the damage region that came back to us. We then use |
| 177 | + * this tracker along with the frame age to determine what damage really |
| 178 | + * needs to be expanded in order to determine the backbuffer update region, |
| 179 | + * and then use the real damage in order to determine what blur regions |
| 180 | + * should be updated |
| 181 | + */ |
| 182 | + backbufferUpdateRegionThisFrame &= emptyRegion; |
| 183 | + CompRegion frameAgeDamage = damageQuery->damageForFrameAge (cScreen->getFrameAge ()); |
| 184 | + foreach (CompWindow *w, screen->windows ()) |
| 185 | { |
| 186 | - int x1, y1, x2, y2; |
| 187 | - int count = 0; |
| 188 | - CompRegion damage (cScreen->currentDamage ()); |
| 189 | - |
| 190 | - foreach (CompWindow *w, screen->windows ()) |
| 191 | - { |
| 192 | - BLUR_WINDOW (w); |
| 193 | - |
| 194 | - if (!w->isViewable () || !CompositeWindow::get (w)->damaged ()) |
| 195 | - continue; |
| 196 | - |
| 197 | - if (!bw->region.isEmpty ()) |
| 198 | - { |
| 199 | - CompRect r = bw->region.boundingRect (); |
| 200 | - CompRect d = damage.boundingRect (); |
| 201 | - x1 = r.x1 () - filterRadius; |
| 202 | - y1 = r.y1 () - filterRadius; |
| 203 | - x2 = r.x2 () + filterRadius; |
| 204 | - y2 = r.y2 () + filterRadius; |
| 205 | - |
| 206 | - if (x1 < d.x2 () && |
| 207 | - y1 < d.y2 () && |
| 208 | - x2 > d.x1 () && |
| 209 | - y2 > d.y1 ()) |
| 210 | - { |
| 211 | - damage.shrink (-filterRadius, -filterRadius); |
| 212 | - count++; |
| 213 | - } |
| 214 | - } |
| 215 | - } |
| 216 | - |
| 217 | - if (count) |
| 218 | - cScreen->damageRegion (damage); |
| 219 | - |
| 220 | - this->count = count; |
| 221 | + /* Skip windows that would not have glPaint called on them */ |
| 222 | + if (w->destroyed ()) |
| 223 | + continue; |
| 224 | + |
| 225 | + if (!w->shaded () && !w->isViewable ()) |
| 226 | + continue; |
| 227 | + |
| 228 | + BlurWindow *bw = BlurWindow::get (w); |
| 229 | + |
| 230 | + if (!bw->cWindow->redirected ()) |
| 231 | + continue; |
| 232 | + |
| 233 | + if (!bw->projectedBlurRegion.isEmpty ()) |
| 234 | + bw->projectedBlurRegion &= emptyRegion; |
| 235 | + |
| 236 | + GLMatrix screenSpace; |
| 237 | + screenSpace.toScreenSpace (this->output, -DEFAULT_Z_CAMERA); |
| 238 | + |
| 239 | + bw->gWindow->glPaint (bw->gWindow->paintAttrib (), screenSpace, |
| 240 | + frameAgeDamage, |
| 241 | + PAINT_WINDOW_NO_CORE_INSTANCE_MASK); |
| 242 | + |
| 243 | + backbufferUpdateRegionThisFrame += bw->projectedBlurRegion; |
| 244 | } |
| 245 | + |
| 246 | + allowAreaDirtyOnOwnDamageBuffer = false; |
| 247 | + cScreen->damageRegion (backbufferUpdateRegionThisFrame); |
| 248 | + allowAreaDirtyOnOwnDamageBuffer = true; |
| 249 | } |
| 250 | + |
| 251 | + cScreen->damageCutoff (); |
| 252 | } |
| 253 | |
| 254 | bool |
| 255 | @@ -471,23 +491,10 @@ |
| 256 | const GLMatrix &transform, const CompRegion ®ion, |
| 257 | CompOutput *output, unsigned int mask) |
| 258 | { |
| 259 | - bool status; |
| 260 | - |
| 261 | if (alphaBlur) |
| 262 | { |
| 263 | stencilBox = region.boundingRect (); |
| 264 | this->region = region; |
| 265 | - |
| 266 | - if (mask & PAINT_SCREEN_REGION_MASK) |
| 267 | - { |
| 268 | - /* we need to redraw more than the screen region being updated */ |
| 269 | - if (count) |
| 270 | - { |
| 271 | - this->region.shrink (-filterRadius * 2, -filterRadius * 2); |
| 272 | - |
| 273 | - this->region &= screen->region (); |
| 274 | - } |
| 275 | - } |
| 276 | } |
| 277 | |
| 278 | if (!blurOcclusion) |
| 279 | @@ -500,12 +507,7 @@ |
| 280 | |
| 281 | this->output = output; |
| 282 | |
| 283 | - if (alphaBlur) |
| 284 | - status = gScreen->glPaintOutput (sAttrib, transform, this->region, output, mask); |
| 285 | - else |
| 286 | - status = gScreen->glPaintOutput (sAttrib, transform, region, output, mask); |
| 287 | - |
| 288 | - return status; |
| 289 | + return gScreen->glPaintOutput (sAttrib, transform, region, output, mask); |
| 290 | } |
| 291 | |
| 292 | void |
| 293 | @@ -542,12 +544,42 @@ |
| 294 | cScreen->donePaint (); |
| 295 | } |
| 296 | |
| 297 | +void |
| 298 | +BlurWindow::glTransformationComplete (const GLMatrix &matrix, |
| 299 | + const CompRegion ®ion, |
| 300 | + unsigned int mask) |
| 301 | +{ |
| 302 | + gWindow->glTransformationComplete (matrix, region, mask); |
| 303 | + |
| 304 | + int clientThreshold; |
| 305 | + const CompRegion *reg = NULL; |
| 306 | + |
| 307 | + /* only care about client window blurring when it's translucent */ |
| 308 | + if (mask & PAINT_WINDOW_TRANSLUCENT_MASK) |
| 309 | + clientThreshold = state[BLUR_STATE_CLIENT].threshold; |
| 310 | + else |
| 311 | + clientThreshold = 0; |
| 312 | + |
| 313 | + if (mask & PAINT_WINDOW_TRANSFORMED_MASK) |
| 314 | + reg = &infiniteRegion; |
| 315 | + else |
| 316 | + reg = ®ion; |
| 317 | + |
| 318 | + bScreen->tmpRegion = this->region.intersected (*reg); |
| 319 | + |
| 320 | + if (state[BLUR_STATE_DECOR].threshold || clientThreshold) |
| 321 | + { |
| 322 | + determineBlurRegion (bScreen->optionGetFilter (), |
| 323 | + matrix, |
| 324 | + clientThreshold); |
| 325 | + } |
| 326 | +} |
| 327 | + |
| 328 | bool |
| 329 | BlurWindow::glPaint (const GLWindowPaintAttrib &attrib, |
| 330 | const GLMatrix &transform, |
| 331 | const CompRegion ®ion, unsigned int mask) |
| 332 | { |
| 333 | - |
| 334 | bool status = gWindow->glPaint (attrib, transform, region, mask); |
| 335 | |
| 336 | if (!bScreen->blurOcclusion && |
| 337 | @@ -564,307 +596,359 @@ |
| 338 | return status; |
| 339 | } |
| 340 | |
| 341 | -GLFragment::FunctionId |
| 342 | -BlurScreen::getSrcBlurFragmentFunction (GLTexture *texture, |
| 343 | - int param) |
| 344 | -{ |
| 345 | - GLFragment::FunctionData data; |
| 346 | +namespace |
| 347 | +{ |
| 348 | +struct SamplerInfo |
| 349 | +{ |
| 350 | + GLint target; |
| 351 | + CompString func; |
| 352 | +}; |
| 353 | + |
| 354 | +SamplerInfo |
| 355 | +getSamplerInfoForSize (const CompSize &size) |
| 356 | +{ |
| 357 | + SamplerInfo info; |
| 358 | + |
| 359 | +#ifdef USE_GLES |
| 360 | + info.target = GL_TEXTURE_2D; |
| 361 | + info.func = "texture2D"; |
| 362 | +#else |
| 363 | + if (GL::textureNonPowerOfTwo || |
| 364 | + (POWER_OF_TWO (size.width ()) && POWER_OF_TWO (size.height ()))) |
| 365 | + { |
| 366 | + info.target = GL_TEXTURE_2D; |
| 367 | + info.func = "texture2D"; |
| 368 | + } |
| 369 | + else |
| 370 | + { |
| 371 | + info.target = GL_TEXTURE_RECTANGLE_NV; |
| 372 | + info.func = "textureRECT"; |
| 373 | + } |
| 374 | +#endif |
| 375 | + |
| 376 | + return info; |
| 377 | +} |
| 378 | +} |
| 379 | + |
| 380 | +/* XXX: param is redundant */ |
| 381 | +const CompString & |
| 382 | +BlurScreen::getSrcBlurFragmentFunction (GLTexture *texture) |
| 383 | +{ |
| 384 | BlurFunction function; |
| 385 | - int target; |
| 386 | - |
| 387 | - if (texture->target () == GL_TEXTURE_2D) |
| 388 | - target = COMP_FETCH_TARGET_2D; |
| 389 | - else |
| 390 | - target = COMP_FETCH_TARGET_RECT; |
| 391 | - |
| 392 | - foreach (BlurFunction &bf, srcBlurFunctions) |
| 393 | - if (bf.param == param && bf.target == target) |
| 394 | - return bf.id; |
| 395 | - |
| 396 | - if (data.status ()) |
| 397 | - { |
| 398 | - static const char *temp[] = { "offset0", "offset1", "sum" }; |
| 399 | - unsigned int i; |
| 400 | - |
| 401 | - for (i = 0; i < sizeof (temp) / sizeof (temp[0]); i++) |
| 402 | - data.addTempHeaderOp (temp[i]); |
| 403 | - |
| 404 | - data.addDataOp ( |
| 405 | - "MUL offset0, program.env[%d].xyzw, { 1.0, 1.0, 0.0, 0.0 };" |
| 406 | - "MUL offset1, program.env[%d].zwww, { 1.0, 1.0, 0.0, 0.0 };", |
| 407 | - param, param); |
| 408 | - |
| 409 | - |
| 410 | - switch (optionGetFilter ()) { |
| 411 | - case BlurOptions::Filter4xbilinear: |
| 412 | - default: |
| 413 | - data.addFetchOp ("output", "offset0", target); |
| 414 | - data.addDataOp ("MUL sum, output, 0.25;"); |
| 415 | - data.addFetchOp ("output", "-offset0", target); |
| 416 | - data.addDataOp ("MAD sum, output, 0.25, sum;"); |
| 417 | - data.addFetchOp ("output", "offset1", target); |
| 418 | - data.addDataOp ("MAD sum, output, 0.25, sum;"); |
| 419 | - data.addFetchOp ("output", "-offset1", target); |
| 420 | - data.addDataOp ("MAD output, output, 0.25, sum;"); |
| 421 | - break; |
| 422 | - } |
| 423 | - |
| 424 | - if (!data.status ()) |
| 425 | - return 0; |
| 426 | - |
| 427 | - function.id = data.createFragmentFunction ("blur"); |
| 428 | - function.target = target; |
| 429 | - function.param = param; |
| 430 | - function.unit = 0; |
| 431 | - |
| 432 | - srcBlurFunctions.push_back (function); |
| 433 | - |
| 434 | - return function.id; |
| 435 | - } |
| 436 | - |
| 437 | - return 0; |
| 438 | + std::stringstream data (std::stringstream::out); |
| 439 | + |
| 440 | + SamplerInfo info (getSamplerInfoForSize (CompSize (texture->width (), |
| 441 | + texture->height ()))); |
| 442 | + |
| 443 | + foreach (const BlurFunction &bf, srcBlurFunctions) |
| 444 | + if (bf.target == info.target) |
| 445 | + return bf.shader; |
| 446 | + |
| 447 | + data << "uniform vec4 focusblur_input_offset;\n"\ |
| 448 | + "\n"\ |
| 449 | + "void focusblur_fragment ()\n"\ |
| 450 | + "{\n"; |
| 451 | + |
| 452 | + if (optionGetFilter () == BlurOptions::Filter4xbilinear) |
| 453 | + data << " float blur_offset0, blur_offset1;\n"\ |
| 454 | + " vec4 blur_sum;\n"\ |
| 455 | + " vec4 offset0 = focusblur_input_offset.xyzw * vec4 (1.0, 1.0, 0.0, 0.0);\n"\ |
| 456 | + " vec4 offset1 = focusblur_input_offset.zwww * vec4 (1.0, 1.0, 0.0, 0.0);\n" |
| 457 | + " vec4 output = texture2D (texture0, vTexCoord0 + offset0);\n"\ |
| 458 | + " blur_sum = output * 0.25;\n"\ |
| 459 | + " output = " << info.func << " (texture0, vTexCoord0 - offset0);\n"\ |
| 460 | + " blur_sum += output * 0.25;\n"\ |
| 461 | + " output = " << info.func << " (texture0, vTexCoord0 + offset1);\n"\ |
| 462 | + " blur_sum += output * 0.25;\n"\ |
| 463 | + " output = " << info.func << " (texture0, vTexCoord0 - offset1);\n"\ |
| 464 | + " output = output * 0.25 + blur_sum;\n"\ |
| 465 | + " gl_FragColor = output;\n"; |
| 466 | + |
| 467 | + data << "}\n"; |
| 468 | + |
| 469 | + function.shader = data.str (); |
| 470 | + function.target = info.target; |
| 471 | + |
| 472 | + srcBlurFunctions.push_back (function); |
| 473 | + |
| 474 | + return srcBlurFunctions.back ().shader; |
| 475 | } |
| 476 | |
| 477 | -GLFragment::FunctionId |
| 478 | +/* This seems incomplete to me */ |
| 479 | + |
| 480 | +const CompString & |
| 481 | BlurScreen::getDstBlurFragmentFunction (GLTexture *texture, |
| 482 | - int param, |
| 483 | - int unit, |
| 484 | + int unit, |
| 485 | int numITC, |
| 486 | int startTC) |
| 487 | { |
| 488 | - BlurFunction function; |
| 489 | - GLFragment::FunctionData data; |
| 490 | - int target; |
| 491 | - char *targetString; |
| 492 | + BlurFunction function; |
| 493 | + std::stringstream data (std::stringstream::out); |
| 494 | + int saturation = optionGetSaturation (); |
| 495 | |
| 496 | - if (texture->target () == GL_TEXTURE_2D) |
| 497 | - { |
| 498 | - target = COMP_FETCH_TARGET_2D; |
| 499 | - targetString = (char *) "2D"; |
| 500 | - } |
| 501 | - else |
| 502 | - { |
| 503 | - target = COMP_FETCH_TARGET_RECT; |
| 504 | - targetString = (char *) "RECT"; |
| 505 | - } |
| 506 | + SamplerInfo info (getSamplerInfoForSize (CompSize (texture->width (), |
| 507 | + texture->height ()))); |
| 508 | |
| 509 | foreach (BlurFunction &function, dstBlurFunctions) |
| 510 | - if (function.param == param && |
| 511 | - function.target == target && |
| 512 | - function.unit == unit && |
| 513 | + if (function.target == info.target && |
| 514 | function.numITC == numITC && |
| 515 | - function.startTC == startTC) |
| 516 | - return function.id; |
| 517 | - |
| 518 | - if (data.status ()) |
| 519 | - { |
| 520 | - static const char *temp[] = { "fCoord", "mask", "sum", "dst" }; |
| 521 | - int i, j; |
| 522 | - char str[1024]; |
| 523 | - int saturation = optionGetSaturation (); |
| 524 | - int numIndirect; |
| 525 | - int numIndirectOp; |
| 526 | - int base, end, ITCbase; |
| 527 | - |
| 528 | - for (i = 0; (unsigned int) i < sizeof (temp) / sizeof (temp[0]); i++) |
| 529 | - data.addTempHeaderOp (temp[i]); |
| 530 | - |
| 531 | - if (saturation < 100) |
| 532 | - data.addTempHeaderOp ("sat"); |
| 533 | - |
| 534 | - switch (optionGetFilter ()) { |
| 535 | - case BlurOptions::Filter4xbilinear: { |
| 536 | - static const char *filterTemp[] = { |
| 537 | - "t0", "t1", "t2", "t3", |
| 538 | - "s0", "s1", "s2", "s3" |
| 539 | - }; |
| 540 | - |
| 541 | - for (i = 0; |
| 542 | - (unsigned int) i < sizeof (filterTemp) / sizeof (filterTemp[0]); |
| 543 | - i++) |
| 544 | - data.addTempHeaderOp (filterTemp[i]); |
| 545 | - |
| 546 | - data.addFetchOp ("output", NULL, target); |
| 547 | - data.addColorOp ("output", "output"); |
| 548 | - |
| 549 | - data.addDataOp ( |
| 550 | - "MUL fCoord, fragment.position, program.env[%d];", |
| 551 | - param); |
| 552 | - |
| 553 | - |
| 554 | - data.addDataOp ( |
| 555 | - "ADD t0, fCoord, program.env[%d];" |
| 556 | - "TEX s0, t0, texture[%d], %s;" |
| 557 | - |
| 558 | - "SUB t1, fCoord, program.env[%d];" |
| 559 | - "TEX s1, t1, texture[%d], %s;" |
| 560 | - |
| 561 | - "MAD t2, program.env[%d], { -1.0, 1.0, 0.0, 0.0 }, fCoord;" |
| 562 | - "TEX s2, t2, texture[%d], %s;" |
| 563 | - |
| 564 | - "MAD t3, program.env[%d], { 1.0, -1.0, 0.0, 0.0 }, fCoord;" |
| 565 | - "TEX s3, t3, texture[%d], %s;" |
| 566 | - |
| 567 | - "MUL_SAT mask, output.a, program.env[%d];" |
| 568 | - |
| 569 | - "MUL sum, s0, 0.25;" |
| 570 | - "MAD sum, s1, 0.25, sum;" |
| 571 | - "MAD sum, s2, 0.25, sum;" |
| 572 | - "MAD sum, s3, 0.25, sum;", |
| 573 | - |
| 574 | - param + 2, unit, targetString, |
| 575 | - param + 2, unit, targetString, |
| 576 | - param + 2, unit, targetString, |
| 577 | - param + 2, unit, targetString, |
| 578 | - param + 1); |
| 579 | - |
| 580 | - } break; |
| 581 | - case BlurOptions::FilterGaussian: { |
| 582 | - |
| 583 | - /* try to use only half of the available temporaries to keep |
| 584 | - other plugins working */ |
| 585 | - if ((maxTemp / 2) - 4 > |
| 586 | - (numTexop + (numTexop - numITC)) * 2) |
| 587 | - { |
| 588 | - numIndirect = 1; |
| 589 | - numIndirectOp = numTexop; |
| 590 | - } |
| 591 | - else |
| 592 | - { |
| 593 | - i = MAX (((maxTemp / 2) - 4) / 4, 1); |
| 594 | - numIndirect = ceil ((float)numTexop / (float)i); |
| 595 | - numIndirectOp = ceil ((float)numTexop / (float)numIndirect); |
| 596 | - } |
| 597 | - |
| 598 | - /* we need to define all coordinate temporaries if we have |
| 599 | - multiple indirection steps */ |
| 600 | - j = (numIndirect > 1) ? 0 : numITC; |
| 601 | - |
| 602 | - for (i = 0; i < numIndirectOp * 2; i++) |
| 603 | - { |
| 604 | - snprintf (str, 1024, "pix_%d", i); |
| 605 | - data.addTempHeaderOp (str); |
| 606 | - } |
| 607 | - |
| 608 | - for (i = j * 2; i < numIndirectOp * 2; i++) |
| 609 | - { |
| 610 | - snprintf (str, 1024, "coord_%d", i); |
| 611 | - data.addTempHeaderOp (str); |
| 612 | - } |
| 613 | - |
| 614 | - data.addFetchOp ("output", NULL, target); |
| 615 | - data.addColorOp ("output", "output"); |
| 616 | - |
| 617 | - data.addDataOp ( |
| 618 | - "MUL fCoord, fragment.position, program.env[%d];", |
| 619 | - param); |
| 620 | - |
| 621 | - |
| 622 | - data.addDataOp ("TEX sum, fCoord, texture[%d], %s;", |
| 623 | - unit + 1, targetString); |
| 624 | - |
| 625 | - |
| 626 | - data.addDataOp ("MUL_SAT mask, output.a, program.env[%d];" |
| 627 | - "MUL sum, sum, %f;", |
| 628 | - param + 1, amp[numTexop]); |
| 629 | - |
| 630 | - for (j = 0; j < numIndirect; j++) |
| 631 | - { |
| 632 | - base = j * numIndirectOp; |
| 633 | - end = MIN ((j + 1) * numIndirectOp, numTexop) - base; |
| 634 | - |
| 635 | - ITCbase = MAX (numITC - base, 0); |
| 636 | - |
| 637 | - for (i = ITCbase; i < end; i++) |
| 638 | - { |
| 639 | - data.addDataOp ( |
| 640 | - "ADD coord_%d, fCoord, {0.0, %g, 0.0, 0.0};" |
| 641 | - "SUB coord_%d, fCoord, {0.0, %g, 0.0, 0.0};", |
| 642 | - i * 2, pos[base + i] * ty, |
| 643 | - (i * 2) + 1, pos[base + i] * ty); |
| 644 | - } |
| 645 | - |
| 646 | - for (i = 0; i < ITCbase; i++) |
| 647 | - { |
| 648 | - data.addDataOp ( |
| 649 | - "TXP pix_%d, fragment.texcoord[%d], texture[%d], %s;" |
| 650 | - "TXP pix_%d, fragment.texcoord[%d], texture[%d], %s;", |
| 651 | - i * 2, startTC + ((i + base) * 2), |
| 652 | - unit + 1, targetString, |
| 653 | - (i * 2) + 1, startTC + 1 + ((i + base) * 2), |
| 654 | - unit + 1, targetString); |
| 655 | - } |
| 656 | - |
| 657 | - for (i = ITCbase; i < end; i++) |
| 658 | - { |
| 659 | - data.addDataOp ( |
| 660 | - "TEX pix_%d, coord_%d, texture[%d], %s;" |
| 661 | - "TEX pix_%d, coord_%d, texture[%d], %s;", |
| 662 | - i * 2, i * 2, |
| 663 | - unit + 1, targetString, |
| 664 | - (i * 2) + 1, (i * 2) + 1, |
| 665 | - unit + 1, targetString); |
| 666 | - } |
| 667 | - |
| 668 | - for (i = 0; i < end * 2; i++) |
| 669 | - { |
| 670 | - data.addDataOp ( |
| 671 | - "MAD sum, pix_%d, %f, sum;", |
| 672 | - i, amp[base + (i / 2)]); |
| 673 | - } |
| 674 | - } |
| 675 | - |
| 676 | - } break; |
| 677 | - case BlurOptions::FilterMipmap: |
| 678 | - data.addFetchOp ("output", NULL, target); |
| 679 | - data.addColorOp ("output", "output"); |
| 680 | - |
| 681 | - data.addDataOp ( |
| 682 | - "MUL fCoord, fragment.position, program.env[%d].xyzz;" |
| 683 | - "MOV fCoord.w, program.env[%d].w;" |
| 684 | - "TXB sum, fCoord, texture[%d], %s;" |
| 685 | - "MUL_SAT mask, output.a, program.env[%d];", |
| 686 | - param, param, unit, targetString, |
| 687 | - param + 1); |
| 688 | - |
| 689 | - break; |
| 690 | - } |
| 691 | - |
| 692 | - if (saturation < 100) |
| 693 | - { |
| 694 | - data.addDataOp ( |
| 695 | - "MUL sat, sum, { 1.0, 1.0, 1.0, 0.0 };" |
| 696 | - "DP3 sat, sat, { %f, %f, %f, %f };" |
| 697 | - "LRP sum.xyz, %f, sum, sat;", |
| 698 | - RED_SATURATION_WEIGHT, GREEN_SATURATION_WEIGHT, |
| 699 | - BLUE_SATURATION_WEIGHT, 0.0f, saturation / 100.0f); |
| 700 | - } |
| 701 | - |
| 702 | - data.addDataOp ( |
| 703 | - "MAD dst, mask, -output.a, mask;" |
| 704 | - "MAD output.rgb, sum, dst.a, output;" |
| 705 | - "ADD output.a, output.a, dst.a;"); |
| 706 | - |
| 707 | - if (!data.status ()) |
| 708 | - { |
| 709 | - return 0; |
| 710 | - } |
| 711 | - |
| 712 | - |
| 713 | - |
| 714 | - function.id = data.createFragmentFunction ("blur"); |
| 715 | - function.target = target; |
| 716 | - function.param = param; |
| 717 | - function.unit = unit; |
| 718 | - function.numITC = numITC; |
| 719 | - function.startTC = startTC; |
| 720 | - |
| 721 | - dstBlurFunctions.push_back (function); |
| 722 | - |
| 723 | - return function.id; |
| 724 | - } |
| 725 | - |
| 726 | - return 0; |
| 727 | + function.startTC == startTC && |
| 728 | + function.saturation == saturation) |
| 729 | + return function.shader; |
| 730 | + |
| 731 | + data << "uniform vec4 blur_translation;\n"\ |
| 732 | + "uniform vec4 blur_threshold;\n"; |
| 733 | + |
| 734 | + int i, j; |
| 735 | + /* These are always initialized if running a gaussian shader */ |
| 736 | + int numIndirect = 0; |
| 737 | + int numIndirectOp = 0; |
| 738 | + int base, end, ITCbase; |
| 739 | + |
| 740 | + /* Set per-shader uniforms */ |
| 741 | + switch (optionGetFilter ()) |
| 742 | + { |
| 743 | + case BlurOptions::Filter4xbilinear: |
| 744 | + data << "uniform vec4 blur_dxdy;\n"; |
| 745 | + break; |
| 746 | + default: |
| 747 | + break; |
| 748 | + } |
| 749 | + |
| 750 | + data << "\n"\ |
| 751 | + "void blur_fragment ()\n"\ |
| 752 | + "{\n"\ |
| 753 | + " vec4 blur_sum, blur_dst, blur_output;\n"\ |
| 754 | + " vec2 blur_fCoord;\n"\ |
| 755 | + " vec4 blur_mask;\n"; |
| 756 | + |
| 757 | + if (saturation < 100) |
| 758 | + data << " float blur_sat;\n"; |
| 759 | + |
| 760 | + /* Define per-filter temporaries */ |
| 761 | + switch (optionGetFilter ()) |
| 762 | + { |
| 763 | + case BlurOptions::Filter4xbilinear: |
| 764 | + { |
| 765 | + static const char *filterTemp[] = { |
| 766 | + "blur_t0", "blur_t1", "blur_t2", "blur_t3", |
| 767 | + }; |
| 768 | + |
| 769 | + static const char *filterSampleTemp[] = { |
| 770 | + "blur_s0", "blur_s1", "blur_s2", "blur_s3" |
| 771 | + }; |
| 772 | + |
| 773 | + for (i = 0; |
| 774 | + (unsigned int) i < sizeof (filterTemp) / sizeof (filterTemp[0]); |
| 775 | + ++i) |
| 776 | + data << " vec2 " << filterTemp[i] << ";\n"; |
| 777 | + |
| 778 | + for (i = 0; |
| 779 | + (unsigned int) i < sizeof (filterSampleTemp) / sizeof (filterSampleTemp[0]); |
| 780 | + ++i) |
| 781 | + data << " vec4 " << filterSampleTemp[i] << ";\n"; |
| 782 | + } |
| 783 | + break; |
| 784 | + case BlurOptions::FilterGaussian: |
| 785 | + { |
| 786 | + /* try to use only half of the available temporaries to keep |
| 787 | + other plugins working */ |
| 788 | + if ((maxTemp / 2) - 4 > |
| 789 | + (numTexop + (numTexop - numITC)) * 2) |
| 790 | + { |
| 791 | + numIndirect = 1; |
| 792 | + numIndirectOp = numTexop; |
| 793 | + } |
| 794 | + else |
| 795 | + { |
| 796 | + i = MAX (((maxTemp / 2) - 4) / 4, 1); |
| 797 | + numIndirect = ceil ((float)numTexop / (float)i); |
| 798 | + numIndirectOp = ceil ((float)numTexop / (float)numIndirect); |
| 799 | + } |
| 800 | + |
| 801 | + /* we need to define all coordinate temporaries if we have |
| 802 | + multiple indirection steps */ |
| 803 | + j = (numIndirect > 1) ? 0 : numITC; |
| 804 | + |
| 805 | + for (i = 0; i < numIndirectOp * 2; i++) |
| 806 | + data << " vec4 blur_pix_" << i << ";\n"; |
| 807 | + |
| 808 | + for (i = j * 2; i < numIndirectOp * 2; i++) |
| 809 | + data << " vec2 blur_coord_" << i << ";\n"; |
| 810 | + } |
| 811 | + break; |
| 812 | + case BlurOptions::FilterMipmap: |
| 813 | + { |
| 814 | + data << " float lod_bias;\n"; |
| 815 | + } |
| 816 | + default: |
| 817 | + break; |
| 818 | + } |
| 819 | + |
| 820 | + /* |
| 821 | + * blur_output: copy the original gl_FragColor determined by sampling |
| 822 | + * the window texture in the core shader |
| 823 | + * blur_fCoord: take the fragment co-ordinate in window co-ordinates |
| 824 | + * and normalize it (eg, blur_translation). Once normalized we can |
| 825 | + * sample texUnitN + 1 (for the copy of the backbuffer we wish to blur) |
| 826 | + * and texUnitN + 2 (scratch fbo for gaussian blurs) |
| 827 | + * blur_mask: take blur_output pixel alpha value, multiply by threshold value |
| 828 | + * and clamp between 0 - 1. We will use this later to mix the blur fragments |
| 829 | + * with the window fragments. |
| 830 | + */ |
| 831 | + data << "\n"\ |
| 832 | + " blur_output = gl_FragColor;\n"\ |
| 833 | + " blur_fCoord = gl_FragCoord.st * blur_translation.st;\n"\ |
| 834 | + " blur_mask = clamp (blur_output.a * blur_threshold, vec4 (0.0, 0.0, 0.0, 0.), vec4 (1.0, 1.0, 1.0, 1.0));\n"\ |
| 835 | + "\n"; |
| 836 | + |
| 837 | + /* Define filter program */ |
| 838 | + switch (optionGetFilter ()) |
| 839 | + { |
| 840 | + case BlurOptions::Filter4xbilinear: |
| 841 | + { |
| 842 | + data << " blur_t0 = blur_fCoord + blur_dxdy.st;\n"\ |
| 843 | + " blur_s0 = " << info.func << " (texture1, blur_t0);\n"\ |
| 844 | + " blur_t1 = blur_fCoord - blur_dxdy.st;\n"\ |
| 845 | + " blur_s1 = " << info.func << " (texture1, blur_t1);\n"\ |
| 846 | + " blur_t2 = blur_fCoord + vec2 (-1.0, 1.0) * blur_dxdy.st;\n"\ |
| 847 | + " blur_s2 = " << info.func << " (texture1, blur_t2);\n"\ |
| 848 | + " blur_t3 = blur_fCoord + vec2 (1.0, -1.0) * blur_dxdy.st;\n"\ |
| 849 | + " blur_s3 = " << info.func << " (texture1, blur_t3);\n"\ |
| 850 | + " blur_sum = blur_s0 * 0.25;\n"\ |
| 851 | + " blur_sum += blur_s1 * 0.25;\n"\ |
| 852 | + " blur_sum += blur_s2 * 0.25;\n"\ |
| 853 | + " blur_sum += blur_s3 * 0.25;\n"; |
| 854 | + } break; |
| 855 | + case BlurOptions::FilterGaussian: |
| 856 | + { |
| 857 | + /* Invert y */ |
| 858 | + data << " blur_fCoord.y = 1.0 - blur_fCoord.y;\n"\ |
| 859 | + " blur_sum = " << info.func << " (texture2, blur_fCoord);\n"\ |
| 860 | + " blur_sum *= " << amp[numTexop] << ";\n"; |
| 861 | + |
| 862 | + for (j = 0; j < numIndirect; j++) |
| 863 | + { |
| 864 | + base = j * numIndirectOp; |
| 865 | + end = MIN ((j + 1) * numIndirectOp, numTexop) - base; |
| 866 | + |
| 867 | + ITCbase = MAX (numITC - base, 0); |
| 868 | + |
| 869 | + for (i = ITCbase; i < end; i++) |
| 870 | + { |
| 871 | + data << " blur_coord_" << i * 2 << " = blur_fCoord + vec2 (0.0, " << pos[base + i] * ty << ");\n"\ |
| 872 | + " blur_coord_" << (i * 2) + 1 << " = blur_fCoord - vec2 (0.0, " << pos[base + i] * ty << ");\n"; |
| 873 | + } |
| 874 | +#if INDEPENDENT_TEX_SUPPORTED |
| 875 | + for (i = 0; i < ITCbase; i++) |
| 876 | + { |
| 877 | + data << " blur_pix_" + i * 2 + " vTexCoord" |
| 878 | + data.addDataOp ( |
| 879 | + "TXP pix_%d, fragment.texcoord[%d], texture[%d], %s;" |
| 880 | + "TXP pix_%d, fragment.texcoord[%d], texture[%d], %s;", |
| 881 | + i * 2, startTC + ((i + base) * 2), |
| 882 | + unit + 1, targetString, |
| 883 | + (i * 2) + 1, startTC + 1 + ((i + base) * 2), |
| 884 | + unit + 1, targetString); |
| 885 | + } |
| 886 | +#endif |
| 887 | + for (i = ITCbase; i < end; i++) |
| 888 | + { |
| 889 | + data << " blur_pix_" << i * 2 << " = " << info.func << " (texture2, blur_coord_" << i * 2 << ");\n"\ |
| 890 | + " blur_pix_" << (i * 2) + 1 << " = " << info.func << " (texture2, blur_coord_" << (i * 2) + 1 << ");\n"; |
| 891 | + } |
| 892 | + |
| 893 | + for (i = 0; i < end * 2; i++) |
| 894 | + data << " blur_sum += blur_pix_" << i << " * " << amp[base + (i / 2)] << ";\n"; |
| 895 | + } |
| 896 | + |
| 897 | + } break; |
| 898 | + case BlurOptions::FilterMipmap: |
| 899 | + data << " lod_bias = blur_translation.w;\n"\ |
| 900 | + " blur_sum = " << info.func << " (texture1, blur_fCoord, lod_bias);\n"; |
| 901 | + |
| 902 | + break; |
| 903 | + } |
| 904 | + |
| 905 | + if (saturation < 100) |
| 906 | + { |
| 907 | + data << " blur_sat = blur_sum * vec4 (1.0, 1.0, 1.0, 0.0);\n"\ |
| 908 | + " blur_sat = dot (blur_sat, vec4 (" << |
| 909 | + RED_SATURATION_WEIGHT << ", " << GREEN_SATURATION_WEIGHT << ", " << |
| 910 | + BLUE_SATURATION_WEIGHT << ", 0.0f);\n"\ |
| 911 | + " blur_sum.xyz = mix (" << saturation / 100.f << ", blur_sat);\n"; |
| 912 | + } |
| 913 | + |
| 914 | + data << " blur_dst = (blur_mask * -blur_output.a) + blur_mask;\n"\ |
| 915 | + " blur_output.rgb = blur_sum.rgb * blur_dst.a + blur_output.rgb;\n"\ |
| 916 | + " blur_output.a += blur_dst.a;\n"\ |
| 917 | + " gl_FragColor = blur_output;\n"\ |
| 918 | + "}"; |
| 919 | + |
| 920 | + function.shader = data.str (); |
| 921 | + function.target = texture->target (); |
| 922 | + function.numITC = numITC; |
| 923 | + function.startTC = startTC; |
| 924 | + function.saturation = saturation; |
| 925 | + |
| 926 | + dstBlurFunctions.push_back (function); |
| 927 | + |
| 928 | + return dstBlurFunctions.back ().shader; |
| 929 | +} |
| 930 | + |
| 931 | +namespace |
| 932 | +{ |
| 933 | +bool |
| 934 | +project (float objx, float objy, float objz, |
| 935 | + const float modelview[16], const float projection[16], |
| 936 | + const GLint viewport[4], |
| 937 | + float *winx, float *winy, float *winz) |
| 938 | +{ |
| 939 | + unsigned int i; |
| 940 | + float in[4]; |
| 941 | + float out[4]; |
| 942 | + |
| 943 | + in[0] = objx; |
| 944 | + in[1] = objy; |
| 945 | + in[2] = objz; |
| 946 | + in[3] = 1.0; |
| 947 | + |
| 948 | + for (i = 0; i < 4; i++) { |
| 949 | + out[i] = |
| 950 | + in[0] * modelview[i] + |
| 951 | + in[1] * modelview[4 + i] + |
| 952 | + in[2] * modelview[8 + i] + |
| 953 | + in[3] * modelview[12 + i]; |
| 954 | + } |
| 955 | + |
| 956 | + for (i = 0; i < 4; i++) { |
| 957 | + in[i] = |
| 958 | + out[0] * projection[i] + |
| 959 | + out[1] * projection[4 + i] + |
| 960 | + out[2] * projection[8 + i] + |
| 961 | + out[3] * projection[12 + i]; |
| 962 | + } |
| 963 | + |
| 964 | + if (in[3] == 0.0) |
| 965 | + return false; |
| 966 | + |
| 967 | + in[0] /= in[3]; |
| 968 | + in[1] /= in[3]; |
| 969 | + in[2] /= in[3]; |
| 970 | + /* Map x, y and z to range 0-1 */ |
| 971 | + in[0] = in[0] * 0.5 + 0.5; |
| 972 | + in[1] = in[1] * 0.5 + 0.5; |
| 973 | + in[2] = in[2] * 0.5 + 0.5; |
| 974 | + |
| 975 | + /* Map x,y to viewport */ |
| 976 | + in[0] = in[0] * viewport[2] + viewport[0]; |
| 977 | + in[1] = in[1] * viewport[3] + viewport[1]; |
| 978 | + |
| 979 | + *winx = in[0]; |
| 980 | + *winy = in[1]; |
| 981 | + *winz = in[2]; |
| 982 | + return true; |
| 983 | +} |
| 984 | } |
| 985 | |
| 986 | bool |
| 987 | @@ -874,11 +958,11 @@ |
| 988 | float *scr, |
| 989 | int n) |
| 990 | { |
| 991 | - GLdouble dProjection[16]; |
| 992 | - GLdouble dModel[16]; |
| 993 | - GLint viewport[4]; |
| 994 | - double x, y, z; |
| 995 | - int i; |
| 996 | + GLfloat dProjection[16]; |
| 997 | + GLfloat dModel[16]; |
| 998 | + GLint viewport[4]; |
| 999 | + float x, y, z; |
| 1000 | + int i; |
| 1001 | |
| 1002 | viewport[0] = output->x1 (); |
| 1003 | viewport[1] = screen->height () - output->y2 (); |
| 1004 | @@ -888,14 +972,14 @@ |
| 1005 | for (i = 0; i < 16; i++) |
| 1006 | { |
| 1007 | dModel[i] = transform.getMatrix ()[i]; |
| 1008 | - dProjection[i] = gScreen->projectionMatrix ()[i]; |
| 1009 | + dProjection[i] = gScreen->projectionMatrix ()->getMatrix ()[i]; |
| 1010 | } |
| 1011 | |
| 1012 | while (n--) |
| 1013 | { |
| 1014 | - if (!gluProject (object[0], object[1], object[2], |
| 1015 | - dModel, dProjection, viewport, |
| 1016 | - &x, &y, &z)) |
| 1017 | + if (!project (object[0], object[1], object[2], |
| 1018 | + dModel, dProjection, viewport, |
| 1019 | + &x, &y, &z)) |
| 1020 | return false; |
| 1021 | |
| 1022 | scr[0] = x; |
| 1023 | @@ -909,57 +993,56 @@ |
| 1024 | } |
| 1025 | |
| 1026 | bool |
| 1027 | -BlurScreen::loadFragmentProgram (GLuint *program, |
| 1028 | - const char *string) |
| 1029 | +BlurScreen::loadFragmentProgram (boost::shared_ptr <GLProgram> &program, |
| 1030 | + const char *vertex, |
| 1031 | + const char *fragment) |
| 1032 | { |
| 1033 | - GLint errorPos; |
| 1034 | - |
| 1035 | - /* clear errors */ |
| 1036 | - glGetError (); |
| 1037 | - |
| 1038 | - if (!*program) |
| 1039 | - (*GL::genPrograms) (1, program); |
| 1040 | - |
| 1041 | - (*GL::bindProgram) (GL_FRAGMENT_PROGRAM_ARB, *program); |
| 1042 | - (*GL::programString) (GL_FRAGMENT_PROGRAM_ARB, |
| 1043 | - GL_PROGRAM_FORMAT_ASCII_ARB, |
| 1044 | - strlen (string), string); |
| 1045 | - |
| 1046 | - glGetIntegerv (GL_PROGRAM_ERROR_POSITION_ARB, &errorPos); |
| 1047 | - if (glGetError () != GL_NO_ERROR || errorPos != -1) |
| 1048 | + if (!program) |
| 1049 | + program.reset (new GLProgram (CompString (vertex), |
| 1050 | + CompString (fragment))); |
| 1051 | + |
| 1052 | + if (program && program->valid ()) |
| 1053 | + return true; |
| 1054 | + else |
| 1055 | { |
| 1056 | + program.reset (); |
| 1057 | compLogMessage ("blur", CompLogLevelError, |
| 1058 | - "Failed to load blur program %s", string); |
| 1059 | - |
| 1060 | - (*GL::deletePrograms) (1, program); |
| 1061 | - *program = 0; |
| 1062 | - |
| 1063 | + "Failed to load blur program %s", fragment); |
| 1064 | return false; |
| 1065 | } |
| 1066 | - |
| 1067 | - return true; |
| 1068 | } |
| 1069 | |
| 1070 | bool |
| 1071 | BlurScreen::loadFilterProgram (int numITC) |
| 1072 | { |
| 1073 | - char buffer[4096]; |
| 1074 | - char *targetString; |
| 1075 | - char *str = buffer; |
| 1076 | + std::stringstream svtx; |
| 1077 | + |
| 1078 | + /* A simple pass-thru vertex shader */ |
| 1079 | + svtx << "#ifdef GL_ES\n"\ |
| 1080 | + "precision mediump float;\n"\ |
| 1081 | + "#endif\n"\ |
| 1082 | + "uniform mat4 modelview;\n"\ |
| 1083 | + "uniform mat4 projection;\n"\ |
| 1084 | + "attribute vec4 position;\n"\ |
| 1085 | + "attribute vec2 texCoord0;\n"\ |
| 1086 | + "varying vec2 vTexCoord0;\n"\ |
| 1087 | + "\n"\ |
| 1088 | + "void main ()\n"\ |
| 1089 | + "{\n"\ |
| 1090 | + " vTexCoord0 = texCoord0;\n"\ |
| 1091 | + " gl_Position = projection * modelview * position;\n"\ |
| 1092 | + "}"; |
| 1093 | + |
| 1094 | + std::stringstream str; |
| 1095 | int i, j; |
| 1096 | int numIndirect; |
| 1097 | int numIndirectOp; |
| 1098 | int base, end, ITCbase; |
| 1099 | |
| 1100 | - if (target == GL_TEXTURE_2D) |
| 1101 | - targetString = (char *) "2D"; |
| 1102 | - else |
| 1103 | - targetString = (char *) "RECT"; |
| 1104 | + SamplerInfo info (getSamplerInfoForSize (*screen)); |
| 1105 | |
| 1106 | - str += sprintf (str, |
| 1107 | - "!!ARBfp1.0" |
| 1108 | - "ATTRIB texcoord = fragment.texcoord[0];" |
| 1109 | - "TEMP sum;"); |
| 1110 | + str << "varying vec2 vTexCoord0;\n"\ |
| 1111 | + "uniform sampler2D texture0;\n"; |
| 1112 | |
| 1113 | if (maxTemp - 1 > (numTexop + (numTexop - numITC)) * 2) |
| 1114 | { |
| 1115 | @@ -977,19 +1060,19 @@ |
| 1116 | multiple indirection steps */ |
| 1117 | j = (numIndirect > 1) ? 0 : numITC; |
| 1118 | |
| 1119 | + str << "\n"\ |
| 1120 | + "void main ()\n"\ |
| 1121 | + "{\n"; |
| 1122 | + |
| 1123 | for (i = 0; i < numIndirectOp; i++) |
| 1124 | - str += sprintf (str,"TEMP pix_%d, pix_%d;", i * 2, (i * 2) + 1); |
| 1125 | + str << " vec4 blur_pix_" << i * 2 << ", blur_pix_" << (i * 2) + 1 << ";\n"; |
| 1126 | |
| 1127 | for (i = j; i < numIndirectOp; i++) |
| 1128 | - str += sprintf (str,"TEMP coord_%d, coord_%d;", i * 2, (i * 2) + 1); |
| 1129 | - |
| 1130 | - str += sprintf (str, |
| 1131 | - "TEX sum, texcoord, texture[0], %s;", |
| 1132 | - targetString); |
| 1133 | - |
| 1134 | - str += sprintf (str, |
| 1135 | - "MUL sum, sum, %f;", |
| 1136 | - amp[numTexop]); |
| 1137 | + str << " vec2 blur_coord_" << i * 2 << ", blur_coord_" << (i * 2) + 1 << ";\n"; |
| 1138 | + |
| 1139 | + str << " vec4 blur_sum;\n"; |
| 1140 | + str << " blur_sum = " << info.func << " (texture0, vTexCoord0);\n"\ |
| 1141 | + " blur_sum = blur_sum * " << amp[numTexop] << ";\n"; |
| 1142 | |
| 1143 | for (j = 0; j < numIndirect; j++) |
| 1144 | { |
| 1145 | @@ -999,37 +1082,30 @@ |
| 1146 | ITCbase = MAX (numITC - base, 0); |
| 1147 | |
| 1148 | for (i = ITCbase; i < end; i++) |
| 1149 | - str += sprintf (str, |
| 1150 | - "ADD coord_%d, texcoord, {%g, 0.0, 0.0, 0.0};" |
| 1151 | - "SUB coord_%d, texcoord, {%g, 0.0, 0.0, 0.0};", |
| 1152 | - i * 2, pos[base + i] * tx, |
| 1153 | - (i * 2) + 1, pos[base + i] * tx); |
| 1154 | - |
| 1155 | + str << " blur_coord_" << i * 2 << " = vTexCoord0 + vec2 (" << pos[base + i] * tx << ", 0.0);\n"\ |
| 1156 | + " blur_coord_" << (i * 2) + 1 << " = vTexCoord0 - vec2 (" << pos[base + i] * tx << ", 0.0);\n"; |
| 1157 | +#if INDEPENDENT_TEX_SUPPORTED |
| 1158 | for (i = 0; i < ITCbase; i++) |
| 1159 | - str += sprintf (str, |
| 1160 | + str << sprintf (str, |
| 1161 | "TEX pix_%d, fragment.texcoord[%d], texture[0], %s;" |
| 1162 | "TEX pix_%d, fragment.texcoord[%d], texture[0], %s;", |
| 1163 | i * 2, ((i + base) * 2) + 1, targetString, |
| 1164 | (i * 2) + 1, ((i + base) * 2) + 2, targetString); |
| 1165 | - |
| 1166 | +#endif |
| 1167 | for (i = ITCbase; i < end; i++) |
| 1168 | - str += sprintf (str, |
| 1169 | - "TEX pix_%d, coord_%d, texture[0], %s;" |
| 1170 | - "TEX pix_%d, coord_%d, texture[0], %s;", |
| 1171 | - i * 2, i * 2, targetString, |
| 1172 | - (i * 2) + 1, (i * 2) + 1, targetString); |
| 1173 | + str << " blur_pix_" << (i * 2) << " = " << info.func << " (texture0, blur_coord_" << i * 2 << ");\n"\ |
| 1174 | + " blur_pix_" << (i * 2) + 1 << " = " << info.func << " (texture0, blur_coord_" << (i * 2) + 1 << ");\n"; |
| 1175 | |
| 1176 | for (i = 0; i < end * 2; i++) |
| 1177 | - str += sprintf (str, |
| 1178 | - "MAD sum, pix_%d, %f, sum;", |
| 1179 | - i, amp[base + (i / 2)]); |
| 1180 | + str << " blur_sum += blur_pix_" << i << " * " << amp[base + (i / 2)] << ";\n"; |
| 1181 | } |
| 1182 | |
| 1183 | - str += sprintf (str, |
| 1184 | - "MOV result.color, sum;" |
| 1185 | - "END"); |
| 1186 | + str << " gl_FragColor = blur_sum;\n"\ |
| 1187 | + "}"; |
| 1188 | |
| 1189 | - return loadFragmentProgram (&program, buffer); |
| 1190 | + return loadFragmentProgram (program, |
| 1191 | + svtx.str ().c_str (), |
| 1192 | + str.str ().c_str ()); |
| 1193 | } |
| 1194 | |
| 1195 | bool |
| 1196 | @@ -1038,51 +1114,7 @@ |
| 1197 | if (!fbo) |
| 1198 | return false; |
| 1199 | |
| 1200 | - (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, fbo); |
| 1201 | - |
| 1202 | - /* bind texture and check status the first time */ |
| 1203 | - if (!fboStatus) |
| 1204 | - { |
| 1205 | - (*GL::framebufferTexture2D) (GL_FRAMEBUFFER_EXT, |
| 1206 | - GL_COLOR_ATTACHMENT0_EXT, |
| 1207 | - target, texture[1], |
| 1208 | - 0); |
| 1209 | - |
| 1210 | - int currStatus = (*GL::checkFramebufferStatus) (GL_FRAMEBUFFER_EXT); |
| 1211 | - if (currStatus != GL_FRAMEBUFFER_COMPLETE_EXT) |
| 1212 | - { |
| 1213 | - compLogMessage ("blur", CompLogLevelError, |
| 1214 | - "Framebuffer incomplete"); |
| 1215 | - |
| 1216 | - (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0); |
| 1217 | - (*GL::deleteFramebuffers) (1, &fbo); |
| 1218 | - |
| 1219 | - fbo = 0; |
| 1220 | - |
| 1221 | - return false; |
| 1222 | - } |
| 1223 | - else |
| 1224 | - fboStatus = true; |
| 1225 | - } |
| 1226 | - |
| 1227 | - glPushAttrib (GL_VIEWPORT_BIT | GL_ENABLE_BIT); |
| 1228 | - |
| 1229 | - glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT); |
| 1230 | - glReadBuffer (GL_COLOR_ATTACHMENT0_EXT); |
| 1231 | - |
| 1232 | - glDisable (GL_CLIP_PLANE0); |
| 1233 | - glDisable (GL_CLIP_PLANE1); |
| 1234 | - glDisable (GL_CLIP_PLANE2); |
| 1235 | - glDisable (GL_CLIP_PLANE3); |
| 1236 | - |
| 1237 | - glViewport (0, 0, width, height); |
| 1238 | - glMatrixMode (GL_PROJECTION); |
| 1239 | - glPushMatrix (); |
| 1240 | - glLoadIdentity (); |
| 1241 | - glOrtho (0.0, width, 0.0, height, -1.0, 1.0); |
| 1242 | - glMatrixMode (GL_MODELVIEW); |
| 1243 | - glPushMatrix (); |
| 1244 | - glLoadIdentity (); |
| 1245 | + oldDrawFramebuffer = fbo->bind (); |
| 1246 | |
| 1247 | return true; |
| 1248 | } |
| 1249 | @@ -1090,37 +1122,22 @@ |
| 1250 | void |
| 1251 | BlurScreen::fboEpilogue () |
| 1252 | { |
| 1253 | - (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0); |
| 1254 | - |
| 1255 | - glMatrixMode (GL_PROJECTION); |
| 1256 | - glLoadIdentity (); |
| 1257 | - glMatrixMode (GL_MODELVIEW); |
| 1258 | - glLoadIdentity (); |
| 1259 | - glDepthRange (0, 1); |
| 1260 | - glViewport (-1, -1, 2, 2); |
| 1261 | - glRasterPos2f (0, 0); |
| 1262 | - |
| 1263 | - gScreen->resetRasterPos (); |
| 1264 | - |
| 1265 | - glMatrixMode (GL_PROJECTION); |
| 1266 | - glPopMatrix (); |
| 1267 | - glMatrixMode (GL_MODELVIEW); |
| 1268 | - glPopMatrix (); |
| 1269 | - |
| 1270 | - glDrawBuffer (GL_BACK); |
| 1271 | - glReadBuffer (GL_BACK); |
| 1272 | - |
| 1273 | - glPopAttrib (); |
| 1274 | + oldDrawFramebuffer->bind (); |
| 1275 | + |
| 1276 | + fbo->tex ()->enable (GLTexture::Good); |
| 1277 | + //GL::generateMipmap (fbo->tex ()->target ()); |
| 1278 | + |
| 1279 | + fbo->tex ()->disable (); |
| 1280 | } |
| 1281 | |
| 1282 | bool |
| 1283 | BlurScreen::fboUpdate (BoxPtr pBox, |
| 1284 | int nBox) |
| 1285 | { |
| 1286 | - int i, y, iTC = 0; |
| 1287 | + float iTC = 0; |
| 1288 | bool wasCulled = glIsEnabled (GL_CULL_FACE); |
| 1289 | |
| 1290 | - if (GL::maxTextureUnits && optionGetIndependentTex ()) |
| 1291 | + if (GL::maxTextureUnits && optionGetIndependentTex () && false) |
| 1292 | iTC = MIN ((GL::maxTextureUnits - 1) / 2, numTexop); |
| 1293 | |
| 1294 | if (!program) |
| 1295 | @@ -1131,83 +1148,51 @@ |
| 1296 | return false; |
| 1297 | |
| 1298 | glDisable (GL_CULL_FACE); |
| 1299 | - |
| 1300 | - glDisableClientState (GL_TEXTURE_COORD_ARRAY); |
| 1301 | - |
| 1302 | - glBindTexture (target, texture[0]); |
| 1303 | - |
| 1304 | - glEnable (GL_FRAGMENT_PROGRAM_ARB); |
| 1305 | - (*GL::bindProgram) (GL_FRAGMENT_PROGRAM_ARB, program); |
| 1306 | - |
| 1307 | - glBegin (GL_QUADS); |
| 1308 | + GL::activeTexture (GL_TEXTURE0); |
| 1309 | + texture[0]->enable (GLTexture::Good); |
| 1310 | + |
| 1311 | + GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer (); |
| 1312 | |
| 1313 | while (nBox--) |
| 1314 | { |
| 1315 | - y = screen->height () - pBox->y2; |
| 1316 | - |
| 1317 | - for (i = 0; i < iTC; i++) |
| 1318 | - { |
| 1319 | - (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2), |
| 1320 | - tx * (pBox->x1 + pos[i]), |
| 1321 | - ty * y); |
| 1322 | - (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2) + 1, |
| 1323 | - tx * (pBox->x1 - pos[i]), |
| 1324 | - ty * y); |
| 1325 | - } |
| 1326 | - |
| 1327 | - glTexCoord2f (tx * pBox->x1, ty * y); |
| 1328 | - glVertex2i (pBox->x1, y); |
| 1329 | - |
| 1330 | - for (i = 0; i < iTC; i++) |
| 1331 | - { |
| 1332 | - (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2), |
| 1333 | - tx * (pBox->x2 + pos[i]), |
| 1334 | - ty * y); |
| 1335 | - (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2) + 1, |
| 1336 | - tx * (pBox->x2 - pos[i]), |
| 1337 | - ty * y); |
| 1338 | - } |
| 1339 | - |
| 1340 | - glTexCoord2f (tx * pBox->x2, ty * y); |
| 1341 | - glVertex2i (pBox->x2, y); |
| 1342 | - |
| 1343 | - y = screen->height () - pBox->y1; |
| 1344 | - |
| 1345 | - for (i = 0; i < iTC; i++) |
| 1346 | - { |
| 1347 | - (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2), |
| 1348 | - tx * (pBox->x2 + pos[i]), |
| 1349 | - ty * y); |
| 1350 | - (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2) + 1, |
| 1351 | - tx * (pBox->x2 - pos[i]), |
| 1352 | - ty * y); |
| 1353 | - } |
| 1354 | - |
| 1355 | - glTexCoord2f (tx * pBox->x2, ty * y); |
| 1356 | - glVertex2i (pBox->x2, y); |
| 1357 | - |
| 1358 | - for (i = 0; i < iTC; i++) |
| 1359 | - { |
| 1360 | - (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2), |
| 1361 | - tx * (pBox->x1 + pos[i]), |
| 1362 | - ty * y); |
| 1363 | - (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2) + 1, |
| 1364 | - tx * (pBox->x1 - pos[i]), |
| 1365 | - ty * y); |
| 1366 | - } |
| 1367 | - |
| 1368 | - glTexCoord2f (tx * pBox->x1, ty * y); |
| 1369 | - glVertex2i (pBox->x1, y); |
| 1370 | + float x1 = pBox->x1; |
| 1371 | + float x2 = pBox->x2; |
| 1372 | + float y1 = screen->height () - pBox->y2; |
| 1373 | + float y2 = screen->height () - pBox->y1; |
| 1374 | + |
| 1375 | + GLfloat texCoords[] = |
| 1376 | + { |
| 1377 | + tx * x1, ty * y1, |
| 1378 | + tx * x1, ty * y2, |
| 1379 | + tx * x2, ty * y1, |
| 1380 | + tx * x2, ty * y2 |
| 1381 | + }; |
| 1382 | + |
| 1383 | + GLfloat vertices[] = |
| 1384 | + { |
| 1385 | + x1, y1, 0, |
| 1386 | + x1, y2, 0, |
| 1387 | + x2, y1, 0, |
| 1388 | + x2, y2, 0 |
| 1389 | + }; |
| 1390 | + |
| 1391 | + GLMatrix mv; |
| 1392 | + mv.toScreenSpace (output, -DEFAULT_Z_CAMERA); |
| 1393 | + |
| 1394 | + streamingBuffer->begin (GL_TRIANGLE_STRIP); |
| 1395 | + streamingBuffer->setProgram (program.get ()); |
| 1396 | + streamingBuffer->addTexCoords (0, 4, texCoords); |
| 1397 | + streamingBuffer->addVertices (4, vertices); |
| 1398 | + |
| 1399 | + if (streamingBuffer->end ()) |
| 1400 | + streamingBuffer->render (mv); |
| 1401 | + |
| 1402 | + /* Unset program */ |
| 1403 | + streamingBuffer->setProgram (NULL); |
| 1404 | |
| 1405 | pBox++; |
| 1406 | } |
| 1407 | |
| 1408 | - glEnd (); |
| 1409 | - |
| 1410 | - glDisable (GL_FRAGMENT_PROGRAM_ARB); |
| 1411 | - |
| 1412 | - glEnableClientState (GL_TEXTURE_COORD_ARRAY); |
| 1413 | - |
| 1414 | if (wasCulled) |
| 1415 | glEnable (GL_CULL_FACE); |
| 1416 | |
| 1417 | @@ -1231,92 +1216,70 @@ |
| 1418 | float *scr; |
| 1419 | |
| 1420 | GLTexture::MatrixList ml; |
| 1421 | - GLWindow::Geometry *gm; |
| 1422 | |
| 1423 | - gWindow->geometry ().reset (); |
| 1424 | + gWindow->vertexBuffer ()->begin (); |
| 1425 | gWindow->glAddGeometry (ml, bScreen->tmpRegion2, infiniteRegion); |
| 1426 | |
| 1427 | - if (!gWindow->geometry ().vCount) |
| 1428 | + if (!gWindow->vertexBuffer ()->end ()) |
| 1429 | return; |
| 1430 | |
| 1431 | - gm = &gWindow->geometry (); |
| 1432 | + GLVertexBuffer *vb = gWindow->vertexBuffer (); |
| 1433 | |
| 1434 | - nVertices = (gm->indexCount) ? gm->indexCount: gm->vCount; |
| 1435 | + nVertices = vb->countVertices (); |
| 1436 | nQuadCombine = 1; |
| 1437 | |
| 1438 | - stride = gm->vertexStride; |
| 1439 | - vert = gm->vertices + (stride - 3); |
| 1440 | - |
| 1441 | - /* we need to find the best value here */ |
| 1442 | - if (nVertices <= MAX_VERTEX_PROJECT_COUNT) |
| 1443 | + stride = vb->getVertexStride (); |
| 1444 | + vert = vb->getVertices () + (stride - 3); |
| 1445 | + |
| 1446 | + /* construct quads from bounding vertices */ |
| 1447 | + minX = screen->width (); |
| 1448 | + maxX = 0; |
| 1449 | + minY = screen->height (); |
| 1450 | + maxY = 0; |
| 1451 | + minZ = 1000000; |
| 1452 | + maxZ = -1000000; |
| 1453 | + |
| 1454 | + for (i = 0; i < vb->countVertices (); i++) |
| 1455 | { |
| 1456 | - for (i = 0; i < nVertices; i++) |
| 1457 | - { |
| 1458 | - if (gm->indexCount) |
| 1459 | - { |
| 1460 | - v = vert + (stride * gm->indices[i]); |
| 1461 | - } |
| 1462 | - else |
| 1463 | - { |
| 1464 | - v = vert + (stride * i); |
| 1465 | - } |
| 1466 | - |
| 1467 | - vertices[i * 3] = v[0]; |
| 1468 | - vertices[(i * 3) + 1] = v[1]; |
| 1469 | - vertices[(i * 3) + 2] = v[2]; |
| 1470 | - } |
| 1471 | + v = vert + (stride * i); |
| 1472 | + |
| 1473 | + if (v[0] < minX) |
| 1474 | + minX = v[0]; |
| 1475 | + |
| 1476 | + if (v[0] > maxX) |
| 1477 | + maxX = v[0]; |
| 1478 | + |
| 1479 | + if (v[1] < minY) |
| 1480 | + minY = v[1]; |
| 1481 | + |
| 1482 | + if (v[1] > maxY) |
| 1483 | + maxY = v[1]; |
| 1484 | + |
| 1485 | + if (v[2] < minZ) |
| 1486 | + minZ = v[2]; |
| 1487 | + |
| 1488 | + if (v[2] > maxZ) |
| 1489 | + maxZ = v[2]; |
| 1490 | } |
| 1491 | - else |
| 1492 | + |
| 1493 | + vertices[0] = vertices[9] = minX; |
| 1494 | + vertices[1] = vertices[4] = minY; |
| 1495 | + vertices[3] = vertices[6] = maxX; |
| 1496 | + vertices[7] = vertices[10] = maxY; |
| 1497 | + vertices[2] = vertices[5] = maxZ; |
| 1498 | + vertices[8] = vertices[11] = maxZ; |
| 1499 | + |
| 1500 | + nVertices = 4; |
| 1501 | + |
| 1502 | + if (maxZ != minZ) |
| 1503 | { |
| 1504 | - minX = screen->width (); |
| 1505 | - maxX = 0; |
| 1506 | - minY = screen->height (); |
| 1507 | - maxY = 0; |
| 1508 | - minZ = 1000000; |
| 1509 | - maxZ = -1000000; |
| 1510 | - |
| 1511 | - for (i = 0; i < gm->vCount; i++) |
| 1512 | - { |
| 1513 | - v = vert + (stride * i); |
| 1514 | - |
| 1515 | - if (v[0] < minX) |
| 1516 | - minX = v[0]; |
| 1517 | - |
| 1518 | - if (v[0] > maxX) |
| 1519 | - maxX = v[0]; |
| 1520 | - |
| 1521 | - if (v[1] < minY) |
| 1522 | - minY = v[1]; |
| 1523 | - |
| 1524 | - if (v[1] > maxY) |
| 1525 | - maxY = v[1]; |
| 1526 | - |
| 1527 | - if (v[2] < minZ) |
| 1528 | - minZ = v[2]; |
| 1529 | - |
| 1530 | - if (v[2] > maxZ) |
| 1531 | - maxZ = v[2]; |
| 1532 | - } |
| 1533 | - |
| 1534 | - vertices[0] = vertices[9] = minX; |
| 1535 | - vertices[1] = vertices[4] = minY; |
| 1536 | - vertices[3] = vertices[6] = maxX; |
| 1537 | - vertices[7] = vertices[10] = maxY; |
| 1538 | - vertices[2] = vertices[5] = maxZ; |
| 1539 | - vertices[8] = vertices[11] = maxZ; |
| 1540 | - |
| 1541 | - nVertices = 4; |
| 1542 | - |
| 1543 | - if (maxZ != minZ) |
| 1544 | - { |
| 1545 | - vertices[12] = vertices[21] = minX; |
| 1546 | - vertices[13] = vertices[16] = minY; |
| 1547 | - vertices[15] = vertices[18] = maxX; |
| 1548 | - vertices[19] = vertices[22] = maxY; |
| 1549 | - vertices[14] = vertices[17] = minZ; |
| 1550 | - vertices[20] = vertices[23] = minZ; |
| 1551 | - nQuadCombine = 2; |
| 1552 | - } |
| 1553 | + vertices[12] = vertices[21] = minX; |
| 1554 | + vertices[13] = vertices[16] = minY; |
| 1555 | + vertices[15] = vertices[18] = maxX; |
| 1556 | + vertices[19] = vertices[22] = maxY; |
| 1557 | + vertices[14] = vertices[17] = minZ; |
| 1558 | + vertices[20] = vertices[23] = minZ; |
| 1559 | + nQuadCombine = 2; |
| 1560 | } |
| 1561 | |
| 1562 | if (!bScreen->projectVertices (output, transform, vertices, scrv, |
| 1563 | @@ -1349,10 +1312,10 @@ |
| 1564 | |
| 1565 | int x1, y1, x2, y2; |
| 1566 | |
| 1567 | - x1 = minX - bScreen->filterRadius; |
| 1568 | - y1 = screen->height () - maxY - bScreen->filterRadius; |
| 1569 | - x2 = maxX + bScreen->filterRadius + 0.5f; |
| 1570 | - y2 = screen->height () - minY + bScreen->filterRadius + 0.5f; |
| 1571 | + x1 = minX - bScreen->filterRadius - 0.5; |
| 1572 | + y1 = screen->height () - maxY - bScreen->filterRadius - 0.5; |
| 1573 | + x2 = maxX + bScreen->filterRadius + 0.5; |
| 1574 | + y2 = screen->height () - minY + bScreen->filterRadius + 0.5; |
| 1575 | |
| 1576 | |
| 1577 | bScreen->tmpRegion3 += CompRect (x1, y1, x2 - x1, y2 - y1); |
| 1578 | @@ -1360,21 +1323,15 @@ |
| 1579 | } |
| 1580 | } |
| 1581 | |
| 1582 | -bool |
| 1583 | -BlurWindow::updateDstTexture (const GLMatrix &transform, |
| 1584 | - CompRect *pExtents, |
| 1585 | - int clientThreshold) |
| 1586 | +void |
| 1587 | +BlurWindow::determineBlurRegion (int filter, |
| 1588 | + const GLMatrix &transform, |
| 1589 | + int clientThreshold) |
| 1590 | { |
| 1591 | - int y; |
| 1592 | - int filter; |
| 1593 | - |
| 1594 | - filter = bScreen->optionGetFilter (); |
| 1595 | - |
| 1596 | bScreen->tmpRegion3 = CompRegion (); |
| 1597 | |
| 1598 | if (filter == BlurOptions::FilterGaussian) |
| 1599 | { |
| 1600 | - |
| 1601 | if (state[BLUR_STATE_DECOR].threshold) |
| 1602 | { |
| 1603 | int xx, yy, ww, hh; |
| 1604 | @@ -1394,7 +1351,7 @@ |
| 1605 | // bottom |
| 1606 | xx = window->x () - window->output ().left; |
| 1607 | yy = window->y () + window->height (); |
| 1608 | - ww = window->width () + window->output ().left + |
| 1609 | + ww = window->width () + window->output ().left + |
| 1610 | window->output ().right; |
| 1611 | hh = window->output ().bottom; |
| 1612 | |
| 1613 | @@ -1410,7 +1367,7 @@ |
| 1614 | ww = window->output ().left; |
| 1615 | hh = window->height (); |
| 1616 | |
| 1617 | - bScreen->tmpRegion2 = bScreen->tmpRegion.intersected ( |
| 1618 | + bScreen->tmpRegion2 = bScreen->tmpRegion.intersected ( |
| 1619 | CompRect (xx, yy, ww, hh)); |
| 1620 | |
| 1621 | if (!bScreen->tmpRegion2.isEmpty ()) |
| 1622 | @@ -1422,7 +1379,7 @@ |
| 1623 | ww = window->output ().right; |
| 1624 | hh = window->height (); |
| 1625 | |
| 1626 | - bScreen->tmpRegion2 = bScreen->tmpRegion.intersected ( |
| 1627 | + bScreen->tmpRegion2 = bScreen->tmpRegion.intersected ( |
| 1628 | CompRect (xx, yy, ww, hh)); |
| 1629 | |
| 1630 | if (!bScreen->tmpRegion2.isEmpty ()) |
| 1631 | @@ -1451,141 +1408,147 @@ |
| 1632 | projectRegion (bScreen->output, transform); |
| 1633 | } |
| 1634 | |
| 1635 | - bScreen->tmpRegion = bScreen->region.intersected (bScreen->tmpRegion3); |
| 1636 | + projectedBlurRegion = bScreen->tmpRegion3; |
| 1637 | +} |
| 1638 | + |
| 1639 | +bool |
| 1640 | +BlurWindow::updateDstTexture (const GLMatrix &transform, |
| 1641 | + CompRect *pExtents, |
| 1642 | + unsigned int mask) |
| 1643 | +{ |
| 1644 | + bool ret = false; |
| 1645 | + int filter = bScreen->optionGetFilter (); |
| 1646 | + |
| 1647 | + /* Paint region n projected region */ |
| 1648 | + bScreen->tmpRegion = bScreen->region.intersected (projectedBlurRegion); |
| 1649 | + |
| 1650 | + if (!bScreen->blurOcclusion && |
| 1651 | + !(mask & PAINT_WINDOW_TRANSFORMED_MASK)) |
| 1652 | + bScreen->tmpRegion -= clip; |
| 1653 | |
| 1654 | if (bScreen->tmpRegion.isEmpty ()) |
| 1655 | return false; |
| 1656 | |
| 1657 | - *pExtents = bScreen->tmpRegion.boundingRect (); |
| 1658 | + CompRect br (bScreen->tmpRegion.boundingRect ()); |
| 1659 | |
| 1660 | - if (!bScreen->texture[0] || bScreen->width != screen->width () || |
| 1661 | - bScreen->height != screen->height ()) |
| 1662 | + if (bScreen->texture.empty () || |
| 1663 | + CompSize (bScreen->texture[0]->width (), |
| 1664 | + bScreen->texture[0]->height ()) != |
| 1665 | + static_cast <const CompSize &> (*screen)) |
| 1666 | { |
| 1667 | - int i, textures = 1; |
| 1668 | - |
| 1669 | - bScreen->width = screen->width (); |
| 1670 | - bScreen->height = screen->height (); |
| 1671 | - |
| 1672 | - if (GL::textureNonPowerOfTwo || |
| 1673 | - (POWER_OF_TWO (bScreen->width) && POWER_OF_TWO (bScreen->height))) |
| 1674 | + bScreen->texture = GLTexture::imageDataToTexture (NULL, |
| 1675 | + *screen, |
| 1676 | + GL_RGB, |
| 1677 | +#if IMAGE_BYTE_ORDER == MSBFirst |
| 1678 | + GL_UNSIGNED_INT_8_8_8_8_REV); |
| 1679 | +#else |
| 1680 | + GL_UNSIGNED_BYTE); |
| 1681 | +#endif |
| 1682 | + |
| 1683 | + if (bScreen->texture[0]->target () == GL_TEXTURE_2D) |
| 1684 | { |
| 1685 | - bScreen->target = GL_TEXTURE_2D; |
| 1686 | - bScreen->tx = 1.0f / bScreen->width; |
| 1687 | - bScreen->ty = 1.0f / bScreen->height; |
| 1688 | + bScreen->tx = 1.0f / bScreen->texture[0]->width (); |
| 1689 | + bScreen->ty = 1.0f / bScreen->texture[0]->height (); |
| 1690 | } |
| 1691 | else |
| 1692 | { |
| 1693 | - bScreen->target = GL_TEXTURE_RECTANGLE_NV; |
| 1694 | bScreen->tx = 1; |
| 1695 | bScreen->ty = 1; |
| 1696 | } |
| 1697 | |
| 1698 | if (filter == BlurOptions::FilterGaussian) |
| 1699 | { |
| 1700 | - if (GL::fbo && !bScreen->fbo) |
| 1701 | - (*GL::genFramebuffers) (1, &bScreen->fbo); |
| 1702 | - |
| 1703 | - if (!bScreen->fbo) |
| 1704 | + bScreen->fbo->allocate (*screen, |
| 1705 | + NULL, |
| 1706 | + GL_BGRA); |
| 1707 | + |
| 1708 | + /* We have to bind it in order to get a status */ |
| 1709 | + GLFramebufferObject *old = bScreen->fbo->bind(); |
| 1710 | + bool status = bScreen->fbo->checkStatus (); |
| 1711 | + old->bind(); |
| 1712 | + |
| 1713 | + if (!status) |
| 1714 | compLogMessage ("blur", CompLogLevelError, |
| 1715 | "Failed to create framebuffer object"); |
| 1716 | |
| 1717 | - textures = 2; |
| 1718 | - } |
| 1719 | - |
| 1720 | - bScreen->fboStatus = false; |
| 1721 | - |
| 1722 | - for (i = 0; i < textures; i++) |
| 1723 | - { |
| 1724 | - if (!bScreen->texture[i]) |
| 1725 | - glGenTextures (1, &bScreen->texture[i]); |
| 1726 | - |
| 1727 | - glBindTexture (bScreen->target, bScreen->texture[i]); |
| 1728 | - |
| 1729 | - glTexImage2D (bScreen->target, 0, GL_RGB, |
| 1730 | - bScreen->width, |
| 1731 | - bScreen->height, |
| 1732 | - 0, GL_BGRA, |
| 1733 | - |
| 1734 | -#if IMAGE_BYTE_ORDER == MSBFirst |
| 1735 | - GL_UNSIGNED_INT_8_8_8_8_REV, |
| 1736 | -#else |
| 1737 | - GL_UNSIGNED_BYTE, |
| 1738 | -#endif |
| 1739 | - |
| 1740 | - NULL); |
| 1741 | - |
| 1742 | - glTexParameteri (bScreen->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 1743 | - glTexParameteri (bScreen->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 1744 | - |
| 1745 | - if (filter == BlurOptions::FilterMipmap) |
| 1746 | + else |
| 1747 | { |
| 1748 | - if (!GL::fbo) |
| 1749 | - { |
| 1750 | - compLogMessage ("blur", CompLogLevelWarn, |
| 1751 | - "GL_EXT_framebuffer_object extension " |
| 1752 | - "is required for mipmap filter"); |
| 1753 | - } |
| 1754 | - else if (bScreen->target != GL_TEXTURE_2D) |
| 1755 | - { |
| 1756 | - compLogMessage ("blur", CompLogLevelWarn, |
| 1757 | - "GL_ARB_texture_non_power_of_two " |
| 1758 | - "extension is required for mipmap filter"); |
| 1759 | - } |
| 1760 | - else |
| 1761 | - { |
| 1762 | - glTexParameteri (bScreen->target, GL_TEXTURE_MIN_FILTER, |
| 1763 | - GL_LINEAR_MIPMAP_LINEAR); |
| 1764 | - glTexParameteri (bScreen->target, GL_TEXTURE_MAG_FILTER, |
| 1765 | - GL_LINEAR_MIPMAP_LINEAR); |
| 1766 | - } |
| 1767 | + unsigned int filter = (bScreen->gScreen->driverHasBrokenFBOMipmaps () ? |
| 1768 | + GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR); |
| 1769 | + bScreen->gScreen->setTextureFilter (filter); |
| 1770 | + |
| 1771 | + bScreen->fbo->tex ()->enable (GLTexture::Good); |
| 1772 | + |
| 1773 | + const CompRect &r (*bScreen->fbo->tex ()); |
| 1774 | + |
| 1775 | + glCopyTexSubImage2D (bScreen->fbo->tex ()->target (), |
| 1776 | + 0, 0, 0, 0, 0, |
| 1777 | + r.width (), |
| 1778 | + r.height ()); |
| 1779 | + |
| 1780 | + if (!bScreen->gScreen->driverHasBrokenFBOMipmaps ()) |
| 1781 | + GL::generateMipmap (bScreen->fbo->tex ()->target ()); |
| 1782 | + |
| 1783 | + bScreen->fbo->tex ()->disable (); |
| 1784 | } |
| 1785 | - |
| 1786 | - glTexParameteri (bScreen->target, GL_TEXTURE_WRAP_S, |
| 1787 | - GL_CLAMP_TO_EDGE); |
| 1788 | - glTexParameteri (bScreen->target, GL_TEXTURE_WRAP_T, |
| 1789 | - GL_CLAMP_TO_EDGE); |
| 1790 | - |
| 1791 | - glCopyTexSubImage2D (bScreen->target, 0, 0, 0, 0, 0, |
| 1792 | - bScreen->width, bScreen->height); |
| 1793 | } |
| 1794 | + |
| 1795 | + /* Set update region to entire screen */ |
| 1796 | + br.setGeometry (0, 0, |
| 1797 | + screen->width (), |
| 1798 | + screen->height ()); |
| 1799 | } |
| 1800 | - else |
| 1801 | + |
| 1802 | + *pExtents = br; |
| 1803 | + |
| 1804 | + CompRegion *updateRegion = NULL; |
| 1805 | + updateRegion = &bScreen->tmpRegion; |
| 1806 | + |
| 1807 | + foreach (GLTexture *tex, bScreen->texture) |
| 1808 | { |
| 1809 | - glBindTexture (bScreen->target, bScreen->texture[0]); |
| 1810 | - |
| 1811 | - CompRect br = bScreen->tmpRegion.boundingRect (); |
| 1812 | - |
| 1813 | - y = screen->height () - br.y2 (); |
| 1814 | - |
| 1815 | - glCopyTexSubImage2D (bScreen->target, 0, |
| 1816 | - br.x1 (), y, |
| 1817 | - br.x1 (), y, |
| 1818 | - br.width (), |
| 1819 | - br.height ()); |
| 1820 | - } |
| 1821 | - |
| 1822 | - switch (filter) { |
| 1823 | - case BlurOptions::FilterGaussian: |
| 1824 | - return bScreen->fboUpdate (bScreen->tmpRegion.handle ()->rects, |
| 1825 | - bScreen->tmpRegion.numRects ()); |
| 1826 | - case BlurOptions::FilterMipmap: |
| 1827 | - if (GL::generateMipmap) |
| 1828 | - (*GL::generateMipmap) (bScreen->target); |
| 1829 | - break; |
| 1830 | - case BlurOptions::Filter4xbilinear: |
| 1831 | - break; |
| 1832 | - } |
| 1833 | - |
| 1834 | - glBindTexture (bScreen->target, 0); |
| 1835 | - |
| 1836 | - return true; |
| 1837 | + /* We need to set the active texture filter to GL_LINEAR_MIPMAP_LINEAR */ |
| 1838 | + if (filter == BlurOptions::FilterMipmap && |
| 1839 | + !bScreen->gScreen->driverHasBrokenFBOMipmaps ()) |
| 1840 | + bScreen->gScreen->setTextureFilter (GL_LINEAR_MIPMAP_LINEAR); |
| 1841 | + |
| 1842 | + tex->enable (GLTexture::Good); |
| 1843 | + |
| 1844 | + CompRect::vector rects (updateRegion->rects ()); |
| 1845 | + |
| 1846 | + foreach (const CompRect &r, rects) |
| 1847 | + { |
| 1848 | + int y = screen->height () - r.y2 (); |
| 1849 | + |
| 1850 | + glCopyTexSubImage2D (bScreen->texture[0]->target (), 0, |
| 1851 | + r.x1 (), y, |
| 1852 | + r.x1 (), y, |
| 1853 | + r.width (), |
| 1854 | + r.height ()); |
| 1855 | + } |
| 1856 | + |
| 1857 | + /* Force mipmap regeneration, because GLTexture assumes static |
| 1858 | + * textures and won't do it for us */ |
| 1859 | + if (filter == BlurOptions::FilterMipmap && |
| 1860 | + !bScreen->gScreen->driverHasBrokenFBOMipmaps ()) |
| 1861 | + GL::generateMipmap (tex->target ()); |
| 1862 | + |
| 1863 | + if (filter == BlurOptions::FilterGaussian) |
| 1864 | + ret |= bScreen->fboUpdate (updateRegion->handle ()->rects, |
| 1865 | + updateRegion->numRects ()); |
| 1866 | + else |
| 1867 | + ret = true; |
| 1868 | + |
| 1869 | + tex->disable (); |
| 1870 | + } |
| 1871 | + |
| 1872 | + return ret; |
| 1873 | } |
| 1874 | |
| 1875 | bool |
| 1876 | -BlurWindow::glDraw (const GLMatrix &transform, |
| 1877 | - GLFragment::Attrib &attrib, |
| 1878 | - const CompRegion ®ion, |
| 1879 | - unsigned int mask) |
| 1880 | +BlurWindow::glDraw (const GLMatrix &transform, |
| 1881 | + const GLWindowPaintAttrib &attrib, |
| 1882 | + const CompRegion ®ion, |
| 1883 | + unsigned int mask) |
| 1884 | { |
| 1885 | bool status; |
| 1886 | |
| 1887 | @@ -1603,22 +1566,11 @@ |
| 1888 | { |
| 1889 | bool clipped = false; |
| 1890 | CompRect box (0, 0, 0, 0); |
| 1891 | - CompRegion reg; |
| 1892 | |
| 1893 | - bScreen->mvp = GLMatrix (bScreen->gScreen->projectionMatrix ()); |
| 1894 | + bScreen->mvp = *(bScreen->gScreen->projectionMatrix ()); |
| 1895 | bScreen->mvp *= transform; |
| 1896 | |
| 1897 | - if (mask & PAINT_WINDOW_TRANSFORMED_MASK) |
| 1898 | - reg = infiniteRegion; |
| 1899 | - else |
| 1900 | - reg = region; |
| 1901 | - |
| 1902 | - bScreen->tmpRegion = this->region.intersected (reg); |
| 1903 | - if (!bScreen->blurOcclusion && |
| 1904 | - !(mask & PAINT_WINDOW_TRANSFORMED_MASK)) |
| 1905 | - bScreen->tmpRegion -= clip; |
| 1906 | - |
| 1907 | - if (updateDstTexture (transform, &box, clientThreshold)) |
| 1908 | + if (updateDstTexture (transform, &box, mask)) |
| 1909 | { |
| 1910 | if (clientThreshold) |
| 1911 | { |
| 1912 | @@ -1672,11 +1624,17 @@ |
| 1913 | if (clipped) |
| 1914 | { |
| 1915 | GLTexture::MatrixList ml; |
| 1916 | - |
| 1917 | - gWindow->geometry ().reset (); |
| 1918 | - |
| 1919 | - gWindow->glAddGeometry (ml, bScreen->tmpRegion, reg); |
| 1920 | - if (gWindow->geometry ().vCount) |
| 1921 | + const CompRegion *reg = NULL; |
| 1922 | + |
| 1923 | + if (mask & PAINT_WINDOW_TRANSFORMED_MASK) |
| 1924 | + reg = &infiniteRegion; |
| 1925 | + else |
| 1926 | + reg = ®ion; |
| 1927 | + |
| 1928 | + gWindow->vertexBuffer ()->begin (); |
| 1929 | + gWindow->glAddGeometry (ml, bScreen->tmpRegion, *reg); |
| 1930 | + gWindow->vertexBuffer ()->color4f (1.0, 1.0, 1.0, 1.0); |
| 1931 | + if (gWindow->vertexBuffer ()->end ()) |
| 1932 | { |
| 1933 | CompRect clearBox = bScreen->stencilBox; |
| 1934 | |
| 1935 | @@ -1684,28 +1642,44 @@ |
| 1936 | |
| 1937 | glEnable (GL_STENCIL_TEST); |
| 1938 | glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); |
| 1939 | + glStencilMask (1); |
| 1940 | |
| 1941 | if (clearBox.x2 () > clearBox.x1 () && |
| 1942 | clearBox.y2 () > clearBox.y1 ()) |
| 1943 | { |
| 1944 | - glPushAttrib (GL_SCISSOR_BIT); |
| 1945 | - glEnable (GL_SCISSOR_TEST); |
| 1946 | + /* We might have a previous scissor region, so we need |
| 1947 | + * to fetch it, however slow that might be .. */ |
| 1948 | + GLint scissorBox[4]; |
| 1949 | + GLboolean scissorEnabled; |
| 1950 | + |
| 1951 | + scissorEnabled = glIsEnabled (GL_SCISSOR_TEST); |
| 1952 | + glGetIntegerv (GL_SCISSOR_BOX, scissorBox); |
| 1953 | + |
| 1954 | + if (!scissorEnabled) |
| 1955 | + glEnable (GL_SCISSOR_TEST); |
| 1956 | + |
| 1957 | glScissor (clearBox.x1 (), |
| 1958 | screen->height () - clearBox.y2 (), |
| 1959 | clearBox.width (), |
| 1960 | clearBox.height ()); |
| 1961 | + glClearStencil (0); |
| 1962 | glClear (GL_STENCIL_BUFFER_BIT); |
| 1963 | - glPopAttrib (); |
| 1964 | + |
| 1965 | + if (!scissorEnabled) |
| 1966 | + glDisable (GL_SCISSOR_TEST); |
| 1967 | + |
| 1968 | + glScissor (scissorBox[0], scissorBox[1], |
| 1969 | + scissorBox[2], scissorBox[3]); |
| 1970 | } |
| 1971 | |
| 1972 | - glStencilFunc (GL_ALWAYS, 0x1, ~0); |
| 1973 | + glStencilFunc (GL_ALWAYS, 1, 1); |
| 1974 | glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| 1975 | |
| 1976 | - glDisableClientState (GL_TEXTURE_COORD_ARRAY); |
| 1977 | - gWindow->glDrawGeometry (); |
| 1978 | - glEnableClientState (GL_TEXTURE_COORD_ARRAY); |
| 1979 | + /* Render a white polygon where the window is */ |
| 1980 | + gWindow->vertexBuffer ()->render (transform); |
| 1981 | |
| 1982 | glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
| 1983 | + glStencilMask (0); |
| 1984 | glDisable (GL_STENCIL_TEST); |
| 1985 | } |
| 1986 | } |
| 1987 | @@ -1720,10 +1694,248 @@ |
| 1988 | return status; |
| 1989 | } |
| 1990 | |
| 1991 | +namespace |
| 1992 | +{ |
| 1993 | +void setupShadersAndUniformsForDstBlur (GLTexture *texture, |
| 1994 | + GLWindow *gWindow, |
| 1995 | + BlurScreen *bScreen, |
| 1996 | + int &unit, |
| 1997 | + int &iTC, |
| 1998 | + float threshold) |
| 1999 | +{ |
| 2000 | + GLfloat dx, dy; |
| 2001 | + |
| 2002 | + switch (bScreen->optionGetFilter ()) |
| 2003 | + { |
| 2004 | + case BlurOptions::Filter4xbilinear: |
| 2005 | + { |
| 2006 | + dx = bScreen->tx / 2.1f; |
| 2007 | + dy = bScreen->ty / 2.1f; |
| 2008 | + |
| 2009 | + unit = 1; // FIXME!! |
| 2010 | + |
| 2011 | + const CompString &function ( |
| 2012 | + bScreen->getDstBlurFragmentFunction ( |
| 2013 | + texture, unit, 0, 0)); |
| 2014 | + |
| 2015 | + if (!function.empty ()) |
| 2016 | + { |
| 2017 | + (*GL::activeTexture) (GL_TEXTURE0 + unit); |
| 2018 | + bScreen->texture[0]->enable (GLTexture::Good); |
| 2019 | + gWindow->vertexBuffer ()->addTexCoords (unit, 0, NULL); |
| 2020 | + (*GL::activeTexture) (GL_TEXTURE0); |
| 2021 | + |
| 2022 | + gWindow->addShaders ("blur", |
| 2023 | + "", |
| 2024 | + function); |
| 2025 | + |
| 2026 | + gWindow->vertexBuffer ()->addUniform4f ("blur_translation", |
| 2027 | + bScreen->tx, bScreen->ty, |
| 2028 | + 0.0f, 0.0f); |
| 2029 | + |
| 2030 | + gWindow->vertexBuffer ()->addUniform4f ("blur_threshold", |
| 2031 | + threshold, |
| 2032 | + threshold, |
| 2033 | + threshold, |
| 2034 | + threshold); |
| 2035 | + |
| 2036 | + gWindow->vertexBuffer ()->addUniform4f ("blur_dxdy", |
| 2037 | + dx, dy, 0.0, 0.0); |
| 2038 | + } |
| 2039 | + } |
| 2040 | + break; |
| 2041 | + case BlurOptions::FilterGaussian: |
| 2042 | + { |
| 2043 | +#if INDEPENDENT_TEX_SUPPORTED |
| 2044 | + if (bScreen->optionGetIndependentTex ()) |
| 2045 | + { |
| 2046 | + /* leave one free texture unit for fragment position */ |
| 2047 | + iTC = MAX (0, GL::maxTextureUnits - |
| 2048 | + (gWindow->geometry ().texUnits + 1)); |
| 2049 | + if (iTC) |
| 2050 | + iTC = MIN (iTC / 2, bScreen->numTexop); |
| 2051 | + } |
| 2052 | +#endif |
| 2053 | + unit = 1; |
| 2054 | + |
| 2055 | + const CompString &function ( |
| 2056 | + bScreen->getDstBlurFragmentFunction ( |
| 2057 | + texture, unit, iTC, |
| 2058 | + gWindow->vertexBuffer ()->countTextures ())); |
| 2059 | + |
| 2060 | + if (!function.empty ()) |
| 2061 | + { |
| 2062 | + gWindow->addShaders ("blur", |
| 2063 | + "", |
| 2064 | + function); |
| 2065 | + |
| 2066 | + (*GL::activeTexture) (GL_TEXTURE0 + unit); |
| 2067 | + bScreen->texture[0]->enable (GLTexture::Good); |
| 2068 | + gWindow->vertexBuffer ()->addTexCoords (unit, 0, NULL); |
| 2069 | + (*GL::activeTexture) (GL_TEXTURE0 + unit + 1); |
| 2070 | + bScreen->fbo->tex ()->enable (GLTexture::Good); |
| 2071 | + gWindow->vertexBuffer ()->addTexCoords (unit + 1, 0, NULL); |
| 2072 | + (*GL::activeTexture) (GL_TEXTURE0); |
| 2073 | + |
| 2074 | + gWindow->vertexBuffer ()->addUniform4f ("blur_translation", |
| 2075 | + bScreen->tx, bScreen->ty, |
| 2076 | + 0.0f, 0.0f); |
| 2077 | + |
| 2078 | + gWindow->vertexBuffer ()->addUniform4f ("blur_threshold", |
| 2079 | + threshold, |
| 2080 | + threshold, |
| 2081 | + threshold, |
| 2082 | + threshold); |
| 2083 | +#if INDEPENDENT_TEX_SUPPORTED |
| 2084 | + if (iTC) |
| 2085 | + { |
| 2086 | + GLMatrix tm, rm; |
| 2087 | + float s_gen[4], t_gen[4], q_gen[4]; |
| 2088 | + |
| 2089 | + for (unsigned int i = 0; i < 16; i++) |
| 2090 | + tm[i] = 0; |
| 2091 | + tm[0] = (bScreen->output->width () / 2.0) * |
| 2092 | + bScreen->tx; |
| 2093 | + tm[5] = (bScreen->output->height () / 2.0) * |
| 2094 | + bScreen->ty; |
| 2095 | + tm[10] = 1; |
| 2096 | + |
| 2097 | + tm[12] = (bScreen->output->width () / 2.0 + |
| 2098 | + bScreen->output->x1 ()) * bScreen->tx; |
| 2099 | + tm[13] = (bScreen->output->height () / 2.0 + |
| 2100 | + screen->height () - |
| 2101 | + bScreen->output->y2 ()) * bScreen->ty; |
| 2102 | + tm[14] = 1; |
| 2103 | + tm[15] = 1; |
| 2104 | + |
| 2105 | + tm *= bScreen->mvp; |
| 2106 | + |
| 2107 | + for (int i = 0; i < iTC; i++) |
| 2108 | + { |
| 2109 | + (*GL::activeTexture) (GL_TEXTURE0 + |
| 2110 | + gWindow->geometry ().texUnits + (i * 2)); |
| 2111 | + |
| 2112 | + rm.reset (); |
| 2113 | + rm[13] = bScreen->ty * bScreen->pos[i]; |
| 2114 | + rm *= tm; |
| 2115 | + |
| 2116 | + s_gen[0] = rm[0]; |
| 2117 | + s_gen[1] = rm[4]; |
| 2118 | + s_gen[2] = rm[8]; |
| 2119 | + s_gen[3] = rm[12]; |
| 2120 | + t_gen[0] = rm[1]; |
| 2121 | + t_gen[1] = rm[5]; |
| 2122 | + t_gen[2] = rm[9]; |
| 2123 | + t_gen[3] = rm[13]; |
| 2124 | + q_gen[0] = rm[3]; |
| 2125 | + q_gen[1] = rm[7]; |
| 2126 | + q_gen[2] = rm[11]; |
| 2127 | + q_gen[3] = rm[15]; |
| 2128 | + |
| 2129 | + glTexGenfv (GL_T, GL_OBJECT_PLANE, t_gen); |
| 2130 | + glTexGenfv (GL_S, GL_OBJECT_PLANE, s_gen); |
| 2131 | + glTexGenfv (GL_Q, GL_OBJECT_PLANE, q_gen); |
| 2132 | + |
| 2133 | + glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, |
| 2134 | + GL_OBJECT_LINEAR); |
| 2135 | + glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, |
| 2136 | + GL_OBJECT_LINEAR); |
| 2137 | + glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE, |
| 2138 | + GL_OBJECT_LINEAR); |
| 2139 | + |
| 2140 | + glEnable (GL_TEXTURE_GEN_S); |
| 2141 | + glEnable (GL_TEXTURE_GEN_T); |
| 2142 | + glEnable (GL_TEXTURE_GEN_Q); |
| 2143 | + |
| 2144 | + (*GL::activeTexture) (GL_TEXTURE0 + |
| 2145 | + gWindow->geometry ().texUnits + |
| 2146 | + 1 + (i * 2)); |
| 2147 | + |
| 2148 | + rm.reset (); |
| 2149 | + |
| 2150 | + rm[13] = -bScreen->ty * bScreen->pos[i]; |
| 2151 | + rm *= tm; |
| 2152 | + |
| 2153 | + s_gen[0] = rm[0]; |
| 2154 | + s_gen[1] = rm[4]; |
| 2155 | + s_gen[2] = rm[8]; |
| 2156 | + s_gen[3] = rm[12]; |
| 2157 | + t_gen[0] = rm[1]; |
| 2158 | + t_gen[1] = rm[5]; |
| 2159 | + t_gen[2] = rm[9]; |
| 2160 | + t_gen[3] = rm[13]; |
| 2161 | + q_gen[0] = rm[3]; |
| 2162 | + q_gen[1] = rm[7]; |
| 2163 | + q_gen[2] = rm[11]; |
| 2164 | + q_gen[3] = rm[15]; |
| 2165 | + |
| 2166 | + glTexGenfv (GL_T, GL_OBJECT_PLANE, t_gen); |
| 2167 | + glTexGenfv (GL_S, GL_OBJECT_PLANE, s_gen); |
| 2168 | + glTexGenfv (GL_Q, GL_OBJECT_PLANE, q_gen); |
| 2169 | + |
| 2170 | + glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, |
| 2171 | + GL_OBJECT_LINEAR); |
| 2172 | + glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, |
| 2173 | + GL_OBJECT_LINEAR); |
| 2174 | + glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE, |
| 2175 | + GL_OBJECT_LINEAR); |
| 2176 | + |
| 2177 | + glEnable (GL_TEXTURE_GEN_S); |
| 2178 | + glEnable (GL_TEXTURE_GEN_T); |
| 2179 | + glEnable (GL_TEXTURE_GEN_Q); |
| 2180 | + } |
| 2181 | + |
| 2182 | + (*GL::activeTexture) (GL_TEXTURE0); |
| 2183 | + } |
| 2184 | +#endif |
| 2185 | + } |
| 2186 | + } |
| 2187 | + break; |
| 2188 | + case BlurOptions::FilterMipmap: |
| 2189 | + { |
| 2190 | + unit = 1; // FIXME!! |
| 2191 | + |
| 2192 | + const CompString &function ( |
| 2193 | + bScreen->getDstBlurFragmentFunction (texture, |
| 2194 | + unit, |
| 2195 | + 0, |
| 2196 | + 0)); |
| 2197 | + |
| 2198 | + if (!function.empty ()) |
| 2199 | + { |
| 2200 | + float lod = |
| 2201 | + bScreen->optionGetMipmapLod (); |
| 2202 | + |
| 2203 | + gWindow->addShaders ("blur", |
| 2204 | + "", |
| 2205 | + function); |
| 2206 | + |
| 2207 | + (*GL::activeTexture) (GL_TEXTURE0 + unit); |
| 2208 | + bScreen->texture[0]->enable (GLTexture::Good); |
| 2209 | + gWindow->vertexBuffer ()->addTexCoords (unit, 0, NULL); |
| 2210 | + (*GL::activeTexture) (GL_TEXTURE0); |
| 2211 | + |
| 2212 | + gWindow->vertexBuffer ()->addUniform4f ("blur_translation", |
| 2213 | + bScreen->tx, bScreen->ty, |
| 2214 | + 0.0f, lod); |
| 2215 | + |
| 2216 | + gWindow->vertexBuffer ()->addUniform4f ("blur_threshold", |
| 2217 | + threshold, |
| 2218 | + threshold, |
| 2219 | + threshold, |
| 2220 | + threshold); |
| 2221 | + } |
| 2222 | + } |
| 2223 | + break; |
| 2224 | + } |
| 2225 | +} |
| 2226 | +} |
| 2227 | + |
| 2228 | void |
| 2229 | -BlurWindow::glDrawTexture (GLTexture *texture, |
| 2230 | - GLFragment::Attrib &attrib, |
| 2231 | - unsigned int mask) |
| 2232 | +BlurWindow::glDrawTexture (GLTexture *texture, |
| 2233 | + const GLMatrix &matrix, |
| 2234 | + const GLWindowPaintAttrib &attrib, |
| 2235 | + unsigned int mask) |
| 2236 | { |
| 2237 | int state = BLUR_STATE_DECOR; |
| 2238 | |
| 2239 | @@ -1733,295 +1945,108 @@ |
| 2240 | |
| 2241 | if (blur || this->state[state].active) |
| 2242 | { |
| 2243 | - GLFragment::Attrib fa (attrib); |
| 2244 | - int param, function; |
| 2245 | int unit = 0; |
| 2246 | - GLfloat dx, dy; |
| 2247 | int iTC = 0; |
| 2248 | |
| 2249 | if (blur) |
| 2250 | { |
| 2251 | - param = fa.allocParameters (1); |
| 2252 | - |
| 2253 | - function = bScreen->getSrcBlurFragmentFunction (texture, param); |
| 2254 | - if (function) |
| 2255 | + GLfloat dx, dy; |
| 2256 | + |
| 2257 | + const CompString &function ( |
| 2258 | + bScreen->getSrcBlurFragmentFunction (texture)); |
| 2259 | + |
| 2260 | + if (!function.empty ()) |
| 2261 | { |
| 2262 | - fa.addFunction (function); |
| 2263 | + gWindow->addShaders ("focusblur", |
| 2264 | + "", |
| 2265 | + function); |
| 2266 | |
| 2267 | dx = ((texture->matrix ().xx / 2.1f) * blur) / 65535.0f; |
| 2268 | dy = ((texture->matrix ().yy / 2.1f) * blur) / 65535.0f; |
| 2269 | |
| 2270 | - (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, |
| 2271 | - param, dx, dy, dx, -dy); |
| 2272 | + gWindow->vertexBuffer ()->addUniform4f ("focusblur_input_offset", |
| 2273 | + dx, dy, dx, -dy); |
| 2274 | |
| 2275 | /* bi-linear filtering is required */ |
| 2276 | mask |= PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK; |
| 2277 | } |
| 2278 | } |
| 2279 | |
| 2280 | + /* We are drawing the scraped texture, blur it */ |
| 2281 | if (this->state[state].active) |
| 2282 | { |
| 2283 | - GLFragment::Attrib dstFa (fa); |
| 2284 | - float threshold = (float) this->state[state].threshold; |
| 2285 | - |
| 2286 | - switch (bScreen->optionGetFilter ()) { |
| 2287 | - case BlurOptions::Filter4xbilinear: |
| 2288 | - dx = bScreen->tx / 2.1f; |
| 2289 | - dy = bScreen->ty / 2.1f; |
| 2290 | - |
| 2291 | - param = dstFa.allocParameters (3); |
| 2292 | - unit = dstFa.allocTextureUnits (1); |
| 2293 | - |
| 2294 | - function = bScreen->getDstBlurFragmentFunction ( |
| 2295 | - texture, param, unit, 0, 0); |
| 2296 | - if (function) |
| 2297 | - { |
| 2298 | - dstFa.addFunction (function); |
| 2299 | - |
| 2300 | - (*GL::activeTexture) (GL_TEXTURE0_ARB + unit); |
| 2301 | - glBindTexture (bScreen->target, bScreen->texture[0]); |
| 2302 | - (*GL::activeTexture) (GL_TEXTURE0_ARB); |
| 2303 | - |
| 2304 | - (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, |
| 2305 | - param, |
| 2306 | - bScreen->tx, bScreen->ty, |
| 2307 | - 0.0f, 0.0f); |
| 2308 | - |
| 2309 | - (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, |
| 2310 | - param + 1, |
| 2311 | - threshold, threshold, |
| 2312 | - threshold, threshold); |
| 2313 | - |
| 2314 | - (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, |
| 2315 | - param + 2, |
| 2316 | - dx, dy, 0.0f, 0.0f); |
| 2317 | - } |
| 2318 | - break; |
| 2319 | - case BlurOptions::FilterGaussian: |
| 2320 | - if (bScreen->optionGetIndependentTex ()) |
| 2321 | - { |
| 2322 | - /* leave one free texture unit for fragment position */ |
| 2323 | - iTC = MAX (0, GL::maxTextureUnits - |
| 2324 | - (gWindow->geometry ().texUnits + 1)); |
| 2325 | - if (iTC) |
| 2326 | - iTC = MIN (iTC / 2, bScreen->numTexop); |
| 2327 | - } |
| 2328 | - |
| 2329 | - param = dstFa.allocParameters (2); |
| 2330 | - unit = dstFa.allocTextureUnits (2); |
| 2331 | - |
| 2332 | - function = bScreen->getDstBlurFragmentFunction ( |
| 2333 | - texture, param, unit, iTC, |
| 2334 | - gWindow->geometry ().texUnits); |
| 2335 | - |
| 2336 | - if (function) |
| 2337 | - { |
| 2338 | - dstFa.addFunction (function); |
| 2339 | - |
| 2340 | - (*GL::activeTexture) (GL_TEXTURE0_ARB + unit); |
| 2341 | - glBindTexture (bScreen->target, bScreen->texture[0]); |
| 2342 | - (*GL::activeTexture) (GL_TEXTURE0_ARB + unit + 1); |
| 2343 | - glBindTexture (bScreen->target, bScreen->texture[1]); |
| 2344 | - (*GL::activeTexture) (GL_TEXTURE0_ARB); |
| 2345 | - |
| 2346 | - (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, |
| 2347 | - param, bScreen->tx, |
| 2348 | - bScreen->ty, 0.0f, 0.0f); |
| 2349 | - |
| 2350 | - (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, |
| 2351 | - param + 1, |
| 2352 | - threshold, threshold, |
| 2353 | - threshold, threshold); |
| 2354 | - |
| 2355 | - if (iTC) |
| 2356 | - { |
| 2357 | - GLMatrix tm, rm; |
| 2358 | - float s_gen[4], t_gen[4], q_gen[4]; |
| 2359 | - |
| 2360 | - for (unsigned int i = 0; i < 16; i++) |
| 2361 | - tm[i] = 0; |
| 2362 | - tm[0] = (bScreen->output->width () / 2.0) * |
| 2363 | - bScreen->tx; |
| 2364 | - tm[5] = (bScreen->output->height () / 2.0) * |
| 2365 | - bScreen->ty; |
| 2366 | - tm[10] = 1; |
| 2367 | - |
| 2368 | - tm[12] = (bScreen->output->width () / 2.0 + |
| 2369 | - bScreen->output->x1 ()) * bScreen->tx; |
| 2370 | - tm[13] = (bScreen->output->height () / 2.0 + |
| 2371 | - screen->height () - |
| 2372 | - bScreen->output->y2 ()) * bScreen->ty; |
| 2373 | - tm[14] = 1; |
| 2374 | - tm[15] = 1; |
| 2375 | - |
| 2376 | - tm *= bScreen->mvp; |
| 2377 | - |
| 2378 | - for (int i = 0; i < iTC; i++) |
| 2379 | - { |
| 2380 | - (*GL::activeTexture) (GL_TEXTURE0_ARB + |
| 2381 | - gWindow->geometry ().texUnits + (i * 2)); |
| 2382 | - |
| 2383 | - rm.reset (); |
| 2384 | - rm[13] = bScreen->ty * bScreen->pos[i]; |
| 2385 | - rm *= tm; |
| 2386 | - |
| 2387 | - s_gen[0] = rm[0]; |
| 2388 | - s_gen[1] = rm[4]; |
| 2389 | - s_gen[2] = rm[8]; |
| 2390 | - s_gen[3] = rm[12]; |
| 2391 | - t_gen[0] = rm[1]; |
| 2392 | - t_gen[1] = rm[5]; |
| 2393 | - t_gen[2] = rm[9]; |
| 2394 | - t_gen[3] = rm[13]; |
| 2395 | - q_gen[0] = rm[3]; |
| 2396 | - q_gen[1] = rm[7]; |
| 2397 | - q_gen[2] = rm[11]; |
| 2398 | - q_gen[3] = rm[15]; |
| 2399 | - |
| 2400 | - glTexGenfv (GL_T, GL_OBJECT_PLANE, t_gen); |
| 2401 | - glTexGenfv (GL_S, GL_OBJECT_PLANE, s_gen); |
| 2402 | - glTexGenfv (GL_Q, GL_OBJECT_PLANE, q_gen); |
| 2403 | - |
| 2404 | - glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, |
| 2405 | - GL_OBJECT_LINEAR); |
| 2406 | - glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, |
| 2407 | - GL_OBJECT_LINEAR); |
| 2408 | - glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE, |
| 2409 | - GL_OBJECT_LINEAR); |
| 2410 | - |
| 2411 | - glEnable (GL_TEXTURE_GEN_S); |
| 2412 | - glEnable (GL_TEXTURE_GEN_T); |
| 2413 | - glEnable (GL_TEXTURE_GEN_Q); |
| 2414 | - |
| 2415 | - (*GL::activeTexture) (GL_TEXTURE0_ARB + |
| 2416 | - gWindow->geometry ().texUnits + |
| 2417 | - 1 + (i * 2)); |
| 2418 | - |
| 2419 | - rm.reset (); |
| 2420 | - |
| 2421 | - rm[13] = -bScreen->ty * bScreen->pos[i]; |
| 2422 | - rm *= tm; |
| 2423 | - |
| 2424 | - s_gen[0] = rm[0]; |
| 2425 | - s_gen[1] = rm[4]; |
| 2426 | - s_gen[2] = rm[8]; |
| 2427 | - s_gen[3] = rm[12]; |
| 2428 | - t_gen[0] = rm[1]; |
| 2429 | - t_gen[1] = rm[5]; |
| 2430 | - t_gen[2] = rm[9]; |
| 2431 | - t_gen[3] = rm[13]; |
| 2432 | - q_gen[0] = rm[3]; |
| 2433 | - q_gen[1] = rm[7]; |
| 2434 | - q_gen[2] = rm[11]; |
| 2435 | - q_gen[3] = rm[15]; |
| 2436 | - |
| 2437 | - glTexGenfv (GL_T, GL_OBJECT_PLANE, t_gen); |
| 2438 | - glTexGenfv (GL_S, GL_OBJECT_PLANE, s_gen); |
| 2439 | - glTexGenfv (GL_Q, GL_OBJECT_PLANE, q_gen); |
| 2440 | - |
| 2441 | - glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, |
| 2442 | - GL_OBJECT_LINEAR); |
| 2443 | - glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, |
| 2444 | - GL_OBJECT_LINEAR); |
| 2445 | - glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE, |
| 2446 | - GL_OBJECT_LINEAR); |
| 2447 | - |
| 2448 | - glEnable (GL_TEXTURE_GEN_S); |
| 2449 | - glEnable (GL_TEXTURE_GEN_T); |
| 2450 | - glEnable (GL_TEXTURE_GEN_Q); |
| 2451 | - } |
| 2452 | - |
| 2453 | - (*GL::activeTexture) (GL_TEXTURE0_ARB); |
| 2454 | - } |
| 2455 | - |
| 2456 | - } |
| 2457 | - break; |
| 2458 | - case BlurOptions::FilterMipmap: |
| 2459 | - param = dstFa.allocParameters (2); |
| 2460 | - unit = dstFa.allocTextureUnits (1); |
| 2461 | - |
| 2462 | - function = |
| 2463 | - bScreen->getDstBlurFragmentFunction (texture, param, |
| 2464 | - unit, 0, 0); |
| 2465 | - if (function) |
| 2466 | - { |
| 2467 | - float lod = |
| 2468 | - bScreen->optionGetMipmapLod (); |
| 2469 | - |
| 2470 | - dstFa.addFunction (function); |
| 2471 | - |
| 2472 | - (*GL::activeTexture) (GL_TEXTURE0_ARB + unit); |
| 2473 | - glBindTexture (bScreen->target, bScreen->texture[0]); |
| 2474 | - (*GL::activeTexture) (GL_TEXTURE0_ARB); |
| 2475 | - |
| 2476 | - (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, |
| 2477 | - param, |
| 2478 | - bScreen->tx, bScreen->ty, |
| 2479 | - 0.0f, lod); |
| 2480 | - |
| 2481 | - (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, |
| 2482 | - param + 1, |
| 2483 | - threshold, threshold, |
| 2484 | - threshold, threshold); |
| 2485 | - } |
| 2486 | - break; |
| 2487 | - } |
| 2488 | + setupShadersAndUniformsForDstBlur (texture, |
| 2489 | + gWindow, |
| 2490 | + bScreen, |
| 2491 | + unit, |
| 2492 | + iTC, |
| 2493 | + this->state[state].threshold); |
| 2494 | |
| 2495 | if (this->state[state].clipped || |
| 2496 | (!bScreen->blurOcclusion && !clip.isEmpty ())) |
| 2497 | { |
| 2498 | glEnable (GL_STENCIL_TEST); |
| 2499 | |
| 2500 | + /* Don't touch the stencil buffer */ |
| 2501 | glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); |
| 2502 | - glStencilFunc (GL_EQUAL, 0x1, ~0); |
| 2503 | - |
| 2504 | - /* draw region with destination blur */ |
| 2505 | - gWindow->glDrawTexture (texture, dstFa, mask); |
| 2506 | - |
| 2507 | - glStencilFunc (GL_EQUAL, 0, ~0); |
| 2508 | + |
| 2509 | + /* Draw region with blur only where the stencil test passes */ |
| 2510 | + glStencilFunc (GL_EQUAL, 1, 1); |
| 2511 | + |
| 2512 | + /* draw region with destination blur - we are relying |
| 2513 | + * on a fairly awkward side-effect here which clears our |
| 2514 | + * active shader once this call is complete */ |
| 2515 | + gWindow->glDrawTexture (texture, matrix, attrib, mask); |
| 2516 | + |
| 2517 | + /* Allow drawing in everywhere but where we just drew */ |
| 2518 | + glStencilFunc (GL_EQUAL, 0, 1); |
| 2519 | |
| 2520 | /* draw region without destination blur */ |
| 2521 | - gWindow->glDrawTexture (texture, fa, mask); |
| 2522 | + gWindow->glDrawTexture (texture, matrix, attrib, mask); |
| 2523 | |
| 2524 | glDisable (GL_STENCIL_TEST); |
| 2525 | } |
| 2526 | else |
| 2527 | { |
| 2528 | /* draw with destination blur */ |
| 2529 | - gWindow->glDrawTexture (texture, dstFa, mask); |
| 2530 | + gWindow->glDrawTexture (texture, matrix, attrib, mask); |
| 2531 | } |
| 2532 | } |
| 2533 | else |
| 2534 | { |
| 2535 | - gWindow->glDrawTexture (texture, fa, mask); |
| 2536 | + gWindow->glDrawTexture (texture, matrix, attrib, mask); |
| 2537 | } |
| 2538 | |
| 2539 | if (unit) |
| 2540 | { |
| 2541 | - (*GL::activeTexture) (GL_TEXTURE0_ARB + unit); |
| 2542 | - glBindTexture (bScreen->target, 0); |
| 2543 | - (*GL::activeTexture) (GL_TEXTURE0_ARB + unit + 1); |
| 2544 | - glBindTexture (bScreen->target, 0); |
| 2545 | - (*GL::activeTexture) (GL_TEXTURE0_ARB); |
| 2546 | + (*GL::activeTexture) (GL_TEXTURE0 + unit); |
| 2547 | + bScreen->texture[0]->disable (); |
| 2548 | + (*GL::activeTexture) (GL_TEXTURE0 + unit + 1); |
| 2549 | + if (bScreen->fbo && |
| 2550 | + bScreen->fbo->tex ()) |
| 2551 | + bScreen->fbo->tex ()->disable (); |
| 2552 | + (*GL::activeTexture) (GL_TEXTURE0); |
| 2553 | } |
| 2554 | |
| 2555 | +#if INDEPENDENT_TEX_SUPPORTED |
| 2556 | if (iTC) |
| 2557 | { |
| 2558 | int i; |
| 2559 | for (i = gWindow->geometry ().texUnits; |
| 2560 | i < gWindow->geometry ().texUnits + (2 * iTC); i++) |
| 2561 | { |
| 2562 | - (*GL::activeTexture) (GL_TEXTURE0_ARB + i); |
| 2563 | + (*GL::activeTexture) (GL_TEXTURE0 + i); |
| 2564 | glDisable (GL_TEXTURE_GEN_S); |
| 2565 | glDisable (GL_TEXTURE_GEN_T); |
| 2566 | glDisable (GL_TEXTURE_GEN_Q); |
| 2567 | } |
| 2568 | - (*GL::activeTexture) (GL_TEXTURE0_ARB); |
| 2569 | + (*GL::activeTexture) (GL_TEXTURE0); |
| 2570 | } |
| 2571 | +#endif |
| 2572 | } |
| 2573 | else |
| 2574 | { |
| 2575 | - gWindow->glDrawTexture (texture, attrib, mask); |
| 2576 | + gWindow->glDrawTexture (texture, matrix, attrib, mask); |
| 2577 | } |
| 2578 | } |
| 2579 | |
| 2580 | @@ -2115,7 +2140,7 @@ |
| 2581 | screen->activeWindow ()); |
| 2582 | |
| 2583 | w = screen->findWindow (xid); |
| 2584 | - if (w && GL::fragmentProgram) |
| 2585 | + if (w && GL::shaders) |
| 2586 | { |
| 2587 | BLUR_SCREEN (screen); |
| 2588 | BLUR_WINDOW (w); |
| 2589 | @@ -2175,7 +2200,7 @@ |
| 2590 | cScreen->damageScreen (); |
| 2591 | break; |
| 2592 | case BlurOptions::AlphaBlur: |
| 2593 | - if (GL::fragmentProgram && optionGetAlphaBlur ()) |
| 2594 | + if (GL::shaders && optionGetAlphaBlur ()) |
| 2595 | alphaBlur = true; |
| 2596 | else |
| 2597 | alphaBlur = false; |
| 2598 | @@ -2228,12 +2253,15 @@ |
| 2599 | dstBlurFunctions (0), |
| 2600 | output (NULL), |
| 2601 | count (0), |
| 2602 | - program (0), |
| 2603 | maxTemp (32), |
| 2604 | - fbo (0), |
| 2605 | - fboStatus (0) |
| 2606 | + fbo (new GLFramebufferObject ()), |
| 2607 | + oldDrawFramebuffer (NULL), |
| 2608 | + determineProjectedBlurRegionsPass (false), |
| 2609 | + damageQuery (cScreen->getDamageQuery (boost::bind ( |
| 2610 | + &BlurScreen::markAreaDirty, |
| 2611 | + this, |
| 2612 | + _1))) |
| 2613 | { |
| 2614 | - |
| 2615 | blurAtom[BLUR_STATE_CLIENT] = |
| 2616 | XInternAtom (screen->dpy (), "_COMPIZ_WM_WINDOW_BLUR", 0); |
| 2617 | blurAtom[BLUR_STATE_DECOR] = |
| 2618 | @@ -2242,27 +2270,20 @@ |
| 2619 | blurTime = 1000.0f / optionGetBlurSpeed (); |
| 2620 | blurOcclusion = optionGetOcclusion (); |
| 2621 | |
| 2622 | - for (int i = 0; i < 2; i++) |
| 2623 | - texture[i] = 0; |
| 2624 | - |
| 2625 | glGetIntegerv (GL_STENCIL_BITS, &stencilBits); |
| 2626 | if (!stencilBits) |
| 2627 | compLogMessage ("blur", CompLogLevelWarn, |
| 2628 | "No stencil buffer. Region based blur disabled"); |
| 2629 | |
| 2630 | - /* We need GL_ARB_fragment_program for blur */ |
| 2631 | - if (GL::fragmentProgram) |
| 2632 | + /* We need GL_ARB_shading_language_100 for blur */ |
| 2633 | + if (GL::shaders) |
| 2634 | alphaBlur = optionGetAlphaBlur (); |
| 2635 | else |
| 2636 | alphaBlur = false; |
| 2637 | |
| 2638 | - if (GL::fragmentProgram) |
| 2639 | + if (GL::shaders) |
| 2640 | { |
| 2641 | - int tmp[4]; |
| 2642 | - GL::getProgramiv (GL_FRAGMENT_PROGRAM_ARB, |
| 2643 | - GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, |
| 2644 | - tmp); |
| 2645 | - maxTemp = tmp[0]; |
| 2646 | + maxTemp = 1024; // FIXME!!!!!!! |
| 2647 | } |
| 2648 | |
| 2649 | updateFilterRadius (); |
| 2650 | @@ -2277,20 +2298,7 @@ |
| 2651 | |
| 2652 | BlurScreen::~BlurScreen () |
| 2653 | { |
| 2654 | - foreach (BlurFunction &bf, srcBlurFunctions) |
| 2655 | - GLFragment::destroyFragmentFunction (bf.id); |
| 2656 | - foreach (BlurFunction &bf, dstBlurFunctions) |
| 2657 | - GLFragment::destroyFragmentFunction (bf.id); |
| 2658 | - |
| 2659 | cScreen->damageScreen (); |
| 2660 | - |
| 2661 | - if (fbo) |
| 2662 | - (*GL::deleteFramebuffers) (1, &fbo); |
| 2663 | - |
| 2664 | - for (int i = 0; i < 2; i++) |
| 2665 | - if (texture[i]) |
| 2666 | - glDeleteTextures (1, &texture[i]); |
| 2667 | - |
| 2668 | } |
| 2669 | |
| 2670 | BlurWindow::BlurWindow (CompWindow *w) : |
| 2671 | @@ -2329,10 +2337,11 @@ |
| 2672 | bool |
| 2673 | BlurPluginVTable::init () |
| 2674 | { |
| 2675 | - if (CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) && |
| 2676 | - CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) && |
| 2677 | - CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI)) |
| 2678 | - return true; |
| 2679 | + if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) | |
| 2680 | + !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) | |
| 2681 | + !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI)) |
| 2682 | + return false; |
| 2683 | |
| 2684 | - return false; |
| 2685 | + return true; |
| 2686 | } |
| 2687 | + |
| 2688 | |
| 2689 | === modified file 'plugins/blur/src/blur.h' |
| 2690 | --- plugins/blur/src/blur.h 2012-09-07 22:37:20 +0000 |
| 2691 | +++ plugins/blur/src/blur.h 2016-05-14 02:33:05 +0000 |
| 2692 | @@ -23,32 +23,35 @@ |
| 2693 | * Author: David Reveman <davidr@novell.com> |
| 2694 | */ |
| 2695 | |
| 2696 | +#include <iosfwd> |
| 2697 | +#include <boost/shared_ptr.hpp> |
| 2698 | + |
| 2699 | +#include <stdlib.h> |
| 2700 | +#include <string.h> |
| 2701 | +#include <math.h> |
| 2702 | +#include <X11/Xatom.h> |
| 2703 | + |
| 2704 | #include "blur_options.h" |
| 2705 | |
| 2706 | #include <composite/composite.h> |
| 2707 | #include <opengl/opengl.h> |
| 2708 | +#include <opengl/program.h> |
| 2709 | #include <decoration.h> |
| 2710 | |
| 2711 | -#include <stdlib.h> |
| 2712 | -#include <string.h> |
| 2713 | -#include <math.h> |
| 2714 | - |
| 2715 | - |
| 2716 | -#include <X11/Xatom.h> |
| 2717 | -#include <GL/glu.h> |
| 2718 | - |
| 2719 | - |
| 2720 | -extern const unsigned short BLUR_GAUSSIAN_RADIUS_MAX; |
| 2721 | - |
| 2722 | -struct BlurFunction { |
| 2723 | - |
| 2724 | - GLFragment::FunctionId id; |
| 2725 | - |
| 2726 | + |
| 2727 | +const unsigned short BLUR_GAUSSIAN_RADIUS_MAX = 15; |
| 2728 | + |
| 2729 | +const unsigned short BLUR_STATE_CLIENT = 0; |
| 2730 | +const unsigned short BLUR_STATE_DECOR = 1; |
| 2731 | +const unsigned short BLUR_STATE_NUM = 2; |
| 2732 | + |
| 2733 | +struct BlurFunction |
| 2734 | +{ |
| 2735 | + CompString shader; |
| 2736 | int target; |
| 2737 | - int param; |
| 2738 | - int unit; |
| 2739 | int startTC; |
| 2740 | int numITC; |
| 2741 | + int saturation; |
| 2742 | }; |
| 2743 | |
| 2744 | struct BlurBox { |
| 2745 | @@ -56,10 +59,6 @@ |
| 2746 | decor_point_t p2; |
| 2747 | }; |
| 2748 | |
| 2749 | -extern const unsigned short BLUR_STATE_CLIENT; |
| 2750 | -extern const unsigned short BLUR_STATE_DECOR; |
| 2751 | -extern const unsigned short BLUR_STATE_NUM; |
| 2752 | - |
| 2753 | struct BlurState { |
| 2754 | int threshold; |
| 2755 | std::vector<BlurBox> box; |
| 2756 | @@ -88,6 +87,8 @@ |
| 2757 | void preparePaint (int); |
| 2758 | void donePaint (); |
| 2759 | |
| 2760 | + void damageCutoff (); |
| 2761 | + |
| 2762 | bool glPaintOutput (const GLScreenPaintAttrib &, |
| 2763 | const GLMatrix &, const CompRegion &, |
| 2764 | CompOutput *, unsigned int); |
| 2765 | @@ -99,12 +100,11 @@ |
| 2766 | void updateFilterRadius (); |
| 2767 | void blurReset (); |
| 2768 | |
| 2769 | - GLFragment::FunctionId getSrcBlurFragmentFunction (GLTexture *, int); |
| 2770 | - GLFragment::FunctionId getDstBlurFragmentFunction (GLTexture *texture, |
| 2771 | - int param, |
| 2772 | - int unit, |
| 2773 | - int numITC, |
| 2774 | - int startTC); |
| 2775 | + const CompString & getSrcBlurFragmentFunction (GLTexture *); |
| 2776 | + const CompString & getDstBlurFragmentFunction (GLTexture *texture, |
| 2777 | + int unit, |
| 2778 | + int numITC, |
| 2779 | + int startTC); |
| 2780 | |
| 2781 | bool projectVertices (CompOutput *output, |
| 2782 | const GLMatrix &transform, |
| 2783 | @@ -112,8 +112,9 @@ |
| 2784 | float *scr, |
| 2785 | int n); |
| 2786 | |
| 2787 | - bool loadFragmentProgram (GLuint *program, |
| 2788 | - const char *string); |
| 2789 | + bool loadFragmentProgram (boost::shared_ptr <GLProgram> &program, |
| 2790 | + const char *vertex, |
| 2791 | + const char *fragment); |
| 2792 | |
| 2793 | bool loadFilterProgram (int numITC); |
| 2794 | |
| 2795 | @@ -152,24 +153,34 @@ |
| 2796 | CompOutput *output; |
| 2797 | int count; |
| 2798 | |
| 2799 | - GLuint texture[2]; |
| 2800 | + GLTexture::List texture; |
| 2801 | |
| 2802 | - GLenum target; |
| 2803 | float tx; |
| 2804 | float ty; |
| 2805 | int width; |
| 2806 | int height; |
| 2807 | |
| 2808 | - GLuint program; |
| 2809 | + boost::shared_ptr <GLProgram> program; |
| 2810 | int maxTemp; |
| 2811 | - GLuint fbo; |
| 2812 | - bool fboStatus; |
| 2813 | + boost::shared_ptr <GLFramebufferObject> fbo; |
| 2814 | + |
| 2815 | + GLFramebufferObject *oldDrawFramebuffer; |
| 2816 | |
| 2817 | float amp[BLUR_GAUSSIAN_RADIUS_MAX]; |
| 2818 | float pos[BLUR_GAUSSIAN_RADIUS_MAX]; |
| 2819 | int numTexop; |
| 2820 | |
| 2821 | GLMatrix mvp; |
| 2822 | + |
| 2823 | + bool determineProjectedBlurRegionsPass; |
| 2824 | + bool allowAreaDirtyOnOwnDamageBuffer; |
| 2825 | + CompRegion backbufferUpdateRegionThisFrame; |
| 2826 | + |
| 2827 | + compiz::composite::buffertracking::AgeDamageQuery::Ptr damageQuery; |
| 2828 | + |
| 2829 | + private: |
| 2830 | + |
| 2831 | + bool markAreaDirty (const CompRegion &r); |
| 2832 | }; |
| 2833 | |
| 2834 | class BlurWindow : |
| 2835 | @@ -188,11 +199,16 @@ |
| 2836 | |
| 2837 | bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &, |
| 2838 | const CompRegion &, unsigned int); |
| 2839 | - bool glDraw (const GLMatrix &, GLFragment::Attrib &, |
| 2840 | + void glTransformationComplete (const GLMatrix &matrix, |
| 2841 | + const CompRegion ®ion, |
| 2842 | + unsigned int mask); |
| 2843 | + |
| 2844 | + bool glDraw (const GLMatrix &, const GLWindowPaintAttrib &, |
| 2845 | const CompRegion &, unsigned int); |
| 2846 | - void glDrawTexture (GLTexture *texture, GLFragment::Attrib &, |
| 2847 | + void glDrawTexture (GLTexture *texture, |
| 2848 | + const GLMatrix &, |
| 2849 | + const GLWindowPaintAttrib &, |
| 2850 | unsigned int); |
| 2851 | - |
| 2852 | void updateRegion (); |
| 2853 | |
| 2854 | void setBlur (int state, |
| 2855 | @@ -206,9 +222,13 @@ |
| 2856 | void projectRegion (CompOutput *output, |
| 2857 | const GLMatrix &transform); |
| 2858 | |
| 2859 | + void determineBlurRegion (int filter, |
| 2860 | + const GLMatrix &transform, |
| 2861 | + int clientThreshold); |
| 2862 | + |
| 2863 | bool updateDstTexture (const GLMatrix &transform, |
| 2864 | CompRect *pExtents, |
| 2865 | - int clientThreshold); |
| 2866 | + unsigned int mask); |
| 2867 | |
| 2868 | public: |
| 2869 | CompWindow *window; |
| 2870 | @@ -225,6 +245,7 @@ |
| 2871 | |
| 2872 | CompRegion region; |
| 2873 | CompRegion clip; |
| 2874 | + CompRegion projectedBlurRegion; |
| 2875 | }; |
| 2876 | |
| 2877 | #define BLUR_SCREEN(s) \ |
| 2878 | |
| 2879 | === modified file 'plugins/opengl/DRIVERS' |
| 2880 | --- plugins/opengl/DRIVERS 2013-02-17 07:28:12 +0000 |
| 2881 | +++ plugins/opengl/DRIVERS 2016-05-14 02:33:05 +0000 |
| 2882 | @@ -74,3 +74,13 @@ |
| 2883 | RESOLVED. WORKAROUND: force the usage of the copy-to-texture path |
| 2884 | when using this driver ("Chromium") and binding an externally |
| 2885 | managed pixmap to a texture |
| 2886 | + |
| 2887 | +vmwgfx |
| 2888 | +====== |
| 2889 | + |
| 2890 | + 1. vmwgfx does not implement glGenerateMipmap for FBO-backed |
| 2891 | + textures. |
| 2892 | + |
| 2893 | + RESOLVED. WORKAROUND: do not use glGenerateMipmap with vmwgfx. This |
| 2894 | + means that some functionality, like smoothed blurs will not be |
| 2895 | + available on this driver. |
| 2896 | |
| 2897 | === modified file 'plugins/opengl/include/opengl/opengl.h' |
| 2898 | --- plugins/opengl/include/opengl/opengl.h 2015-10-26 17:15:43 +0000 |
| 2899 | +++ plugins/opengl/include/opengl/opengl.h 2016-05-14 02:33:05 +0000 |
| 2900 | @@ -59,7 +59,7 @@ |
| 2901 | #include <opengl/programcache.h> |
| 2902 | #include <opengl/shadercache.h> |
| 2903 | |
| 2904 | -#define COMPIZ_OPENGL_ABI 7 |
| 2905 | +#define COMPIZ_OPENGL_ABI 8 |
| 2906 | |
| 2907 | /* |
| 2908 | * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but |
| 2909 | @@ -851,6 +851,8 @@ |
| 2910 | |
| 2911 | bool glInitContext (XVisualInfo *); |
| 2912 | |
| 2913 | + bool driverHasBrokenFBOMipmaps () const; |
| 2914 | + |
| 2915 | WRAPABLE_HND (0, GLScreenInterface, bool, glPaintOutput, |
| 2916 | const GLScreenPaintAttrib &, const GLMatrix &, |
| 2917 | const CompRegion &, CompOutput *, unsigned int); |
| 2918 | @@ -957,12 +959,20 @@ |
| 2919 | unsigned int max = MAXSHORT); |
| 2920 | virtual void glDrawTexture (GLTexture *texture, const GLMatrix &, |
| 2921 | const GLWindowPaintAttrib &, unsigned int); |
| 2922 | + |
| 2923 | + /** |
| 2924 | + * Hookable function to notify transformation was complete, plugins |
| 2925 | + * should use the results of transformation from glPaint here |
| 2926 | + */ |
| 2927 | + virtual void glTransformationComplete (const GLMatrix &matrix, |
| 2928 | + const CompRegion ®ion, |
| 2929 | + unsigned int mask); |
| 2930 | }; |
| 2931 | |
| 2932 | extern template class PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI>; |
| 2933 | |
| 2934 | class GLWindow : |
| 2935 | - public WrapableHandler<GLWindowInterface, 4>, |
| 2936 | + public WrapableHandler<GLWindowInterface, 5>, |
| 2937 | public PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI> |
| 2938 | { |
| 2939 | public: |
| 2940 | @@ -1041,6 +1051,8 @@ |
| 2941 | WRAPABLE_HND (3, GLWindowInterface, void, glDrawTexture, |
| 2942 | GLTexture *texture, const GLMatrix &, |
| 2943 | const GLWindowPaintAttrib &, unsigned int); |
| 2944 | + WRAPABLE_HND (4, GLWindowInterface, void, glTransformationComplete, |
| 2945 | + const GLMatrix &, const CompRegion &, unsigned int); |
| 2946 | |
| 2947 | friend class GLScreen; |
| 2948 | friend class PrivateGLScreen; |
| 2949 | |
| 2950 | === modified file 'plugins/opengl/include/opengl/program.h' |
| 2951 | --- plugins/opengl/include/opengl/program.h 2012-05-17 10:41:21 +0000 |
| 2952 | +++ plugins/opengl/include/opengl/program.h 2016-05-14 02:33:05 +0000 |
| 2953 | @@ -40,7 +40,7 @@ |
| 2954 | class GLProgram |
| 2955 | { |
| 2956 | public: |
| 2957 | - GLProgram (CompString &vertexShader, CompString &fragmentShader); |
| 2958 | + GLProgram (const CompString &vertexShader, const CompString &fragmentShader); |
| 2959 | ~GLProgram (); |
| 2960 | |
| 2961 | bool valid (); |
| 2962 | |
| 2963 | === modified file 'plugins/opengl/include/opengl/vertexbuffer.h' |
| 2964 | --- plugins/opengl/include/opengl/vertexbuffer.h 2012-08-14 06:33:22 +0000 |
| 2965 | +++ plugins/opengl/include/opengl/vertexbuffer.h 2016-05-14 02:33:05 +0000 |
| 2966 | @@ -89,6 +89,7 @@ |
| 2967 | void addTexCoords (GLuint texture, |
| 2968 | GLuint nTexcoords, |
| 2969 | const GLfloat *texcoords); |
| 2970 | + GLuint countTextures () const; |
| 2971 | |
| 2972 | void addUniform (const char *name, GLfloat value); |
| 2973 | void addUniform (const char *name, GLint value); |
| 2974 | |
| 2975 | === modified file 'plugins/opengl/src/paint.cpp' |
| 2976 | --- plugins/opengl/src/paint.cpp 2015-04-07 14:20:32 +0000 |
| 2977 | +++ plugins/opengl/src/paint.cpp 2016-05-14 02:33:05 +0000 |
| 2978 | @@ -1367,6 +1367,14 @@ |
| 2979 | return true; |
| 2980 | } |
| 2981 | |
| 2982 | +void |
| 2983 | +GLWindow::glTransformationComplete (const GLMatrix &matrix, |
| 2984 | + const CompRegion ®, |
| 2985 | + unsigned int mask) |
| 2986 | +{ |
| 2987 | + WRAPABLE_HND_FUNCTN (glTransformationComplete, matrix, reg, mask); |
| 2988 | +} |
| 2989 | + |
| 2990 | bool |
| 2991 | GLWindow::glPaint (const GLWindowPaintAttrib &attrib, |
| 2992 | const GLMatrix &transform, |
| 2993 | @@ -1384,6 +1392,8 @@ |
| 2994 | |
| 2995 | priv->lastMask = mask; |
| 2996 | |
| 2997 | + glTransformationComplete (transform, region, mask); |
| 2998 | + |
| 2999 | if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) |
| 3000 | { |
| 3001 | if (mask & PAINT_WINDOW_TRANSFORMED_MASK) |
| 3002 | |
| 3003 | === modified file 'plugins/opengl/src/privates.h' |
| 3004 | --- plugins/opengl/src/privates.h 2015-10-26 17:15:43 +0000 |
| 3005 | +++ plugins/opengl/src/privates.h 2016-05-14 02:33:05 +0000 |
| 3006 | @@ -131,6 +131,7 @@ |
| 3007 | virtual ~FrameProvider () {} |
| 3008 | |
| 3009 | virtual GLuint getCurrentFrame () = 0; |
| 3010 | + virtual void useCurrentFrame () = 0; |
| 3011 | virtual void endFrame () = 0; |
| 3012 | |
| 3013 | virtual bool providesPersistence () = 0; |
| 3014 | @@ -268,6 +269,8 @@ |
| 3015 | std::vector<XToGLSync*>::size_type currentSyncNum; |
| 3016 | XToGLSync *currentSync; |
| 3017 | std::vector<XToGLSync*>::size_type warmupSyncs; |
| 3018 | + |
| 3019 | + bool driverHasBrokenFBOMipmapImplementation; |
| 3020 | }; |
| 3021 | |
| 3022 | class PrivateGLWindow : |
| 3023 | |
| 3024 | === modified file 'plugins/opengl/src/program.cpp' |
| 3025 | --- plugins/opengl/src/program.cpp 2012-12-04 12:15:34 +0000 |
| 3026 | +++ plugins/opengl/src/program.cpp 2016-05-14 02:33:05 +0000 |
| 3027 | @@ -69,7 +69,7 @@ |
| 3028 | } |
| 3029 | } |
| 3030 | |
| 3031 | -static bool compileShader (GLuint *shader, GLenum type, CompString &source) |
| 3032 | +static bool compileShader (GLuint *shader, GLenum type, const CompString &source) |
| 3033 | { |
| 3034 | const GLchar *data; |
| 3035 | GLint status; |
| 3036 | @@ -84,7 +84,7 @@ |
| 3037 | return (status == GL_TRUE); |
| 3038 | } |
| 3039 | |
| 3040 | -GLProgram::GLProgram (CompString &vertexShader, CompString &fragmentShader) : |
| 3041 | +GLProgram::GLProgram (const CompString &vertexShader, const CompString &fragmentShader) : |
| 3042 | priv (new PrivateProgram ()) |
| 3043 | { |
| 3044 | GLuint vertex, fragment; |
| 3045 | |
| 3046 | === modified file 'plugins/opengl/src/screen.cpp' |
| 3047 | --- plugins/opengl/src/screen.cpp 2015-10-26 17:15:43 +0000 |
| 3048 | +++ plugins/opengl/src/screen.cpp 2016-05-14 02:33:05 +0000 |
| 3049 | @@ -345,6 +345,10 @@ |
| 3050 | return age; |
| 3051 | } |
| 3052 | |
| 3053 | + void useCurrentFrame () |
| 3054 | + { |
| 3055 | + } |
| 3056 | + |
| 3057 | void endFrame () |
| 3058 | { |
| 3059 | } |
| 3060 | @@ -436,6 +440,10 @@ |
| 3061 | return 0; |
| 3062 | } |
| 3063 | |
| 3064 | + void useCurrentFrame () |
| 3065 | + { |
| 3066 | + } |
| 3067 | + |
| 3068 | void endFrame () |
| 3069 | { |
| 3070 | } |
| 3071 | @@ -468,12 +476,14 @@ |
| 3072 | |
| 3073 | unsigned int getCurrentFrame () |
| 3074 | { |
| 3075 | + return mAge; |
| 3076 | + } |
| 3077 | + |
| 3078 | + void useCurrentFrame () |
| 3079 | + { |
| 3080 | /* We are now using this buffer, reset |
| 3081 | * age back to zero */ |
| 3082 | - unsigned int lastAge = mAge; |
| 3083 | mAge = 0; |
| 3084 | - |
| 3085 | - return lastAge; |
| 3086 | } |
| 3087 | |
| 3088 | void endFrame () |
| 3089 | @@ -526,6 +536,14 @@ |
| 3090 | return mBackbuffer->getCurrentFrame (); |
| 3091 | } |
| 3092 | |
| 3093 | + void useCurrentFrame () |
| 3094 | + { |
| 3095 | + if (mPPRequired ()) |
| 3096 | + mScratchbuffer->useCurrentFrame (); |
| 3097 | + else |
| 3098 | + mBackbuffer->useCurrentFrame (); |
| 3099 | + } |
| 3100 | + |
| 3101 | void endFrame () |
| 3102 | { |
| 3103 | mScratchbuffer->endFrame (); |
| 3104 | @@ -896,6 +914,20 @@ |
| 3105 | priv->incorrectRefreshRate = true; |
| 3106 | } |
| 3107 | |
| 3108 | + if (glVendor != NULL && strstr (glVendor, "VMware") && |
| 3109 | + glRenderer != NULL && strstr (glRenderer, "on SVGA3D")) |
| 3110 | + { |
| 3111 | + /* vmwgfx has an incomplete glGenerateMipmap implementation. |
| 3112 | + * It does not seem to support generating mipmaps for |
| 3113 | + * FBO backed textures - instead it raises SIGABRT with |
| 3114 | + * an exception stating that the command does not exist. |
| 3115 | + * |
| 3116 | + * This is actually supported in the spec, it just seems |
| 3117 | + * to be unavailable in the driver. |
| 3118 | + */ |
| 3119 | + priv->driverHasBrokenFBOMipmapImplementation = true; |
| 3120 | + } |
| 3121 | + |
| 3122 | if (strstr (glExtensions, "GL_ARB_texture_non_power_of_two")) |
| 3123 | GL::textureNonPowerOfTwo = true; |
| 3124 | GL::textureNonPowerOfTwoMipmap = GL::textureNonPowerOfTwo; |
| 3125 | @@ -1163,6 +1195,12 @@ |
| 3126 | return true; |
| 3127 | } |
| 3128 | |
| 3129 | +bool |
| 3130 | +GLScreen::driverHasBrokenFBOMipmaps () const |
| 3131 | +{ |
| 3132 | + return priv->driverHasBrokenFBOMipmapImplementation; |
| 3133 | +} |
| 3134 | + |
| 3135 | |
| 3136 | template class PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>; |
| 3137 | |
| 3138 | @@ -1536,7 +1574,8 @@ |
| 3139 | prevBlacklisted (false), |
| 3140 | currentSyncNum (0), |
| 3141 | currentSync (0), |
| 3142 | - warmupSyncs (0) |
| 3143 | + warmupSyncs (0), |
| 3144 | + driverHasBrokenFBOMipmapImplementation (false) |
| 3145 | { |
| 3146 | ScreenInterface::setHandler (screen); |
| 3147 | CompositeScreenInterface::setHandler (cScreen); |
| 3148 | @@ -2608,6 +2647,7 @@ |
| 3149 | PrivateGLScreen::damageCutoff () |
| 3150 | { |
| 3151 | cScreen->applyDamageForFrameAge (frameProvider->getCurrentFrame ()); |
| 3152 | + frameProvider->useCurrentFrame (); |
| 3153 | cScreen->damageCutoff (); |
| 3154 | } |
| 3155 | |
| 3156 | |
| 3157 | === modified file 'plugins/opengl/src/shadercache.cpp' |
| 3158 | --- plugins/opengl/src/shadercache.cpp 2014-10-30 12:47:25 +0000 |
| 3159 | +++ plugins/opengl/src/shadercache.cpp 2016-05-14 02:33:05 +0000 |
| 3160 | @@ -232,10 +232,11 @@ |
| 3161 | else if (params.color == GLShaderVariableVarying) |
| 3162 | ss << "vColor *"; |
| 3163 | |
| 3164 | - for (int i = 0; i < params.numTextures; i++) |
| 3165 | - ss << " texture2D(texture" << i << ", vTexCoord" << i << ") *"; |
| 3166 | - |
| 3167 | - ss << " 1.0;\n"; |
| 3168 | + /* Sample first texture only */ |
| 3169 | + if (params.numTextures) |
| 3170 | + ss << " texture2D(texture0, vTexCoord0);\n"; |
| 3171 | + else |
| 3172 | + ss << " 1.0;\n"; |
| 3173 | |
| 3174 | if (params.saturation) { |
| 3175 | ss << "vec3 desaturated = color.rgb * vec3 (0.30, 0.59, 0.11);\n" << |
| 3176 | |
| 3177 | === modified file 'plugins/opengl/src/vertexbuffer.cpp' |
| 3178 | --- plugins/opengl/src/vertexbuffer.cpp 2015-04-29 11:15:48 +0000 |
| 3179 | +++ plugins/opengl/src/vertexbuffer.cpp 2016-05-14 02:33:05 +0000 |
| 3180 | @@ -240,6 +240,11 @@ |
| 3181 | data.push_back (texcoords[i]); |
| 3182 | } |
| 3183 | |
| 3184 | +GLuint GLVertexBuffer::countTextures () const |
| 3185 | +{ |
| 3186 | + return priv->nTextures; |
| 3187 | +} |
| 3188 | + |
| 3189 | void GLVertexBuffer::addUniform (const char *name, GLfloat value) |
| 3190 | { |
| 3191 | // we're casting to double here to make our template va_arg happy |
| 3192 | |
| 3193 | === modified file 'plugins/opengl/src/window.cpp' |
| 3194 | --- plugins/opengl/src/window.cpp 2014-10-30 12:47:25 +0000 |
| 3195 | +++ plugins/opengl/src/window.cpp 2016-05-14 02:33:05 +0000 |
| 3196 | @@ -210,6 +210,12 @@ |
| 3197 | priv->needsRebind = true; |
| 3198 | } |
| 3199 | |
| 3200 | +void |
| 3201 | +GLWindowInterface::glTransformationComplete (const GLMatrix &matrix, |
| 3202 | + const CompRegion ®ion, |
| 3203 | + unsigned int mask) |
| 3204 | + WRAPABLE_DEF (glTransformationComplete, matrix, region, mask) |
| 3205 | + |
| 3206 | bool |
| 3207 | GLWindowInterface::glPaint (const GLWindowPaintAttrib &attrib, |
| 3208 | const GLMatrix &transform, |

FAILED: Continuous integration, rev:4018 jenkins. qa.ubuntu. com/job/ compiz- ci/126/ jenkins. qa.ubuntu. com/job/ compiz- xenial- amd64-ci/ 17/console jenkins. qa.ubuntu. com/job/ compiz- xenial- armhf-ci/ 17 jenkins. qa.ubuntu. com/job/ compiz- xenial- i386-ci/ 17/console
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/compiz- ci/126/ rebuild
http://