From f4f83848b09f85ad6769227cc6870ea365a40bae Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 15 Feb 2022 13:17:43 +0200 Subject: [PATCH] kwinglutils: Make GLRenderTarget not store GLTexture reference This allows us to make the GLRenderTarget a bit nicer when using it to wrap the default fbo as we don't know what the color attachment texture is besides its size. This means that the responsibility of ensuring that the color attachment outlives the fbo is now up to the caller. However, most of kwin code has been written that way, so it's not an issue. --- src/backends/drm/shadowbuffer.cpp | 2 +- src/backends/virtual/egl_gbm_backend.cpp | 2 +- src/dmabuftexture.cpp | 2 +- src/effects/blur/blur.cpp | 39 ++++++++++--------- src/effects/blur/blur.h | 2 +- src/effects/lookingglass/lookingglass.cpp | 2 +- src/effects/magnifier/magnifier.cpp | 4 +- src/effects/screenshot/screenshot.cpp | 4 +- .../screentransform/screentransform.cpp | 2 +- src/libkwineffects/kwindeformeffect.cpp | 2 +- src/libkwineffects/kwinglutils.cpp | 21 +++++----- src/libkwineffects/kwinglutils.h | 11 +++--- .../scenes/opengl/abstract_egl_backend.cpp | 2 +- .../screencast/windowscreencastsource.cpp | 2 +- src/scenes/opengl/lanczosfilter.cpp | 2 +- src/scripting/thumbnailitem.cpp | 4 +- 16 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/backends/drm/shadowbuffer.cpp b/src/backends/drm/shadowbuffer.cpp index 768817bf0b..3d0724df3d 100644 --- a/src/backends/drm/shadowbuffer.cpp +++ b/src/backends/drm/shadowbuffer.cpp @@ -41,7 +41,7 @@ ShadowBuffer::ShadowBuffer(const QSize &size, const GbmFormat &format) m_texture.reset(new GLTexture(internalFormat(format), size)); m_texture->setFilter(GL_NEAREST); - m_renderTarget.reset(new GLRenderTarget(*m_texture)); + m_renderTarget.reset(new GLRenderTarget(m_texture.data())); if (!m_renderTarget->valid()) { qCCritical(KWIN_DRM) << "Error: framebuffer not complete!"; return; diff --git a/src/backends/virtual/egl_gbm_backend.cpp b/src/backends/virtual/egl_gbm_backend.cpp index ea216a7377..57c68a2274 100644 --- a/src/backends/virtual/egl_gbm_backend.cpp +++ b/src/backends/virtual/egl_gbm_backend.cpp @@ -84,7 +84,7 @@ void EglGbmBackend::init() initKWinGL(); m_backBuffer = new GLTexture(GL_RGB8, screens()->size().width(), screens()->size().height()); - m_fbo = new GLRenderTarget(*m_backBuffer); + m_fbo = new GLRenderTarget(m_backBuffer); if (!m_fbo->valid()) { setFailed("Could not create framebuffer object"); return; diff --git a/src/dmabuftexture.cpp b/src/dmabuftexture.cpp index 3b1feaa601..86532d24cc 100644 --- a/src/dmabuftexture.cpp +++ b/src/dmabuftexture.cpp @@ -14,7 +14,7 @@ namespace KWin DmaBufTexture::DmaBufTexture(KWin::GLTexture *texture) : m_texture(texture) - , m_framebuffer(new KWin::GLRenderTarget(*m_texture)) + , m_framebuffer(new KWin::GLRenderTarget(texture)) { } diff --git a/src/effects/blur/blur.cpp b/src/effects/blur/blur.cpp index 9a455f0d54..70d6344c43 100644 --- a/src/effects/blur/blur.cpp +++ b/src/effects/blur/blur.cpp @@ -118,6 +118,7 @@ bool BlurEffect::renderTargetsValid() const void BlurEffect::deleteFBOs() { qDeleteAll(m_renderTargets); + qDeleteAll(m_renderTextures); m_renderTargets.clear(); m_renderTextures.clear(); @@ -161,19 +162,19 @@ void BlurEffect::updateTexture() } for (int i = 0; i <= m_downSampleIterations; i++) { - m_renderTextures.append(GLTexture(textureFormat, effects->virtualScreenSize() / (1 << i))); - m_renderTextures.last().setFilter(GL_LINEAR); - m_renderTextures.last().setWrapMode(GL_CLAMP_TO_EDGE); + m_renderTextures.append(new GLTexture(textureFormat, effects->virtualScreenSize() / (1 << i))); + m_renderTextures.constLast()->setFilter(GL_LINEAR); + m_renderTextures.constLast()->setWrapMode(GL_CLAMP_TO_EDGE); - m_renderTargets.append(new GLRenderTarget(m_renderTextures.last())); + m_renderTargets.append(new GLRenderTarget(m_renderTextures.constLast())); } // This last set is used as a temporary helper texture - m_renderTextures.append(GLTexture(textureFormat, effects->virtualScreenSize())); - m_renderTextures.last().setFilter(GL_LINEAR); - m_renderTextures.last().setWrapMode(GL_CLAMP_TO_EDGE); + m_renderTextures.append(new GLTexture(textureFormat, effects->virtualScreenSize())); + m_renderTextures.constLast()->setFilter(GL_LINEAR); + m_renderTextures.constLast()->setWrapMode(GL_CLAMP_TO_EDGE); - m_renderTargets.append(new GLRenderTarget(m_renderTextures.last())); + m_renderTargets.append(new GLRenderTarget(m_renderTextures.constLast())); m_renderTargetsValid = renderTargetsValid(); @@ -693,7 +694,7 @@ void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float o const QRegion expandedBlurRegion = expand(shape) & expand(screen); - const bool useSRGB = m_renderTextures.first().internalFormat() == GL_SRGB8_ALPHA8; + const bool useSRGB = m_renderTextures.constFirst()->internalFormat() == GL_SRGB8_ALPHA8; // Upload geometry for the down and upsample iterations GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); @@ -790,10 +791,10 @@ void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float o void BlurEffect::upscaleRenderToScreen(GLVertexBuffer *vbo, int vboStart, int blurRectCount, const QMatrix4x4 &screenProjection, QPoint windowPosition) { - m_renderTextures[1].bind(); + m_renderTextures[1]->bind(); m_shader->bind(BlurShader::UpSampleType); - m_shader->setTargetTextureSize(m_renderTextures[0].size() * effects->renderTargetScale()); + m_shader->setTargetTextureSize(m_renderTextures[0]->size() * effects->renderTargetScale()); m_shader->setOffset(m_offset); m_shader->setModelViewProjectionMatrix(screenProjection); @@ -806,7 +807,7 @@ void BlurEffect::upscaleRenderToScreen(GLVertexBuffer *vbo, int vboStart, int bl void BlurEffect::applyNoise(GLVertexBuffer *vbo, int vboStart, int blurRectCount, const QMatrix4x4 &screenProjection, QPoint windowPosition) { m_shader->bind(BlurShader::NoiseSampleType); - m_shader->setTargetTextureSize(m_renderTextures[0].size() * effects->renderTargetScale()); + m_shader->setTargetTextureSize(m_renderTextures[0]->size() * effects->renderTargetScale()); m_shader->setNoiseTextureSize(m_noiseTexture->size() * effects->renderTargetScale()); m_shader->setTexturePosition(windowPosition * effects->renderTargetScale()); @@ -828,13 +829,13 @@ void BlurEffect::downSampleTexture(GLVertexBuffer *vbo, int blurRectCount) for (int i = 1; i <= m_downSampleIterations; i++) { modelViewProjectionMatrix.setToIdentity(); - modelViewProjectionMatrix.ortho(0, m_renderTextures[i].width(), m_renderTextures[i].height(), 0 , 0, 65535); + modelViewProjectionMatrix.ortho(0, m_renderTextures[i]->width(), m_renderTextures[i]->height(), 0 , 0, 65535); m_shader->setModelViewProjectionMatrix(modelViewProjectionMatrix); - m_shader->setTargetTextureSize(m_renderTextures[i].size()); + m_shader->setTargetTextureSize(m_renderTextures[i]->size()); //Copy the image from this texture - m_renderTextures[i - 1].bind(); + m_renderTextures[i - 1]->bind(); vbo->draw(GL_TRIANGLES, blurRectCount * i, blurRectCount); GLRenderTarget::popRenderTarget(); @@ -852,13 +853,13 @@ void BlurEffect::upSampleTexture(GLVertexBuffer *vbo, int blurRectCount) for (int i = m_downSampleIterations - 1; i >= 1; i--) { modelViewProjectionMatrix.setToIdentity(); - modelViewProjectionMatrix.ortho(0, m_renderTextures[i].width(), m_renderTextures[i].height(), 0 , 0, 65535); + modelViewProjectionMatrix.ortho(0, m_renderTextures[i]->width(), m_renderTextures[i]->height(), 0 , 0, 65535); m_shader->setModelViewProjectionMatrix(modelViewProjectionMatrix); - m_shader->setTargetTextureSize(m_renderTextures[i].size()); + m_shader->setTargetTextureSize(m_renderTextures[i]->size()); //Copy the image from this texture - m_renderTextures[i + 1].bind(); + m_renderTextures[i + 1]->bind(); vbo->draw(GL_TRIANGLES, blurRectCount * i, blurRectCount); GLRenderTarget::popRenderTarget(); @@ -879,7 +880,7 @@ void BlurEffect::copyScreenSampleTexture(GLVertexBuffer *vbo, int blurRectCount, * right next to this window. */ m_shader->setBlurRect(blurShape.boundingRect().adjusted(1, 1, -1, -1), effects->virtualScreenSize()); - m_renderTextures.last().bind(); + m_renderTextures.last()->bind(); vbo->draw(GL_TRIANGLES, 0, blurRectCount); GLRenderTarget::popRenderTarget(); diff --git a/src/effects/blur/blur.h b/src/effects/blur/blur.h index 1b81c99535..66209b08f8 100644 --- a/src/effects/blur/blur.h +++ b/src/effects/blur/blur.h @@ -85,7 +85,7 @@ private: private: BlurShader *m_shader; QVector m_renderTargets; - QVector m_renderTextures; + QVector m_renderTextures; QStack m_renderTargetStack; QScopedPointer m_noiseTexture; diff --git a/src/effects/lookingglass/lookingglass.cpp b/src/effects/lookingglass/lookingglass.cpp index f55f7bfa39..e40661ad32 100644 --- a/src/effects/lookingglass/lookingglass.cpp +++ b/src/effects/lookingglass/lookingglass.cpp @@ -109,7 +109,7 @@ bool LookingGlassEffect::loadData() m_texture->setFilter(GL_LINEAR_MIPMAP_LINEAR); m_texture->setWrapMode(GL_CLAMP_TO_EDGE); - m_fbo = new GLRenderTarget(*m_texture); + m_fbo = new GLRenderTarget(m_texture); if (!m_fbo->valid()) { return false; } diff --git a/src/effects/magnifier/magnifier.cpp b/src/effects/magnifier/magnifier.cpp index 6541b7da1a..4dad0869c8 100644 --- a/src/effects/magnifier/magnifier.cpp +++ b/src/effects/magnifier/magnifier.cpp @@ -206,7 +206,7 @@ void MagnifierEffect::zoomIn() effects->makeOpenGLContextCurrent(); m_texture = new GLTexture(GL_RGBA8, magnifier_size.width(), magnifier_size.height()); m_texture->setYInverted(false); - m_fbo = new GLRenderTarget(*m_texture); + m_fbo = new GLRenderTarget(m_texture); } effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH)); } @@ -245,7 +245,7 @@ void MagnifierEffect::toggle() effects->makeOpenGLContextCurrent(); m_texture = new GLTexture(GL_RGBA8, magnifier_size.width(), magnifier_size.height()); m_texture->setYInverted(false); - m_fbo = new GLRenderTarget(*m_texture); + m_fbo = new GLRenderTarget(m_texture); } } else { target_zoom = 1; diff --git a/src/effects/screenshot/screenshot.cpp b/src/effects/screenshot/screenshot.cpp index eadd66129c..d3603d5d72 100644 --- a/src/effects/screenshot/screenshot.cpp +++ b/src/effects/screenshot/screenshot.cpp @@ -224,7 +224,7 @@ void ScreenShotEffect::takeScreenShot(ScreenShotWindowData *screenshot) offscreenTexture.reset(new GLTexture(GL_RGBA8, geometry.size() * devicePixelRatio)); offscreenTexture->setFilter(GL_LINEAR); offscreenTexture->setWrapMode(GL_CLAMP_TO_EDGE); - target.reset(new GLRenderTarget(*offscreenTexture)); + target.reset(new GLRenderTarget(offscreenTexture.data())); validTarget = target->valid(); } if (validTarget) { @@ -363,7 +363,7 @@ QImage ScreenShotEffect::blitScreenshot(const QRect &geometry, qreal devicePixel if (GLRenderTarget::blitSupported() && !GLPlatform::instance()->isGLES()) { image = QImage(nativeSize.width(), nativeSize.height(), QImage::Format_ARGB32); GLTexture texture(GL_RGBA8, nativeSize.width(), nativeSize.height()); - GLRenderTarget target(texture); + GLRenderTarget target(&texture); target.blitFromFramebuffer(effects->mapToRenderTarget(geometry)); // copy content from framebuffer into image texture.bind(); diff --git a/src/effects/screentransform/screentransform.cpp b/src/effects/screentransform/screentransform.cpp index 411e8c0b2d..8f2a2fc2ce 100644 --- a/src/effects/screentransform/screentransform.cpp +++ b/src/effects/screentransform/screentransform.cpp @@ -65,7 +65,7 @@ void ScreenTransformEffect::addScreen(EffectScreen *screen) // Rendering the current scene into a texture const bool c = state.m_texture->create(); Q_ASSERT(c); - GLRenderTarget renderTarget(*state.m_texture); + GLRenderTarget renderTarget(state.m_texture.data()); GLRenderTarget::pushRenderTarget(&renderTarget); effects->renderScreen(screen); diff --git a/src/libkwineffects/kwindeformeffect.cpp b/src/libkwineffects/kwindeformeffect.cpp index 54b97bd879..1303f668ec 100644 --- a/src/libkwineffects/kwindeformeffect.cpp +++ b/src/libkwineffects/kwindeformeffect.cpp @@ -89,7 +89,7 @@ GLTexture *DeformEffectPrivate::maybeRender(EffectWindow *window, DeformOffscree offscreenData->texture.reset(new GLTexture(GL_RGBA8, textureSize)); offscreenData->texture->setFilter(GL_LINEAR); offscreenData->texture->setWrapMode(GL_CLAMP_TO_EDGE); - offscreenData->renderTarget.reset(new GLRenderTarget(*offscreenData->texture)); + offscreenData->renderTarget.reset(new GLRenderTarget(offscreenData->texture.data())); offscreenData->isDirty = true; } diff --git a/src/libkwineffects/kwinglutils.cpp b/src/libkwineffects/kwinglutils.cpp index 511af09664..5f5164736a 100644 --- a/src/libkwineffects/kwinglutils.cpp +++ b/src/libkwineffects/kwinglutils.cpp @@ -972,24 +972,22 @@ GLRenderTarget* GLRenderTarget::popRenderTarget() } GLRenderTarget::GLRenderTarget() - : mTexture(GL_TEXTURE_2D) { } -GLRenderTarget::GLRenderTarget(const GLTexture& color) - : mTexture(color) - , mSize(color.size()) +GLRenderTarget::GLRenderTarget(GLTexture *colorAttachment) + : mSize(colorAttachment->size()) { // Make sure FBO is supported - if (sSupported && !mTexture.isNull()) { - initFBO(); - } else + if (sSupported && !colorAttachment->isNull()) { + initFBO(colorAttachment); + } else { qCCritical(LIBKWINGLUTILS) << "Render targets aren't supported!"; + } } GLRenderTarget::GLRenderTarget(GLuint handle, const QSize &size) - : mTexture({}) - , mFramebuffer(handle) + : mFramebuffer(handle) , mSize(size) , mValid(true) , mForeign(true) @@ -1012,7 +1010,6 @@ bool GLRenderTarget::bind() glBindFramebuffer(GL_FRAMEBUFFER, handle()); glViewport(0, 0, mSize.width(), mSize.height()); - mTexture.setDirty(); return true; } @@ -1049,7 +1046,7 @@ static QString formatFramebufferStatus(GLenum status) } } -void GLRenderTarget::initFBO() +void GLRenderTarget::initFBO(GLTexture *colorAttachment) { #if DEBUG_GLRENDERTARGET GLenum err = glGetError(); @@ -1082,7 +1079,7 @@ void GLRenderTarget::initFBO() #endif glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - mTexture.target(), mTexture.texture(), 0); + colorAttachment->target(), colorAttachment->texture(), 0); #if DEBUG_GLRENDERTARGET if ((err = glGetError()) != GL_NO_ERROR) { diff --git a/src/libkwineffects/kwinglutils.h b/src/libkwineffects/kwinglutils.h index 1bc8940a40..6f6046d74a 100644 --- a/src/libkwineffects/kwinglutils.h +++ b/src/libkwineffects/kwinglutils.h @@ -397,10 +397,12 @@ public: explicit GLRenderTarget(); /** - * Constructs a GLRenderTarget - * @param color texture where the scene will be rendered onto + * Constructs a GLRenderTarget. Note that ensuring the color attachment outlives + * the render target is the responsibility of the caller. + * + * @param colorAttachment texture where the scene will be rendered onto */ - explicit GLRenderTarget(const GLTexture& color); + explicit GLRenderTarget(GLTexture *colorAttachment); /** * Constructs a wrapper for an already created render target object. The GLRenderTarget @@ -470,7 +472,7 @@ public: void blitFromFramebuffer(const QRect &source = QRect(), const QRect &destination = QRect(), GLenum filter = GL_LINEAR); protected: - void initFBO(); + void initFBO(GLTexture *colorAttachment); private: bool bind(); @@ -481,7 +483,6 @@ private: static bool s_blitSupported; static QStack s_renderTargets; - GLTexture mTexture; GLuint mFramebuffer = 0; QSize mSize; bool mValid = false; diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp index f3964494b3..e5fa3eaa4f 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -369,7 +369,7 @@ void AbstractEglBackend::setSurface(const EGLSurface &surface) QSharedPointer AbstractEglBackend::textureForOutput(AbstractOutput *requestedOutput) const { QSharedPointer texture(new GLTexture(GL_RGBA8, requestedOutput->pixelSize())); - GLRenderTarget renderTarget(*texture); + GLRenderTarget renderTarget(texture.data()); renderTarget.blitFromFramebuffer(QRect(0, texture->height(), texture->width(), -texture->height())); return texture; } diff --git a/src/plugins/screencast/windowscreencastsource.cpp b/src/plugins/screencast/windowscreencastsource.cpp index 40e4fab81e..3d1677d1ff 100644 --- a/src/plugins/screencast/windowscreencastsource.cpp +++ b/src/plugins/screencast/windowscreencastsource.cpp @@ -40,7 +40,7 @@ QSize WindowScreenCastSource::textureSize() const void WindowScreenCastSource::render(QImage *image) { GLTexture offscreenTexture(hasAlphaChannel() ? GL_RGBA8 : GL_RGB8, textureSize()); - GLRenderTarget offscreenTarget(offscreenTexture); + GLRenderTarget offscreenTarget(&offscreenTexture); render(&offscreenTarget); grabTexture(&offscreenTexture, image); diff --git a/src/scenes/opengl/lanczosfilter.cpp b/src/scenes/opengl/lanczosfilter.cpp index 4d80cb09e3..2158d6f60c 100644 --- a/src/scenes/opengl/lanczosfilter.cpp +++ b/src/scenes/opengl/lanczosfilter.cpp @@ -99,7 +99,7 @@ void LanczosFilter::updateOffscreenSurfaces() m_offscreenTex = new GLTexture(GL_RGBA8, w, h); m_offscreenTex->setFilter(GL_LINEAR); m_offscreenTex->setWrapMode(GL_CLAMP_TO_EDGE); - m_offscreenTarget = new GLRenderTarget(*m_offscreenTex); + m_offscreenTarget = new GLRenderTarget(m_offscreenTex); } } diff --git a/src/scripting/thumbnailitem.cpp b/src/scripting/thumbnailitem.cpp index f1983a3bc0..38410ac539 100644 --- a/src/scripting/thumbnailitem.cpp +++ b/src/scripting/thumbnailitem.cpp @@ -404,7 +404,7 @@ void WindowThumbnailItem::updateOffscreenTexture() m_offscreenTexture.reset(new GLTexture(GL_RGBA8, textureSize)); m_offscreenTexture->setFilter(GL_LINEAR); m_offscreenTexture->setWrapMode(GL_CLAMP_TO_EDGE); - m_offscreenTarget.reset(new GLRenderTarget(*m_offscreenTexture)); + m_offscreenTarget.reset(new GLRenderTarget(m_offscreenTexture.data())); } GLRenderTarget::pushRenderTarget(m_offscreenTarget.data()); @@ -493,7 +493,7 @@ void DesktopThumbnailItem::updateOffscreenTexture() m_offscreenTexture->setFilter(GL_LINEAR); m_offscreenTexture->setWrapMode(GL_CLAMP_TO_EDGE); m_offscreenTexture->setYInverted(true); - m_offscreenTarget.reset(new GLRenderTarget(*m_offscreenTexture)); + m_offscreenTarget.reset(new GLRenderTarget(m_offscreenTexture.data())); } GLRenderTarget::pushRenderTarget(m_offscreenTarget.data());