Changeset View
Standalone View
effects/blur/blur.cpp
Show First 20 Lines • Show All 120 Lines • ▼ Show 20 Line(s) | 118 | { | |||
---|---|---|---|---|---|
121 | /* Reserve memory for: | 121 | /* Reserve memory for: | ||
122 | * - The original sized texture (1) | 122 | * - The original sized texture (1) | ||
123 | * - The downsized textures (m_downSampleIterations) | 123 | * - The downsized textures (m_downSampleIterations) | ||
124 | * - The helper texture (1) | 124 | * - The helper texture (1) | ||
125 | */ | 125 | */ | ||
126 | m_renderTargets.reserve(m_downSampleIterations + 2); | 126 | m_renderTargets.reserve(m_downSampleIterations + 2); | ||
127 | m_renderTextures.reserve(m_downSampleIterations + 2); | 127 | m_renderTextures.reserve(m_downSampleIterations + 2); | ||
128 | 128 | | |||
129 | const GLenum textureFormat = GLPlatform::instance()->isGLES() ? GL_RGBA8 : GL_SRGB8_ALPHA8; | 129 | GLenum textureFormat = GL_RGBA8; | ||
130 | | ||||
131 | // Check the color encoding of the default framebuffer | ||||
132 | if (!GLPlatform::instance()->isGLES()) { | ||||
133 | GLuint prevFbo = 0; | ||||
zzag: Do we need to check whether the default framebuffer object is bound? | |||||
fredrik: Yes, that's probably a good idea. | |||||
134 | glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, reinterpret_cast<GLint *>(&prevFbo)); | ||||
zzag: Please use `reinterpret_cast` instead of c-style cast. | |||||
135 | | ||||
136 | if (prevFbo != 0) { | ||||
137 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | ||||
138 | } | ||||
Coding style nitpick: Use curly braces even when the body of a conditional statement contains only one line. zzag: Coding style nitpick: Use curly braces even when the body of a conditional statement contains… | |||||
139 | | ||||
140 | GLenum colorEncoding = GL_LINEAR; | ||||
141 | glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_BACK_LEFT, | ||||
142 | GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, | ||||
143 | reinterpret_cast<GLint *>(&colorEncoding)); | ||||
144 | | ||||
145 | if (prevFbo != 0) { | ||||
146 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo); | ||||
147 | } | ||||
148 | | ||||
149 | if (colorEncoding == GL_SRGB) { | ||||
150 | textureFormat = GL_SRGB8_ALPHA8; | ||||
151 | } | ||||
152 | } | ||||
130 | 153 | | |||
131 | for (int i = 0; i <= m_downSampleIterations; i++) { | 154 | for (int i = 0; i <= m_downSampleIterations; i++) { | ||
132 | m_renderTextures.append(GLTexture(textureFormat, effects->virtualScreenSize() / (1 << i))); | 155 | m_renderTextures.append(GLTexture(textureFormat, effects->virtualScreenSize() / (1 << i))); | ||
133 | m_renderTextures.last().setFilter(GL_LINEAR); | 156 | m_renderTextures.last().setFilter(GL_LINEAR); | ||
134 | m_renderTextures.last().setWrapMode(GL_CLAMP_TO_EDGE); | 157 | m_renderTextures.last().setWrapMode(GL_CLAMP_TO_EDGE); | ||
135 | 158 | | |||
136 | m_renderTargets.append(new GLRenderTarget(m_renderTextures.last())); | 159 | m_renderTargets.append(new GLRenderTarget(m_renderTextures.last())); | ||
137 | } | 160 | } | ||
▲ Show 20 Lines • Show All 500 Lines • ▼ Show 20 Line(s) | |||||
638 | { | 661 | { | ||
639 | // Blur would not render correctly on a secondary monitor because of wrong coordinates | 662 | // Blur would not render correctly on a secondary monitor because of wrong coordinates | ||
640 | // BUG: 393723 | 663 | // BUG: 393723 | ||
641 | const int xTranslate = -screen.x(); | 664 | const int xTranslate = -screen.x(); | ||
642 | const int yTranslate = effects->virtualScreenSize().height() - screen.height() - screen.y(); | 665 | const int yTranslate = effects->virtualScreenSize().height() - screen.height() - screen.y(); | ||
643 | 666 | | |||
644 | const QRegion expandedBlurRegion = expand(shape) & expand(screen); | 667 | const QRegion expandedBlurRegion = expand(shape) & expand(screen); | ||
645 | 668 | | |||
646 | const bool isGLES = GLPlatform::instance()->isGLES(); | 669 | const bool useSRGB = m_renderTextures.first().internalFormat() == GL_SRGB8_ALPHA8; | ||
Do we have to worry about the looking glass effect and all other effects that render the scene to a texture? zzag: Do we have to worry about the looking glass effect and all other effects that render the scene… | |||||
Yes, those effects will need to use an sRGB texture as well. That being said, it looks to me like the blur effect is just broken in general when it's not rendering to the default framebuffer. fredrik: Yes, those effects will need to use an sRGB texture as well.
That being said, it looks to me… | |||||
And the reason is that GLRenderTarget::blitFromFramebuffer() always blits from the default framebuffer. fredrik: And the reason is that GLRenderTarget::blitFromFramebuffer() always blits from the default… | |||||
zzag: Aye, the source framebuffer object is hard coded. | |||||
I suggest that we ignore this issue in the stable branch for now since this is not a regression. I don't want to risk further fallout by changing the behavior of blitFromFramebuffer() there. That this has been broken for a very long time without anyone noticing also speaks volumes about how many people use the looking glass effect. fredrik: I suggest that we ignore this issue in the stable branch for now since this is not a regression. | |||||
zzag: Agreed. | |||||
647 | 670 | | |||
648 | // Upload geometry for the down and upsample iterations | 671 | // Upload geometry for the down and upsample iterations | ||
649 | GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); | 672 | GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); | ||
650 | vbo->reset(); | 673 | vbo->reset(); | ||
651 | 674 | | |||
652 | uploadGeometry(vbo, expandedBlurRegion.translated(xTranslate, yTranslate), shape); | 675 | uploadGeometry(vbo, expandedBlurRegion.translated(xTranslate, yTranslate), shape); | ||
653 | vbo->bindArrays(); | 676 | vbo->bindArrays(); | ||
654 | 677 | | |||
655 | const QRect sourceRect = expandedBlurRegion.boundingRect() & screen; | 678 | const QRect sourceRect = expandedBlurRegion.boundingRect() & screen; | ||
656 | const QRect destRect = sourceRect.translated(xTranslate, yTranslate); | 679 | const QRect destRect = sourceRect.translated(xTranslate, yTranslate); | ||
657 | 680 | | |||
658 | GLRenderTarget::pushRenderTargets(m_renderTargetStack); | 681 | GLRenderTarget::pushRenderTargets(m_renderTargetStack); | ||
659 | int blurRectCount = expandedBlurRegion.rectCount() * 6; | 682 | int blurRectCount = expandedBlurRegion.rectCount() * 6; | ||
660 | 683 | | |||
661 | /* | 684 | /* | ||
662 | * If the window is a dock or panel we avoid the "extended blur" effect. | 685 | * If the window is a dock or panel we avoid the "extended blur" effect. | ||
663 | * Extended blur is when windows that are not under the blurred area affect | 686 | * Extended blur is when windows that are not under the blurred area affect | ||
664 | * the final blur result. | 687 | * the final blur result. | ||
665 | * We want to avoid this on panels, because it looks really weird and ugly | 688 | * We want to avoid this on panels, because it looks really weird and ugly | ||
666 | * when maximized windows or windows near the panel affect the dock blur. | 689 | * when maximized windows or windows near the panel affect the dock blur. | ||
667 | */ | 690 | */ | ||
668 | if (isDock) { | 691 | if (isDock) { | ||
669 | m_renderTargets.last()->blitFromFramebuffer(sourceRect, destRect); | 692 | m_renderTargets.last()->blitFromFramebuffer(sourceRect, destRect); | ||
670 | 693 | | |||
671 | if (!isGLES) { | 694 | if (useSRGB) { | ||
672 | glEnable(GL_FRAMEBUFFER_SRGB); | 695 | glEnable(GL_FRAMEBUFFER_SRGB); | ||
673 | } | 696 | } | ||
674 | 697 | | |||
675 | copyScreenSampleTexture(vbo, blurRectCount, shape.translated(xTranslate, yTranslate), screenProjection); | 698 | copyScreenSampleTexture(vbo, blurRectCount, shape.translated(xTranslate, yTranslate), screenProjection); | ||
676 | } else { | 699 | } else { | ||
677 | m_renderTargets.first()->blitFromFramebuffer(sourceRect, destRect); | 700 | m_renderTargets.first()->blitFromFramebuffer(sourceRect, destRect); | ||
678 | 701 | | |||
679 | if (!isGLES) { | 702 | if (useSRGB) { | ||
680 | glEnable(GL_FRAMEBUFFER_SRGB); | 703 | glEnable(GL_FRAMEBUFFER_SRGB); | ||
681 | } | 704 | } | ||
682 | 705 | | |||
683 | // Remove the m_renderTargets[0] from the top of the stack that we will not use | 706 | // Remove the m_renderTargets[0] from the top of the stack that we will not use | ||
684 | GLRenderTarget::popRenderTarget(); | 707 | GLRenderTarget::popRenderTarget(); | ||
685 | } | 708 | } | ||
686 | 709 | | |||
687 | downSampleTexture(vbo, blurRectCount); | 710 | downSampleTexture(vbo, blurRectCount); | ||
Show All 10 Lines | 719 | #else // sigmoid shape, above y = x for x > 0.5, below y = x for x < 0.5 | |||
698 | o = 0.5f + o / (1.0f + qAbs(o)); | 721 | o = 0.5f + o / (1.0f + qAbs(o)); | ||
699 | #endif | 722 | #endif | ||
700 | glBlendColor(0, 0, 0, o); | 723 | glBlendColor(0, 0, 0, o); | ||
701 | glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); | 724 | glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); | ||
702 | } | 725 | } | ||
703 | 726 | | |||
704 | upscaleRenderToScreen(vbo, blurRectCount * (m_downSampleIterations + 1), shape.rectCount() * 6, screenProjection, windowRect.topLeft()); | 727 | upscaleRenderToScreen(vbo, blurRectCount * (m_downSampleIterations + 1), shape.rectCount() * 6, screenProjection, windowRect.topLeft()); | ||
705 | 728 | | |||
706 | if (!isGLES) { | 729 | if (useSRGB) { | ||
707 | glDisable(GL_FRAMEBUFFER_SRGB); | 730 | glDisable(GL_FRAMEBUFFER_SRGB); | ||
708 | } | 731 | } | ||
709 | 732 | | |||
710 | if (opacity < 1.0) { | 733 | if (opacity < 1.0) { | ||
711 | glDisable(GL_BLEND); | 734 | glDisable(GL_BLEND); | ||
712 | } | 735 | } | ||
713 | 736 | | |||
714 | vbo->unbindArrays(); | 737 | vbo->unbindArrays(); | ||
▲ Show 20 Lines • Show All 100 Lines • Show Last 20 Lines |
Do we need to check whether the default framebuffer object is bound?