kwineffects: Allow creating GLTexture without allocated storage
This allows creating a GLTexture object and attaching a dmabuf to it. Currently, we can do that by using the foreign GLTexture constructor, but it makes the deletion of the texture handle more error prone. In the future, we can add a method that allocates the texture storage, but there's no need for that yet.
This commit is contained in:
parent
2b8453abb8
commit
10769548db
7 changed files with 51 additions and 29 deletions
|
@ -630,9 +630,9 @@ void BlurEffect::generateNoiseTexture()
|
|||
// The noise texture looks distorted when not scaled with integer
|
||||
noiseImage = noiseImage.scaled(noiseImage.size() * m_scalingFactor);
|
||||
|
||||
m_noiseTexture = GLTexture(noiseImage);
|
||||
m_noiseTexture.setFilter(GL_NEAREST);
|
||||
m_noiseTexture.setWrapMode(GL_REPEAT);
|
||||
m_noiseTexture.reset(new GLTexture(noiseImage));
|
||||
m_noiseTexture->setFilter(GL_NEAREST);
|
||||
m_noiseTexture->setWrapMode(GL_REPEAT);
|
||||
}
|
||||
|
||||
void BlurEffect::doBlur(const QRegion& shape, const QRect& screen, const float opacity, const QMatrix4x4 &screenProjection, bool isDock, QRect windowRect)
|
||||
|
@ -726,11 +726,11 @@ void BlurEffect::upscaleRenderToScreen(GLVertexBuffer *vbo, int vboStart, int bl
|
|||
if (m_noiseStrength > 0) {
|
||||
m_shader->bind(BlurShader::NoiseSampleType);
|
||||
m_shader->setTargetTextureSize(m_renderTextures[0].size() * GLRenderTarget::virtualScreenScale());
|
||||
m_shader->setNoiseTextureSize(m_noiseTexture.size() * GLRenderTarget::virtualScreenScale());
|
||||
m_shader->setNoiseTextureSize(m_noiseTexture->size() * GLRenderTarget::virtualScreenScale());
|
||||
m_shader->setTexturePosition(windowPosition * GLRenderTarget::virtualScreenScale());
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_noiseTexture.bind();
|
||||
m_noiseTexture->bind();
|
||||
} else {
|
||||
m_shader->bind(BlurShader::UpSampleType);
|
||||
m_shader->setTargetTextureSize(m_renderTextures[0].size() * GLRenderTarget::virtualScreenScale());
|
||||
|
|
|
@ -86,7 +86,7 @@ private:
|
|||
QVector <GLTexture> m_renderTextures;
|
||||
QStack <GLRenderTarget*> m_renderTargetStack;
|
||||
|
||||
GLTexture m_noiseTexture;
|
||||
QScopedPointer<GLTexture> m_noiseTexture;
|
||||
|
||||
bool m_renderTargetsValid;
|
||||
long net_wm_blur_region;
|
||||
|
|
|
@ -40,9 +40,11 @@ uint GLTexturePrivate::s_textureObjectCounter = 0;
|
|||
uint GLTexturePrivate::s_fbo = 0;
|
||||
|
||||
|
||||
GLTexture::GLTexture()
|
||||
GLTexture::GLTexture(GLenum target)
|
||||
: d_ptr(new GLTexturePrivate())
|
||||
{
|
||||
Q_D(GLTexture);
|
||||
d->m_target = target;
|
||||
}
|
||||
|
||||
GLTexture::GLTexture(GLTexturePrivate& dd)
|
||||
|
@ -80,7 +82,7 @@ GLTexture::GLTexture(const QImage& image, GLenum target)
|
|||
|
||||
d->updateMatrix();
|
||||
|
||||
glGenTextures(1, &d->m_texture);
|
||||
create();
|
||||
bind();
|
||||
|
||||
if (!GLPlatform::instance()->isGLES()) {
|
||||
|
@ -193,7 +195,7 @@ GLTexture::GLTexture(GLenum internalFormat, int width, int height, int levels, b
|
|||
|
||||
d->updateMatrix();
|
||||
|
||||
glGenTextures(1, &d->m_texture);
|
||||
create();
|
||||
bind();
|
||||
|
||||
if (!GLPlatform::instance()->isGLES()) {
|
||||
|
@ -249,6 +251,16 @@ GLTexture::~GLTexture()
|
|||
{
|
||||
}
|
||||
|
||||
bool GLTexture::create()
|
||||
{
|
||||
Q_D(GLTexture);
|
||||
if (!isNull()) {
|
||||
return true;
|
||||
}
|
||||
glGenTextures(1, &d->m_texture);
|
||||
return d->m_texture != GL_NONE;
|
||||
}
|
||||
|
||||
GLTexture& GLTexture::operator = (const GLTexture& tex)
|
||||
{
|
||||
d_ptr = tex.d_ptr;
|
||||
|
@ -334,6 +346,16 @@ QSize GLTexture::size() const
|
|||
return d->m_size;
|
||||
}
|
||||
|
||||
void GLTexture::setSize(const QSize &size)
|
||||
{
|
||||
Q_D(GLTexture);
|
||||
if (!isNull()) {
|
||||
return;
|
||||
}
|
||||
d->m_size = size;
|
||||
d->updateMatrix();
|
||||
}
|
||||
|
||||
void GLTexture::update(const QImage &image, const QPoint &offset, const QRect &src)
|
||||
{
|
||||
if (image.isNull() || isNull())
|
||||
|
@ -397,6 +419,7 @@ void GLTexture::discard()
|
|||
void GLTexture::bind()
|
||||
{
|
||||
Q_D(GLTexture);
|
||||
Q_ASSERT(d->m_texture);
|
||||
|
||||
glBindTexture(d->m_target, d->m_texture);
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ enum TextureCoordinateType {
|
|||
class KWINGLUTILS_EXPORT GLTexture
|
||||
{
|
||||
public:
|
||||
GLTexture();
|
||||
explicit GLTexture(GLenum target);
|
||||
GLTexture(const GLTexture& tex);
|
||||
explicit GLTexture(const QImage& image, GLenum target = GL_TEXTURE_2D);
|
||||
explicit GLTexture(const QPixmap& pixmap, GLenum target = GL_TEXTURE_2D);
|
||||
|
@ -49,6 +49,13 @@ public:
|
|||
GLTexture(GLenum internalFormat, int width, int height, int levels = 1, bool needsMutability = false);
|
||||
explicit GLTexture(GLenum internalFormat, const QSize &size, int levels = 1, bool needsMutability = false);
|
||||
|
||||
/**
|
||||
* Creates the underlying texture object. Returns @c true if the texture has been created
|
||||
* successfully; otherwise returns @c false. Note that this does not allocate any storage
|
||||
* for the texture.
|
||||
*/
|
||||
bool create();
|
||||
|
||||
/**
|
||||
* Create a GLTexture wrapper around an existing texture.
|
||||
* Management of the underlying texture remains the responsibility of the caller.
|
||||
|
@ -61,6 +68,7 @@ public:
|
|||
|
||||
bool isNull() const;
|
||||
QSize size() const;
|
||||
void setSize(const QSize &size);
|
||||
int width() const;
|
||||
int height() const;
|
||||
/**
|
||||
|
|
|
@ -1093,19 +1093,15 @@ GLRenderTarget* GLRenderTarget::popRenderTarget()
|
|||
}
|
||||
|
||||
GLRenderTarget::GLRenderTarget()
|
||||
: mValid(false)
|
||||
, mTexture(GL_TEXTURE_2D)
|
||||
{
|
||||
// Reset variables
|
||||
mValid = false;
|
||||
mTexture = GLTexture();
|
||||
}
|
||||
|
||||
GLRenderTarget::GLRenderTarget(const GLTexture& color)
|
||||
: mValid(false)
|
||||
, mTexture(color)
|
||||
{
|
||||
// Reset variables
|
||||
mValid = false;
|
||||
|
||||
mTexture = color;
|
||||
|
||||
// Make sure FBO is supported
|
||||
if (sSupported && !mTexture.isNull()) {
|
||||
initFBO();
|
||||
|
|
|
@ -57,10 +57,6 @@ void BasicEGLSurfaceTextureWayland::destroy()
|
|||
eglDestroyImageKHR(backend()->eglDisplay(), m_image);
|
||||
m_image = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
if (m_textureId) {
|
||||
glDeleteTextures(1, &m_textureId);
|
||||
m_textureId = 0;
|
||||
}
|
||||
m_texture.reset();
|
||||
m_bufferType = BufferType::None;
|
||||
}
|
||||
|
@ -130,9 +126,9 @@ bool BasicEGLSurfaceTextureWayland::loadEglTexture(KWaylandServer::BufferInterfa
|
|||
return false;
|
||||
}
|
||||
|
||||
glGenTextures(1, &m_textureId);
|
||||
|
||||
m_texture.reset(new GLTexture(m_textureId, 0, buffer->size()));
|
||||
m_texture.reset(new GLTexture(GL_TEXTURE_2D));
|
||||
m_texture->setSize(buffer->size());
|
||||
m_texture->create();
|
||||
m_texture->setWrapMode(GL_CLAMP_TO_EDGE);
|
||||
m_texture->setFilter(GL_LINEAR);
|
||||
m_texture->bind();
|
||||
|
@ -176,9 +172,9 @@ bool BasicEGLSurfaceTextureWayland::loadDmabufTexture(KWaylandServer::BufferInte
|
|||
return false;
|
||||
}
|
||||
|
||||
glGenTextures(1, &m_textureId);
|
||||
|
||||
m_texture.reset(new GLTexture(m_textureId, 0, dmabuf->size()));
|
||||
m_texture.reset(new GLTexture(GL_TEXTURE_2D));
|
||||
m_texture->setSize(dmabuf->size());
|
||||
m_texture->create();
|
||||
m_texture->setWrapMode(GL_CLAMP_TO_EDGE);
|
||||
m_texture->setFilter(GL_NEAREST);
|
||||
m_texture->bind();
|
||||
|
|
|
@ -50,7 +50,6 @@ private:
|
|||
|
||||
EGLImageKHR m_image = EGL_NO_IMAGE_KHR;
|
||||
BufferType m_bufferType = BufferType::None;
|
||||
GLuint m_textureId = 0;
|
||||
};
|
||||
|
||||
} // namespace KWin
|
||||
|
|
Loading…
Reference in a new issue