diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-09-15 15:51:43 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2015-10-14 14:11:07 +0000 |
commit | 715a8e6f4ed3f8fd5c6d98c88b6260e5c1dba428 (patch) | |
tree | 47f599c93661e8b2d91f8f1be101e78a7989db9d /src/platformsupport/platformcompositor | |
parent | 281121697340084f7d385eab530f41916789b94d (diff) |
Avoid image copy in toTexture() on GLES 3.0 as well
The default backingstore implementation is now cleaned for ES_2 ifdefs.
All the checks are now done at runtime and ES 3.0+ is included as well
for the efficient, QImage::copy()-less path.
For embedded a customized backingstore is used so the change has to be
done separately there.
This should result in a slight improvement for QOpenGLWidget/QQuickWidget
when running on GLES 3.x.
Task-number: QTBUG-37624
Change-Id: I107330c25a993c5cdcd92e4ebdc17ae172a03da8
Reviewed-by: Paul Olav Tvete <paul.tvete@theqtcompany.com>
Diffstat (limited to 'src/platformsupport/platformcompositor')
-rw-r--r-- | src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 8ce1ed2d2b..bb3ea6981a 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -39,6 +39,10 @@ #include "qopenglcompositorbackingstore_p.h" #include "qopenglcompositor_p.h" +#ifndef GL_UNPACK_ROW_LENGTH +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#endif + QT_BEGIN_NAMESPACE /*! @@ -100,29 +104,39 @@ void QOpenGLCompositorBackingStore::updateTexture() QRegion fixed; QRect imageRect = m_image.rect(); - 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()); + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { + foreach (const QRect &rect, m_dirty.rects()) { + QRect r = imageRect & rect; + glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image.width()); + glTexSubImage2D(GL_TEXTURE_2D, 0, r.x(), r.y(), r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE, + m_image.constScanLine(r.y()) + r.x() * 4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } - - fixed |= r; - } - - 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()); + } else { + 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; + } + 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()); + } } } |