Changeset View
Changeset View
Standalone View
Standalone View
effects/backgroundcontrast/contrast.cpp
Show First 20 Lines • Show All 82 Lines • ▼ Show 20 Line(s) | 78 | { | |||
---|---|---|---|---|---|
83 | 83 | | |||
84 | if (!shader || !shader->isValid()) { | 84 | if (!shader || !shader->isValid()) { | ||
85 | effects->removeSupportProperty(s_contrastAtomName, this); | 85 | effects->removeSupportProperty(s_contrastAtomName, this); | ||
86 | delete m_contrastManager; | 86 | delete m_contrastManager; | ||
87 | m_contrastManager = nullptr; | 87 | m_contrastManager = nullptr; | ||
88 | } | 88 | } | ||
89 | } | 89 | } | ||
90 | 90 | | |||
91 | void ContrastEffect::updateContrastRegion(EffectWindow *w) const | 91 | void ContrastEffect::updateContrastRegion(EffectWindow *w) | ||
92 | { | 92 | { | ||
93 | QRegion region; | 93 | QRegion region; | ||
94 | float colorTransform[16]; | 94 | float colorTransform[16]; | ||
95 | 95 | | |||
96 | const QByteArray value = w->readProperty(net_wm_contrast_region, net_wm_contrast_region, 32); | 96 | const QByteArray value = w->readProperty(net_wm_contrast_region, net_wm_contrast_region, 32); | ||
97 | 97 | | |||
98 | if (value.size() > 0 && !((value.size() - (16 * sizeof(uint32_t))) % ((4 * sizeof(uint32_t))))) { | 98 | if (value.size() > 0 && !((value.size() - (16 * sizeof(uint32_t))) % ((4 * sizeof(uint32_t))))) { | ||
99 | const uint32_t *cardinals = reinterpret_cast<const uint32_t*>(value.constData()); | 99 | const uint32_t *cardinals = reinterpret_cast<const uint32_t*>(value.constData()); | ||
100 | const float *floatCardinals = reinterpret_cast<const float*>(value.constData()); | 100 | const float *floatCardinals = reinterpret_cast<const float*>(value.constData()); | ||
101 | unsigned int i = 0; | 101 | unsigned int i = 0; | ||
102 | for (; i < ((value.size() - (16 * sizeof(uint32_t)))) / sizeof(uint32_t);) { | 102 | for (; i < ((value.size() - (16 * sizeof(uint32_t)))) / sizeof(uint32_t);) { | ||
103 | int x = cardinals[i++]; | 103 | int x = cardinals[i++]; | ||
104 | int y = cardinals[i++]; | 104 | int y = cardinals[i++]; | ||
105 | int w = cardinals[i++]; | 105 | int w = cardinals[i++]; | ||
106 | int h = cardinals[i++]; | 106 | int h = cardinals[i++]; | ||
107 | region += QRect(x, y, w, h); | 107 | region += QRect(x, y, w, h); | ||
108 | } | 108 | } | ||
109 | 109 | | |||
110 | for (unsigned int j = 0; j < 16; ++j) { | 110 | for (unsigned int j = 0; j < 16; ++j) { | ||
111 | colorTransform[j] = floatCardinals[i + j]; | 111 | colorTransform[j] = floatCardinals[i + j]; | ||
112 | } | 112 | } | ||
113 | 113 | | |||
114 | QMatrix4x4 colorMatrix(colorTransform); | 114 | QMatrix4x4 colorMatrix(colorTransform); | ||
115 | shader->setColorMatrix(colorMatrix); | 115 | m_colorMatrices[w] = colorMatrix; | ||
116 | } | 116 | } | ||
117 | 117 | | |||
118 | KWayland::Server::SurfaceInterface *surf = w->surface(); | 118 | KWayland::Server::SurfaceInterface *surf = w->surface(); | ||
119 | 119 | | |||
120 | if (surf && surf->contrast()) { | 120 | if (surf && surf->contrast()) { | ||
121 | region = surf->contrast()->region(); | 121 | region = surf->contrast()->region(); | ||
122 | shader->setColorMatrix(colorMatrix(surf->contrast()->contrast(), surf->contrast()->intensity(), surf->contrast()->saturation())); | 122 | m_colorMatrices[w] = colorMatrix(surf->contrast()->contrast(), surf->contrast()->intensity(), surf->contrast()->saturation()); | ||
123 | } | 123 | } | ||
124 | 124 | | |||
125 | //!value.isNull() full window in X11 case, surf->contrast() | 125 | //!value.isNull() full window in X11 case, surf->contrast() | ||
126 | //valid, full window in wayland case | 126 | //valid, full window in wayland case | ||
127 | if (region.isEmpty() && (!value.isNull() || (surf && surf->contrast()))) { | 127 | if (region.isEmpty() && (!value.isNull() || (surf && surf->contrast()))) { | ||
128 | // Set the data to a dummy value. | 128 | // Set the data to a dummy value. | ||
129 | // This is needed to be able to distinguish between the value not | 129 | // This is needed to be able to distinguish between the value not | ||
130 | // being set, and being set to an empty region. | 130 | // being set, and being set to an empty region. | ||
Show All 17 Lines | 137 | { | |||
148 | updateContrastRegion(w); | 148 | updateContrastRegion(w); | ||
149 | } | 149 | } | ||
150 | 150 | | |||
151 | void ContrastEffect::slotWindowDeleted(EffectWindow *w) | 151 | void ContrastEffect::slotWindowDeleted(EffectWindow *w) | ||
152 | { | 152 | { | ||
153 | if (m_contrastChangedConnections.contains(w)) { | 153 | if (m_contrastChangedConnections.contains(w)) { | ||
154 | disconnect(m_contrastChangedConnections[w]); | 154 | disconnect(m_contrastChangedConnections[w]); | ||
155 | m_contrastChangedConnections.remove(w); | 155 | m_contrastChangedConnections.remove(w); | ||
156 | m_colorMatrices.remove(w); | ||||
156 | } | 157 | } | ||
157 | } | 158 | } | ||
158 | 159 | | |||
159 | void ContrastEffect::slotPropertyNotify(EffectWindow *w, long atom) | 160 | void ContrastEffect::slotPropertyNotify(EffectWindow *w, long atom) | ||
160 | { | 161 | { | ||
161 | if (w && atom == net_wm_contrast_region) { | 162 | if (w && atom == net_wm_contrast_region) { | ||
162 | updateContrastRegion(w); | 163 | updateContrastRegion(w); | ||
163 | } | 164 | } | ||
▲ Show 20 Lines • Show All 228 Lines • ▼ Show 20 Line(s) | 375 | if (shouldContrast(w, mask, data)) { | |||
392 | 393 | | |||
393 | //Only translated, not scaled | 394 | //Only translated, not scaled | ||
394 | } else if (translated) { | 395 | } else if (translated) { | ||
395 | shape = shape.translated(data.xTranslation(), data.yTranslation()); | 396 | shape = shape.translated(data.xTranslation(), data.yTranslation()); | ||
396 | shape = shape & region; | 397 | shape = shape & region; | ||
397 | } | 398 | } | ||
398 | 399 | | |||
399 | if (!shape.isEmpty()) { | 400 | if (!shape.isEmpty()) { | ||
400 | doContrast(shape, screen, data.opacity(), data.screenProjectionMatrix()); | 401 | doContrast(w, shape, screen, data.opacity(), data.screenProjectionMatrix()); | ||
401 | } | 402 | } | ||
402 | } | 403 | } | ||
403 | 404 | | |||
404 | // Draw the window over the contrast area | 405 | // Draw the window over the contrast area | ||
405 | effects->drawWindow(w, mask, region, data); | 406 | effects->drawWindow(w, mask, region, data); | ||
406 | } | 407 | } | ||
407 | 408 | | |||
408 | void ContrastEffect::paintEffectFrame(EffectFrame *frame, QRegion region, double opacity, double frameOpacity) | 409 | void ContrastEffect::paintEffectFrame(EffectFrame *frame, QRegion region, double opacity, double frameOpacity) | ||
409 | { | 410 | { | ||
410 | //FIXME: this is a no-op for now, it should figure out the right contrast, intensity, saturation | 411 | //FIXME: this is a no-op for now, it should figure out the right contrast, intensity, saturation | ||
411 | effects->paintEffectFrame(frame, region, opacity, frameOpacity); | 412 | effects->paintEffectFrame(frame, region, opacity, frameOpacity); | ||
412 | } | 413 | } | ||
413 | 414 | | |||
414 | void ContrastEffect::doContrast(const QRegion& shape, const QRect& screen, const float opacity, const QMatrix4x4 &screenProjection) | 415 | void ContrastEffect::doContrast(EffectWindow *w, const QRegion& shape, const QRect& screen, const float opacity, const QMatrix4x4 &screenProjection) | ||
415 | { | 416 | { | ||
416 | const QRegion actualShape = shape & screen; | 417 | const QRegion actualShape = shape & screen; | ||
417 | const QRect r = actualShape.boundingRect(); | 418 | const QRect r = actualShape.boundingRect(); | ||
418 | 419 | | |||
419 | // Upload geometry for the horizontal and vertical passes | 420 | // Upload geometry for the horizontal and vertical passes | ||
420 | GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); | 421 | GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); | ||
421 | uploadGeometry(vbo, actualShape); | 422 | uploadGeometry(vbo, actualShape); | ||
422 | vbo->bindArrays(); | 423 | vbo->bindArrays(); | ||
423 | 424 | | |||
424 | // Create a scratch texture and copy the area in the back buffer that we're | 425 | // Create a scratch texture and copy the area in the back buffer that we're | ||
425 | // going to blur into it | 426 | // going to blur into it | ||
426 | GLTexture scratch(GL_RGBA8, r.width(), r.height()); | 427 | GLTexture scratch(GL_RGBA8, r.width(), r.height()); | ||
427 | scratch.setFilter(GL_LINEAR); | 428 | scratch.setFilter(GL_LINEAR); | ||
428 | scratch.setWrapMode(GL_CLAMP_TO_EDGE); | 429 | scratch.setWrapMode(GL_CLAMP_TO_EDGE); | ||
429 | scratch.bind(); | 430 | scratch.bind(); | ||
430 | 431 | | |||
431 | const QRect sg = GLRenderTarget::virtualScreenGeometry(); | 432 | const QRect sg = GLRenderTarget::virtualScreenGeometry(); | ||
432 | glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r.x() - sg.x(), sg.height() - sg.y() - r.y() - r.height(), | 433 | glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r.x() - sg.x(), sg.height() - sg.y() - r.y() - r.height(), | ||
433 | r.width(), r.height()); | 434 | r.width(), r.height()); | ||
434 | 435 | | |||
435 | // Draw the texture on the offscreen framebuffer object, while blurring it horizontally | 436 | // Draw the texture on the offscreen framebuffer object, while blurring it horizontally | ||
436 | 437 | | |||
438 | shader->setColorMatrix(m_colorMatrices.value(w)); | ||||
437 | shader->bind(); | 439 | shader->bind(); | ||
438 | 440 | | |||
439 | 441 | | |||
440 | shader->setOpacity(opacity); | 442 | shader->setOpacity(opacity); | ||
441 | // Set up the texture matrix to transform from screen coordinates | 443 | // Set up the texture matrix to transform from screen coordinates | ||
442 | // to texture coordinates. | 444 | // to texture coordinates. | ||
443 | QMatrix4x4 textureMatrix; | 445 | QMatrix4x4 textureMatrix; | ||
444 | textureMatrix.scale(1.0 / scratch.width(), -1.0 / scratch.height(), 1); | 446 | textureMatrix.scale(1.0 / scratch.width(), -1.0 / scratch.height(), 1); | ||
Show All 20 Lines |