egl: encapsulate and share duplicated code

Summary:
Removes a few TODO items mentioning that some code was exactly the same
in a couple of different places.

drm: Remove unnecessary cast

Test Plan:
Using it right now
Will push in 2 different commits

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: zzag, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D28708
This commit is contained in:
Aleix Pol 2020-04-09 19:55:16 +02:00
parent cf7762eaa8
commit 19bfa7c065
2 changed files with 56 additions and 128 deletions

View file

@ -434,12 +434,61 @@ void AbstractEglTexture::updateTexture(WindowPixmap *pixmap)
}
}
Q_ASSERT(image.size() == m_size);
q->bind();
const QRegion damage = s->trackedDamage();
s->resetTrackedDamage();
auto scale = s->scale(); //damage is normalised, so needs converting up to match texture
// TODO: this should be shared with GLTexture::update
createTextureSubImage(s->scale(), image, damage);
}
bool AbstractEglTexture::createTextureImage(const QImage &image)
{
if (image.isNull()) {
return false;
}
glGenTextures(1, &m_texture);
q->setFilter(GL_LINEAR);
q->setWrapMode(GL_CLAMP_TO_EDGE);
const QSize &size = image.size();
q->bind();
GLenum format = 0;
switch (image.format()) {
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
format = GL_RGBA8;
break;
case QImage::Format_RGB32:
format = GL_RGB8;
break;
default:
return false;
}
if (GLPlatform::instance()->isGLES()) {
if (s_supportsARGB32 && format == GL_RGBA8) {
const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
glTexImage2D(m_target, 0, GL_BGRA_EXT, im.width(), im.height(),
0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, im.bits());
} else {
const QImage im = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
glTexImage2D(m_target, 0, GL_RGBA, im.width(), im.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, im.bits());
}
} else {
glTexImage2D(m_target, 0, format, size.width(), size.height(), 0,
GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
}
q->unbind();
q->setYInverted(true);
m_size = size;
updateMatrix();
return true;
}
void AbstractEglTexture::createTextureSubImage(int scale, const QImage &image, const QRegion &damage)
{
q->bind();
if (GLPlatform::instance()->isGLES()) {
if (s_supportsARGB32 && (image.format() == QImage::Format_ARGB32 || image.format() == QImage::Format_ARGB32_Premultiplied)) {
const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
@ -469,50 +518,7 @@ void AbstractEglTexture::updateTexture(WindowPixmap *pixmap)
bool AbstractEglTexture::loadShmTexture(const QPointer< KWayland::Server::BufferInterface > &buffer)
{
const QImage &image = buffer->data();
if (image.isNull()) {
return false;
}
glGenTextures(1, &m_texture);
q->setWrapMode(GL_CLAMP_TO_EDGE);
q->setFilter(GL_LINEAR);
q->bind();
const QSize &size = image.size();
// TODO: this should be shared with GLTexture(const QImage&, GLenum)
GLenum format = 0;
switch (image.format()) {
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
format = GL_RGBA8;
break;
case QImage::Format_RGB32:
format = GL_RGB8;
break;
default:
return false;
}
if (GLPlatform::instance()->isGLES()) {
if (s_supportsARGB32 && format == GL_RGBA8) {
const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
glTexImage2D(m_target, 0, GL_BGRA_EXT, im.width(), im.height(),
0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, im.bits());
} else {
const QImage im = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
glTexImage2D(m_target, 0, GL_RGBA, im.width(), im.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, im.bits());
}
} else {
glTexImage2D(m_target, 0, format, size.width(), size.height(), 0,
GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
}
q->unbind();
q->setYInverted(true);
m_size = size;
updateMatrix();
return true;
return createTextureImage(buffer->data());
}
bool AbstractEglTexture::loadEglTexture(const QPointer< KWayland::Server::BufferInterface > &buffer)
@ -566,54 +572,7 @@ bool AbstractEglTexture::loadDmabufTexture(const QPointer< KWayland::Server::Buf
bool AbstractEglTexture::loadInternalImageObject(WindowPixmap *pixmap)
{
// FIXME: Share some code with loadShmTexture().
const QImage image = pixmap->internalImage();
if (image.isNull()) {
return false;
}
glGenTextures(1, &m_texture);
q->setFilter(GL_LINEAR);
q->setWrapMode(GL_CLAMP_TO_EDGE);
q->setYInverted(true);
q->bind();
const QSize &size = image.size();
// TODO: this should be shared with GLTexture(const QImage&, GLenum)
GLenum format = 0;
switch (image.format()) {
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
format = GL_RGBA8;
break;
case QImage::Format_RGB32:
format = GL_RGB8;
break;
default:
return false;
}
if (GLPlatform::instance()->isGLES()) {
if (s_supportsARGB32 && format == GL_RGBA8) {
const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
glTexImage2D(m_target, 0, GL_BGRA_EXT, im.width(), im.height(),
0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, im.bits());
} else {
const QImage im = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
glTexImage2D(m_target, 0, GL_RGBA, im.width(), im.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, im.bits());
}
} else {
glTexImage2D(m_target, 0, format, size.width(), size.height(), 0,
GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
}
q->unbind();
m_size = size;
updateMatrix();
return true;
return createTextureImage(pixmap->internalImage());
}
EGLImageKHR AbstractEglTexture::attach(const QPointer< KWayland::Server::BufferInterface > &buffer)
@ -660,8 +619,6 @@ bool AbstractEglTexture::updateFromFBO(const QSharedPointer<QOpenGLFramebufferOb
bool AbstractEglTexture::updateFromInternalImageObject(WindowPixmap *pixmap)
{
// FIXME: Share some code with the shm fallback in updateTexture().
const QImage image = pixmap->internalImage();
if (image.isNull()) {
return false;
@ -672,38 +629,7 @@ bool AbstractEglTexture::updateFromInternalImageObject(WindowPixmap *pixmap)
return loadInternalImageObject(pixmap);
}
const QRegion damage = pixmap->toplevel()->damage();
const qreal scale = image.devicePixelRatio();
q->bind();
// TODO: this should be shared with GLTexture::update
if (GLPlatform::instance()->isGLES()) {
if (s_supportsARGB32 && (image.format() == QImage::Format_ARGB32 || image.format() == QImage::Format_ARGB32_Premultiplied)) {
const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
for (const QRect &rect : damage) {
auto scaledRect = QRect(rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale);
glTexSubImage2D(m_target, 0, scaledRect.x(), scaledRect.y(), scaledRect.width(), scaledRect.height(),
GL_BGRA_EXT, GL_UNSIGNED_BYTE, im.copy(scaledRect).bits());
}
} else {
const QImage im = image.convertToFormat(QImage::Format_RGBA8888_Premultiplied);
for (const QRect &rect : damage) {
auto scaledRect = QRect(rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale);
glTexSubImage2D(m_target, 0, scaledRect.x(), scaledRect.y(), scaledRect.width(), scaledRect.height(),
GL_RGBA, GL_UNSIGNED_BYTE, im.copy(scaledRect).bits());
}
}
} else {
const QImage im = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
for (const QRect &rect : damage) {
auto scaledRect = QRect(rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale);
glTexSubImage2D(m_target, 0, scaledRect.x(), scaledRect.y(), scaledRect.width(), scaledRect.height(),
GL_BGRA, GL_UNSIGNED_BYTE, im.copy(scaledRect).bits());
}
}
q->unbind();
createTextureSubImage(image.devicePixelRatio(), image, pixmap->toplevel()->damage());
return true;
}

View file

@ -111,6 +111,8 @@ protected:
}
private:
void createTextureSubImage(int scale, const QImage &image, const QRegion &damage);
bool createTextureImage(const QImage &image);
bool loadShmTexture(const QPointer<KWayland::Server::BufferInterface> &buffer);
bool loadEglTexture(const QPointer<KWayland::Server::BufferInterface> &buffer);
bool loadDmabufTexture(const QPointer< KWayland::Server::BufferInterface > &buffer);