summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qplatformgraphicsbufferhelper.cpp54
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp48
2 files changed, 83 insertions, 19 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());
}
}
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index ef1652b48b..83b75ae605 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -57,6 +57,12 @@
#ifndef GL_UNPACK_ROW_LENGTH
#define GL_UNPACK_ROW_LENGTH 0x0CF2
#endif
+#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
@@ -448,7 +454,11 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
QImage image = toImage();
QSize imageSize = image.size();
- bool needConvert = false;
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ GLenum internalFormat = GL_RGBA;
+ GLuint pixelType = GL_UNSIGNED_BYTE;
+
+ bool needsConversion = false;
*flags = 0;
switch (image.format()) {
case QImage::Format_ARGB32_Premultiplied:
@@ -464,8 +474,28 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
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;
+ *flags |= TexturePremultiplied;
+ } 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;
+ *flags |= TextureSwizzle | TexturePremultiplied;
+ } else {
+ needsConversion = true;
+ }
+ break;
default:
- needConvert = true;
+ needsConversion = true;
break;
}
if (imageSize.isEmpty()) {
@@ -481,16 +511,15 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
*textureSize = imageSize;
- if (needConvert)
+ if (needsConversion)
image = image.convertToFormat(QImage::Format_RGBA8888);
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ QOpenGLFunctions *funcs = ctx->functions();
if (resized) {
if (d_ptr->textureId)
funcs->glDeleteTextures(1, &d_ptr->textureId);
funcs->glGenTextures(1, &d_ptr->textureId);
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
@@ -500,17 +529,16 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, imageSize.width(), imageSize.height(), 0, GL_RGBA, pixelType,
const_cast<uchar*>(image.constBits()));
} else {
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
QRect imageRect = image.rect();
QRect rect = dirtyRegion.boundingRect() & imageRect;
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
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 {
@@ -525,10 +553,10 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
// OpenGL instead of copying, since there's no gap between scanlines
if (rect.width() == imageRect.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());
}
}