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:
parent
dcd1e3b87a
commit
f4f83848b0
16 changed files with 51 additions and 52 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue