Avoid format conversion in backing store texture upload
Use glPixelStorei where possible Fixes: QTBUG-84189 Change-Id: Iadf039b5c6d8e7b6bb11d031a94683343dee0dc6 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> (cherry picked from commit 01b2ea83aa0e8e1d624f6c25d78bb5184cd35483) Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
5a1f9cf8c3
commit
2fbcca719e
@ -46,6 +46,10 @@
|
|||||||
#include <QtGui/QOpenGLContext>
|
#include <QtGui/QOpenGLContext>
|
||||||
#include <QtGui/QOpenGLFunctions>
|
#include <QtGui/QOpenGLFunctions>
|
||||||
|
|
||||||
|
#ifndef GL_UNPACK_ROW_LENGTH
|
||||||
|
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef GL_RGB10_A2
|
#ifndef GL_RGB10_A2
|
||||||
#define GL_RGB10_A2 0x8059
|
#define GL_RGB10_A2 0x8059
|
||||||
#endif
|
#endif
|
||||||
@ -161,66 +165,68 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
|
|||||||
bool premultiplied = false;
|
bool premultiplied = false;
|
||||||
QImage::Format imageformat = QImage::toImageFormat(graphicsBuffer->format());
|
QImage::Format imageformat = QImage::toImageFormat(graphicsBuffer->format());
|
||||||
QImage image(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), imageformat);
|
QImage image(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), imageformat);
|
||||||
if (graphicsBuffer->bytesPerLine() != (size.width() * 4)) {
|
switch (imageformat) {
|
||||||
needsConversion = true;
|
case QImage::Format_ARGB32_Premultiplied:
|
||||||
} else {
|
premultiplied = true;
|
||||||
switch (imageformat) {
|
Q_FALLTHROUGH();
|
||||||
case QImage::Format_ARGB32_Premultiplied:
|
case QImage::Format_RGB32:
|
||||||
|
case QImage::Format_ARGB32:
|
||||||
|
swizzle = true;
|
||||||
|
break;
|
||||||
|
case QImage::Format_RGBA8888_Premultiplied:
|
||||||
|
premultiplied = true;
|
||||||
|
Q_FALLTHROUGH();
|
||||||
|
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;
|
premultiplied = true;
|
||||||
Q_FALLTHROUGH();
|
} else {
|
||||||
case QImage::Format_RGB32:
|
|
||||||
case QImage::Format_ARGB32:
|
|
||||||
swizzle = true;
|
|
||||||
break;
|
|
||||||
case QImage::Format_RGBA8888_Premultiplied:
|
|
||||||
premultiplied = true;
|
|
||||||
Q_FALLTHROUGH();
|
|
||||||
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;
|
needsConversion = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
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.bytesPerLine() != (size.width() * 4) && ctx->isOpenGLES() && ctx->format().majorVersion() < 3)
|
||||||
|
needsConversion = true;
|
||||||
if (needsConversion)
|
if (needsConversion)
|
||||||
image = image.convertToFormat(QImage::Format_RGBA8888);
|
image = image.convertToFormat(QImage::Format_RGBA8888);
|
||||||
|
|
||||||
|
bool needsRowLength = (image.bytesPerLine() != image.width() * 4);
|
||||||
QOpenGLFunctions *funcs = ctx->functions();
|
QOpenGLFunctions *funcs = ctx->functions();
|
||||||
|
|
||||||
QRect rect = subRect;
|
QRect rect = subRect;
|
||||||
if (rect.isNull() || rect == QRect(QPoint(0,0),size)) {
|
if (rect.isNull() || rect == QRect(QPoint(0,0),size)) {
|
||||||
|
if (needsRowLength)
|
||||||
|
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.bytesPerLine() / 4);
|
||||||
funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size.width(), size.height(), 0, GL_RGBA, pixelType, image.constBits());
|
funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size.width(), size.height(), 0, GL_RGBA, pixelType, image.constBits());
|
||||||
|
if (needsRowLength)
|
||||||
|
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
} else {
|
} else {
|
||||||
#ifndef QT_OPENGL_ES_2
|
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
|
||||||
if (!ctx->isOpenGLES()) {
|
// OpenGL 2.1+ or OpenGL ES/3+
|
||||||
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
|
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.bytesPerLine() / 4);
|
||||||
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
|
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
|
||||||
image.constScanLine(rect.y()) + rect.x() * 4);
|
image.constScanLine(rect.y()) + rect.x() * 4);
|
||||||
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
} else
|
} else
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
// if the rect is wide enough it's cheaper to just
|
// if the rect is wide enough it's cheaper to just
|
||||||
// extend it instead of doing an image copy
|
// extend it instead of doing an image copy
|
||||||
@ -232,7 +238,7 @@ bool QPlatformGraphicsBufferHelper::bindSWToTexture(const QPlatformGraphicsBuffe
|
|||||||
// if the sub-rect is full-width we can pass the image data directly to
|
// 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
|
// OpenGL instead of copying, since there's no gap between scanlines
|
||||||
|
|
||||||
if (rect.width() == size.width()) {
|
if (rect.width() == image.bytesPerLine() / 4) {
|
||||||
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
|
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
|
||||||
image.constScanLine(rect.y()));
|
image.constScanLine(rect.y()));
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user