opengl: Add GLTexture::update() overload that takes a region

This ensures a couple of things:

- avoid pointlessly binding and unbinding the texture
- if the image format needs to be changed, it will be done only once
This commit is contained in:
Vlad Zahorodnii 2024-08-15 15:08:35 +03:00
parent bfff8ac52a
commit 46e452127e
3 changed files with 16 additions and 16 deletions

View file

@ -147,6 +147,11 @@ void GLTexture::setSize(const QSize &size)
}
void GLTexture::update(const QImage &image, const QPoint &offset, const QRect &src)
{
update(image, src.isEmpty() ? image.rect() : src, offset);
}
void GLTexture::update(const QImage &image, const QRegion &region, const QPoint &offset)
{
if (image.isNull() || isNull()) {
return;
@ -188,25 +193,22 @@ void GLTexture::update(const QImage &image, const QPoint &offset, const QRect &s
im.convertTo(uploadFormat);
}
QRect rect = src;
if (rect.isEmpty()) {
rect = im.rect();
}
bind();
for (const QRect &rect : region) {
Q_ASSERT(im.depth() % 8 == 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, im.bytesPerLine() / (im.depth() / 8));
glPixelStorei(GL_UNPACK_SKIP_PIXELS, rect.x());
glPixelStorei(GL_UNPACK_SKIP_ROWS, rect.y());
bind();
glTexSubImage2D(d->m_target, 0, offset.x(), offset.y(), rect.width(), rect.height(), glFormat, type, im.constBits());
unbind();
glTexSubImage2D(d->m_target, 0, offset.x() + rect.x(), offset.y() + rect.y(), rect.width(), rect.height(), glFormat, type, im.constBits());
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
unbind();
}
void GLTexture::bind()

View file

@ -85,6 +85,7 @@ public:
QMatrix4x4 matrix(TextureCoordinateType type) const;
void update(const QImage &image, const QPoint &offset = QPoint(0, 0), const QRect &src = QRect());
void update(const QImage &image, const QRegion &region, const QPoint &offset = QPoint());
void bind();
void unbind();
void render(const QSizeF &size);

View file

@ -108,10 +108,7 @@ void BasicEGLSurfaceTextureWayland::updateShmTexture(GraphicsBuffer *buffer, con
return;
}
const QRegion simplifiedDamage = simplifyDamage(region);
for (const QRect &rect : simplifiedDamage) {
m_texture.planes[0]->update(*view.image(), rect.topLeft(), rect);
}
m_texture.planes[0]->update(*view.image(), simplifyDamage(region));
}
bool BasicEGLSurfaceTextureWayland::loadDmabufTexture(GraphicsBuffer *buffer)