Changeset View
Changeset View
Standalone View
Standalone View
effects/blur/blur.cpp
Show All 37 Lines | |||||
38 | { | 38 | { | ||
39 | 39 | | |||
40 | static const QByteArray s_blurAtomName = QByteArrayLiteral("_KDE_NET_WM_BLUR_BEHIND_REGION"); | 40 | static const QByteArray s_blurAtomName = QByteArrayLiteral("_KDE_NET_WM_BLUR_BEHIND_REGION"); | ||
41 | 41 | | |||
42 | BlurEffect::BlurEffect() | 42 | BlurEffect::BlurEffect() | ||
43 | { | 43 | { | ||
44 | initConfig<BlurConfig>(); | 44 | initConfig<BlurConfig>(); | ||
45 | m_shader = BlurShader::create(); | 45 | m_shader = BlurShader::create(); | ||
46 | m_simpleShader = ShaderManager::instance()->generateShaderFromResources(ShaderTrait::MapTexture, QString(), QStringLiteral("logout-blur.frag")); | | |||
47 | m_simpleTarget = new GLRenderTarget(); | | |||
48 | | ||||
49 | if (!m_simpleShader->isValid()) { | | |||
50 | qCDebug(KWINEFFECTS) << "Simple blur shader failed to load"; | | |||
51 | } | | |||
52 | 46 | | |||
53 | initBlurStrengthValues(); | 47 | initBlurStrengthValues(); | ||
54 | reconfigure(ReconfigureAll); | 48 | reconfigure(ReconfigureAll); | ||
55 | 49 | | |||
56 | // ### Hackish way to announce support. | 50 | // ### Hackish way to announce support. | ||
57 | // Should be included in _NET_SUPPORTED instead. | 51 | // Should be included in _NET_SUPPORTED instead. | ||
58 | if (m_shader && m_shader->isValid() && m_renderTargetsValid) { | 52 | if (m_shader && m_shader->isValid() && m_renderTargetsValid) { | ||
59 | net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this); | 53 | net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this); | ||
Show All 22 Lines | |||||
82 | foreach (EffectWindow *window, effects->stackingOrder()) | 76 | foreach (EffectWindow *window, effects->stackingOrder()) | ||
83 | updateBlurRegion(window); | 77 | updateBlurRegion(window); | ||
84 | } | 78 | } | ||
85 | 79 | | |||
86 | BlurEffect::~BlurEffect() | 80 | BlurEffect::~BlurEffect() | ||
87 | { | 81 | { | ||
88 | deleteFBOs(); | 82 | deleteFBOs(); | ||
89 | 83 | | |||
90 | delete m_simpleTarget; | | |||
91 | m_simpleTarget = nullptr; | | |||
92 | | ||||
93 | delete m_simpleShader; | | |||
94 | m_simpleShader = nullptr; | | |||
95 | | ||||
96 | delete m_shader; | 84 | delete m_shader; | ||
97 | m_shader = nullptr; | 85 | m_shader = nullptr; | ||
98 | } | 86 | } | ||
99 | 87 | | |||
100 | void BlurEffect::slotScreenGeometryChanged() | 88 | void BlurEffect::slotScreenGeometryChanged() | ||
101 | { | 89 | { | ||
102 | effects->makeOpenGLContextCurrent(); | 90 | effects->makeOpenGLContextCurrent(); | ||
103 | updateTexture(); | 91 | updateTexture(); | ||
▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Line(s) | |||||
230 | } | 218 | } | ||
231 | 219 | | |||
232 | void BlurEffect::reconfigure(ReconfigureFlags flags) | 220 | void BlurEffect::reconfigure(ReconfigureFlags flags) | ||
233 | { | 221 | { | ||
234 | Q_UNUSED(flags) | 222 | Q_UNUSED(flags) | ||
235 | 223 | | |||
236 | BlurConfig::self()->read(); | 224 | BlurConfig::self()->read(); | ||
237 | 225 | | |||
238 | m_useSimpleBlur = BlurConfig::useSimpleBlur(); | | |||
239 | | ||||
240 | int blurStrength = BlurConfig::blurStrength() - 1; | 226 | int blurStrength = BlurConfig::blurStrength() - 1; | ||
241 | m_downSampleIterations = blurStrengthValues[blurStrength].iteration; | 227 | m_downSampleIterations = blurStrengthValues[blurStrength].iteration; | ||
242 | m_offset = blurStrengthValues[blurStrength].offset; | 228 | m_offset = blurStrengthValues[blurStrength].offset; | ||
243 | m_expandSize = blurOffsets[m_downSampleIterations - 1].expandSize; | 229 | m_expandSize = blurOffsets[m_downSampleIterations - 1].expandSize; | ||
244 | 230 | | |||
245 | updateTexture(); | 231 | updateTexture(); | ||
246 | 232 | | |||
247 | if (!m_shader || !m_shader->isValid()) { | 233 | if (!m_shader || !m_shader->isValid()) { | ||
▲ Show 20 Lines • Show All 311 Lines • ▼ Show 20 Line(s) | 527 | if (shouldBlur(w, mask, data)) { | |||
559 | 545 | | |||
560 | //Only translated, not scaled | 546 | //Only translated, not scaled | ||
561 | } else if (translated) { | 547 | } else if (translated) { | ||
562 | shape = shape.translated(data.xTranslation(), data.yTranslation()); | 548 | shape = shape.translated(data.xTranslation(), data.yTranslation()); | ||
563 | shape = shape & region; | 549 | shape = shape & region; | ||
564 | } | 550 | } | ||
565 | 551 | | |||
566 | if (!shape.isEmpty()) { | 552 | if (!shape.isEmpty()) { | ||
567 | if (m_useSimpleBlur && | | |||
568 | w->isFullScreen() && | | |||
569 | GLRenderTarget::blitSupported() && | | |||
570 | m_simpleShader->isValid() && | | |||
571 | !GLPlatform::instance()->supports(LimitedNPOT) && | | |||
572 | shape.boundingRect() == w->geometry()) { | | |||
573 | doSimpleBlur(w, data.opacity(), data.screenProjectionMatrix()); | | |||
574 | } else { | | |||
575 | doBlur(shape, screen, data.opacity(), data.screenProjectionMatrix(), w->isDock()); | 553 | doBlur(shape, screen, data.opacity(), data.screenProjectionMatrix(), w->isDock()); | ||
576 | } | 554 | } | ||
577 | } | 555 | } | ||
578 | } | | |||
579 | 556 | | |||
580 | // Draw the window over the blurred area | 557 | // Draw the window over the blurred area | ||
581 | effects->drawWindow(w, mask, region, data); | 558 | effects->drawWindow(w, mask, region, data); | ||
582 | } | 559 | } | ||
583 | 560 | | |||
584 | void BlurEffect::paintEffectFrame(EffectFrame *frame, QRegion region, double opacity, double frameOpacity) | 561 | void BlurEffect::paintEffectFrame(EffectFrame *frame, QRegion region, double opacity, double frameOpacity) | ||
585 | { | 562 | { | ||
586 | const QRect screen = effects->virtualScreenGeometry(); | 563 | const QRect screen = effects->virtualScreenGeometry(); | ||
587 | bool valid = m_renderTargetsValid && m_shader && m_shader->isValid(); | 564 | bool valid = m_renderTargetsValid && m_shader && m_shader->isValid(); | ||
588 | 565 | | |||
589 | QRegion shape = frame->geometry().adjusted(-borderSize, -borderSize, borderSize, borderSize) & screen; | 566 | QRegion shape = frame->geometry().adjusted(-borderSize, -borderSize, borderSize, borderSize) & screen; | ||
590 | 567 | | |||
591 | if (valid && !shape.isEmpty() && region.intersects(shape.boundingRect()) && frame->style() != EffectFrameNone) { | 568 | if (valid && !shape.isEmpty() && region.intersects(shape.boundingRect()) && frame->style() != EffectFrameNone) { | ||
592 | doBlur(shape, screen, opacity * frameOpacity, frame->screenProjectionMatrix(), false); | 569 | doBlur(shape, screen, opacity * frameOpacity, frame->screenProjectionMatrix(), false); | ||
593 | } | 570 | } | ||
594 | effects->paintEffectFrame(frame, region, opacity, frameOpacity); | 571 | effects->paintEffectFrame(frame, region, opacity, frameOpacity); | ||
595 | } | 572 | } | ||
596 | 573 | | |||
597 | void BlurEffect::doSimpleBlur(EffectWindow *w, const float opacity, const QMatrix4x4 &screenProjection) | | |||
598 | { | | |||
599 | // The fragment shader uses a LOD bias of 1.75, so we need 3 mipmap levels. | | |||
600 | GLTexture blurTexture = GLTexture(GL_RGBA8, w->size(), 3); | | |||
601 | blurTexture.setFilter(GL_LINEAR_MIPMAP_LINEAR); | | |||
602 | blurTexture.setWrapMode(GL_CLAMP_TO_EDGE); | | |||
603 | | ||||
604 | m_simpleTarget->attachTexture(blurTexture); | | |||
605 | m_simpleTarget->blitFromFramebuffer(w->geometry(), QRect(QPoint(0, 0), w->size())); | | |||
606 | m_simpleTarget->detachTexture(); | | |||
607 | | ||||
608 | // Unmodified base image | | |||
609 | ShaderBinder binder(m_simpleShader); | | |||
610 | QMatrix4x4 mvp = screenProjection; | | |||
611 | mvp.translate(w->x(), w->y()); | | |||
612 | m_simpleShader->setUniform(GLShader::ModelViewProjectionMatrix, mvp); | | |||
613 | m_simpleShader->setUniform("u_alphaProgress", opacity); | | |||
614 | glEnable(GL_BLEND); | | |||
615 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | | |||
616 | blurTexture.bind(); | | |||
617 | blurTexture.generateMipmaps(); | | |||
618 | blurTexture.render(infiniteRegion(), w->geometry()); | | |||
619 | blurTexture.unbind(); | | |||
620 | glDisable(GL_BLEND); | | |||
621 | } | | |||
622 | | ||||
623 | void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float opacity, const QMatrix4x4 &screenProjection, bool isDock) | 574 | void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float opacity, const QMatrix4x4 &screenProjection, bool isDock) | ||
624 | { | 575 | { | ||
625 | QRegion expandedBlurRegion = expand(shape) & expand(screen); | 576 | QRegion expandedBlurRegion = expand(shape) & expand(screen); | ||
626 | 577 | | |||
627 | // Upload geometry for the down and upsample iterations | 578 | // Upload geometry for the down and upsample iterations | ||
628 | GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); | 579 | GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); | ||
629 | uploadGeometry(vbo, expandedBlurRegion, shape); | 580 | uploadGeometry(vbo, expandedBlurRegion, shape); | ||
630 | vbo->bindArrays(); | 581 | vbo->bindArrays(); | ||
▲ Show 20 Lines • Show All 139 Lines • Show Last 20 Lines |