Merge lp:~smspillaz/compiz/compiz.revenge-of-the-blur-plugin into lp:compiz/0.9.12

Proposed by Sam Spilsbury
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
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+294604@code.launchpad.net

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 glTransformationComplete to GLWindow. Other than that there's very little impact on other plugins.

To post a comment you must log in.
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
4019. By Sam Spilsbury <email address hidden> on 2016-05-13

debian: Install the blur plugin as part of compiz-plugins

PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
4020. By Sam Spilsbury <email address hidden> on 2016-05-14

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 :
review: Approve (continuous-integration)
Marco Trevisan (Treviño) (3v1n0) wrote :

Nice cleanup, thanks a lot.

ABI changes are in fact not relevant for other parts.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/compiz-plugins.install'
--- debian/compiz-plugins.install 2015-07-24 16:28:37 +0000
+++ debian/compiz-plugins.install 2016-05-14 02:33:05 +0000
@@ -4,6 +4,8 @@
4usr/share/compiz/*annotate.*4usr/share/compiz/*annotate.*
5usr/lib/*/compiz/*bench.*5usr/lib/*/compiz/*bench.*
6usr/share/compiz/*bench.*6usr/share/compiz/*bench.*
7usr/lib/*/compiz/*blur.*
8usr/share/compiz/*blur.*
7usr/lib/*/compiz/*clone.*9usr/lib/*/compiz/*clone.*
8usr/share/compiz/*clone.*10usr/share/compiz/*clone.*
9usr/lib/*/compiz/*crashhandler.*11usr/lib/*/compiz/*crashhandler.*
1012
=== modified file 'plugins/CMakeLists.txt'
--- plugins/CMakeLists.txt 2016-03-03 14:23:38 +0000
+++ plugins/CMakeLists.txt 2016-05-14 02:33:05 +0000
@@ -12,7 +12,6 @@
12# temporarily disable plugins that aren't ported yet12# temporarily disable plugins that aren't ported yet
13set (COMPIZ_DISABLE_PLUGIN_ANIMATIONADDON ON)13set (COMPIZ_DISABLE_PLUGIN_ANIMATIONADDON ON)
14set (COMPIZ_DISABLE_PLUGIN_BICUBIC ON)14set (COMPIZ_DISABLE_PLUGIN_BICUBIC ON)
15set (COMPIZ_DISABLE_PLUGIN_BLUR ON)
16set (COMPIZ_DISABLE_PLUGIN_COLORFILTER ON)15set (COMPIZ_DISABLE_PLUGIN_COLORFILTER ON)
17set (COMPIZ_DISABLE_PLUGIN_GROUP ON)16set (COMPIZ_DISABLE_PLUGIN_GROUP ON)
18set (COMPIZ_DISABLE_PLUGIN_LOGINOUT ON)17set (COMPIZ_DISABLE_PLUGIN_LOGINOUT ON)
1918
=== modified file 'plugins/blur/CMakeLists.txt'
--- plugins/blur/CMakeLists.txt 2012-05-17 10:41:21 +0000
+++ plugins/blur/CMakeLists.txt 2016-05-14 02:33:05 +0000
@@ -2,15 +2,15 @@
22
3include (CompizPlugin)3include (CompizPlugin)
44
5#find_package (OpenGL)5find_package (OpenGL)
66
7#if (OPENGL_GLU_FOUND)7if (OPENGL_GLU_FOUND)
8# compiz_plugin(blur PLUGINDEPS composite opengl LIBRARIES decoration ${OPENGL_glu_LIBRARY} INCDIRS ${OPENGL_INCLUDE_DIR})8 compiz_plugin(blur PLUGINDEPS composite opengl LIBRARIES decoration ${OPENGL_glu_LIBRARY} INCDIRS ${OPENGL_INCLUDE_DIR})
99
10# if (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_BLUR)10 if (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_BLUR)
11# set_target_properties (11 set_target_properties (
12# blur PROPERTIES12 blur PROPERTIES
13# INSTALL_RPATH "${COMPIZ_LIBDIR}"13 INSTALL_RPATH "${COMPIZ_LIBDIR}"
14# )14 )
15# endif (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_BLUR)15 endif (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_BLUR)
16#endif ()16endif ()
1717
=== modified file 'plugins/blur/src/blur.cpp'
--- plugins/blur/src/blur.cpp 2013-05-09 13:43:07 +0000
+++ plugins/blur/src/blur.cpp 2016-05-14 02:33:05 +0000
@@ -22,19 +22,22 @@
22 *22 *
23 * Author: David Reveman <davidr@novell.com>23 * Author: David Reveman <davidr@novell.com>
24 */24 */
25
26#include <blur.h>25#include <blur.h>
26#include <sstream>
27#include <opengl/framebufferobject.h>
28
29/* Supporting independent texture fetch operations will require
30 * GLVertexBuffer to support per-plugin attributes as texture co-ordinates
31 * are two-component and not four-component
32 */
33#define INDEPENDENT_TEX_SUPPORTED 0
2734
28COMPIZ_PLUGIN_20090315 (blur, BlurPluginVTable)35COMPIZ_PLUGIN_20090315 (blur, BlurPluginVTable)
2936
30const unsigned short BLUR_GAUSSIAN_RADIUS_MAX = 15;
31
32const unsigned short BLUR_STATE_CLIENT = 0;
33const unsigned short BLUR_STATE_DECOR = 1;
34const unsigned short BLUR_STATE_NUM = 2;
35
36/* pascal triangle based kernel generator */37/* pascal triangle based kernel generator */
37static int38namespace
39{
40int
38blurCreateGaussianLinearKernel (int radius,41blurCreateGaussianLinearKernel (int radius,
39 float strength,42 float strength,
40 float *amp,43 float *amp,
@@ -106,6 +109,7 @@
106109
107 return radius;110 return radius;
108}111}
112}
109113
110void114void
111BlurScreen::updateFilterRadius ()115BlurScreen::updateFilterRadius ()
@@ -137,20 +141,11 @@
137{141{
138 updateFilterRadius ();142 updateFilterRadius ();
139143
140 foreach (BlurFunction &bf, srcBlurFunctions)
141 GLFragment::destroyFragmentFunction (bf.id);
142 srcBlurFunctions.clear ();144 srcBlurFunctions.clear ();
143 foreach (BlurFunction &bf, dstBlurFunctions)
144 GLFragment::destroyFragmentFunction (bf.id);
145 dstBlurFunctions.clear ();145 dstBlurFunctions.clear ();
146146
147 width = height = 0;147 program.reset ();
148148 texture.clear ();
149 if (program)
150 {
151 GL::deletePrograms (1, &program);
152 program = 0;
153 }
154}149}
155150
156static CompRegion151static CompRegion
@@ -249,7 +244,6 @@
249 int threshold,244 int threshold,
250 std::vector<BlurBox> box)245 std::vector<BlurBox> box)
251{246{
252
253 this->state[state].threshold = threshold;247 this->state[state].threshold = threshold;
254 this->state[state].box = box;248 this->state[state].box = box;
255249
@@ -289,7 +283,7 @@
289283
290 match = &bScreen->optionGetFocusBlurMatch ();284 match = &bScreen->optionGetFocusBlurMatch ();
291285
292 focus = GL::fragmentProgram && match->evaluate (window);286 focus = GL::shaders && match->evaluate (window);
293 if (focus != focusBlur)287 if (focus != focusBlur)
294 {288 {
295 focusBlur = focus;289 focusBlur = focus;
@@ -421,49 +415,75 @@
421 }415 }
422416
423 cScreen->preparePaint (msSinceLastPaint);417 cScreen->preparePaint (msSinceLastPaint);
424418}
425 if (cScreen->damageMask () & COMPOSITE_SCREEN_DAMAGE_REGION_MASK)419
420bool
421BlurScreen::markAreaDirty (const CompRegion &r)
422{
423 return allowAreaDirtyOnOwnDamageBuffer;
424}
425
426void
427BlurScreen::damageCutoff ()
428{
429 if (alphaBlur)
426 {430 {
427 /* walk from bottom to top and expand damage */431 this->output = &screen->fullscreenOutput ();
428 if (alphaBlur)432
433 /* We need to do a primary pass here with glPaint to check which
434 * regions of the backbuffer need to be updated.
435 *
436 * Because the backbuffer is effectively partially undefined, we are completely
437 * reliant on what core is telling us the repair regions of the
438 * backbuffer need to be - but obviously we can't completely rely
439 * on it because of a feedback effect, as we need to expand
440 * the repair region slightly so that the texture sampler
441 * doesn't go out of range of the damage region. If we were to
442 * simply expand the damage region, then that would feedback to us
443 * on the next frame, until the damage region eventually became infinite.
444 *
445 * As such, we have a tracker in core to track all damage except the effect
446 * of expanding the damage region that came back to us. We then use
447 * this tracker along with the frame age to determine what damage really
448 * needs to be expanded in order to determine the backbuffer update region,
449 * and then use the real damage in order to determine what blur regions
450 * should be updated
451 */
452 backbufferUpdateRegionThisFrame &= emptyRegion;
453 CompRegion frameAgeDamage = damageQuery->damageForFrameAge (cScreen->getFrameAge ());
454 foreach (CompWindow *w, screen->windows ())
429 {455 {
430 int x1, y1, x2, y2;456 /* Skip windows that would not have glPaint called on them */
431 int count = 0;457 if (w->destroyed ())
432 CompRegion damage (cScreen->currentDamage ());458 continue;
433459
434 foreach (CompWindow *w, screen->windows ())460 if (!w->shaded () && !w->isViewable ())
435 {461 continue;
436 BLUR_WINDOW (w);462
437463 BlurWindow *bw = BlurWindow::get (w);
438 if (!w->isViewable () || !CompositeWindow::get (w)->damaged ())464
439 continue;465 if (!bw->cWindow->redirected ())
440466 continue;
441 if (!bw->region.isEmpty ())467
442 {468 if (!bw->projectedBlurRegion.isEmpty ())
443 CompRect r = bw->region.boundingRect ();469 bw->projectedBlurRegion &= emptyRegion;
444 CompRect d = damage.boundingRect ();470
445 x1 = r.x1 () - filterRadius;471 GLMatrix screenSpace;
446 y1 = r.y1 () - filterRadius;472 screenSpace.toScreenSpace (this->output, -DEFAULT_Z_CAMERA);
447 x2 = r.x2 () + filterRadius;473
448 y2 = r.y2 () + filterRadius;474 bw->gWindow->glPaint (bw->gWindow->paintAttrib (), screenSpace,
449475 frameAgeDamage,
450 if (x1 < d.x2 () &&476 PAINT_WINDOW_NO_CORE_INSTANCE_MASK);
451 y1 < d.y2 () &&477
452 x2 > d.x1 () &&478 backbufferUpdateRegionThisFrame += bw->projectedBlurRegion;
453 y2 > d.y1 ())
454 {
455 damage.shrink (-filterRadius, -filterRadius);
456 count++;
457 }
458 }
459 }
460
461 if (count)
462 cScreen->damageRegion (damage);
463
464 this->count = count;
465 }479 }
480
481 allowAreaDirtyOnOwnDamageBuffer = false;
482 cScreen->damageRegion (backbufferUpdateRegionThisFrame);
483 allowAreaDirtyOnOwnDamageBuffer = true;
466 }484 }
485
486 cScreen->damageCutoff ();
467}487}
468488
469bool489bool
@@ -471,23 +491,10 @@
471 const GLMatrix &transform, const CompRegion &region,491 const GLMatrix &transform, const CompRegion &region,
472 CompOutput *output, unsigned int mask)492 CompOutput *output, unsigned int mask)
473{493{
474 bool status;
475
476 if (alphaBlur)494 if (alphaBlur)
477 {495 {
478 stencilBox = region.boundingRect ();496 stencilBox = region.boundingRect ();
479 this->region = region;497 this->region = region;
480
481 if (mask & PAINT_SCREEN_REGION_MASK)
482 {
483 /* we need to redraw more than the screen region being updated */
484 if (count)
485 {
486 this->region.shrink (-filterRadius * 2, -filterRadius * 2);
487
488 this->region &= screen->region ();
489 }
490 }
491 }498 }
492499
493 if (!blurOcclusion)500 if (!blurOcclusion)
@@ -500,12 +507,7 @@
500507
501 this->output = output;508 this->output = output;
502509
503 if (alphaBlur)510 return gScreen->glPaintOutput (sAttrib, transform, region, output, mask);
504 status = gScreen->glPaintOutput (sAttrib, transform, this->region, output, mask);
505 else
506 status = gScreen->glPaintOutput (sAttrib, transform, region, output, mask);
507
508 return status;
509}511}
510512
511void513void
@@ -542,12 +544,42 @@
542 cScreen->donePaint ();544 cScreen->donePaint ();
543}545}
544546
547void
548BlurWindow::glTransformationComplete (const GLMatrix &matrix,
549 const CompRegion &region,
550 unsigned int mask)
551{
552 gWindow->glTransformationComplete (matrix, region, mask);
553
554 int clientThreshold;
555 const CompRegion *reg = NULL;
556
557 /* only care about client window blurring when it's translucent */
558 if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
559 clientThreshold = state[BLUR_STATE_CLIENT].threshold;
560 else
561 clientThreshold = 0;
562
563 if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
564 reg = &infiniteRegion;
565 else
566 reg = &region;
567
568 bScreen->tmpRegion = this->region.intersected (*reg);
569
570 if (state[BLUR_STATE_DECOR].threshold || clientThreshold)
571 {
572 determineBlurRegion (bScreen->optionGetFilter (),
573 matrix,
574 clientThreshold);
575 }
576}
577
545bool578bool
546BlurWindow::glPaint (const GLWindowPaintAttrib &attrib,579BlurWindow::glPaint (const GLWindowPaintAttrib &attrib,
547 const GLMatrix &transform,580 const GLMatrix &transform,
548 const CompRegion &region, unsigned int mask)581 const CompRegion &region, unsigned int mask)
549{582{
550
551 bool status = gWindow->glPaint (attrib, transform, region, mask);583 bool status = gWindow->glPaint (attrib, transform, region, mask);
552584
553 if (!bScreen->blurOcclusion &&585 if (!bScreen->blurOcclusion &&
@@ -564,307 +596,359 @@
564 return status;596 return status;
565}597}
566598
567GLFragment::FunctionId599namespace
568BlurScreen::getSrcBlurFragmentFunction (GLTexture *texture,600{
569 int param)601struct SamplerInfo
570{602{
571 GLFragment::FunctionData data;603 GLint target;
604 CompString func;
605};
606
607SamplerInfo
608getSamplerInfoForSize (const CompSize &size)
609{
610 SamplerInfo info;
611
612#ifdef USE_GLES
613 info.target = GL_TEXTURE_2D;
614 info.func = "texture2D";
615#else
616 if (GL::textureNonPowerOfTwo ||
617 (POWER_OF_TWO (size.width ()) && POWER_OF_TWO (size.height ())))
618 {
619 info.target = GL_TEXTURE_2D;
620 info.func = "texture2D";
621 }
622 else
623 {
624 info.target = GL_TEXTURE_RECTANGLE_NV;
625 info.func = "textureRECT";
626 }
627#endif
628
629 return info;
630}
631}
632
633/* XXX: param is redundant */
634const CompString &
635BlurScreen::getSrcBlurFragmentFunction (GLTexture *texture)
636{
572 BlurFunction function;637 BlurFunction function;
573 int target;638 std::stringstream data (std::stringstream::out);
574639
575 if (texture->target () == GL_TEXTURE_2D)640 SamplerInfo info (getSamplerInfoForSize (CompSize (texture->width (),
576 target = COMP_FETCH_TARGET_2D;641 texture->height ())));
577 else642
578 target = COMP_FETCH_TARGET_RECT;643 foreach (const BlurFunction &bf, srcBlurFunctions)
579644 if (bf.target == info.target)
580 foreach (BlurFunction &bf, srcBlurFunctions)645 return bf.shader;
581 if (bf.param == param && bf.target == target)646
582 return bf.id;647 data << "uniform vec4 focusblur_input_offset;\n"\
583648 "\n"\
584 if (data.status ())649 "void focusblur_fragment ()\n"\
585 {650 "{\n";
586 static const char *temp[] = { "offset0", "offset1", "sum" };651
587 unsigned int i;652 if (optionGetFilter () == BlurOptions::Filter4xbilinear)
588653 data << " float blur_offset0, blur_offset1;\n"\
589 for (i = 0; i < sizeof (temp) / sizeof (temp[0]); i++)654 " vec4 blur_sum;\n"\
590 data.addTempHeaderOp (temp[i]);655 " vec4 offset0 = focusblur_input_offset.xyzw * vec4 (1.0, 1.0, 0.0, 0.0);\n"\
591656 " vec4 offset1 = focusblur_input_offset.zwww * vec4 (1.0, 1.0, 0.0, 0.0);\n"
592 data.addDataOp (657 " vec4 output = texture2D (texture0, vTexCoord0 + offset0);\n"\
593 "MUL offset0, program.env[%d].xyzw, { 1.0, 1.0, 0.0, 0.0 };"658 " blur_sum = output * 0.25;\n"\
594 "MUL offset1, program.env[%d].zwww, { 1.0, 1.0, 0.0, 0.0 };",659 " output = " << info.func << " (texture0, vTexCoord0 - offset0);\n"\
595 param, param);660 " blur_sum += output * 0.25;\n"\
596661 " output = " << info.func << " (texture0, vTexCoord0 + offset1);\n"\
597662 " blur_sum += output * 0.25;\n"\
598 switch (optionGetFilter ()) {663 " output = " << info.func << " (texture0, vTexCoord0 - offset1);\n"\
599 case BlurOptions::Filter4xbilinear:664 " output = output * 0.25 + blur_sum;\n"\
600 default:665 " gl_FragColor = output;\n";
601 data.addFetchOp ("output", "offset0", target);666
602 data.addDataOp ("MUL sum, output, 0.25;");667 data << "}\n";
603 data.addFetchOp ("output", "-offset0", target);668
604 data.addDataOp ("MAD sum, output, 0.25, sum;");669 function.shader = data.str ();
605 data.addFetchOp ("output", "offset1", target);670 function.target = info.target;
606 data.addDataOp ("MAD sum, output, 0.25, sum;");671
607 data.addFetchOp ("output", "-offset1", target);672 srcBlurFunctions.push_back (function);
608 data.addDataOp ("MAD output, output, 0.25, sum;");673
609 break;674 return srcBlurFunctions.back ().shader;
610 }
611
612 if (!data.status ())
613 return 0;
614
615 function.id = data.createFragmentFunction ("blur");
616 function.target = target;
617 function.param = param;
618 function.unit = 0;
619
620 srcBlurFunctions.push_back (function);
621
622 return function.id;
623 }
624
625 return 0;
626}675}
627676
628GLFragment::FunctionId677/* This seems incomplete to me */
678
679const CompString &
629BlurScreen::getDstBlurFragmentFunction (GLTexture *texture,680BlurScreen::getDstBlurFragmentFunction (GLTexture *texture,
630 int param,681 int unit,
631 int unit,
632 int numITC,682 int numITC,
633 int startTC)683 int startTC)
634{684{
635 BlurFunction function;685 BlurFunction function;
636 GLFragment::FunctionData data;686 std::stringstream data (std::stringstream::out);
637 int target;687 int saturation = optionGetSaturation ();
638 char *targetString;
639688
640 if (texture->target () == GL_TEXTURE_2D)689 SamplerInfo info (getSamplerInfoForSize (CompSize (texture->width (),
641 {690 texture->height ())));
642 target = COMP_FETCH_TARGET_2D;
643 targetString = (char *) "2D";
644 }
645 else
646 {
647 target = COMP_FETCH_TARGET_RECT;
648 targetString = (char *) "RECT";
649 }
650691
651 foreach (BlurFunction &function, dstBlurFunctions)692 foreach (BlurFunction &function, dstBlurFunctions)
652 if (function.param == param &&693 if (function.target == info.target &&
653 function.target == target &&
654 function.unit == unit &&
655 function.numITC == numITC &&694 function.numITC == numITC &&
656 function.startTC == startTC)695 function.startTC == startTC &&
657 return function.id;696 function.saturation == saturation)
658697 return function.shader;
659 if (data.status ())698
660 {699 data << "uniform vec4 blur_translation;\n"\
661 static const char *temp[] = { "fCoord", "mask", "sum", "dst" };700 "uniform vec4 blur_threshold;\n";
662 int i, j;701
663 char str[1024];702 int i, j;
664 int saturation = optionGetSaturation ();703 /* These are always initialized if running a gaussian shader */
665 int numIndirect;704 int numIndirect = 0;
666 int numIndirectOp;705 int numIndirectOp = 0;
667 int base, end, ITCbase;706 int base, end, ITCbase;
668707
669 for (i = 0; (unsigned int) i < sizeof (temp) / sizeof (temp[0]); i++)708 /* Set per-shader uniforms */
670 data.addTempHeaderOp (temp[i]);709 switch (optionGetFilter ())
671710 {
672 if (saturation < 100)711 case BlurOptions::Filter4xbilinear:
673 data.addTempHeaderOp ("sat");712 data << "uniform vec4 blur_dxdy;\n";
674713 break;
675 switch (optionGetFilter ()) {714 default:
676 case BlurOptions::Filter4xbilinear: {715 break;
677 static const char *filterTemp[] = {716 }
678 "t0", "t1", "t2", "t3",717
679 "s0", "s1", "s2", "s3"718 data << "\n"\
680 };719 "void blur_fragment ()\n"\
681720 "{\n"\
682 for (i = 0;721 " vec4 blur_sum, blur_dst, blur_output;\n"\
683 (unsigned int) i < sizeof (filterTemp) / sizeof (filterTemp[0]);722 " vec2 blur_fCoord;\n"\
684 i++)723 " vec4 blur_mask;\n";
685 data.addTempHeaderOp (filterTemp[i]);724
686725 if (saturation < 100)
687 data.addFetchOp ("output", NULL, target);726 data << " float blur_sat;\n";
688 data.addColorOp ("output", "output");727
689728 /* Define per-filter temporaries */
690 data.addDataOp (729 switch (optionGetFilter ())
691 "MUL fCoord, fragment.position, program.env[%d];",730 {
692 param);731 case BlurOptions::Filter4xbilinear:
693732 {
694733 static const char *filterTemp[] = {
695 data.addDataOp (734 "blur_t0", "blur_t1", "blur_t2", "blur_t3",
696 "ADD t0, fCoord, program.env[%d];"735 };
697 "TEX s0, t0, texture[%d], %s;"736
698737 static const char *filterSampleTemp[] = {
699 "SUB t1, fCoord, program.env[%d];"738 "blur_s0", "blur_s1", "blur_s2", "blur_s3"
700 "TEX s1, t1, texture[%d], %s;"739 };
701740
702 "MAD t2, program.env[%d], { -1.0, 1.0, 0.0, 0.0 }, fCoord;"741 for (i = 0;
703 "TEX s2, t2, texture[%d], %s;"742 (unsigned int) i < sizeof (filterTemp) / sizeof (filterTemp[0]);
704743 ++i)
705 "MAD t3, program.env[%d], { 1.0, -1.0, 0.0, 0.0 }, fCoord;"744 data << " vec2 " << filterTemp[i] << ";\n";
706 "TEX s3, t3, texture[%d], %s;"745
707746 for (i = 0;
708 "MUL_SAT mask, output.a, program.env[%d];"747 (unsigned int) i < sizeof (filterSampleTemp) / sizeof (filterSampleTemp[0]);
709748 ++i)
710 "MUL sum, s0, 0.25;"749 data << " vec4 " << filterSampleTemp[i] << ";\n";
711 "MAD sum, s1, 0.25, sum;"750 }
712 "MAD sum, s2, 0.25, sum;"751 break;
713 "MAD sum, s3, 0.25, sum;",752 case BlurOptions::FilterGaussian:
714753 {
715 param + 2, unit, targetString,754 /* try to use only half of the available temporaries to keep
716 param + 2, unit, targetString,755 other plugins working */
717 param + 2, unit, targetString,756 if ((maxTemp / 2) - 4 >
718 param + 2, unit, targetString,757 (numTexop + (numTexop - numITC)) * 2)
719 param + 1);758 {
720759 numIndirect = 1;
721 } break;760 numIndirectOp = numTexop;
722 case BlurOptions::FilterGaussian: {761 }
723762 else
724 /* try to use only half of the available temporaries to keep763 {
725 other plugins working */764 i = MAX (((maxTemp / 2) - 4) / 4, 1);
726 if ((maxTemp / 2) - 4 >765 numIndirect = ceil ((float)numTexop / (float)i);
727 (numTexop + (numTexop - numITC)) * 2)766 numIndirectOp = ceil ((float)numTexop / (float)numIndirect);
728 {767 }
729 numIndirect = 1;768
730 numIndirectOp = numTexop;769 /* we need to define all coordinate temporaries if we have
731 }770 multiple indirection steps */
732 else771 j = (numIndirect > 1) ? 0 : numITC;
733 {772
734 i = MAX (((maxTemp / 2) - 4) / 4, 1);773 for (i = 0; i < numIndirectOp * 2; i++)
735 numIndirect = ceil ((float)numTexop / (float)i);774 data << " vec4 blur_pix_" << i << ";\n";
736 numIndirectOp = ceil ((float)numTexop / (float)numIndirect);775
737 }776 for (i = j * 2; i < numIndirectOp * 2; i++)
738777 data << " vec2 blur_coord_" << i << ";\n";
739 /* we need to define all coordinate temporaries if we have778 }
740 multiple indirection steps */779 break;
741 j = (numIndirect > 1) ? 0 : numITC;780 case BlurOptions::FilterMipmap:
742781 {
743 for (i = 0; i < numIndirectOp * 2; i++)782 data << " float lod_bias;\n";
744 {783 }
745 snprintf (str, 1024, "pix_%d", i);784 default:
746 data.addTempHeaderOp (str);785 break;
747 }786 }
748787
749 for (i = j * 2; i < numIndirectOp * 2; i++)788 /*
750 {789 * blur_output: copy the original gl_FragColor determined by sampling
751 snprintf (str, 1024, "coord_%d", i);790 * the window texture in the core shader
752 data.addTempHeaderOp (str);791 * blur_fCoord: take the fragment co-ordinate in window co-ordinates
753 }792 * and normalize it (eg, blur_translation). Once normalized we can
754793 * sample texUnitN + 1 (for the copy of the backbuffer we wish to blur)
755 data.addFetchOp ("output", NULL, target);794 * and texUnitN + 2 (scratch fbo for gaussian blurs)
756 data.addColorOp ("output", "output");795 * blur_mask: take blur_output pixel alpha value, multiply by threshold value
757796 * and clamp between 0 - 1. We will use this later to mix the blur fragments
758 data.addDataOp (797 * with the window fragments.
759 "MUL fCoord, fragment.position, program.env[%d];",798 */
760 param);799 data << "\n"\
761800 " blur_output = gl_FragColor;\n"\
762801 " blur_fCoord = gl_FragCoord.st * blur_translation.st;\n"\
763 data.addDataOp ("TEX sum, fCoord, texture[%d], %s;",802 " 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"\
764 unit + 1, targetString);803 "\n";
765804
766805 /* Define filter program */
767 data.addDataOp ("MUL_SAT mask, output.a, program.env[%d];"806 switch (optionGetFilter ())
768 "MUL sum, sum, %f;",807 {
769 param + 1, amp[numTexop]);808 case BlurOptions::Filter4xbilinear:
770809 {
771 for (j = 0; j < numIndirect; j++)810 data << " blur_t0 = blur_fCoord + blur_dxdy.st;\n"\
772 {811 " blur_s0 = " << info.func << " (texture1, blur_t0);\n"\
773 base = j * numIndirectOp;812 " blur_t1 = blur_fCoord - blur_dxdy.st;\n"\
774 end = MIN ((j + 1) * numIndirectOp, numTexop) - base;813 " blur_s1 = " << info.func << " (texture1, blur_t1);\n"\
775814 " blur_t2 = blur_fCoord + vec2 (-1.0, 1.0) * blur_dxdy.st;\n"\
776 ITCbase = MAX (numITC - base, 0);815 " blur_s2 = " << info.func << " (texture1, blur_t2);\n"\
777816 " blur_t3 = blur_fCoord + vec2 (1.0, -1.0) * blur_dxdy.st;\n"\
778 for (i = ITCbase; i < end; i++)817 " blur_s3 = " << info.func << " (texture1, blur_t3);\n"\
779 {818 " blur_sum = blur_s0 * 0.25;\n"\
780 data.addDataOp (819 " blur_sum += blur_s1 * 0.25;\n"\
781 "ADD coord_%d, fCoord, {0.0, %g, 0.0, 0.0};"820 " blur_sum += blur_s2 * 0.25;\n"\
782 "SUB coord_%d, fCoord, {0.0, %g, 0.0, 0.0};",821 " blur_sum += blur_s3 * 0.25;\n";
783 i * 2, pos[base + i] * ty,822 } break;
784 (i * 2) + 1, pos[base + i] * ty);823 case BlurOptions::FilterGaussian:
785 }824 {
786825 /* Invert y */
787 for (i = 0; i < ITCbase; i++)826 data << " blur_fCoord.y = 1.0 - blur_fCoord.y;\n"\
788 {827 " blur_sum = " << info.func << " (texture2, blur_fCoord);\n"\
789 data.addDataOp (828 " blur_sum *= " << amp[numTexop] << ";\n";
790 "TXP pix_%d, fragment.texcoord[%d], texture[%d], %s;"829
791 "TXP pix_%d, fragment.texcoord[%d], texture[%d], %s;",830 for (j = 0; j < numIndirect; j++)
792 i * 2, startTC + ((i + base) * 2),831 {
793 unit + 1, targetString,832 base = j * numIndirectOp;
794 (i * 2) + 1, startTC + 1 + ((i + base) * 2),833 end = MIN ((j + 1) * numIndirectOp, numTexop) - base;
795 unit + 1, targetString);834
796 }835 ITCbase = MAX (numITC - base, 0);
797836
798 for (i = ITCbase; i < end; i++)837 for (i = ITCbase; i < end; i++)
799 {838 {
800 data.addDataOp (839 data << " blur_coord_" << i * 2 << " = blur_fCoord + vec2 (0.0, " << pos[base + i] * ty << ");\n"\
801 "TEX pix_%d, coord_%d, texture[%d], %s;"840 " blur_coord_" << (i * 2) + 1 << " = blur_fCoord - vec2 (0.0, " << pos[base + i] * ty << ");\n";
802 "TEX pix_%d, coord_%d, texture[%d], %s;",841 }
803 i * 2, i * 2,842#if INDEPENDENT_TEX_SUPPORTED
804 unit + 1, targetString,843 for (i = 0; i < ITCbase; i++)
805 (i * 2) + 1, (i * 2) + 1,844 {
806 unit + 1, targetString);845 data << " blur_pix_" + i * 2 + " vTexCoord"
807 }846 data.addDataOp (
808847 "TXP pix_%d, fragment.texcoord[%d], texture[%d], %s;"
809 for (i = 0; i < end * 2; i++)848 "TXP pix_%d, fragment.texcoord[%d], texture[%d], %s;",
810 {849 i * 2, startTC + ((i + base) * 2),
811 data.addDataOp (850 unit + 1, targetString,
812 "MAD sum, pix_%d, %f, sum;",851 (i * 2) + 1, startTC + 1 + ((i + base) * 2),
813 i, amp[base + (i / 2)]);852 unit + 1, targetString);
814 }853 }
815 }854#endif
816855 for (i = ITCbase; i < end; i++)
817 } break;856 {
818 case BlurOptions::FilterMipmap:857 data << " blur_pix_" << i * 2 << " = " << info.func << " (texture2, blur_coord_" << i * 2 << ");\n"\
819 data.addFetchOp ("output", NULL, target);858 " blur_pix_" << (i * 2) + 1 << " = " << info.func << " (texture2, blur_coord_" << (i * 2) + 1 << ");\n";
820 data.addColorOp ("output", "output");859 }
821860
822 data.addDataOp (861 for (i = 0; i < end * 2; i++)
823 "MUL fCoord, fragment.position, program.env[%d].xyzz;"862 data << " blur_sum += blur_pix_" << i << " * " << amp[base + (i / 2)] << ";\n";
824 "MOV fCoord.w, program.env[%d].w;"863 }
825 "TXB sum, fCoord, texture[%d], %s;"864
826 "MUL_SAT mask, output.a, program.env[%d];",865 } break;
827 param, param, unit, targetString,866 case BlurOptions::FilterMipmap:
828 param + 1);867 data << " lod_bias = blur_translation.w;\n"\
829868 " blur_sum = " << info.func << " (texture1, blur_fCoord, lod_bias);\n";
830 break;869
831 }870 break;
832871 }
833 if (saturation < 100)872
834 {873 if (saturation < 100)
835 data.addDataOp (874 {
836 "MUL sat, sum, { 1.0, 1.0, 1.0, 0.0 };"875 data << " blur_sat = blur_sum * vec4 (1.0, 1.0, 1.0, 0.0);\n"\
837 "DP3 sat, sat, { %f, %f, %f, %f };"876 " blur_sat = dot (blur_sat, vec4 (" <<
838 "LRP sum.xyz, %f, sum, sat;",877 RED_SATURATION_WEIGHT << ", " << GREEN_SATURATION_WEIGHT << ", " <<
839 RED_SATURATION_WEIGHT, GREEN_SATURATION_WEIGHT,878 BLUE_SATURATION_WEIGHT << ", 0.0f);\n"\
840 BLUE_SATURATION_WEIGHT, 0.0f, saturation / 100.0f);879 " blur_sum.xyz = mix (" << saturation / 100.f << ", blur_sat);\n";
841 }880 }
842881
843 data.addDataOp (882 data << " blur_dst = (blur_mask * -blur_output.a) + blur_mask;\n"\
844 "MAD dst, mask, -output.a, mask;"883 " blur_output.rgb = blur_sum.rgb * blur_dst.a + blur_output.rgb;\n"\
845 "MAD output.rgb, sum, dst.a, output;"884 " blur_output.a += blur_dst.a;\n"\
846 "ADD output.a, output.a, dst.a;");885 " gl_FragColor = blur_output;\n"\
847886 "}";
848 if (!data.status ())887
849 {888 function.shader = data.str ();
850 return 0;889 function.target = texture->target ();
851 }890 function.numITC = numITC;
852891 function.startTC = startTC;
853892 function.saturation = saturation;
854893
855 function.id = data.createFragmentFunction ("blur");894 dstBlurFunctions.push_back (function);
856 function.target = target;895
857 function.param = param;896 return dstBlurFunctions.back ().shader;
858 function.unit = unit;897}
859 function.numITC = numITC;898
860 function.startTC = startTC;899namespace
861900{
862 dstBlurFunctions.push_back (function);901bool
863902project (float objx, float objy, float objz,
864 return function.id;903 const float modelview[16], const float projection[16],
865 }904 const GLint viewport[4],
866905 float *winx, float *winy, float *winz)
867 return 0;906{
907 unsigned int i;
908 float in[4];
909 float out[4];
910
911 in[0] = objx;
912 in[1] = objy;
913 in[2] = objz;
914 in[3] = 1.0;
915
916 for (i = 0; i < 4; i++) {
917 out[i] =
918 in[0] * modelview[i] +
919 in[1] * modelview[4 + i] +
920 in[2] * modelview[8 + i] +
921 in[3] * modelview[12 + i];
922 }
923
924 for (i = 0; i < 4; i++) {
925 in[i] =
926 out[0] * projection[i] +
927 out[1] * projection[4 + i] +
928 out[2] * projection[8 + i] +
929 out[3] * projection[12 + i];
930 }
931
932 if (in[3] == 0.0)
933 return false;
934
935 in[0] /= in[3];
936 in[1] /= in[3];
937 in[2] /= in[3];
938 /* Map x, y and z to range 0-1 */
939 in[0] = in[0] * 0.5 + 0.5;
940 in[1] = in[1] * 0.5 + 0.5;
941 in[2] = in[2] * 0.5 + 0.5;
942
943 /* Map x,y to viewport */
944 in[0] = in[0] * viewport[2] + viewport[0];
945 in[1] = in[1] * viewport[3] + viewport[1];
946
947 *winx = in[0];
948 *winy = in[1];
949 *winz = in[2];
950 return true;
951}
868}952}
869953
870bool954bool
@@ -874,11 +958,11 @@
874 float *scr,958 float *scr,
875 int n)959 int n)
876{960{
877 GLdouble dProjection[16];961 GLfloat dProjection[16];
878 GLdouble dModel[16];962 GLfloat dModel[16];
879 GLint viewport[4];963 GLint viewport[4];
880 double x, y, z;964 float x, y, z;
881 int i;965 int i;
882966
883 viewport[0] = output->x1 ();967 viewport[0] = output->x1 ();
884 viewport[1] = screen->height () - output->y2 ();968 viewport[1] = screen->height () - output->y2 ();
@@ -888,14 +972,14 @@
888 for (i = 0; i < 16; i++)972 for (i = 0; i < 16; i++)
889 {973 {
890 dModel[i] = transform.getMatrix ()[i];974 dModel[i] = transform.getMatrix ()[i];
891 dProjection[i] = gScreen->projectionMatrix ()[i];975 dProjection[i] = gScreen->projectionMatrix ()->getMatrix ()[i];
892 }976 }
893977
894 while (n--)978 while (n--)
895 {979 {
896 if (!gluProject (object[0], object[1], object[2],980 if (!project (object[0], object[1], object[2],
897 dModel, dProjection, viewport,981 dModel, dProjection, viewport,
898 &x, &y, &z))982 &x, &y, &z))
899 return false;983 return false;
900984
901 scr[0] = x;985 scr[0] = x;
@@ -909,57 +993,56 @@
909}993}
910994
911bool995bool
912BlurScreen::loadFragmentProgram (GLuint *program,996BlurScreen::loadFragmentProgram (boost::shared_ptr <GLProgram> &program,
913 const char *string)997 const char *vertex,
998 const char *fragment)
914{999{
915 GLint errorPos;1000 if (!program)
9161001 program.reset (new GLProgram (CompString (vertex),
917 /* clear errors */1002 CompString (fragment)));
918 glGetError ();1003
9191004 if (program && program->valid ())
920 if (!*program)1005 return true;
921 (*GL::genPrograms) (1, program);1006 else
922
923 (*GL::bindProgram) (GL_FRAGMENT_PROGRAM_ARB, *program);
924 (*GL::programString) (GL_FRAGMENT_PROGRAM_ARB,
925 GL_PROGRAM_FORMAT_ASCII_ARB,
926 strlen (string), string);
927
928 glGetIntegerv (GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
929 if (glGetError () != GL_NO_ERROR || errorPos != -1)
930 {1007 {
1008 program.reset ();
931 compLogMessage ("blur", CompLogLevelError,1009 compLogMessage ("blur", CompLogLevelError,
932 "Failed to load blur program %s", string);1010 "Failed to load blur program %s", fragment);
933
934 (*GL::deletePrograms) (1, program);
935 *program = 0;
936
937 return false;1011 return false;
938 }1012 }
939
940 return true;
941}1013}
9421014
943bool1015bool
944BlurScreen::loadFilterProgram (int numITC)1016BlurScreen::loadFilterProgram (int numITC)
945{1017{
946 char buffer[4096];1018 std::stringstream svtx;
947 char *targetString;1019
948 char *str = buffer;1020 /* A simple pass-thru vertex shader */
1021 svtx << "#ifdef GL_ES\n"\
1022 "precision mediump float;\n"\
1023 "#endif\n"\
1024 "uniform mat4 modelview;\n"\
1025 "uniform mat4 projection;\n"\
1026 "attribute vec4 position;\n"\
1027 "attribute vec2 texCoord0;\n"\
1028 "varying vec2 vTexCoord0;\n"\
1029 "\n"\
1030 "void main ()\n"\
1031 "{\n"\
1032 " vTexCoord0 = texCoord0;\n"\
1033 " gl_Position = projection * modelview * position;\n"\
1034 "}";
1035
1036 std::stringstream str;
949 int i, j;1037 int i, j;
950 int numIndirect;1038 int numIndirect;
951 int numIndirectOp;1039 int numIndirectOp;
952 int base, end, ITCbase;1040 int base, end, ITCbase;
9531041
954 if (target == GL_TEXTURE_2D)1042 SamplerInfo info (getSamplerInfoForSize (*screen));
955 targetString = (char *) "2D";
956 else
957 targetString = (char *) "RECT";
9581043
959 str += sprintf (str,1044 str << "varying vec2 vTexCoord0;\n"\
960 "!!ARBfp1.0"1045 "uniform sampler2D texture0;\n";
961 "ATTRIB texcoord = fragment.texcoord[0];"
962 "TEMP sum;");
9631046
964 if (maxTemp - 1 > (numTexop + (numTexop - numITC)) * 2)1047 if (maxTemp - 1 > (numTexop + (numTexop - numITC)) * 2)
965 {1048 {
@@ -977,19 +1060,19 @@
977 multiple indirection steps */1060 multiple indirection steps */
978 j = (numIndirect > 1) ? 0 : numITC;1061 j = (numIndirect > 1) ? 0 : numITC;
9791062
1063 str << "\n"\
1064 "void main ()\n"\
1065 "{\n";
1066
980 for (i = 0; i < numIndirectOp; i++)1067 for (i = 0; i < numIndirectOp; i++)
981 str += sprintf (str,"TEMP pix_%d, pix_%d;", i * 2, (i * 2) + 1);1068 str << " vec4 blur_pix_" << i * 2 << ", blur_pix_" << (i * 2) + 1 << ";\n";
9821069
983 for (i = j; i < numIndirectOp; i++)1070 for (i = j; i < numIndirectOp; i++)
984 str += sprintf (str,"TEMP coord_%d, coord_%d;", i * 2, (i * 2) + 1);1071 str << " vec2 blur_coord_" << i * 2 << ", blur_coord_" << (i * 2) + 1 << ";\n";
9851072
986 str += sprintf (str,1073 str << " vec4 blur_sum;\n";
987 "TEX sum, texcoord, texture[0], %s;",1074 str << " blur_sum = " << info.func << " (texture0, vTexCoord0);\n"\
988 targetString);1075 " blur_sum = blur_sum * " << amp[numTexop] << ";\n";
989
990 str += sprintf (str,
991 "MUL sum, sum, %f;",
992 amp[numTexop]);
9931076
994 for (j = 0; j < numIndirect; j++)1077 for (j = 0; j < numIndirect; j++)
995 {1078 {
@@ -999,37 +1082,30 @@
999 ITCbase = MAX (numITC - base, 0);1082 ITCbase = MAX (numITC - base, 0);
10001083
1001 for (i = ITCbase; i < end; i++)1084 for (i = ITCbase; i < end; i++)
1002 str += sprintf (str,1085 str << " blur_coord_" << i * 2 << " = vTexCoord0 + vec2 (" << pos[base + i] * tx << ", 0.0);\n"\
1003 "ADD coord_%d, texcoord, {%g, 0.0, 0.0, 0.0};"1086 " blur_coord_" << (i * 2) + 1 << " = vTexCoord0 - vec2 (" << pos[base + i] * tx << ", 0.0);\n";
1004 "SUB coord_%d, texcoord, {%g, 0.0, 0.0, 0.0};",1087#if INDEPENDENT_TEX_SUPPORTED
1005 i * 2, pos[base + i] * tx,
1006 (i * 2) + 1, pos[base + i] * tx);
1007
1008 for (i = 0; i < ITCbase; i++)1088 for (i = 0; i < ITCbase; i++)
1009 str += sprintf (str,1089 str << sprintf (str,
1010 "TEX pix_%d, fragment.texcoord[%d], texture[0], %s;"1090 "TEX pix_%d, fragment.texcoord[%d], texture[0], %s;"
1011 "TEX pix_%d, fragment.texcoord[%d], texture[0], %s;",1091 "TEX pix_%d, fragment.texcoord[%d], texture[0], %s;",
1012 i * 2, ((i + base) * 2) + 1, targetString,1092 i * 2, ((i + base) * 2) + 1, targetString,
1013 (i * 2) + 1, ((i + base) * 2) + 2, targetString);1093 (i * 2) + 1, ((i + base) * 2) + 2, targetString);
10141094#endif
1015 for (i = ITCbase; i < end; i++)1095 for (i = ITCbase; i < end; i++)
1016 str += sprintf (str,1096 str << " blur_pix_" << (i * 2) << " = " << info.func << " (texture0, blur_coord_" << i * 2 << ");\n"\
1017 "TEX pix_%d, coord_%d, texture[0], %s;"1097 " blur_pix_" << (i * 2) + 1 << " = " << info.func << " (texture0, blur_coord_" << (i * 2) + 1 << ");\n";
1018 "TEX pix_%d, coord_%d, texture[0], %s;",
1019 i * 2, i * 2, targetString,
1020 (i * 2) + 1, (i * 2) + 1, targetString);
10211098
1022 for (i = 0; i < end * 2; i++)1099 for (i = 0; i < end * 2; i++)
1023 str += sprintf (str,1100 str << " blur_sum += blur_pix_" << i << " * " << amp[base + (i / 2)] << ";\n";
1024 "MAD sum, pix_%d, %f, sum;",
1025 i, amp[base + (i / 2)]);
1026 }1101 }
10271102
1028 str += sprintf (str,1103 str << " gl_FragColor = blur_sum;\n"\
1029 "MOV result.color, sum;"1104 "}";
1030 "END");
10311105
1032 return loadFragmentProgram (&program, buffer);1106 return loadFragmentProgram (program,
1107 svtx.str ().c_str (),
1108 str.str ().c_str ());
1033}1109}
10341110
1035bool1111bool
@@ -1038,51 +1114,7 @@
1038 if (!fbo)1114 if (!fbo)
1039 return false;1115 return false;
10401116
1041 (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, fbo);1117 oldDrawFramebuffer = fbo->bind ();
1042
1043 /* bind texture and check status the first time */
1044 if (!fboStatus)
1045 {
1046 (*GL::framebufferTexture2D) (GL_FRAMEBUFFER_EXT,
1047 GL_COLOR_ATTACHMENT0_EXT,
1048 target, texture[1],
1049 0);
1050
1051 int currStatus = (*GL::checkFramebufferStatus) (GL_FRAMEBUFFER_EXT);
1052 if (currStatus != GL_FRAMEBUFFER_COMPLETE_EXT)
1053 {
1054 compLogMessage ("blur", CompLogLevelError,
1055 "Framebuffer incomplete");
1056
1057 (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0);
1058 (*GL::deleteFramebuffers) (1, &fbo);
1059
1060 fbo = 0;
1061
1062 return false;
1063 }
1064 else
1065 fboStatus = true;
1066 }
1067
1068 glPushAttrib (GL_VIEWPORT_BIT | GL_ENABLE_BIT);
1069
1070 glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
1071 glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
1072
1073 glDisable (GL_CLIP_PLANE0);
1074 glDisable (GL_CLIP_PLANE1);
1075 glDisable (GL_CLIP_PLANE2);
1076 glDisable (GL_CLIP_PLANE3);
1077
1078 glViewport (0, 0, width, height);
1079 glMatrixMode (GL_PROJECTION);
1080 glPushMatrix ();
1081 glLoadIdentity ();
1082 glOrtho (0.0, width, 0.0, height, -1.0, 1.0);
1083 glMatrixMode (GL_MODELVIEW);
1084 glPushMatrix ();
1085 glLoadIdentity ();
10861118
1087 return true;1119 return true;
1088}1120}
@@ -1090,37 +1122,22 @@
1090void1122void
1091BlurScreen::fboEpilogue ()1123BlurScreen::fboEpilogue ()
1092{1124{
1093 (*GL::bindFramebuffer) (GL_FRAMEBUFFER_EXT, 0);1125 oldDrawFramebuffer->bind ();
10941126
1095 glMatrixMode (GL_PROJECTION);1127 fbo->tex ()->enable (GLTexture::Good);
1096 glLoadIdentity ();1128 //GL::generateMipmap (fbo->tex ()->target ());
1097 glMatrixMode (GL_MODELVIEW);1129
1098 glLoadIdentity ();1130 fbo->tex ()->disable ();
1099 glDepthRange (0, 1);
1100 glViewport (-1, -1, 2, 2);
1101 glRasterPos2f (0, 0);
1102
1103 gScreen->resetRasterPos ();
1104
1105 glMatrixMode (GL_PROJECTION);
1106 glPopMatrix ();
1107 glMatrixMode (GL_MODELVIEW);
1108 glPopMatrix ();
1109
1110 glDrawBuffer (GL_BACK);
1111 glReadBuffer (GL_BACK);
1112
1113 glPopAttrib ();
1114}1131}
11151132
1116bool1133bool
1117BlurScreen::fboUpdate (BoxPtr pBox,1134BlurScreen::fboUpdate (BoxPtr pBox,
1118 int nBox)1135 int nBox)
1119{1136{
1120 int i, y, iTC = 0;1137 float iTC = 0;
1121 bool wasCulled = glIsEnabled (GL_CULL_FACE);1138 bool wasCulled = glIsEnabled (GL_CULL_FACE);
11221139
1123 if (GL::maxTextureUnits && optionGetIndependentTex ())1140 if (GL::maxTextureUnits && optionGetIndependentTex () && false)
1124 iTC = MIN ((GL::maxTextureUnits - 1) / 2, numTexop);1141 iTC = MIN ((GL::maxTextureUnits - 1) / 2, numTexop);
11251142
1126 if (!program)1143 if (!program)
@@ -1131,83 +1148,51 @@
1131 return false;1148 return false;
11321149
1133 glDisable (GL_CULL_FACE);1150 glDisable (GL_CULL_FACE);
11341151 GL::activeTexture (GL_TEXTURE0);
1135 glDisableClientState (GL_TEXTURE_COORD_ARRAY);1152 texture[0]->enable (GLTexture::Good);
11361153
1137 glBindTexture (target, texture[0]);1154 GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
1138
1139 glEnable (GL_FRAGMENT_PROGRAM_ARB);
1140 (*GL::bindProgram) (GL_FRAGMENT_PROGRAM_ARB, program);
1141
1142 glBegin (GL_QUADS);
11431155
1144 while (nBox--)1156 while (nBox--)
1145 {1157 {
1146 y = screen->height () - pBox->y2;1158 float x1 = pBox->x1;
11471159 float x2 = pBox->x2;
1148 for (i = 0; i < iTC; i++)1160 float y1 = screen->height () - pBox->y2;
1149 {1161 float y2 = screen->height () - pBox->y1;
1150 (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2),1162
1151 tx * (pBox->x1 + pos[i]),1163 GLfloat texCoords[] =
1152 ty * y);1164 {
1153 (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2) + 1,1165 tx * x1, ty * y1,
1154 tx * (pBox->x1 - pos[i]),1166 tx * x1, ty * y2,
1155 ty * y);1167 tx * x2, ty * y1,
1156 }1168 tx * x2, ty * y2
11571169 };
1158 glTexCoord2f (tx * pBox->x1, ty * y);1170
1159 glVertex2i (pBox->x1, y);1171 GLfloat vertices[] =
11601172 {
1161 for (i = 0; i < iTC; i++)1173 x1, y1, 0,
1162 {1174 x1, y2, 0,
1163 (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2),1175 x2, y1, 0,
1164 tx * (pBox->x2 + pos[i]),1176 x2, y2, 0
1165 ty * y);1177 };
1166 (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2) + 1,1178
1167 tx * (pBox->x2 - pos[i]),1179 GLMatrix mv;
1168 ty * y);1180 mv.toScreenSpace (output, -DEFAULT_Z_CAMERA);
1169 }1181
11701182 streamingBuffer->begin (GL_TRIANGLE_STRIP);
1171 glTexCoord2f (tx * pBox->x2, ty * y);1183 streamingBuffer->setProgram (program.get ());
1172 glVertex2i (pBox->x2, y);1184 streamingBuffer->addTexCoords (0, 4, texCoords);
11731185 streamingBuffer->addVertices (4, vertices);
1174 y = screen->height () - pBox->y1;1186
11751187 if (streamingBuffer->end ())
1176 for (i = 0; i < iTC; i++)1188 streamingBuffer->render (mv);
1177 {1189
1178 (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2),1190 /* Unset program */
1179 tx * (pBox->x2 + pos[i]),1191 streamingBuffer->setProgram (NULL);
1180 ty * y);
1181 (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2) + 1,
1182 tx * (pBox->x2 - pos[i]),
1183 ty * y);
1184 }
1185
1186 glTexCoord2f (tx * pBox->x2, ty * y);
1187 glVertex2i (pBox->x2, y);
1188
1189 for (i = 0; i < iTC; i++)
1190 {
1191 (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2),
1192 tx * (pBox->x1 + pos[i]),
1193 ty * y);
1194 (*GL::multiTexCoord2f) (GL_TEXTURE1_ARB + (i * 2) + 1,
1195 tx * (pBox->x1 - pos[i]),
1196 ty * y);
1197 }
1198
1199 glTexCoord2f (tx * pBox->x1, ty * y);
1200 glVertex2i (pBox->x1, y);
12011192
1202 pBox++;1193 pBox++;
1203 }1194 }
12041195
1205 glEnd ();
1206
1207 glDisable (GL_FRAGMENT_PROGRAM_ARB);
1208
1209 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
1210
1211 if (wasCulled)1196 if (wasCulled)
1212 glEnable (GL_CULL_FACE);1197 glEnable (GL_CULL_FACE);
12131198
@@ -1231,92 +1216,70 @@
1231 float *scr;1216 float *scr;
12321217
1233 GLTexture::MatrixList ml;1218 GLTexture::MatrixList ml;
1234 GLWindow::Geometry *gm;
12351219
1236 gWindow->geometry ().reset ();1220 gWindow->vertexBuffer ()->begin ();
1237 gWindow->glAddGeometry (ml, bScreen->tmpRegion2, infiniteRegion);1221 gWindow->glAddGeometry (ml, bScreen->tmpRegion2, infiniteRegion);
12381222
1239 if (!gWindow->geometry ().vCount)1223 if (!gWindow->vertexBuffer ()->end ())
1240 return;1224 return;
12411225
1242 gm = &gWindow->geometry ();1226 GLVertexBuffer *vb = gWindow->vertexBuffer ();
12431227
1244 nVertices = (gm->indexCount) ? gm->indexCount: gm->vCount;1228 nVertices = vb->countVertices ();
1245 nQuadCombine = 1;1229 nQuadCombine = 1;
12461230
1247 stride = gm->vertexStride;1231 stride = vb->getVertexStride ();
1248 vert = gm->vertices + (stride - 3);1232 vert = vb->getVertices () + (stride - 3);
12491233
1250 /* we need to find the best value here */1234 /* construct quads from bounding vertices */
1251 if (nVertices <= MAX_VERTEX_PROJECT_COUNT)1235 minX = screen->width ();
1236 maxX = 0;
1237 minY = screen->height ();
1238 maxY = 0;
1239 minZ = 1000000;
1240 maxZ = -1000000;
1241
1242 for (i = 0; i < vb->countVertices (); i++)
1252 {1243 {
1253 for (i = 0; i < nVertices; i++)1244 v = vert + (stride * i);
1254 {1245
1255 if (gm->indexCount)1246 if (v[0] < minX)
1256 {1247 minX = v[0];
1257 v = vert + (stride * gm->indices[i]);1248
1258 }1249 if (v[0] > maxX)
1259 else1250 maxX = v[0];
1260 {1251
1261 v = vert + (stride * i);1252 if (v[1] < minY)
1262 }1253 minY = v[1];
12631254
1264 vertices[i * 3] = v[0];1255 if (v[1] > maxY)
1265 vertices[(i * 3) + 1] = v[1];1256 maxY = v[1];
1266 vertices[(i * 3) + 2] = v[2];1257
1267 }1258 if (v[2] < minZ)
1259 minZ = v[2];
1260
1261 if (v[2] > maxZ)
1262 maxZ = v[2];
1268 }1263 }
1269 else1264
1265 vertices[0] = vertices[9] = minX;
1266 vertices[1] = vertices[4] = minY;
1267 vertices[3] = vertices[6] = maxX;
1268 vertices[7] = vertices[10] = maxY;
1269 vertices[2] = vertices[5] = maxZ;
1270 vertices[8] = vertices[11] = maxZ;
1271
1272 nVertices = 4;
1273
1274 if (maxZ != minZ)
1270 {1275 {
1271 minX = screen->width ();1276 vertices[12] = vertices[21] = minX;
1272 maxX = 0;1277 vertices[13] = vertices[16] = minY;
1273 minY = screen->height ();1278 vertices[15] = vertices[18] = maxX;
1274 maxY = 0;1279 vertices[19] = vertices[22] = maxY;
1275 minZ = 1000000;1280 vertices[14] = vertices[17] = minZ;
1276 maxZ = -1000000;1281 vertices[20] = vertices[23] = minZ;
12771282 nQuadCombine = 2;
1278 for (i = 0; i < gm->vCount; i++)
1279 {
1280 v = vert + (stride * i);
1281
1282 if (v[0] < minX)
1283 minX = v[0];
1284
1285 if (v[0] > maxX)
1286 maxX = v[0];
1287
1288 if (v[1] < minY)
1289 minY = v[1];
1290
1291 if (v[1] > maxY)
1292 maxY = v[1];
1293
1294 if (v[2] < minZ)
1295 minZ = v[2];
1296
1297 if (v[2] > maxZ)
1298 maxZ = v[2];
1299 }
1300
1301 vertices[0] = vertices[9] = minX;
1302 vertices[1] = vertices[4] = minY;
1303 vertices[3] = vertices[6] = maxX;
1304 vertices[7] = vertices[10] = maxY;
1305 vertices[2] = vertices[5] = maxZ;
1306 vertices[8] = vertices[11] = maxZ;
1307
1308 nVertices = 4;
1309
1310 if (maxZ != minZ)
1311 {
1312 vertices[12] = vertices[21] = minX;
1313 vertices[13] = vertices[16] = minY;
1314 vertices[15] = vertices[18] = maxX;
1315 vertices[19] = vertices[22] = maxY;
1316 vertices[14] = vertices[17] = minZ;
1317 vertices[20] = vertices[23] = minZ;
1318 nQuadCombine = 2;
1319 }
1320 }1283 }
13211284
1322 if (!bScreen->projectVertices (output, transform, vertices, scrv,1285 if (!bScreen->projectVertices (output, transform, vertices, scrv,
@@ -1349,10 +1312,10 @@
13491312
1350 int x1, y1, x2, y2;1313 int x1, y1, x2, y2;
13511314
1352 x1 = minX - bScreen->filterRadius;1315 x1 = minX - bScreen->filterRadius - 0.5;
1353 y1 = screen->height () - maxY - bScreen->filterRadius;1316 y1 = screen->height () - maxY - bScreen->filterRadius - 0.5;
1354 x2 = maxX + bScreen->filterRadius + 0.5f;1317 x2 = maxX + bScreen->filterRadius + 0.5;
1355 y2 = screen->height () - minY + bScreen->filterRadius + 0.5f;1318 y2 = screen->height () - minY + bScreen->filterRadius + 0.5;
13561319
13571320
1358 bScreen->tmpRegion3 += CompRect (x1, y1, x2 - x1, y2 - y1);1321 bScreen->tmpRegion3 += CompRect (x1, y1, x2 - x1, y2 - y1);
@@ -1360,21 +1323,15 @@
1360 }1323 }
1361}1324}
13621325
1363bool1326void
1364BlurWindow::updateDstTexture (const GLMatrix &transform,1327BlurWindow::determineBlurRegion (int filter,
1365 CompRect *pExtents,1328 const GLMatrix &transform,
1366 int clientThreshold)1329 int clientThreshold)
1367{1330{
1368 int y;
1369 int filter;
1370
1371 filter = bScreen->optionGetFilter ();
1372
1373 bScreen->tmpRegion3 = CompRegion ();1331 bScreen->tmpRegion3 = CompRegion ();
13741332
1375 if (filter == BlurOptions::FilterGaussian)1333 if (filter == BlurOptions::FilterGaussian)
1376 {1334 {
1377
1378 if (state[BLUR_STATE_DECOR].threshold)1335 if (state[BLUR_STATE_DECOR].threshold)
1379 {1336 {
1380 int xx, yy, ww, hh;1337 int xx, yy, ww, hh;
@@ -1394,7 +1351,7 @@
1394 // bottom1351 // bottom
1395 xx = window->x () - window->output ().left;1352 xx = window->x () - window->output ().left;
1396 yy = window->y () + window->height ();1353 yy = window->y () + window->height ();
1397 ww = window->width () + window->output ().left +1354 ww = window->width () + window->output ().left +
1398 window->output ().right;1355 window->output ().right;
1399 hh = window->output ().bottom;1356 hh = window->output ().bottom;
14001357
@@ -1410,7 +1367,7 @@
1410 ww = window->output ().left;1367 ww = window->output ().left;
1411 hh = window->height ();1368 hh = window->height ();
14121369
1413 bScreen->tmpRegion2 = bScreen->tmpRegion.intersected (1370 bScreen->tmpRegion2 = bScreen->tmpRegion.intersected (
1414 CompRect (xx, yy, ww, hh));1371 CompRect (xx, yy, ww, hh));
14151372
1416 if (!bScreen->tmpRegion2.isEmpty ())1373 if (!bScreen->tmpRegion2.isEmpty ())
@@ -1422,7 +1379,7 @@
1422 ww = window->output ().right;1379 ww = window->output ().right;
1423 hh = window->height ();1380 hh = window->height ();
14241381
1425 bScreen->tmpRegion2 = bScreen->tmpRegion.intersected (1382 bScreen->tmpRegion2 = bScreen->tmpRegion.intersected (
1426 CompRect (xx, yy, ww, hh));1383 CompRect (xx, yy, ww, hh));
14271384
1428 if (!bScreen->tmpRegion2.isEmpty ())1385 if (!bScreen->tmpRegion2.isEmpty ())
@@ -1451,141 +1408,147 @@
1451 projectRegion (bScreen->output, transform);1408 projectRegion (bScreen->output, transform);
1452 }1409 }
14531410
1454 bScreen->tmpRegion = bScreen->region.intersected (bScreen->tmpRegion3);1411 projectedBlurRegion = bScreen->tmpRegion3;
1412}
1413
1414bool
1415BlurWindow::updateDstTexture (const GLMatrix &transform,
1416 CompRect *pExtents,
1417 unsigned int mask)
1418{
1419 bool ret = false;
1420 int filter = bScreen->optionGetFilter ();
1421
1422 /* Paint region n projected region */
1423 bScreen->tmpRegion = bScreen->region.intersected (projectedBlurRegion);
1424
1425 if (!bScreen->blurOcclusion &&
1426 !(mask & PAINT_WINDOW_TRANSFORMED_MASK))
1427 bScreen->tmpRegion -= clip;
14551428
1456 if (bScreen->tmpRegion.isEmpty ())1429 if (bScreen->tmpRegion.isEmpty ())
1457 return false;1430 return false;
14581431
1459 *pExtents = bScreen->tmpRegion.boundingRect ();1432 CompRect br (bScreen->tmpRegion.boundingRect ());
14601433
1461 if (!bScreen->texture[0] || bScreen->width != screen->width () ||1434 if (bScreen->texture.empty () ||
1462 bScreen->height != screen->height ())1435 CompSize (bScreen->texture[0]->width (),
1436 bScreen->texture[0]->height ()) !=
1437 static_cast <const CompSize &> (*screen))
1463 {1438 {
1464 int i, textures = 1;1439 bScreen->texture = GLTexture::imageDataToTexture (NULL,
14651440 *screen,
1466 bScreen->width = screen->width ();1441 GL_RGB,
1467 bScreen->height = screen->height ();1442#if IMAGE_BYTE_ORDER == MSBFirst
14681443 GL_UNSIGNED_INT_8_8_8_8_REV);
1469 if (GL::textureNonPowerOfTwo ||1444#else
1470 (POWER_OF_TWO (bScreen->width) && POWER_OF_TWO (bScreen->height)))1445 GL_UNSIGNED_BYTE);
1446#endif
1447
1448 if (bScreen->texture[0]->target () == GL_TEXTURE_2D)
1471 {1449 {
1472 bScreen->target = GL_TEXTURE_2D;1450 bScreen->tx = 1.0f / bScreen->texture[0]->width ();
1473 bScreen->tx = 1.0f / bScreen->width;1451 bScreen->ty = 1.0f / bScreen->texture[0]->height ();
1474 bScreen->ty = 1.0f / bScreen->height;
1475 }1452 }
1476 else1453 else
1477 {1454 {
1478 bScreen->target = GL_TEXTURE_RECTANGLE_NV;
1479 bScreen->tx = 1;1455 bScreen->tx = 1;
1480 bScreen->ty = 1;1456 bScreen->ty = 1;
1481 }1457 }
14821458
1483 if (filter == BlurOptions::FilterGaussian)1459 if (filter == BlurOptions::FilterGaussian)
1484 {1460 {
1485 if (GL::fbo && !bScreen->fbo)1461 bScreen->fbo->allocate (*screen,
1486 (*GL::genFramebuffers) (1, &bScreen->fbo);1462 NULL,
14871463 GL_BGRA);
1488 if (!bScreen->fbo)1464
1465 /* We have to bind it in order to get a status */
1466 GLFramebufferObject *old = bScreen->fbo->bind();
1467 bool status = bScreen->fbo->checkStatus ();
1468 old->bind();
1469
1470 if (!status)
1489 compLogMessage ("blur", CompLogLevelError,1471 compLogMessage ("blur", CompLogLevelError,
1490 "Failed to create framebuffer object");1472 "Failed to create framebuffer object");
14911473
1492 textures = 2;1474 else
1493 }
1494
1495 bScreen->fboStatus = false;
1496
1497 for (i = 0; i < textures; i++)
1498 {
1499 if (!bScreen->texture[i])
1500 glGenTextures (1, &bScreen->texture[i]);
1501
1502 glBindTexture (bScreen->target, bScreen->texture[i]);
1503
1504 glTexImage2D (bScreen->target, 0, GL_RGB,
1505 bScreen->width,
1506 bScreen->height,
1507 0, GL_BGRA,
1508
1509#if IMAGE_BYTE_ORDER == MSBFirst
1510 GL_UNSIGNED_INT_8_8_8_8_REV,
1511#else
1512 GL_UNSIGNED_BYTE,
1513#endif
1514
1515 NULL);
1516
1517 glTexParameteri (bScreen->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1518 glTexParameteri (bScreen->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1519
1520 if (filter == BlurOptions::FilterMipmap)
1521 {1475 {
1522 if (!GL::fbo)1476 unsigned int filter = (bScreen->gScreen->driverHasBrokenFBOMipmaps () ?
1523 {1477 GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR);
1524 compLogMessage ("blur", CompLogLevelWarn,1478 bScreen->gScreen->setTextureFilter (filter);
1525 "GL_EXT_framebuffer_object extension "1479
1526 "is required for mipmap filter");1480 bScreen->fbo->tex ()->enable (GLTexture::Good);
1527 }1481
1528 else if (bScreen->target != GL_TEXTURE_2D)1482 const CompRect &r (*bScreen->fbo->tex ());
1529 {1483
1530 compLogMessage ("blur", CompLogLevelWarn,1484 glCopyTexSubImage2D (bScreen->fbo->tex ()->target (),
1531 "GL_ARB_texture_non_power_of_two "1485 0, 0, 0, 0, 0,
1532 "extension is required for mipmap filter");1486 r.width (),
1533 }1487 r.height ());
1534 else1488
1535 {1489 if (!bScreen->gScreen->driverHasBrokenFBOMipmaps ())
1536 glTexParameteri (bScreen->target, GL_TEXTURE_MIN_FILTER,1490 GL::generateMipmap (bScreen->fbo->tex ()->target ());
1537 GL_LINEAR_MIPMAP_LINEAR);1491
1538 glTexParameteri (bScreen->target, GL_TEXTURE_MAG_FILTER,1492 bScreen->fbo->tex ()->disable ();
1539 GL_LINEAR_MIPMAP_LINEAR);
1540 }
1541 }1493 }
1542
1543 glTexParameteri (bScreen->target, GL_TEXTURE_WRAP_S,
1544 GL_CLAMP_TO_EDGE);
1545 glTexParameteri (bScreen->target, GL_TEXTURE_WRAP_T,
1546 GL_CLAMP_TO_EDGE);
1547
1548 glCopyTexSubImage2D (bScreen->target, 0, 0, 0, 0, 0,
1549 bScreen->width, bScreen->height);
1550 }1494 }
1495
1496 /* Set update region to entire screen */
1497 br.setGeometry (0, 0,
1498 screen->width (),
1499 screen->height ());
1551 }1500 }
1552 else1501
1502 *pExtents = br;
1503
1504 CompRegion *updateRegion = NULL;
1505 updateRegion = &bScreen->tmpRegion;
1506
1507 foreach (GLTexture *tex, bScreen->texture)
1553 {1508 {
1554 glBindTexture (bScreen->target, bScreen->texture[0]);1509 /* We need to set the active texture filter to GL_LINEAR_MIPMAP_LINEAR */
15551510 if (filter == BlurOptions::FilterMipmap &&
1556 CompRect br = bScreen->tmpRegion.boundingRect ();1511 !bScreen->gScreen->driverHasBrokenFBOMipmaps ())
15571512 bScreen->gScreen->setTextureFilter (GL_LINEAR_MIPMAP_LINEAR);
1558 y = screen->height () - br.y2 ();1513
15591514 tex->enable (GLTexture::Good);
1560 glCopyTexSubImage2D (bScreen->target, 0,1515
1561 br.x1 (), y,1516 CompRect::vector rects (updateRegion->rects ());
1562 br.x1 (), y,1517
1563 br.width (),1518 foreach (const CompRect &r, rects)
1564 br.height ());1519 {
1565 }1520 int y = screen->height () - r.y2 ();
15661521
1567 switch (filter) {1522 glCopyTexSubImage2D (bScreen->texture[0]->target (), 0,
1568 case BlurOptions::FilterGaussian:1523 r.x1 (), y,
1569 return bScreen->fboUpdate (bScreen->tmpRegion.handle ()->rects,1524 r.x1 (), y,
1570 bScreen->tmpRegion.numRects ());1525 r.width (),
1571 case BlurOptions::FilterMipmap:1526 r.height ());
1572 if (GL::generateMipmap)1527 }
1573 (*GL::generateMipmap) (bScreen->target);1528
1574 break;1529 /* Force mipmap regeneration, because GLTexture assumes static
1575 case BlurOptions::Filter4xbilinear:1530 * textures and won't do it for us */
1576 break;1531 if (filter == BlurOptions::FilterMipmap &&
1577 }1532 !bScreen->gScreen->driverHasBrokenFBOMipmaps ())
15781533 GL::generateMipmap (tex->target ());
1579 glBindTexture (bScreen->target, 0);1534
15801535 if (filter == BlurOptions::FilterGaussian)
1581 return true;1536 ret |= bScreen->fboUpdate (updateRegion->handle ()->rects,
1537 updateRegion->numRects ());
1538 else
1539 ret = true;
1540
1541 tex->disable ();
1542 }
1543
1544 return ret;
1582}1545}
15831546
1584bool1547bool
1585BlurWindow::glDraw (const GLMatrix &transform,1548BlurWindow::glDraw (const GLMatrix &transform,
1586 GLFragment::Attrib &attrib,1549 const GLWindowPaintAttrib &attrib,
1587 const CompRegion &region,1550 const CompRegion &region,
1588 unsigned int mask)1551 unsigned int mask)
1589{1552{
1590 bool status;1553 bool status;
15911554
@@ -1603,22 +1566,11 @@
1603 {1566 {
1604 bool clipped = false;1567 bool clipped = false;
1605 CompRect box (0, 0, 0, 0);1568 CompRect box (0, 0, 0, 0);
1606 CompRegion reg;
16071569
1608 bScreen->mvp = GLMatrix (bScreen->gScreen->projectionMatrix ());1570 bScreen->mvp = *(bScreen->gScreen->projectionMatrix ());
1609 bScreen->mvp *= transform;1571 bScreen->mvp *= transform;
16101572
1611 if (mask & PAINT_WINDOW_TRANSFORMED_MASK)1573 if (updateDstTexture (transform, &box, mask))
1612 reg = infiniteRegion;
1613 else
1614 reg = region;
1615
1616 bScreen->tmpRegion = this->region.intersected (reg);
1617 if (!bScreen->blurOcclusion &&
1618 !(mask & PAINT_WINDOW_TRANSFORMED_MASK))
1619 bScreen->tmpRegion -= clip;
1620
1621 if (updateDstTexture (transform, &box, clientThreshold))
1622 {1574 {
1623 if (clientThreshold)1575 if (clientThreshold)
1624 {1576 {
@@ -1672,11 +1624,17 @@
1672 if (clipped)1624 if (clipped)
1673 {1625 {
1674 GLTexture::MatrixList ml;1626 GLTexture::MatrixList ml;
16751627 const CompRegion *reg = NULL;
1676 gWindow->geometry ().reset ();1628
16771629 if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
1678 gWindow->glAddGeometry (ml, bScreen->tmpRegion, reg);1630 reg = &infiniteRegion;
1679 if (gWindow->geometry ().vCount)1631 else
1632 reg = &region;
1633
1634 gWindow->vertexBuffer ()->begin ();
1635 gWindow->glAddGeometry (ml, bScreen->tmpRegion, *reg);
1636 gWindow->vertexBuffer ()->color4f (1.0, 1.0, 1.0, 1.0);
1637 if (gWindow->vertexBuffer ()->end ())
1680 {1638 {
1681 CompRect clearBox = bScreen->stencilBox;1639 CompRect clearBox = bScreen->stencilBox;
16821640
@@ -1684,28 +1642,44 @@
16841642
1685 glEnable (GL_STENCIL_TEST);1643 glEnable (GL_STENCIL_TEST);
1686 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);1644 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1645 glStencilMask (1);
16871646
1688 if (clearBox.x2 () > clearBox.x1 () &&1647 if (clearBox.x2 () > clearBox.x1 () &&
1689 clearBox.y2 () > clearBox.y1 ())1648 clearBox.y2 () > clearBox.y1 ())
1690 {1649 {
1691 glPushAttrib (GL_SCISSOR_BIT);1650 /* We might have a previous scissor region, so we need
1692 glEnable (GL_SCISSOR_TEST);1651 * to fetch it, however slow that might be .. */
1652 GLint scissorBox[4];
1653 GLboolean scissorEnabled;
1654
1655 scissorEnabled = glIsEnabled (GL_SCISSOR_TEST);
1656 glGetIntegerv (GL_SCISSOR_BOX, scissorBox);
1657
1658 if (!scissorEnabled)
1659 glEnable (GL_SCISSOR_TEST);
1660
1693 glScissor (clearBox.x1 (),1661 glScissor (clearBox.x1 (),
1694 screen->height () - clearBox.y2 (),1662 screen->height () - clearBox.y2 (),
1695 clearBox.width (),1663 clearBox.width (),
1696 clearBox.height ());1664 clearBox.height ());
1665 glClearStencil (0);
1697 glClear (GL_STENCIL_BUFFER_BIT);1666 glClear (GL_STENCIL_BUFFER_BIT);
1698 glPopAttrib ();1667
1668 if (!scissorEnabled)
1669 glDisable (GL_SCISSOR_TEST);
1670
1671 glScissor (scissorBox[0], scissorBox[1],
1672 scissorBox[2], scissorBox[3]);
1699 }1673 }
17001674
1701 glStencilFunc (GL_ALWAYS, 0x1, ~0);1675 glStencilFunc (GL_ALWAYS, 1, 1);
1702 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);1676 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
17031677
1704 glDisableClientState (GL_TEXTURE_COORD_ARRAY);1678 /* Render a white polygon where the window is */
1705 gWindow->glDrawGeometry ();1679 gWindow->vertexBuffer ()->render (transform);
1706 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
17071680
1708 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);1681 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1682 glStencilMask (0);
1709 glDisable (GL_STENCIL_TEST);1683 glDisable (GL_STENCIL_TEST);
1710 }1684 }
1711 }1685 }
@@ -1720,10 +1694,248 @@
1720 return status;1694 return status;
1721}1695}
17221696
1697namespace
1698{
1699void setupShadersAndUniformsForDstBlur (GLTexture *texture,
1700 GLWindow *gWindow,
1701 BlurScreen *bScreen,
1702 int &unit,
1703 int &iTC,
1704 float threshold)
1705{
1706 GLfloat dx, dy;
1707
1708 switch (bScreen->optionGetFilter ())
1709 {
1710 case BlurOptions::Filter4xbilinear:
1711 {
1712 dx = bScreen->tx / 2.1f;
1713 dy = bScreen->ty / 2.1f;
1714
1715 unit = 1; // FIXME!!
1716
1717 const CompString &function (
1718 bScreen->getDstBlurFragmentFunction (
1719 texture, unit, 0, 0));
1720
1721 if (!function.empty ())
1722 {
1723 (*GL::activeTexture) (GL_TEXTURE0 + unit);
1724 bScreen->texture[0]->enable (GLTexture::Good);
1725 gWindow->vertexBuffer ()->addTexCoords (unit, 0, NULL);
1726 (*GL::activeTexture) (GL_TEXTURE0);
1727
1728 gWindow->addShaders ("blur",
1729 "",
1730 function);
1731
1732 gWindow->vertexBuffer ()->addUniform4f ("blur_translation",
1733 bScreen->tx, bScreen->ty,
1734 0.0f, 0.0f);
1735
1736 gWindow->vertexBuffer ()->addUniform4f ("blur_threshold",
1737 threshold,
1738 threshold,
1739 threshold,
1740 threshold);
1741
1742 gWindow->vertexBuffer ()->addUniform4f ("blur_dxdy",
1743 dx, dy, 0.0, 0.0);
1744 }
1745 }
1746 break;
1747 case BlurOptions::FilterGaussian:
1748 {
1749#if INDEPENDENT_TEX_SUPPORTED
1750 if (bScreen->optionGetIndependentTex ())
1751 {
1752 /* leave one free texture unit for fragment position */
1753 iTC = MAX (0, GL::maxTextureUnits -
1754 (gWindow->geometry ().texUnits + 1));
1755 if (iTC)
1756 iTC = MIN (iTC / 2, bScreen->numTexop);
1757 }
1758#endif
1759 unit = 1;
1760
1761 const CompString &function (
1762 bScreen->getDstBlurFragmentFunction (
1763 texture, unit, iTC,
1764 gWindow->vertexBuffer ()->countTextures ()));
1765
1766 if (!function.empty ())
1767 {
1768 gWindow->addShaders ("blur",
1769 "",
1770 function);
1771
1772 (*GL::activeTexture) (GL_TEXTURE0 + unit);
1773 bScreen->texture[0]->enable (GLTexture::Good);
1774 gWindow->vertexBuffer ()->addTexCoords (unit, 0, NULL);
1775 (*GL::activeTexture) (GL_TEXTURE0 + unit + 1);
1776 bScreen->fbo->tex ()->enable (GLTexture::Good);
1777 gWindow->vertexBuffer ()->addTexCoords (unit + 1, 0, NULL);
1778 (*GL::activeTexture) (GL_TEXTURE0);
1779
1780 gWindow->vertexBuffer ()->addUniform4f ("blur_translation",
1781 bScreen->tx, bScreen->ty,
1782 0.0f, 0.0f);
1783
1784 gWindow->vertexBuffer ()->addUniform4f ("blur_threshold",
1785 threshold,
1786 threshold,
1787 threshold,
1788 threshold);
1789#if INDEPENDENT_TEX_SUPPORTED
1790 if (iTC)
1791 {
1792 GLMatrix tm, rm;
1793 float s_gen[4], t_gen[4], q_gen[4];
1794
1795 for (unsigned int i = 0; i < 16; i++)
1796 tm[i] = 0;
1797 tm[0] = (bScreen->output->width () / 2.0) *
1798 bScreen->tx;
1799 tm[5] = (bScreen->output->height () / 2.0) *
1800 bScreen->ty;
1801 tm[10] = 1;
1802
1803 tm[12] = (bScreen->output->width () / 2.0 +
1804 bScreen->output->x1 ()) * bScreen->tx;
1805 tm[13] = (bScreen->output->height () / 2.0 +
1806 screen->height () -
1807 bScreen->output->y2 ()) * bScreen->ty;
1808 tm[14] = 1;
1809 tm[15] = 1;
1810
1811 tm *= bScreen->mvp;
1812
1813 for (int i = 0; i < iTC; i++)
1814 {
1815 (*GL::activeTexture) (GL_TEXTURE0 +
1816 gWindow->geometry ().texUnits + (i * 2));
1817
1818 rm.reset ();
1819 rm[13] = bScreen->ty * bScreen->pos[i];
1820 rm *= tm;
1821
1822 s_gen[0] = rm[0];
1823 s_gen[1] = rm[4];
1824 s_gen[2] = rm[8];
1825 s_gen[3] = rm[12];
1826 t_gen[0] = rm[1];
1827 t_gen[1] = rm[5];
1828 t_gen[2] = rm[9];
1829 t_gen[3] = rm[13];
1830 q_gen[0] = rm[3];
1831 q_gen[1] = rm[7];
1832 q_gen[2] = rm[11];
1833 q_gen[3] = rm[15];
1834
1835 glTexGenfv (GL_T, GL_OBJECT_PLANE, t_gen);
1836 glTexGenfv (GL_S, GL_OBJECT_PLANE, s_gen);
1837 glTexGenfv (GL_Q, GL_OBJECT_PLANE, q_gen);
1838
1839 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE,
1840 GL_OBJECT_LINEAR);
1841 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE,
1842 GL_OBJECT_LINEAR);
1843 glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE,
1844 GL_OBJECT_LINEAR);
1845
1846 glEnable (GL_TEXTURE_GEN_S);
1847 glEnable (GL_TEXTURE_GEN_T);
1848 glEnable (GL_TEXTURE_GEN_Q);
1849
1850 (*GL::activeTexture) (GL_TEXTURE0 +
1851 gWindow->geometry ().texUnits +
1852 1 + (i * 2));
1853
1854 rm.reset ();
1855
1856 rm[13] = -bScreen->ty * bScreen->pos[i];
1857 rm *= tm;
1858
1859 s_gen[0] = rm[0];
1860 s_gen[1] = rm[4];
1861 s_gen[2] = rm[8];
1862 s_gen[3] = rm[12];
1863 t_gen[0] = rm[1];
1864 t_gen[1] = rm[5];
1865 t_gen[2] = rm[9];
1866 t_gen[3] = rm[13];
1867 q_gen[0] = rm[3];
1868 q_gen[1] = rm[7];
1869 q_gen[2] = rm[11];
1870 q_gen[3] = rm[15];
1871
1872 glTexGenfv (GL_T, GL_OBJECT_PLANE, t_gen);
1873 glTexGenfv (GL_S, GL_OBJECT_PLANE, s_gen);
1874 glTexGenfv (GL_Q, GL_OBJECT_PLANE, q_gen);
1875
1876 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE,
1877 GL_OBJECT_LINEAR);
1878 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE,
1879 GL_OBJECT_LINEAR);
1880 glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE,
1881 GL_OBJECT_LINEAR);
1882
1883 glEnable (GL_TEXTURE_GEN_S);
1884 glEnable (GL_TEXTURE_GEN_T);
1885 glEnable (GL_TEXTURE_GEN_Q);
1886 }
1887
1888 (*GL::activeTexture) (GL_TEXTURE0);
1889 }
1890#endif
1891 }
1892 }
1893 break;
1894 case BlurOptions::FilterMipmap:
1895 {
1896 unit = 1; // FIXME!!
1897
1898 const CompString &function (
1899 bScreen->getDstBlurFragmentFunction (texture,
1900 unit,
1901 0,
1902 0));
1903
1904 if (!function.empty ())
1905 {
1906 float lod =
1907 bScreen->optionGetMipmapLod ();
1908
1909 gWindow->addShaders ("blur",
1910 "",
1911 function);
1912
1913 (*GL::activeTexture) (GL_TEXTURE0 + unit);
1914 bScreen->texture[0]->enable (GLTexture::Good);
1915 gWindow->vertexBuffer ()->addTexCoords (unit, 0, NULL);
1916 (*GL::activeTexture) (GL_TEXTURE0);
1917
1918 gWindow->vertexBuffer ()->addUniform4f ("blur_translation",
1919 bScreen->tx, bScreen->ty,
1920 0.0f, lod);
1921
1922 gWindow->vertexBuffer ()->addUniform4f ("blur_threshold",
1923 threshold,
1924 threshold,
1925 threshold,
1926 threshold);
1927 }
1928 }
1929 break;
1930 }
1931}
1932}
1933
1723void1934void
1724BlurWindow::glDrawTexture (GLTexture *texture,1935BlurWindow::glDrawTexture (GLTexture *texture,
1725 GLFragment::Attrib &attrib,1936 const GLMatrix &matrix,
1726 unsigned int mask)1937 const GLWindowPaintAttrib &attrib,
1938 unsigned int mask)
1727{1939{
1728 int state = BLUR_STATE_DECOR;1940 int state = BLUR_STATE_DECOR;
17291941
@@ -1733,295 +1945,108 @@
17331945
1734 if (blur || this->state[state].active)1946 if (blur || this->state[state].active)
1735 {1947 {
1736 GLFragment::Attrib fa (attrib);
1737 int param, function;
1738 int unit = 0;1948 int unit = 0;
1739 GLfloat dx, dy;
1740 int iTC = 0;1949 int iTC = 0;
17411950
1742 if (blur)1951 if (blur)
1743 {1952 {
1744 param = fa.allocParameters (1);1953 GLfloat dx, dy;
17451954
1746 function = bScreen->getSrcBlurFragmentFunction (texture, param);1955 const CompString &function (
1747 if (function)1956 bScreen->getSrcBlurFragmentFunction (texture));
1957
1958 if (!function.empty ())
1748 {1959 {
1749 fa.addFunction (function);1960 gWindow->addShaders ("focusblur",
1961 "",
1962 function);
17501963
1751 dx = ((texture->matrix ().xx / 2.1f) * blur) / 65535.0f;1964 dx = ((texture->matrix ().xx / 2.1f) * blur) / 65535.0f;
1752 dy = ((texture->matrix ().yy / 2.1f) * blur) / 65535.0f;1965 dy = ((texture->matrix ().yy / 2.1f) * blur) / 65535.0f;
17531966
1754 (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB,1967 gWindow->vertexBuffer ()->addUniform4f ("focusblur_input_offset",
1755 param, dx, dy, dx, -dy);1968 dx, dy, dx, -dy);
17561969
1757 /* bi-linear filtering is required */1970 /* bi-linear filtering is required */
1758 mask |= PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;1971 mask |= PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
1759 }1972 }
1760 }1973 }
17611974
1975 /* We are drawing the scraped texture, blur it */
1762 if (this->state[state].active)1976 if (this->state[state].active)
1763 {1977 {
1764 GLFragment::Attrib dstFa (fa);1978 setupShadersAndUniformsForDstBlur (texture,
1765 float threshold = (float) this->state[state].threshold;1979 gWindow,
17661980 bScreen,
1767 switch (bScreen->optionGetFilter ()) {1981 unit,
1768 case BlurOptions::Filter4xbilinear:1982 iTC,
1769 dx = bScreen->tx / 2.1f;1983 this->state[state].threshold);
1770 dy = bScreen->ty / 2.1f;
1771
1772 param = dstFa.allocParameters (3);
1773 unit = dstFa.allocTextureUnits (1);
1774
1775 function = bScreen->getDstBlurFragmentFunction (
1776 texture, param, unit, 0, 0);
1777 if (function)
1778 {
1779 dstFa.addFunction (function);
1780
1781 (*GL::activeTexture) (GL_TEXTURE0_ARB + unit);
1782 glBindTexture (bScreen->target, bScreen->texture[0]);
1783 (*GL::activeTexture) (GL_TEXTURE0_ARB);
1784
1785 (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB,
1786 param,
1787 bScreen->tx, bScreen->ty,
1788 0.0f, 0.0f);
1789
1790 (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB,
1791 param + 1,
1792 threshold, threshold,
1793 threshold, threshold);
1794
1795 (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB,
1796 param + 2,
1797 dx, dy, 0.0f, 0.0f);
1798 }
1799 break;
1800 case BlurOptions::FilterGaussian:
1801 if (bScreen->optionGetIndependentTex ())
1802 {
1803 /* leave one free texture unit for fragment position */
1804 iTC = MAX (0, GL::maxTextureUnits -
1805 (gWindow->geometry ().texUnits + 1));
1806 if (iTC)
1807 iTC = MIN (iTC / 2, bScreen->numTexop);
1808 }
1809
1810 param = dstFa.allocParameters (2);
1811 unit = dstFa.allocTextureUnits (2);
1812
1813 function = bScreen->getDstBlurFragmentFunction (
1814 texture, param, unit, iTC,
1815 gWindow->geometry ().texUnits);
1816
1817 if (function)
1818 {
1819 dstFa.addFunction (function);
1820
1821 (*GL::activeTexture) (GL_TEXTURE0_ARB + unit);
1822 glBindTexture (bScreen->target, bScreen->texture[0]);
1823 (*GL::activeTexture) (GL_TEXTURE0_ARB + unit + 1);
1824 glBindTexture (bScreen->target, bScreen->texture[1]);
1825 (*GL::activeTexture) (GL_TEXTURE0_ARB);
1826
1827 (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB,
1828 param, bScreen->tx,
1829 bScreen->ty, 0.0f, 0.0f);
1830
1831 (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB,
1832 param + 1,
1833 threshold, threshold,
1834 threshold, threshold);
1835
1836 if (iTC)
1837 {
1838 GLMatrix tm, rm;
1839 float s_gen[4], t_gen[4], q_gen[4];
1840
1841 for (unsigned int i = 0; i < 16; i++)
1842 tm[i] = 0;
1843 tm[0] = (bScreen->output->width () / 2.0) *
1844 bScreen->tx;
1845 tm[5] = (bScreen->output->height () / 2.0) *
1846 bScreen->ty;
1847 tm[10] = 1;
1848
1849 tm[12] = (bScreen->output->width () / 2.0 +
1850 bScreen->output->x1 ()) * bScreen->tx;
1851 tm[13] = (bScreen->output->height () / 2.0 +
1852 screen->height () -
1853 bScreen->output->y2 ()) * bScreen->ty;
1854 tm[14] = 1;
1855 tm[15] = 1;
1856
1857 tm *= bScreen->mvp;
1858
1859 for (int i = 0; i < iTC; i++)
1860 {
1861 (*GL::activeTexture) (GL_TEXTURE0_ARB +
1862 gWindow->geometry ().texUnits + (i * 2));
1863
1864 rm.reset ();
1865 rm[13] = bScreen->ty * bScreen->pos[i];
1866 rm *= tm;
1867
1868 s_gen[0] = rm[0];
1869 s_gen[1] = rm[4];
1870 s_gen[2] = rm[8];
1871 s_gen[3] = rm[12];
1872 t_gen[0] = rm[1];
1873 t_gen[1] = rm[5];
1874 t_gen[2] = rm[9];
1875 t_gen[3] = rm[13];
1876 q_gen[0] = rm[3];
1877 q_gen[1] = rm[7];
1878 q_gen[2] = rm[11];
1879 q_gen[3] = rm[15];
1880
1881 glTexGenfv (GL_T, GL_OBJECT_PLANE, t_gen);
1882 glTexGenfv (GL_S, GL_OBJECT_PLANE, s_gen);
1883 glTexGenfv (GL_Q, GL_OBJECT_PLANE, q_gen);
1884
1885 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE,
1886 GL_OBJECT_LINEAR);
1887 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE,
1888 GL_OBJECT_LINEAR);
1889 glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE,
1890 GL_OBJECT_LINEAR);
1891
1892 glEnable (GL_TEXTURE_GEN_S);
1893 glEnable (GL_TEXTURE_GEN_T);
1894 glEnable (GL_TEXTURE_GEN_Q);
1895
1896 (*GL::activeTexture) (GL_TEXTURE0_ARB +
1897 gWindow->geometry ().texUnits +
1898 1 + (i * 2));
1899
1900 rm.reset ();
1901
1902 rm[13] = -bScreen->ty * bScreen->pos[i];
1903 rm *= tm;
1904
1905 s_gen[0] = rm[0];
1906 s_gen[1] = rm[4];
1907 s_gen[2] = rm[8];
1908 s_gen[3] = rm[12];
1909 t_gen[0] = rm[1];
1910 t_gen[1] = rm[5];
1911 t_gen[2] = rm[9];
1912 t_gen[3] = rm[13];
1913 q_gen[0] = rm[3];
1914 q_gen[1] = rm[7];
1915 q_gen[2] = rm[11];
1916 q_gen[3] = rm[15];
1917
1918 glTexGenfv (GL_T, GL_OBJECT_PLANE, t_gen);
1919 glTexGenfv (GL_S, GL_OBJECT_PLANE, s_gen);
1920 glTexGenfv (GL_Q, GL_OBJECT_PLANE, q_gen);
1921
1922 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE,
1923 GL_OBJECT_LINEAR);
1924 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE,
1925 GL_OBJECT_LINEAR);
1926 glTexGeni (GL_Q, GL_TEXTURE_GEN_MODE,
1927 GL_OBJECT_LINEAR);
1928
1929 glEnable (GL_TEXTURE_GEN_S);
1930 glEnable (GL_TEXTURE_GEN_T);
1931 glEnable (GL_TEXTURE_GEN_Q);
1932 }
1933
1934 (*GL::activeTexture) (GL_TEXTURE0_ARB);
1935 }
1936
1937 }
1938 break;
1939 case BlurOptions::FilterMipmap:
1940 param = dstFa.allocParameters (2);
1941 unit = dstFa.allocTextureUnits (1);
1942
1943 function =
1944 bScreen->getDstBlurFragmentFunction (texture, param,
1945 unit, 0, 0);
1946 if (function)
1947 {
1948 float lod =
1949 bScreen->optionGetMipmapLod ();
1950
1951 dstFa.addFunction (function);
1952
1953 (*GL::activeTexture) (GL_TEXTURE0_ARB + unit);
1954 glBindTexture (bScreen->target, bScreen->texture[0]);
1955 (*GL::activeTexture) (GL_TEXTURE0_ARB);
1956
1957 (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB,
1958 param,
1959 bScreen->tx, bScreen->ty,
1960 0.0f, lod);
1961
1962 (*GL::programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB,
1963 param + 1,
1964 threshold, threshold,
1965 threshold, threshold);
1966 }
1967 break;
1968 }
19691984
1970 if (this->state[state].clipped ||1985 if (this->state[state].clipped ||
1971 (!bScreen->blurOcclusion && !clip.isEmpty ()))1986 (!bScreen->blurOcclusion && !clip.isEmpty ()))
1972 {1987 {
1973 glEnable (GL_STENCIL_TEST);1988 glEnable (GL_STENCIL_TEST);
19741989
1990 /* Don't touch the stencil buffer */
1975 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);1991 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
1976 glStencilFunc (GL_EQUAL, 0x1, ~0);1992
19771993 /* Draw region with blur only where the stencil test passes */
1978 /* draw region with destination blur */1994 glStencilFunc (GL_EQUAL, 1, 1);
1979 gWindow->glDrawTexture (texture, dstFa, mask);1995
19801996 /* draw region with destination blur - we are relying
1981 glStencilFunc (GL_EQUAL, 0, ~0);1997 * on a fairly awkward side-effect here which clears our
1998 * active shader once this call is complete */
1999 gWindow->glDrawTexture (texture, matrix, attrib, mask);
2000
2001 /* Allow drawing in everywhere but where we just drew */
2002 glStencilFunc (GL_EQUAL, 0, 1);
19822003
1983 /* draw region without destination blur */2004 /* draw region without destination blur */
1984 gWindow->glDrawTexture (texture, fa, mask);2005 gWindow->glDrawTexture (texture, matrix, attrib, mask);
19852006
1986 glDisable (GL_STENCIL_TEST);2007 glDisable (GL_STENCIL_TEST);
1987 }2008 }
1988 else2009 else
1989 {2010 {
1990 /* draw with destination blur */2011 /* draw with destination blur */
1991 gWindow->glDrawTexture (texture, dstFa, mask);2012 gWindow->glDrawTexture (texture, matrix, attrib, mask);
1992 }2013 }
1993 }2014 }
1994 else2015 else
1995 {2016 {
1996 gWindow->glDrawTexture (texture, fa, mask);2017 gWindow->glDrawTexture (texture, matrix, attrib, mask);
1997 }2018 }
19982019
1999 if (unit)2020 if (unit)
2000 {2021 {
2001 (*GL::activeTexture) (GL_TEXTURE0_ARB + unit);2022 (*GL::activeTexture) (GL_TEXTURE0 + unit);
2002 glBindTexture (bScreen->target, 0);2023 bScreen->texture[0]->disable ();
2003 (*GL::activeTexture) (GL_TEXTURE0_ARB + unit + 1);2024 (*GL::activeTexture) (GL_TEXTURE0 + unit + 1);
2004 glBindTexture (bScreen->target, 0);2025 if (bScreen->fbo &&
2005 (*GL::activeTexture) (GL_TEXTURE0_ARB);2026 bScreen->fbo->tex ())
2027 bScreen->fbo->tex ()->disable ();
2028 (*GL::activeTexture) (GL_TEXTURE0);
2006 }2029 }
20072030
2031#if INDEPENDENT_TEX_SUPPORTED
2008 if (iTC)2032 if (iTC)
2009 {2033 {
2010 int i;2034 int i;
2011 for (i = gWindow->geometry ().texUnits;2035 for (i = gWindow->geometry ().texUnits;
2012 i < gWindow->geometry ().texUnits + (2 * iTC); i++)2036 i < gWindow->geometry ().texUnits + (2 * iTC); i++)
2013 {2037 {
2014 (*GL::activeTexture) (GL_TEXTURE0_ARB + i);2038 (*GL::activeTexture) (GL_TEXTURE0 + i);
2015 glDisable (GL_TEXTURE_GEN_S);2039 glDisable (GL_TEXTURE_GEN_S);
2016 glDisable (GL_TEXTURE_GEN_T);2040 glDisable (GL_TEXTURE_GEN_T);
2017 glDisable (GL_TEXTURE_GEN_Q);2041 glDisable (GL_TEXTURE_GEN_Q);
2018 }2042 }
2019 (*GL::activeTexture) (GL_TEXTURE0_ARB);2043 (*GL::activeTexture) (GL_TEXTURE0);
2020 }2044 }
2045#endif
2021 }2046 }
2022 else2047 else
2023 {2048 {
2024 gWindow->glDrawTexture (texture, attrib, mask);2049 gWindow->glDrawTexture (texture, matrix, attrib, mask);
2025 }2050 }
2026}2051}
20272052
@@ -2115,7 +2140,7 @@
2115 screen->activeWindow ());2140 screen->activeWindow ());
21162141
2117 w = screen->findWindow (xid);2142 w = screen->findWindow (xid);
2118 if (w && GL::fragmentProgram)2143 if (w && GL::shaders)
2119 {2144 {
2120 BLUR_SCREEN (screen);2145 BLUR_SCREEN (screen);
2121 BLUR_WINDOW (w);2146 BLUR_WINDOW (w);
@@ -2175,7 +2200,7 @@
2175 cScreen->damageScreen ();2200 cScreen->damageScreen ();
2176 break;2201 break;
2177 case BlurOptions::AlphaBlur:2202 case BlurOptions::AlphaBlur:
2178 if (GL::fragmentProgram && optionGetAlphaBlur ())2203 if (GL::shaders && optionGetAlphaBlur ())
2179 alphaBlur = true;2204 alphaBlur = true;
2180 else2205 else
2181 alphaBlur = false;2206 alphaBlur = false;
@@ -2228,12 +2253,15 @@
2228 dstBlurFunctions (0),2253 dstBlurFunctions (0),
2229 output (NULL),2254 output (NULL),
2230 count (0),2255 count (0),
2231 program (0),
2232 maxTemp (32),2256 maxTemp (32),
2233 fbo (0),2257 fbo (new GLFramebufferObject ()),
2234 fboStatus (0)2258 oldDrawFramebuffer (NULL),
2259 determineProjectedBlurRegionsPass (false),
2260 damageQuery (cScreen->getDamageQuery (boost::bind (
2261 &BlurScreen::markAreaDirty,
2262 this,
2263 _1)))
2235{2264{
2236
2237 blurAtom[BLUR_STATE_CLIENT] =2265 blurAtom[BLUR_STATE_CLIENT] =
2238 XInternAtom (screen->dpy (), "_COMPIZ_WM_WINDOW_BLUR", 0);2266 XInternAtom (screen->dpy (), "_COMPIZ_WM_WINDOW_BLUR", 0);
2239 blurAtom[BLUR_STATE_DECOR] =2267 blurAtom[BLUR_STATE_DECOR] =
@@ -2242,27 +2270,20 @@
2242 blurTime = 1000.0f / optionGetBlurSpeed ();2270 blurTime = 1000.0f / optionGetBlurSpeed ();
2243 blurOcclusion = optionGetOcclusion ();2271 blurOcclusion = optionGetOcclusion ();
22442272
2245 for (int i = 0; i < 2; i++)
2246 texture[i] = 0;
2247
2248 glGetIntegerv (GL_STENCIL_BITS, &stencilBits);2273 glGetIntegerv (GL_STENCIL_BITS, &stencilBits);
2249 if (!stencilBits)2274 if (!stencilBits)
2250 compLogMessage ("blur", CompLogLevelWarn,2275 compLogMessage ("blur", CompLogLevelWarn,
2251 "No stencil buffer. Region based blur disabled");2276 "No stencil buffer. Region based blur disabled");
22522277
2253 /* We need GL_ARB_fragment_program for blur */2278 /* We need GL_ARB_shading_language_100 for blur */
2254 if (GL::fragmentProgram)2279 if (GL::shaders)
2255 alphaBlur = optionGetAlphaBlur ();2280 alphaBlur = optionGetAlphaBlur ();
2256 else2281 else
2257 alphaBlur = false;2282 alphaBlur = false;
22582283
2259 if (GL::fragmentProgram)2284 if (GL::shaders)
2260 {2285 {
2261 int tmp[4];2286 maxTemp = 1024; // FIXME!!!!!!!
2262 GL::getProgramiv (GL_FRAGMENT_PROGRAM_ARB,
2263 GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB,
2264 tmp);
2265 maxTemp = tmp[0];
2266 }2287 }
22672288
2268 updateFilterRadius ();2289 updateFilterRadius ();
@@ -2277,20 +2298,7 @@
22772298
2278BlurScreen::~BlurScreen ()2299BlurScreen::~BlurScreen ()
2279{2300{
2280 foreach (BlurFunction &bf, srcBlurFunctions)
2281 GLFragment::destroyFragmentFunction (bf.id);
2282 foreach (BlurFunction &bf, dstBlurFunctions)
2283 GLFragment::destroyFragmentFunction (bf.id);
2284
2285 cScreen->damageScreen ();2301 cScreen->damageScreen ();
2286
2287 if (fbo)
2288 (*GL::deleteFramebuffers) (1, &fbo);
2289
2290 for (int i = 0; i < 2; i++)
2291 if (texture[i])
2292 glDeleteTextures (1, &texture[i]);
2293
2294}2302}
22952303
2296BlurWindow::BlurWindow (CompWindow *w) :2304BlurWindow::BlurWindow (CompWindow *w) :
@@ -2329,10 +2337,11 @@
2329bool2337bool
2330BlurPluginVTable::init ()2338BlurPluginVTable::init ()
2331{2339{
2332 if (CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) &&2340 if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) |
2333 CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) &&2341 !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) |
2334 CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))2342 !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
2335 return true;2343 return false;
23362344
2337 return false;2345 return true;
2338}2346}
2347
23392348
=== modified file 'plugins/blur/src/blur.h'
--- plugins/blur/src/blur.h 2012-09-07 22:37:20 +0000
+++ plugins/blur/src/blur.h 2016-05-14 02:33:05 +0000
@@ -23,32 +23,35 @@
23 * Author: David Reveman <davidr@novell.com>23 * Author: David Reveman <davidr@novell.com>
24 */24 */
2525
26#include <iosfwd>
27#include <boost/shared_ptr.hpp>
28
29#include <stdlib.h>
30#include <string.h>
31#include <math.h>
32#include <X11/Xatom.h>
33
26#include "blur_options.h"34#include "blur_options.h"
2735
28#include <composite/composite.h>36#include <composite/composite.h>
29#include <opengl/opengl.h>37#include <opengl/opengl.h>
38#include <opengl/program.h>
30#include <decoration.h>39#include <decoration.h>
3140
32#include <stdlib.h>41
33#include <string.h>42const unsigned short BLUR_GAUSSIAN_RADIUS_MAX = 15;
34#include <math.h>43
3544const unsigned short BLUR_STATE_CLIENT = 0;
3645const unsigned short BLUR_STATE_DECOR = 1;
37#include <X11/Xatom.h>46const unsigned short BLUR_STATE_NUM = 2;
38#include <GL/glu.h>47
3948struct BlurFunction
4049{
41extern const unsigned short BLUR_GAUSSIAN_RADIUS_MAX;50 CompString shader;
42
43struct BlurFunction {
44
45 GLFragment::FunctionId id;
46
47 int target;51 int target;
48 int param;
49 int unit;
50 int startTC;52 int startTC;
51 int numITC;53 int numITC;
54 int saturation;
52};55};
5356
54struct BlurBox {57struct BlurBox {
@@ -56,10 +59,6 @@
56 decor_point_t p2;59 decor_point_t p2;
57};60};
5861
59extern const unsigned short BLUR_STATE_CLIENT;
60extern const unsigned short BLUR_STATE_DECOR;
61extern const unsigned short BLUR_STATE_NUM;
62
63struct BlurState {62struct BlurState {
64 int threshold;63 int threshold;
65 std::vector<BlurBox> box;64 std::vector<BlurBox> box;
@@ -88,6 +87,8 @@
88 void preparePaint (int);87 void preparePaint (int);
89 void donePaint ();88 void donePaint ();
9089
90 void damageCutoff ();
91
91 bool glPaintOutput (const GLScreenPaintAttrib &,92 bool glPaintOutput (const GLScreenPaintAttrib &,
92 const GLMatrix &, const CompRegion &,93 const GLMatrix &, const CompRegion &,
93 CompOutput *, unsigned int);94 CompOutput *, unsigned int);
@@ -99,12 +100,11 @@
99 void updateFilterRadius ();100 void updateFilterRadius ();
100 void blurReset ();101 void blurReset ();
101102
102 GLFragment::FunctionId getSrcBlurFragmentFunction (GLTexture *, int);103 const CompString & getSrcBlurFragmentFunction (GLTexture *);
103 GLFragment::FunctionId getDstBlurFragmentFunction (GLTexture *texture,104 const CompString & getDstBlurFragmentFunction (GLTexture *texture,
104 int param,105 int unit,
105 int unit,106 int numITC,
106 int numITC,107 int startTC);
107 int startTC);
108108
109 bool projectVertices (CompOutput *output,109 bool projectVertices (CompOutput *output,
110 const GLMatrix &transform,110 const GLMatrix &transform,
@@ -112,8 +112,9 @@
112 float *scr,112 float *scr,
113 int n);113 int n);
114114
115 bool loadFragmentProgram (GLuint *program,115 bool loadFragmentProgram (boost::shared_ptr <GLProgram> &program,
116 const char *string);116 const char *vertex,
117 const char *fragment);
117118
118 bool loadFilterProgram (int numITC);119 bool loadFilterProgram (int numITC);
119120
@@ -152,24 +153,34 @@
152 CompOutput *output;153 CompOutput *output;
153 int count;154 int count;
154155
155 GLuint texture[2];156 GLTexture::List texture;
156157
157 GLenum target;
158 float tx;158 float tx;
159 float ty;159 float ty;
160 int width;160 int width;
161 int height;161 int height;
162162
163 GLuint program;163 boost::shared_ptr <GLProgram> program;
164 int maxTemp;164 int maxTemp;
165 GLuint fbo;165 boost::shared_ptr <GLFramebufferObject> fbo;
166 bool fboStatus;166
167 GLFramebufferObject *oldDrawFramebuffer;
167168
168 float amp[BLUR_GAUSSIAN_RADIUS_MAX];169 float amp[BLUR_GAUSSIAN_RADIUS_MAX];
169 float pos[BLUR_GAUSSIAN_RADIUS_MAX];170 float pos[BLUR_GAUSSIAN_RADIUS_MAX];
170 int numTexop;171 int numTexop;
171172
172 GLMatrix mvp;173 GLMatrix mvp;
174
175 bool determineProjectedBlurRegionsPass;
176 bool allowAreaDirtyOnOwnDamageBuffer;
177 CompRegion backbufferUpdateRegionThisFrame;
178
179 compiz::composite::buffertracking::AgeDamageQuery::Ptr damageQuery;
180
181 private:
182
183 bool markAreaDirty (const CompRegion &r);
173};184};
174185
175class BlurWindow :186class BlurWindow :
@@ -188,11 +199,16 @@
188199
189 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,200 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,
190 const CompRegion &, unsigned int);201 const CompRegion &, unsigned int);
191 bool glDraw (const GLMatrix &, GLFragment::Attrib &,202 void glTransformationComplete (const GLMatrix &matrix,
203 const CompRegion &region,
204 unsigned int mask);
205
206 bool glDraw (const GLMatrix &, const GLWindowPaintAttrib &,
192 const CompRegion &, unsigned int);207 const CompRegion &, unsigned int);
193 void glDrawTexture (GLTexture *texture, GLFragment::Attrib &,208 void glDrawTexture (GLTexture *texture,
209 const GLMatrix &,
210 const GLWindowPaintAttrib &,
194 unsigned int);211 unsigned int);
195
196 void updateRegion ();212 void updateRegion ();
197213
198 void setBlur (int state,214 void setBlur (int state,
@@ -206,9 +222,13 @@
206 void projectRegion (CompOutput *output,222 void projectRegion (CompOutput *output,
207 const GLMatrix &transform);223 const GLMatrix &transform);
208224
225 void determineBlurRegion (int filter,
226 const GLMatrix &transform,
227 int clientThreshold);
228
209 bool updateDstTexture (const GLMatrix &transform,229 bool updateDstTexture (const GLMatrix &transform,
210 CompRect *pExtents,230 CompRect *pExtents,
211 int clientThreshold);231 unsigned int mask);
212232
213 public:233 public:
214 CompWindow *window;234 CompWindow *window;
@@ -225,6 +245,7 @@
225245
226 CompRegion region;246 CompRegion region;
227 CompRegion clip;247 CompRegion clip;
248 CompRegion projectedBlurRegion;
228};249};
229250
230#define BLUR_SCREEN(s) \251#define BLUR_SCREEN(s) \
231252
=== modified file 'plugins/opengl/DRIVERS'
--- plugins/opengl/DRIVERS 2013-02-17 07:28:12 +0000
+++ plugins/opengl/DRIVERS 2016-05-14 02:33:05 +0000
@@ -74,3 +74,13 @@
74 RESOLVED. WORKAROUND: force the usage of the copy-to-texture path74 RESOLVED. WORKAROUND: force the usage of the copy-to-texture path
75 when using this driver ("Chromium") and binding an externally75 when using this driver ("Chromium") and binding an externally
76 managed pixmap to a texture76 managed pixmap to a texture
77
78vmwgfx
79======
80
81 1. vmwgfx does not implement glGenerateMipmap for FBO-backed
82 textures.
83
84 RESOLVED. WORKAROUND: do not use glGenerateMipmap with vmwgfx. This
85 means that some functionality, like smoothed blurs will not be
86 available on this driver.
7787
=== modified file 'plugins/opengl/include/opengl/opengl.h'
--- plugins/opengl/include/opengl/opengl.h 2015-10-26 17:15:43 +0000
+++ plugins/opengl/include/opengl/opengl.h 2016-05-14 02:33:05 +0000
@@ -59,7 +59,7 @@
59#include <opengl/programcache.h>59#include <opengl/programcache.h>
60#include <opengl/shadercache.h>60#include <opengl/shadercache.h>
6161
62#define COMPIZ_OPENGL_ABI 762#define COMPIZ_OPENGL_ABI 8
6363
64/*64/*
65 * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but65 * Some plugins check for #ifdef USE_MODERN_COMPIZ_GL. Support it for now, but
@@ -851,6 +851,8 @@
851851
852 bool glInitContext (XVisualInfo *);852 bool glInitContext (XVisualInfo *);
853853
854 bool driverHasBrokenFBOMipmaps () const;
855
854 WRAPABLE_HND (0, GLScreenInterface, bool, glPaintOutput,856 WRAPABLE_HND (0, GLScreenInterface, bool, glPaintOutput,
855 const GLScreenPaintAttrib &, const GLMatrix &,857 const GLScreenPaintAttrib &, const GLMatrix &,
856 const CompRegion &, CompOutput *, unsigned int);858 const CompRegion &, CompOutput *, unsigned int);
@@ -957,12 +959,20 @@
957 unsigned int max = MAXSHORT);959 unsigned int max = MAXSHORT);
958 virtual void glDrawTexture (GLTexture *texture, const GLMatrix &,960 virtual void glDrawTexture (GLTexture *texture, const GLMatrix &,
959 const GLWindowPaintAttrib &, unsigned int);961 const GLWindowPaintAttrib &, unsigned int);
962
963 /**
964 * Hookable function to notify transformation was complete, plugins
965 * should use the results of transformation from glPaint here
966 */
967 virtual void glTransformationComplete (const GLMatrix &matrix,
968 const CompRegion &region,
969 unsigned int mask);
960};970};
961971
962extern template class PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI>;972extern template class PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI>;
963973
964class GLWindow :974class GLWindow :
965 public WrapableHandler<GLWindowInterface, 4>,975 public WrapableHandler<GLWindowInterface, 5>,
966 public PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI>976 public PluginClassHandler<GLWindow, CompWindow, COMPIZ_OPENGL_ABI>
967{977{
968 public:978 public:
@@ -1041,6 +1051,8 @@
1041 WRAPABLE_HND (3, GLWindowInterface, void, glDrawTexture,1051 WRAPABLE_HND (3, GLWindowInterface, void, glDrawTexture,
1042 GLTexture *texture, const GLMatrix &,1052 GLTexture *texture, const GLMatrix &,
1043 const GLWindowPaintAttrib &, unsigned int);1053 const GLWindowPaintAttrib &, unsigned int);
1054 WRAPABLE_HND (4, GLWindowInterface, void, glTransformationComplete,
1055 const GLMatrix &, const CompRegion &, unsigned int);
10441056
1045 friend class GLScreen;1057 friend class GLScreen;
1046 friend class PrivateGLScreen;1058 friend class PrivateGLScreen;
10471059
=== modified file 'plugins/opengl/include/opengl/program.h'
--- plugins/opengl/include/opengl/program.h 2012-05-17 10:41:21 +0000
+++ plugins/opengl/include/opengl/program.h 2016-05-14 02:33:05 +0000
@@ -40,7 +40,7 @@
40class GLProgram40class GLProgram
41{41{
42 public:42 public:
43 GLProgram (CompString &vertexShader, CompString &fragmentShader);43 GLProgram (const CompString &vertexShader, const CompString &fragmentShader);
44 ~GLProgram ();44 ~GLProgram ();
4545
46 bool valid ();46 bool valid ();
4747
=== modified file 'plugins/opengl/include/opengl/vertexbuffer.h'
--- plugins/opengl/include/opengl/vertexbuffer.h 2012-08-14 06:33:22 +0000
+++ plugins/opengl/include/opengl/vertexbuffer.h 2016-05-14 02:33:05 +0000
@@ -89,6 +89,7 @@
89 void addTexCoords (GLuint texture,89 void addTexCoords (GLuint texture,
90 GLuint nTexcoords,90 GLuint nTexcoords,
91 const GLfloat *texcoords);91 const GLfloat *texcoords);
92 GLuint countTextures () const;
9293
93 void addUniform (const char *name, GLfloat value);94 void addUniform (const char *name, GLfloat value);
94 void addUniform (const char *name, GLint value);95 void addUniform (const char *name, GLint value);
9596
=== modified file 'plugins/opengl/src/paint.cpp'
--- plugins/opengl/src/paint.cpp 2015-04-07 14:20:32 +0000
+++ plugins/opengl/src/paint.cpp 2016-05-14 02:33:05 +0000
@@ -1367,6 +1367,14 @@
1367 return true;1367 return true;
1368}1368}
13691369
1370void
1371GLWindow::glTransformationComplete (const GLMatrix &matrix,
1372 const CompRegion &reg,
1373 unsigned int mask)
1374{
1375 WRAPABLE_HND_FUNCTN (glTransformationComplete, matrix, reg, mask);
1376}
1377
1370bool1378bool
1371GLWindow::glPaint (const GLWindowPaintAttrib &attrib,1379GLWindow::glPaint (const GLWindowPaintAttrib &attrib,
1372 const GLMatrix &transform,1380 const GLMatrix &transform,
@@ -1384,6 +1392,8 @@
13841392
1385 priv->lastMask = mask;1393 priv->lastMask = mask;
13861394
1395 glTransformationComplete (transform, region, mask);
1396
1387 if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)1397 if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
1388 {1398 {
1389 if (mask & PAINT_WINDOW_TRANSFORMED_MASK)1399 if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
13901400
=== modified file 'plugins/opengl/src/privates.h'
--- plugins/opengl/src/privates.h 2015-10-26 17:15:43 +0000
+++ plugins/opengl/src/privates.h 2016-05-14 02:33:05 +0000
@@ -131,6 +131,7 @@
131 virtual ~FrameProvider () {}131 virtual ~FrameProvider () {}
132132
133 virtual GLuint getCurrentFrame () = 0;133 virtual GLuint getCurrentFrame () = 0;
134 virtual void useCurrentFrame () = 0;
134 virtual void endFrame () = 0;135 virtual void endFrame () = 0;
135136
136 virtual bool providesPersistence () = 0;137 virtual bool providesPersistence () = 0;
@@ -268,6 +269,8 @@
268 std::vector<XToGLSync*>::size_type currentSyncNum;269 std::vector<XToGLSync*>::size_type currentSyncNum;
269 XToGLSync *currentSync;270 XToGLSync *currentSync;
270 std::vector<XToGLSync*>::size_type warmupSyncs;271 std::vector<XToGLSync*>::size_type warmupSyncs;
272
273 bool driverHasBrokenFBOMipmapImplementation;
271};274};
272275
273class PrivateGLWindow :276class PrivateGLWindow :
274277
=== modified file 'plugins/opengl/src/program.cpp'
--- plugins/opengl/src/program.cpp 2012-12-04 12:15:34 +0000
+++ plugins/opengl/src/program.cpp 2016-05-14 02:33:05 +0000
@@ -69,7 +69,7 @@
69 }69 }
70}70}
7171
72static bool compileShader (GLuint *shader, GLenum type, CompString &source)72static bool compileShader (GLuint *shader, GLenum type, const CompString &source)
73{73{
74 const GLchar *data;74 const GLchar *data;
75 GLint status;75 GLint status;
@@ -84,7 +84,7 @@
84 return (status == GL_TRUE);84 return (status == GL_TRUE);
85}85}
8686
87GLProgram::GLProgram (CompString &vertexShader, CompString &fragmentShader) :87GLProgram::GLProgram (const CompString &vertexShader, const CompString &fragmentShader) :
88 priv (new PrivateProgram ())88 priv (new PrivateProgram ())
89{89{
90 GLuint vertex, fragment;90 GLuint vertex, fragment;
9191
=== modified file 'plugins/opengl/src/screen.cpp'
--- plugins/opengl/src/screen.cpp 2015-10-26 17:15:43 +0000
+++ plugins/opengl/src/screen.cpp 2016-05-14 02:33:05 +0000
@@ -345,6 +345,10 @@
345 return age;345 return age;
346 }346 }
347347
348 void useCurrentFrame ()
349 {
350 }
351
348 void endFrame ()352 void endFrame ()
349 {353 {
350 }354 }
@@ -436,6 +440,10 @@
436 return 0;440 return 0;
437 }441 }
438442
443 void useCurrentFrame ()
444 {
445 }
446
439 void endFrame ()447 void endFrame ()
440 {448 {
441 }449 }
@@ -468,12 +476,14 @@
468476
469 unsigned int getCurrentFrame ()477 unsigned int getCurrentFrame ()
470 {478 {
479 return mAge;
480 }
481
482 void useCurrentFrame ()
483 {
471 /* We are now using this buffer, reset484 /* We are now using this buffer, reset
472 * age back to zero */485 * age back to zero */
473 unsigned int lastAge = mAge;
474 mAge = 0;486 mAge = 0;
475
476 return lastAge;
477 }487 }
478488
479 void endFrame ()489 void endFrame ()
@@ -526,6 +536,14 @@
526 return mBackbuffer->getCurrentFrame ();536 return mBackbuffer->getCurrentFrame ();
527 }537 }
528538
539 void useCurrentFrame ()
540 {
541 if (mPPRequired ())
542 mScratchbuffer->useCurrentFrame ();
543 else
544 mBackbuffer->useCurrentFrame ();
545 }
546
529 void endFrame ()547 void endFrame ()
530 {548 {
531 mScratchbuffer->endFrame ();549 mScratchbuffer->endFrame ();
@@ -896,6 +914,20 @@
896 priv->incorrectRefreshRate = true;914 priv->incorrectRefreshRate = true;
897 }915 }
898916
917 if (glVendor != NULL && strstr (glVendor, "VMware") &&
918 glRenderer != NULL && strstr (glRenderer, "on SVGA3D"))
919 {
920 /* vmwgfx has an incomplete glGenerateMipmap implementation.
921 * It does not seem to support generating mipmaps for
922 * FBO backed textures - instead it raises SIGABRT with
923 * an exception stating that the command does not exist.
924 *
925 * This is actually supported in the spec, it just seems
926 * to be unavailable in the driver.
927 */
928 priv->driverHasBrokenFBOMipmapImplementation = true;
929 }
930
899 if (strstr (glExtensions, "GL_ARB_texture_non_power_of_two"))931 if (strstr (glExtensions, "GL_ARB_texture_non_power_of_two"))
900 GL::textureNonPowerOfTwo = true;932 GL::textureNonPowerOfTwo = true;
901 GL::textureNonPowerOfTwoMipmap = GL::textureNonPowerOfTwo;933 GL::textureNonPowerOfTwoMipmap = GL::textureNonPowerOfTwo;
@@ -1163,6 +1195,12 @@
1163 return true;1195 return true;
1164}1196}
11651197
1198bool
1199GLScreen::driverHasBrokenFBOMipmaps () const
1200{
1201 return priv->driverHasBrokenFBOMipmapImplementation;
1202}
1203
11661204
1167template class PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>;1205template class PluginClassHandler<GLScreen, CompScreen, COMPIZ_OPENGL_ABI>;
11681206
@@ -1536,7 +1574,8 @@
1536 prevBlacklisted (false),1574 prevBlacklisted (false),
1537 currentSyncNum (0),1575 currentSyncNum (0),
1538 currentSync (0),1576 currentSync (0),
1539 warmupSyncs (0)1577 warmupSyncs (0),
1578 driverHasBrokenFBOMipmapImplementation (false)
1540{1579{
1541 ScreenInterface::setHandler (screen);1580 ScreenInterface::setHandler (screen);
1542 CompositeScreenInterface::setHandler (cScreen);1581 CompositeScreenInterface::setHandler (cScreen);
@@ -2608,6 +2647,7 @@
2608PrivateGLScreen::damageCutoff ()2647PrivateGLScreen::damageCutoff ()
2609{2648{
2610 cScreen->applyDamageForFrameAge (frameProvider->getCurrentFrame ());2649 cScreen->applyDamageForFrameAge (frameProvider->getCurrentFrame ());
2650 frameProvider->useCurrentFrame ();
2611 cScreen->damageCutoff ();2651 cScreen->damageCutoff ();
2612}2652}
26132653
26142654
=== modified file 'plugins/opengl/src/shadercache.cpp'
--- plugins/opengl/src/shadercache.cpp 2014-10-30 12:47:25 +0000
+++ plugins/opengl/src/shadercache.cpp 2016-05-14 02:33:05 +0000
@@ -232,10 +232,11 @@
232 else if (params.color == GLShaderVariableVarying)232 else if (params.color == GLShaderVariableVarying)
233 ss << "vColor *";233 ss << "vColor *";
234234
235 for (int i = 0; i < params.numTextures; i++)235 /* Sample first texture only */
236 ss << " texture2D(texture" << i << ", vTexCoord" << i << ") *";236 if (params.numTextures)
237237 ss << " texture2D(texture0, vTexCoord0);\n";
238 ss << " 1.0;\n";238 else
239 ss << " 1.0;\n";
239240
240 if (params.saturation) {241 if (params.saturation) {
241 ss << "vec3 desaturated = color.rgb * vec3 (0.30, 0.59, 0.11);\n" <<242 ss << "vec3 desaturated = color.rgb * vec3 (0.30, 0.59, 0.11);\n" <<
242243
=== modified file 'plugins/opengl/src/vertexbuffer.cpp'
--- plugins/opengl/src/vertexbuffer.cpp 2015-04-29 11:15:48 +0000
+++ plugins/opengl/src/vertexbuffer.cpp 2016-05-14 02:33:05 +0000
@@ -240,6 +240,11 @@
240 data.push_back (texcoords[i]);240 data.push_back (texcoords[i]);
241}241}
242242
243GLuint GLVertexBuffer::countTextures () const
244{
245 return priv->nTextures;
246}
247
243void GLVertexBuffer::addUniform (const char *name, GLfloat value)248void GLVertexBuffer::addUniform (const char *name, GLfloat value)
244{249{
245 // we're casting to double here to make our template va_arg happy250 // we're casting to double here to make our template va_arg happy
246251
=== modified file 'plugins/opengl/src/window.cpp'
--- plugins/opengl/src/window.cpp 2014-10-30 12:47:25 +0000
+++ plugins/opengl/src/window.cpp 2016-05-14 02:33:05 +0000
@@ -210,6 +210,12 @@
210 priv->needsRebind = true;210 priv->needsRebind = true;
211}211}
212212
213void
214GLWindowInterface::glTransformationComplete (const GLMatrix &matrix,
215 const CompRegion &region,
216 unsigned int mask)
217 WRAPABLE_DEF (glTransformationComplete, matrix, region, mask)
218
213bool219bool
214GLWindowInterface::glPaint (const GLWindowPaintAttrib &attrib,220GLWindowInterface::glPaint (const GLWindowPaintAttrib &attrib,
215 const GLMatrix &transform,221 const GLMatrix &transform,

Subscribers

People subscribed via source and target branches