From 46e452127e0322e813282be16705d09ce700fbbf Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Thu, 15 Aug 2024 15:08:35 +0300 Subject: [PATCH] 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 --- src/opengl/gltexture.cpp | 26 ++++++++++--------- src/opengl/gltexture.h | 1 + .../opengl/basiceglsurfacetexture_wayland.cpp | 5 +--- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/opengl/gltexture.cpp b/src/opengl/gltexture.cpp index f522713cbf..29a8e2efdc 100644 --- a/src/opengl/gltexture.cpp +++ b/src/opengl/gltexture.cpp @@ -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 ®ion, 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(); - } - - 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()); + 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()); - 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() diff --git a/src/opengl/gltexture.h b/src/opengl/gltexture.h index 1e30a29ccd..43671620ea 100644 --- a/src/opengl/gltexture.h +++ b/src/opengl/gltexture.h @@ -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 ®ion, const QPoint &offset = QPoint()); void bind(); void unbind(); void render(const QSizeF &size); diff --git a/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp b/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp index 9f05c32724..c844e511fe 100644 --- a/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp +++ b/src/platformsupport/scenes/opengl/basiceglsurfacetexture_wayland.cpp @@ -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)