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.
This commit is contained in:
Vlad Zahorodnii 2022-02-15 13:17:43 +02:00
parent dcd1e3b87a
commit f4f83848b0
16 changed files with 51 additions and 52 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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))
{
}

View file

@ -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();

View file

@ -85,7 +85,7 @@ private:
private:
BlurShader *m_shader;
QVector <GLRenderTarget*> m_renderTargets;
QVector <GLTexture> m_renderTextures;
QVector<GLTexture *> m_renderTextures;
QStack <GLRenderTarget*> m_renderTargetStack;
QScopedPointer<GLTexture> m_noiseTexture;

View file

@ -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;
}

View file

@ -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;

View file

@ -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();

View file

@ -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);

View file

@ -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;
}

View file

@ -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) {

View file

@ -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<GLRenderTarget*> s_renderTargets;
GLTexture mTexture;
GLuint mFramebuffer = 0;
QSize mSize;
bool mValid = false;

View file

@ -369,7 +369,7 @@ void AbstractEglBackend::setSurface(const EGLSurface &surface)
QSharedPointer<GLTexture> AbstractEglBackend::textureForOutput(AbstractOutput *requestedOutput) const
{
QSharedPointer<GLTexture> 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;
}

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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());