summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-01-11 16:33:45 +0100
committerAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-01-15 08:59:28 +0000
commit4f71654385438a015931a0c7be52f2c7188c9f7d (patch)
tree4ff2a0425ff43b45cb16f815cc1bf80d4e543c43 /src/gui/kernel/qplatformgraphicsbufferhelper.cpp
parentd53f614740abcda84a1fae7f09fa68b94583e79f (diff)
Handle RGB30 formats in OpenGL backing-store integration
Optimizes composition on platforms that may use 10-bit per color channel formats. Change-Id: Ib303c391d47795c79a4ba55d78dbb1c3c702d90a Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Diffstat (limited to 'src/gui/kernel/qplatformgraphicsbufferhelper.cpp')
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.cpp54
1 files changed, 45 insertions, 9 deletions
diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
index 7f2672bc5e..c0c51b8d5e 100644
--- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
+++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp
@@ -40,6 +40,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
/*!
@@ -115,7 +123,8 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
const QRect &subRect)
{
#ifndef QT_NO_OPENGL
- if (!QOpenGLContext::currentContext())
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx)
return false;
if (!(graphicsBuffer->isLocked() & QPlatformGraphicsBuffer::SWReadAccess))
@@ -125,12 +134,16 @@ 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);
+ needsConversion = true;
} else {
switch (imageformat) {
case QImage::Format_ARGB32_Premultiplied:
@@ -146,22 +159,45 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
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:
- image = image.convertToFormat(QImage::Format_RGBA8888);
+ 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
@@ -178,10 +214,10 @@ 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());
}
}