KWin::GLTexture support external textures

Summary:
Currently KWin::GLTexture is a nice wrapper for creating a GL texture
and performing various operations including rendering.

In a pending patch I want to render the FBO from a QQuickScene directly,
where we have an underlying texture already, but it makes sense to
re-use this class for the rendering. A similar need is in haagch's kwin
VR patchset.

This patch adds a constructor to GLTexture that takes an externally
managed texture and provides the relevant useful KWin features.

Test Plan: Used in patch series

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: zzag, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D24206
This commit is contained in:
David Edmundson 2019-09-25 14:27:40 +01:00
parent 0c876cd93f
commit d78fda30ef
3 changed files with 30 additions and 1 deletions

View file

@ -239,6 +239,24 @@ GLTexture::GLTexture(GLenum internalFormat, const QSize &size, int levels)
{ {
} }
GLTexture::GLTexture(GLuint textureId, GLenum internalFormat, const QSize &size, int levels)
: d_ptr(new GLTexturePrivate())
{
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;
d->m_canUseMipmaps = levels > 1;
d->m_mipLevels = levels;
d->m_filter = levels > 1 ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST;
d->m_internalFormat = internalFormat;
d->updateMatrix();
}
GLTexture::~GLTexture() GLTexture::~GLTexture()
{ {
} }
@ -261,6 +279,7 @@ GLTexturePrivate::GLTexturePrivate()
, m_filterChanged(true) , m_filterChanged(true)
, m_wrapModeChanged(false) , m_wrapModeChanged(false)
, m_immutable(false) , m_immutable(false)
, m_foreign(false)
, m_mipLevels(1) , m_mipLevels(1)
, m_unnormalizeActive(0) , m_unnormalizeActive(0)
, m_normalizeActive(0) , m_normalizeActive(0)
@ -272,7 +291,7 @@ GLTexturePrivate::GLTexturePrivate()
GLTexturePrivate::~GLTexturePrivate() GLTexturePrivate::~GLTexturePrivate()
{ {
delete m_vbo; delete m_vbo;
if (m_texture != 0) { if (m_texture != 0 && !m_foreign) {
glDeleteTextures(1, &m_texture); glDeleteTextures(1, &m_texture);
} }
// Delete the FBO if this is the last Texture // Delete the FBO if this is the last Texture
@ -333,6 +352,7 @@ void GLTexture::update(const QImage &image, const QPoint &offset, const QRect &s
return; return;
Q_D(GLTexture); Q_D(GLTexture);
Q_ASSERT(!d->m_foreign);
bool useUnpack = !src.isNull() && d->s_supportsUnpack && d->s_supportsARGB32 && image.format() == QImage::Format_ARGB32_Premultiplied; bool useUnpack = !src.isNull() && d->s_supportsUnpack && d->s_supportsARGB32 && image.format() == QImage::Format_ARGB32_Premultiplied;
@ -510,6 +530,7 @@ GLenum GLTexture::internalFormat() const
void GLTexture::clear() void GLTexture::clear()
{ {
Q_D(GLTexture); Q_D(GLTexture);
Q_ASSERT(!d->m_foreign);
if (!GLTexturePrivate::s_fbo && GLRenderTarget::supported() && if (!GLTexturePrivate::s_fbo && GLRenderTarget::supported() &&
GLPlatform::instance()->driver() != Driver_Catalyst) // fail. -> bug #323065 GLPlatform::instance()->driver() != Driver_Catalyst) // fail. -> bug #323065
glGenFramebuffers(1, &GLTexturePrivate::s_fbo); glGenFramebuffers(1, &GLTexturePrivate::s_fbo);

View file

@ -59,6 +59,13 @@ public:
explicit GLTexture(const QString& fileName); explicit GLTexture(const QString& fileName);
GLTexture(GLenum internalFormat, int width, int height, int levels = 1); GLTexture(GLenum internalFormat, int width, int height, int levels = 1);
explicit GLTexture(GLenum internalFormat, const QSize &size, int levels = 1); explicit GLTexture(GLenum internalFormat, const QSize &size, int levels = 1);
/**
* Create a GLTexture wrapper around an existing texture.
* Management of the underlying texture remains the responsibility of the caller.
* @since 5.18
*/
explicit GLTexture(GLuint textureId, GLenum internalFormat, const QSize &size, int levels = 1);
virtual ~GLTexture(); virtual ~GLTexture();
GLTexture & operator = (const GLTexture& tex); GLTexture & operator = (const GLTexture& tex);

View file

@ -63,6 +63,7 @@ public:
bool m_filterChanged; bool m_filterChanged;
bool m_wrapModeChanged; bool m_wrapModeChanged;
bool m_immutable; bool m_immutable;
bool m_foreign;
int m_mipLevels; int m_mipLevels;
int m_unnormalizeActive; // 0 - no, otherwise refcount int m_unnormalizeActive; // 0 - no, otherwise refcount