diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-01-21 08:17:21 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2016-01-21 08:17:21 +0100 |
commit | 158a3a4159bdc5a49caecd63e021dacbc06cf23c (patch) | |
tree | c3ed9aee6cabd46e5e8615b3815b92d32857c4da /src/gui/kernel/qplatformgraphicsbufferhelper.cpp | |
parent | 26ece94a68fb5ae680c5639716b06c4e1ae979a8 (diff) | |
parent | 7b2fb038ae4b8b9231ae989ad309b6eca107a858 (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts:
src/corelib/io/qiodevice_p.h
src/corelib/kernel/qvariant_p.h
src/corelib/tools/qsimd.cpp
src/gui/kernel/qguiapplication.cpp
tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
Change-Id: I742a093cbb231b282b43e463ec67173e0d29f57a
Diffstat (limited to 'src/gui/kernel/qplatformgraphicsbufferhelper.cpp')
-rw-r--r-- | src/gui/kernel/qplatformgraphicsbufferhelper.cpp | 86 |
1 files changed, 71 insertions, 15 deletions
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp index 57c28e87b4..46a536c923 100644 --- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp +++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp @@ -46,6 +46,14 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLFunctions> +#ifndef GL_RGB10_A2 +#define GL_RGB10_A2 0x8059 +#endif + +#ifndef GL_UNSIGNED_INT_2_10_10_10_REV +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#endif + QT_BEGIN_NAMESPACE /*! @@ -70,7 +78,7 @@ QT_BEGIN_NAMESPACE bound texture, otherwise returns false. */ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer *graphicsBuffer, - bool *swizzle, + bool *swizzle, bool *premultiplied, const QRect &rect) { if (graphicsBuffer->lock(QPlatformGraphicsBuffer::TextureAccess)) { @@ -80,8 +88,10 @@ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer } if (swizzle) *swizzle = false; + if (premultiplied) + *premultiplied = false; } else if (graphicsBuffer->lock(QPlatformGraphicsBuffer::SWReadAccess)) { - if (!bindSWToTexture(graphicsBuffer, swizzle, rect)) { + if (!bindSWToTexture(graphicsBuffer, swizzle, premultiplied, rect)) { qWarning("Failed to bind %sgraphicsbuffer to texture", "SW "); return false; } @@ -115,11 +125,12 @@ bool QPlatformGraphicsBufferHelper::lockAndBindToTexture(QPlatformGraphicsBuffer Returns true on success, otherwise false. */ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffer *graphicsBuffer, - bool *swizzleRandB, + bool *swizzleRandB, bool *premultipliedB, const QRect &subRect) { #ifndef QT_NO_OPENGL - if (!QOpenGLContext::currentContext()) + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (!ctx) return false; if (!(graphicsBuffer->isLocked() & QPlatformGraphicsBuffer::SWReadAccess)) @@ -129,27 +140,70 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe Q_ASSERT(subRect.isEmpty() || QRect(QPoint(0,0), size).contains(subRect)); + GLenum internalFormat = GL_RGBA; + GLuint pixelType = GL_UNSIGNED_BYTE; + + bool needsConversion = false; bool swizzle = false; + bool premultiplied = false; QImage::Format imageformat = QImage::toImageFormat(graphicsBuffer->format()); QImage image(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), imageformat); if (graphicsBuffer->bytesPerLine() != (size.width() * 4)) { - image = image.convertToFormat(QImage::Format_RGBA8888); - } else if (imageformat == QImage::Format_RGB32) { - swizzle = true; - } else if (imageformat != QImage::Format_RGBA8888) { - image = image.convertToFormat(QImage::Format_RGBA8888); + needsConversion = true; + } else { + switch (imageformat) { + case QImage::Format_ARGB32_Premultiplied: + premultiplied = true; + // no break + case QImage::Format_RGB32: + case QImage::Format_ARGB32: + swizzle = true; + break; + case QImage::Format_RGBA8888_Premultiplied: + premultiplied = true; + // no break + case QImage::Format_RGBX8888: + case QImage::Format_RGBA8888: + break; + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { + pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; + internalFormat = GL_RGB10_A2; + premultiplied = true; + } else { + needsConversion = true; + } + break; + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: + if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) { + pixelType = GL_UNSIGNED_INT_2_10_10_10_REV; + internalFormat = GL_RGB10_A2; + premultiplied = true; + swizzle = true; + } else { + needsConversion = true; + } + break; + default: + needsConversion = true; + break; + } } + if (needsConversion) + image = image.convertToFormat(QImage::Format_RGBA8888); - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions *funcs = ctx->functions(); QRect rect = subRect; if (rect.isNull() || rect == QRect(QPoint(0,0),size)) { - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); + funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size.width(), size.height(), 0, GL_RGBA, pixelType, image.constBits()); } else { #ifndef QT_OPENGL_ES_2 - if (!QOpenGLContext::currentContext()->isOpenGLES()) { + if (!ctx->isOpenGLES()) { funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width()); - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.constScanLine(rect.y()) + rect.x() * 4); funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } else @@ -166,16 +220,18 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe // OpenGL instead of copying, since there's no gap between scanlines if (rect.width() == size.width()) { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.constScanLine(rect.y())); } else { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, + funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType, image.copy(rect).constBits()); } } } if (swizzleRandB) *swizzleRandB = swizzle; + if (premultipliedB) + *premultipliedB = premultiplied; return true; |