From 770175045a308b823a7f0faa5d5530836532cc00 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 25 Jul 2012 11:52:07 +0300 Subject: Update only dirty areas in kms backingstore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not upload the entire (typically fullscreen) image all the time. Taken from eglfs' backingstore implementation. Change-Id: I53db5cf54577ebea715d6cbd7215b9d2154e8960 Reviewed-by: Jørgen Lind --- src/plugins/platforms/kms/qkmsbackingstore.cpp | 38 ++++++++++++++++++++++++-- src/plugins/platforms/kms/qkmsbackingstore.h | 1 + 2 files changed, 36 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms/kms') diff --git a/src/plugins/platforms/kms/qkmsbackingstore.cpp b/src/plugins/platforms/kms/qkmsbackingstore.cpp index 9fb828ab26..15f436be3a 100644 --- a/src/plugins/platforms/kms/qkmsbackingstore.cpp +++ b/src/plugins/platforms/kms/qkmsbackingstore.cpp @@ -73,8 +73,9 @@ QPaintDevice *QKmsBackingStore::paintDevice() return &m_image; } -void QKmsBackingStore::beginPaint(const QRegion &) +void QKmsBackingStore::beginPaint(const QRegion &rgn) { + m_dirty |= rgn; } void QKmsBackingStore::endPaint() @@ -146,8 +147,39 @@ void QKmsBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoin glBindTexture(GL_TEXTURE_2D, m_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_image.width(), m_image.height(), - 0, GL_RGBA, GL_UNSIGNED_BYTE, m_image.constScanLine(0)); + if (!m_dirty.isNull()) { + QRect imageRect = m_image.rect(); + QRegion fixed; + Q_FOREACH (const QRect &rect, m_dirty.rects()) { + // intersect with image rect to be sure + QRect r = imageRect & rect; + // if the rect is wide enough it's cheaper to just + // extend it instead of doing an image copy + if (r.width() >= imageRect.width() / 2) { + r.setX(0); + r.setWidth(imageRect.width()); + } + fixed |= r; + } + + Q_FOREACH (const QRect &rect, fixed.rects()) { + // if the sub-rect is full-width we can pass the image data directly to + // OpenGL instead of copying, since there's no gap between scanlines + if (rect.width() == imageRect.width()) { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), + rect.width(), rect.height(), + GL_RGBA, GL_UNSIGNED_BYTE, + m_image.constScanLine(rect.y())); + } else { + glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), + rect.width(), rect.height(), + GL_RGBA, GL_UNSIGNED_BYTE, + m_image.copy(rect).constBits()); + } + } + + m_dirty = QRegion(); + } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); diff --git a/src/plugins/platforms/kms/qkmsbackingstore.h b/src/plugins/platforms/kms/qkmsbackingstore.h index 6357019210..e9d103b5c3 100644 --- a/src/plugins/platforms/kms/qkmsbackingstore.h +++ b/src/plugins/platforms/kms/qkmsbackingstore.h @@ -69,6 +69,7 @@ private: QImage m_image; uint m_texture; QOpenGLShaderProgram *m_program; + QRegion m_dirty; }; QT_END_NAMESPACE -- cgit v1.2.3