libkwineffects: simplify gltexture

Instead of using custom private classes for taking care of backend specific
stuff, store that directly in the GLTexture subclasses
This commit is contained in:
Xaver Hugl 2023-05-15 18:27:45 +02:00
parent 16fb2848ed
commit 20b4f26045
8 changed files with 58 additions and 150 deletions

View file

@ -418,41 +418,29 @@ void EglSurfaceTextureX11::update(const QRegion &region)
}
EglPixmapTexture::EglPixmapTexture(EglBackend *backend)
: GLTexture(std::make_unique<EglPixmapTexturePrivate>(this, backend))
{
}
bool EglPixmapTexture::create(SurfacePixmapX11 *texture)
{
Q_D(EglPixmapTexture);
return d->create(texture);
}
EglPixmapTexturePrivate::EglPixmapTexturePrivate(EglPixmapTexture *texture, EglBackend *backend)
: q(texture)
: GLTexture(GL_TEXTURE_2D)
, m_backend(backend)
{
m_target = GL_TEXTURE_2D;
}
EglPixmapTexturePrivate::~EglPixmapTexturePrivate()
EglPixmapTexture::~EglPixmapTexture()
{
if (m_image != EGL_NO_IMAGE_KHR) {
eglDestroyImageKHR(m_backend->eglDisplay(), m_image);
}
}
bool EglPixmapTexturePrivate::create(SurfacePixmapX11 *pixmap)
bool EglPixmapTexture::create(SurfacePixmapX11 *pixmap)
{
const xcb_pixmap_t nativePixmap = pixmap->pixmap();
if (nativePixmap == XCB_NONE) {
return false;
}
glGenTextures(1, &m_texture);
q->setWrapMode(GL_CLAMP_TO_EDGE);
q->setFilter(GL_LINEAR);
q->bind();
glGenTextures(1, &d->m_texture);
setWrapMode(GL_CLAMP_TO_EDGE);
setFilter(GL_LINEAR);
bind();
const EGLint attribs[] = {
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
EGL_NONE};
@ -464,18 +452,18 @@ bool EglPixmapTexturePrivate::create(SurfacePixmapX11 *pixmap)
if (EGL_NO_IMAGE_KHR == m_image) {
qCDebug(KWIN_X11STANDALONE) << "failed to create egl image";
q->unbind();
unbind();
return false;
}
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, static_cast<GLeglImageOES>(m_image));
q->unbind();
q->setContentTransform(TextureTransform::MirrorY);
m_size = pixmap->size();
updateMatrix();
unbind();
setContentTransform(TextureTransform::MirrorY);
d->m_size = pixmap->size();
d->updateMatrix();
return true;
}
void EglPixmapTexturePrivate::onDamage()
void EglPixmapTexture::onDamage()
{
if (options->isGlStrictBinding()) {
// This is just implemented to be consistent with
@ -483,7 +471,6 @@ void EglPixmapTexturePrivate::onDamage()
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, static_cast<GLeglImageOES>(m_image));
}
GLTexturePrivate::onDamage();
}
} // namespace KWin

View file

@ -78,27 +78,14 @@ class EglPixmapTexture : public GLTexture
{
public:
explicit EglPixmapTexture(EglBackend *backend);
~EglPixmapTexture() override;
bool create(SurfacePixmapX11 *texture);
private:
Q_DECLARE_PRIVATE(EglPixmapTexture)
};
class EglPixmapTexturePrivate : public GLTexturePrivate
{
public:
EglPixmapTexturePrivate(EglPixmapTexture *texture, EglBackend *backend);
~EglPixmapTexturePrivate() override;
bool create(SurfacePixmapX11 *texture);
protected:
void onDamage() override;
private:
EglPixmapTexture *q;
EglBackend *m_backend;
EglBackend *const m_backend;
EGLImageKHR m_image = EGL_NO_IMAGE_KHR;
};

View file

@ -871,24 +871,13 @@ void GlxSurfaceTextureX11::update(const QRegion &region)
}
GlxPixmapTexture::GlxPixmapTexture(GlxBackend *backend)
: GLTexture(std::make_unique<GlxPixmapTexturePrivate>(this, backend))
{
}
bool GlxPixmapTexture::create(SurfacePixmapX11 *texture)
{
Q_D(GlxPixmapTexture);
return d->create(texture);
}
GlxPixmapTexturePrivate::GlxPixmapTexturePrivate(GlxPixmapTexture *texture, GlxBackend *backend)
: m_backend(backend)
, q(texture)
: GLTexture(GL_TEXTURE_2D)
, m_backend(backend)
, m_glxPixmap(None)
{
}
GlxPixmapTexturePrivate::~GlxPixmapTexturePrivate()
GlxPixmapTexture::~GlxPixmapTexture()
{
if (m_glxPixmap != None) {
if (!options->isGlStrictBinding()) {
@ -899,16 +888,7 @@ GlxPixmapTexturePrivate::~GlxPixmapTexturePrivate()
}
}
void GlxPixmapTexturePrivate::onDamage()
{
if (options->isGlStrictBinding() && m_glxPixmap) {
glXReleaseTexImageEXT(m_backend->display(), m_glxPixmap, GLX_FRONT_LEFT_EXT);
glXBindTexImageEXT(m_backend->display(), m_glxPixmap, GLX_FRONT_LEFT_EXT, nullptr);
}
GLTexturePrivate::onDamage();
}
bool GlxPixmapTexturePrivate::create(SurfacePixmapX11 *texture)
bool GlxPixmapTexture::create(SurfacePixmapX11 *texture)
{
if (texture->pixmap() == XCB_NONE || texture->size().isEmpty() || texture->visual() == XCB_NONE) {
return false;
@ -920,39 +900,47 @@ bool GlxPixmapTexturePrivate::create(SurfacePixmapX11 *texture)
}
if (info.texture_targets & GLX_TEXTURE_2D_BIT_EXT) {
m_target = GL_TEXTURE_2D;
m_scale.setWidth(1.0f / m_size.width());
m_scale.setHeight(1.0f / m_size.height());
d->m_target = GL_TEXTURE_2D;
d->m_scale.setWidth(1.0f / d->m_size.width());
d->m_scale.setHeight(1.0f / d->m_size.height());
} else {
Q_ASSERT(info.texture_targets & GLX_TEXTURE_RECTANGLE_BIT_EXT);
m_target = GL_TEXTURE_RECTANGLE;
m_scale.setWidth(1.0f);
m_scale.setHeight(1.0f);
d->m_target = GL_TEXTURE_RECTANGLE;
d->m_scale.setWidth(1.0f);
d->m_scale.setHeight(1.0f);
}
const int attrs[] = {
GLX_TEXTURE_FORMAT_EXT, info.bind_texture_format,
GLX_MIPMAP_TEXTURE_EXT, false,
GLX_TEXTURE_TARGET_EXT, m_target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT : GLX_TEXTURE_RECTANGLE_EXT,
GLX_TEXTURE_TARGET_EXT, d->m_target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT : GLX_TEXTURE_RECTANGLE_EXT,
0};
m_glxPixmap = glXCreatePixmap(m_backend->display(), info.fbconfig, texture->pixmap(), attrs);
m_size = texture->size();
q->setContentTransform(info.y_inverted ? TextureTransform::MirrorY : TextureTransforms());
m_canUseMipmaps = false;
d->m_size = texture->size();
setContentTransform(info.y_inverted ? TextureTransform::MirrorY : TextureTransforms());
d->m_canUseMipmaps = false;
glGenTextures(1, &m_texture);
glGenTextures(1, &d->m_texture);
q->setDirty();
q->setFilter(GL_LINEAR);
q->setWrapMode(GL_CLAMP_TO_EDGE);
setDirty();
setFilter(GL_LINEAR);
setWrapMode(GL_CLAMP_TO_EDGE);
glBindTexture(m_target, m_texture);
glBindTexture(d->m_target, d->m_texture);
glXBindTexImageEXT(m_backend->display(), m_glxPixmap, GLX_FRONT_LEFT_EXT, nullptr);
updateMatrix();
d->updateMatrix();
return true;
}
void GlxPixmapTexture::onDamage()
{
if (options->isGlStrictBinding() && m_glxPixmap) {
glXReleaseTexImageEXT(m_backend->display(), m_glxPixmap, GLX_FRONT_LEFT_EXT);
glXBindTexImageEXT(m_backend->display(), m_glxPixmap, GLX_FRONT_LEFT_EXT, nullptr);
}
}
} // namespace

View file

@ -134,34 +134,21 @@ private:
X11StandaloneBackend *m_backend;
std::unique_ptr<VsyncMonitor> m_vsyncMonitor;
std::unique_ptr<GlxLayer> m_layer;
friend class GlxPixmapTexturePrivate;
friend class GlxPixmapTexture;
};
class GlxPixmapTexture final : public GLTexture
{
public:
explicit GlxPixmapTexture(GlxBackend *backend);
~GlxPixmapTexture();
bool create(SurfacePixmapX11 *texture);
private:
Q_DECLARE_PRIVATE(GlxPixmapTexture)
};
class GlxPixmapTexturePrivate final : public GLTexturePrivate
{
public:
GlxPixmapTexturePrivate(GlxPixmapTexture *texture, GlxBackend *backend);
~GlxPixmapTexturePrivate() override;
bool create(SurfacePixmapX11 *texture);
protected:
void onDamage() override;
private:
GlxBackend *m_backend;
GlxPixmapTexture *q;
GlxBackend *const m_backend;
GLXPixmap m_glxPixmap;
};

View file

@ -21,7 +21,7 @@ EGLImageTexture::EGLImageTexture(::EGLDisplay display, EGLImage image, uint text
, m_image(image)
, m_display(display)
{
d_ptr->m_foreign = false;
d->m_foreign = false;
setContentTransform(TextureTransform::MirrorY);
}

View file

@ -83,24 +83,16 @@ struct
};
GLTexture::GLTexture(GLenum target)
: d_ptr(new GLTexturePrivate())
: d(std::make_unique<GLTexturePrivate>())
{
Q_D(GLTexture);
d->m_target = target;
}
GLTexture::GLTexture(std::unique_ptr<GLTexturePrivate> &&dd)
: d_ptr(std::move(dd))
{
}
GLTexture::GLTexture(GLuint textureId, GLenum internalFormat, const QSize &size, int levels, bool isImmutable)
: d_ptr(new GLTexturePrivate())
: GLTexture(GL_TEXTURE_2D)
{
Q_D(GLTexture);
d->m_foreign = true;
d->m_texture = textureId;
d->m_target = GL_TEXTURE_2D;
d->m_scale.setWidth(1.0 / size.width());
d->m_scale.setHeight(1.0 / size.height());
d->m_size = size;
@ -119,7 +111,6 @@ GLTexture::~GLTexture()
bool GLTexture::create()
{
Q_D(GLTexture);
if (!isNull()) {
return true;
}
@ -191,19 +182,16 @@ void GLTexturePrivate::cleanup()
bool GLTexture::isNull() const
{
Q_D(const GLTexture);
return GL_NONE == d->m_texture;
}
QSize GLTexture::size() const
{
Q_D(const GLTexture);
return d->m_size;
}
void GLTexture::setSize(const QSize &size)
{
Q_D(GLTexture);
if (!isNull()) {
return;
}
@ -217,7 +205,6 @@ void GLTexture::update(const QImage &image, const QPoint &offset, const QRect &s
return;
}
Q_D(GLTexture);
Q_ASSERT(!d->m_foreign);
GLenum glFormat;
@ -289,13 +276,12 @@ void GLTexture::update(const QImage &image, const QPoint &offset, const QRect &s
void GLTexture::bind()
{
Q_D(GLTexture);
Q_ASSERT(d->m_texture);
glBindTexture(d->m_target, d->m_texture);
if (d->m_markedDirty) {
d->onDamage();
onDamage();
}
if (d->m_filterChanged) {
GLenum minFilter = GL_NEAREST;
@ -337,8 +323,6 @@ void GLTexture::bind()
void GLTexture::generateMipmaps()
{
Q_D(GLTexture);
if (d->m_canUseMipmaps && d->s_supportsFramebufferObjects) {
glGenerateMipmap(d->m_target);
}
@ -346,7 +330,6 @@ void GLTexture::generateMipmaps()
void GLTexture::unbind()
{
Q_D(GLTexture);
glBindTexture(d->m_target, 0);
}
@ -357,14 +340,12 @@ void GLTexture::render(const QSizeF &size, qreal scale)
void GLTexture::render(const QRegion &region, const QSizeF &targetSize, double scale, bool hardwareClipping)
{
Q_D(GLTexture);
const auto rotatedSize = d->m_textureToBufferMatrix.mapRect(QRect(QPoint(), size())).size();
render(QRectF(QPoint(), rotatedSize), region, targetSize, scale, hardwareClipping);
}
void GLTexture::render(const QRectF &source, const QRegion &region, const QSizeF &targetSize, double scale, bool hardwareClipping)
{
Q_D(GLTexture);
if (targetSize.isEmpty()) {
return; // nothing to paint and m_vbo is likely nullptr and d->m_cachedSize empty as well, #337090
}
@ -416,31 +397,26 @@ void GLTexture::render(const QRectF &source, const QRegion &region, const QSizeF
GLuint GLTexture::texture() const
{
Q_D(const GLTexture);
return d->m_texture;
}
GLenum GLTexture::target() const
{
Q_D(const GLTexture);
return d->m_target;
}
GLenum GLTexture::filter() const
{
Q_D(const GLTexture);
return d->m_filter;
}
GLenum GLTexture::internalFormat() const
{
Q_D(const GLTexture);
return d->m_internalFormat;
}
void GLTexture::clear()
{
Q_D(GLTexture);
Q_ASSERT(!d->m_foreign);
if (!GLTexturePrivate::s_fbo && GLFramebuffer::supported() && GLPlatform::instance()->driver() != Driver_Catalyst) { // fail. -> bug #323065
glGenFramebuffers(1, &GLTexturePrivate::s_fbo);
@ -478,13 +454,11 @@ void GLTexture::clear()
bool GLTexture::isDirty() const
{
Q_D(const GLTexture);
return d->m_markedDirty;
}
void GLTexture::setFilter(GLenum filter)
{
Q_D(GLTexture);
if (filter != d->m_filter) {
d->m_filter = filter;
d->m_filterChanged = true;
@ -493,24 +467,21 @@ void GLTexture::setFilter(GLenum filter)
void GLTexture::setWrapMode(GLenum mode)
{
Q_D(GLTexture);
if (mode != d->m_wrapMode) {
d->m_wrapMode = mode;
d->m_wrapModeChanged = true;
}
}
void GLTexturePrivate::onDamage()
{
// No-op
}
void GLTexture::setDirty()
{
Q_D(GLTexture);
d->m_markedDirty = true;
}
void GLTexture::onDamage()
{
}
void GLTexturePrivate::updateMatrix()
{
m_textureToBufferMatrix.setToIdentity();
@ -551,7 +522,6 @@ void GLTexturePrivate::updateMatrix()
void GLTexture::setContentTransform(TextureTransforms transform)
{
Q_D(GLTexture);
if (d->m_textureToBufferTransform != transform) {
d->m_textureToBufferTransform = transform;
d->updateMatrix();
@ -560,20 +530,16 @@ void GLTexture::setContentTransform(TextureTransforms transform)
TextureTransforms GLTexture::contentTransforms() const
{
Q_D(const GLTexture);
return d->m_textureToBufferTransform;
}
QMatrix4x4 GLTexture::contentTransformMatrix() const
{
Q_D(const GLTexture);
return d->m_textureToBufferMatrix;
}
void GLTexture::setSwizzle(GLenum red, GLenum green, GLenum blue, GLenum alpha)
{
Q_D(GLTexture);
if (!GLPlatform::instance()->isGLES()) {
const GLuint swizzle[] = {red, green, blue, alpha};
glTexParameteriv(d->m_target, GL_TEXTURE_SWIZZLE_RGBA, (const GLint *)swizzle);
@ -587,19 +553,16 @@ void GLTexture::setSwizzle(GLenum red, GLenum green, GLenum blue, GLenum alpha)
int GLTexture::width() const
{
Q_D(const GLTexture);
return d->m_size.width();
}
int GLTexture::height() const
{
Q_D(const GLTexture);
return d->m_size.height();
}
QMatrix4x4 GLTexture::matrix(TextureCoordinateType type) const
{
Q_D(const GLTexture);
return d->m_matrix[type];
}
@ -672,7 +635,7 @@ std::unique_ptr<GLTexture> GLTexture::allocate(GLenum internalFormat, const QSiz
}
glBindTexture(GL_TEXTURE_2D, 0);
auto ret = std::make_unique<GLTexture>(texture, internalFormat, size, levels, immutable);
ret->d_ptr->m_foreign = false;
ret->d->m_foreign = false;
return ret;
}
@ -737,7 +700,7 @@ std::unique_ptr<GLTexture> GLTexture::upload(const QImage &image)
glBindTexture(GL_TEXTURE_2D, 0);
auto ret = std::make_unique<GLTexture>(texture, internalFormat, image.size(), 1, immutable);
ret->setContentTransform(TextureTransform::MirrorY);
ret->d_ptr->m_foreign = false;
ret->d->m_foreign = false;
return ret;
}

View file

@ -158,11 +158,9 @@ public:
static std::unique_ptr<GLTexture> upload(const QPixmap &pixmap);
protected:
const std::unique_ptr<GLTexturePrivate> d_ptr;
GLTexture(std::unique_ptr<GLTexturePrivate> &&dd);
const std::unique_ptr<GLTexturePrivate> d;
private:
Q_DECLARE_PRIVATE(GLTexture)
virtual void onDamage();
};
} // namespace

View file

@ -33,8 +33,6 @@ public:
GLTexturePrivate();
virtual ~GLTexturePrivate();
virtual void onDamage();
void updateMatrix();
GLuint m_texture;