summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Dyomin <artem.dyomin@qt.io>2024-02-05 15:27:25 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-02-09 09:32:19 +0000
commit07059d4d1d167b21fb83b27f85af3668f6587146 (patch)
tree6d1f2753f8d6f93acc8516574227be028002440c
parentf1cb2edd1e6a306f4ddacf43135d42e46d2d30b2 (diff)
Fix loading QRhiTexture from image on gles
The code should consider that image may be created by a pointer to user data, with original alignments. It means that we the way of setting parameters from raw data and QImage should be the same. In Qt Multimedia we want to pass a zero-copy image to rhi creation to get rid of an extra copy: codereview.qt-project.org/c/qt/qtmultimedia/+/537062 Aslo, data align has been fixed. Due to the documentation, GL_UNPACK_ALIGNMENT can be 8, 4, 2, 1. Let's find the biggest possible align. Task-number: QTBUG-121934 Pick-to: 6.6 6.5 Change-Id: Ic0f1617d4699217a7549c13e916be96108183d03 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> (cherry picked from commit 1d6bb23f6285252f7fa6cac87003cbe0f33f51af) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/gui/rhi/qrhigles2.cpp67
1 files changed, 30 insertions, 37 deletions
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index e41ac6d353..2f0659909f 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -2287,17 +2287,15 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
const GLenum effectiveTarget = faceTargetBase + (isCubeMap ? uint(layer) : 0u);
const QPoint dp = subresDesc.destinationTopLeft();
const QByteArray rawData = subresDesc.data();
- if (!subresDesc.image().isNull()) {
- QImage img = subresDesc.image();
- QSize size = img.size();
+
+ auto setCmdByNotCompressedData = [&](const void* data, QSize size, quint32 dataStride)
+ {
+ quint32 bytesPerLine = 0;
+ quint32 bytesPerPixel = 0;
+ textureFormatInfo(texD->m_format, size, &bytesPerLine, nullptr, &bytesPerPixel);
+
QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::SubImage;
- if (!subresDesc.sourceSize().isEmpty() || !subresDesc.sourceTopLeft().isNull()) {
- const QPoint sp = subresDesc.sourceTopLeft();
- if (!subresDesc.sourceSize().isEmpty())
- size = subresDesc.sourceSize();
- img = img.copy(sp.x(), sp.y(), size.width(), size.height());
- }
cmd.args.subImage.target = texD->target;
cmd.args.subImage.texture = texD->texture;
cmd.args.subImage.faceTarget = effectiveTarget;
@@ -2309,9 +2307,27 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
cmd.args.subImage.h = size.height();
cmd.args.subImage.glformat = texD->glformat;
cmd.args.subImage.gltype = texD->gltype;
- cmd.args.subImage.rowStartAlign = 4;
- cmd.args.subImage.rowLength = 0;
- cmd.args.subImage.data = cbD->retainImage(img);
+
+ if (dataStride == 0)
+ dataStride = bytesPerLine;
+
+ cmd.args.subImage.rowStartAlign = (dataStride & 3) ? 1 : 4;
+ cmd.args.subImage.rowLength = bytesPerPixel ? dataStride / bytesPerPixel : 0;
+
+ cmd.args.subImage.data = data;
+ };
+
+ if (!subresDesc.image().isNull()) {
+ QImage img = subresDesc.image();
+ QSize size = img.size();
+ if (!subresDesc.sourceSize().isEmpty() || !subresDesc.sourceTopLeft().isNull()) {
+ const QPoint sp = subresDesc.sourceTopLeft();
+ if (!subresDesc.sourceSize().isEmpty())
+ size = subresDesc.sourceSize();
+ img = img.copy(sp.x(), sp.y(), size.width(), size.height());
+ }
+
+ setCmdByNotCompressedData(cbD->retainImage(img), size, img.bytesPerLine());
} else if (!rawData.isEmpty() && isCompressed) {
const int depth = qMax(1, texD->m_depth);
const int arraySize = qMax(0, texD->m_arraySize);
@@ -2379,31 +2395,8 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb
} else if (!rawData.isEmpty()) {
const QSize size = subresDesc.sourceSize().isEmpty() ? q->sizeForMipLevel(level, texD->m_pixelSize)
: subresDesc.sourceSize();
- quint32 bytesPerLine = 0;
- quint32 bytesPerPixel = 0;
- textureFormatInfo(texD->m_format, size, &bytesPerLine, nullptr, &bytesPerPixel);
- QGles2CommandBuffer::Command &cmd(cbD->commands.get());
- cmd.cmd = QGles2CommandBuffer::Command::SubImage;
- cmd.args.subImage.target = texD->target;
- cmd.args.subImage.texture = texD->texture;
- cmd.args.subImage.faceTarget = effectiveTarget;
- cmd.args.subImage.level = level;
- cmd.args.subImage.dx = dp.x();
- cmd.args.subImage.dy = is1D && isArray ? layer : dp.y();
- cmd.args.subImage.dz = is3D || isArray ? layer : 0;
- cmd.args.subImage.w = size.width();
- cmd.args.subImage.h = size.height();
- cmd.args.subImage.glformat = texD->glformat;
- cmd.args.subImage.gltype = texD->gltype;
- // Default unpack alignment (row start alignment
- // requirement) is 4. QImage guarantees 4 byte aligned
- // row starts, but our raw data here does not.
- cmd.args.subImage.rowStartAlign = (bytesPerLine & 3) ? 1 : 4;
- if (subresDesc.dataStride() && bytesPerPixel)
- cmd.args.subImage.rowLength = subresDesc.dataStride() / bytesPerPixel;
- else
- cmd.args.subImage.rowLength = 0;
- cmd.args.subImage.data = cbD->retainData(rawData);
+
+ setCmdByNotCompressedData(cbD->retainData(rawData), size, subresDesc.dataStride());
} else {
qWarning("Invalid texture upload for %p layer=%d mip=%d", texD, layer, level);
}