summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/kms
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2012-07-25 11:52:07 +0300
committerQt by Nokia <qt-info@nokia.com>2012-07-25 14:50:16 +0200
commit770175045a308b823a7f0faa5d5530836532cc00 (patch)
treeed1b6e5db528a5e7837ad35724b70847c4c49be7 /src/plugins/platforms/kms
parent189a5d8af12788a30121210066de647a6dc3a167 (diff)
Update only dirty areas in kms backingstore
Do not upload the entire (typically fullscreen) image all the time. Taken from eglfs' backingstore implementation. Change-Id: I53db5cf54577ebea715d6cbd7215b9d2154e8960 Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'src/plugins/platforms/kms')
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.cpp38
-rw-r--r--src/plugins/platforms/kms/qkmsbackingstore.h1
2 files changed, 36 insertions, 3 deletions
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 &region, 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