Support arbitrary strides in the QPlatformBackingStore compositor
Otherwise platform backingstores providing QImages with extra pixels would break horribly. The only such platform is wayland for now. Previously the need to support this case was masked by the RGBA8888 image conversion that happened always with wayland due to its ARGB32_Pre format. With the recent improvements this is not done anymore and so the problems became apparent. Task-number: QTBUG-50894 Change-Id: I27d7a1c8e25d152ca1227af1e2c38f7d4b6acbab Reviewed-by: Paul Olav Tvete <paul.tvete@theqtcompany.com>
This commit is contained in:
parent
b6630a5181
commit
4c1b6cdd29
@ -516,7 +516,23 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
|
||||
if (needsConversion)
|
||||
image = image.convertToFormat(QImage::Format_RGBA8888);
|
||||
|
||||
// The image provided by the backingstore may have a stride larger than width * 4, for
|
||||
// instance on platforms that manually implement client-side decorations.
|
||||
static const int bytesPerPixel = 4;
|
||||
const int strideInPixels = image.bytesPerLine() / bytesPerPixel;
|
||||
const bool hasUnpackRowLength = !ctx->isOpenGLES() || ctx->format().majorVersion() >= 3;
|
||||
|
||||
QOpenGLFunctions *funcs = ctx->functions();
|
||||
|
||||
if (hasUnpackRowLength) {
|
||||
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, strideInPixels);
|
||||
} else if (strideInPixels != image.width()) {
|
||||
// No UNPACK_ROW_LENGTH on ES 2.0 and yet we would need it. This case is typically
|
||||
// hit with QtWayland which is rarely used in combination with a ES2.0-only GL
|
||||
// implementation. Therefore, accept the performance hit and do a copy.
|
||||
image = image.copy();
|
||||
}
|
||||
|
||||
if (resized) {
|
||||
if (d_ptr->textureId)
|
||||
funcs->glDeleteTextures(1, &d_ptr->textureId);
|
||||
@ -538,11 +554,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
|
||||
QRect imageRect = image.rect();
|
||||
QRect rect = dirtyRegion.boundingRect() & imageRect;
|
||||
|
||||
if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
|
||||
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
|
||||
if (hasUnpackRowLength) {
|
||||
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);
|
||||
image.constScanLine(rect.y()) + rect.x() * bytesPerPixel);
|
||||
} else {
|
||||
// if the rect is wide enough it's cheaper to just
|
||||
// extend it instead of doing an image copy
|
||||
@ -564,6 +578,9 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textu
|
||||
}
|
||||
}
|
||||
|
||||
if (hasUnpackRowLength)
|
||||
funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
return d_ptr->textureId;
|
||||
}
|
||||
#endif // QT_NO_OPENGL
|
||||
|
Loading…
Reference in New Issue
Block a user