NinePatchImage: support the compressed texture image

The compressed texture image is supported by qquickimage and
the qquickninepatchimage is inherited by qquickimage.
But the compressed texture is not shown when the source of
qquickninepatchimage is set as compressed texture because the
updatePaintNode of qquickninepatchimage only consider non-compressed
texture.

This patch is not intended to use the HW compressed image as an
actual 9-patch image, but to display them using the super class
qquickimage in the case of an HW compressed image other than a normal
pixmap image.

If the source is HW compressed textures such as ASTC, KTX, and PKM,
we have to call updatePaintNode of QQuickImage before checking the
validity of the pixmap image.
(because nullptr is returned if pixmap image is not valid)

The containers themselves (pkm, ktx) are universally supported but
the compressed texture formats is up to the underlying 3D API
implementation and may vary.
So, if the format is not supported by RHI, we skip the test.
Refer to QTBUG-113565 for a detailed discussion on texture formats.

And when using the software backend, we also skip test cases.

Fixes: QTBUG-113446
Pick-to: 6.2 6.4 6.5
Change-Id: I2704f86e94b50b3c187eca359fdc1a69eb217811
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Jaehak Lee 2023-04-25 18:17:58 +09:00 committed by Seokha Ko
parent e6dd62ff19
commit ed69a9d4f3
6 changed files with 63 additions and 8 deletions

View File

@ -443,6 +443,9 @@ QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
d->resetNode = false;
}
if (d->ninePatch.isNull())
return QQuickImage::updatePaintNode(oldNode, data);
QSizeF sz = size();
QImage image = d->pix.image();
if (!sz.isValid() || image.isNull()) {
@ -452,9 +455,6 @@ QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
return nullptr;
}
if (d->ninePatch.isNull())
return QQuickImage::updatePaintNode(oldNode, data);
QQuickNinePatchNode *patchNode = static_cast<QQuickNinePatchNode *>(oldNode);
if (!patchNode)
patchNode = new QQuickNinePatchNode;

View File

@ -16,11 +16,7 @@ endif()
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/data/*.qml)
list(APPEND test_data ${test_data_glob})
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/data/*.png)
${CMAKE_CURRENT_SOURCE_DIR}/data/*)
list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qquickninepatchimage

View File

@ -11,8 +11,10 @@
#include <QtQuick/qquickview.h>
#include <QtQuick/qquickitemgrabresult.h>
#include <QtQuick/private/qquickimage_p.h>
#include <QtQuick/private/qquickimage_p_p.h>
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtQuickTestUtils/private/visualtestutils_p.h>
#include <QtGui/private/qrhi_p.h>
using namespace QQuickVisualTestUtils;
@ -32,6 +34,8 @@ private slots:
void inset();
void implicitSize_data();
void implicitSize();
void hwCompressedImages_data();
void hwCompressedImages();
};
static QImage grabItemToImage(QQuickItem *item)
@ -230,6 +234,61 @@ void tst_qquickninepatchimage::implicitSize()
QCOMPARE(ninePatchImage->implicitHeight(), implicitSize.height());
}
void tst_qquickninepatchimage::hwCompressedImages_data()
{
QTest::addColumn<int>("dpr");
QTest::addColumn<QString>("file");
QTest::addColumn<QSize>("size");
QTest::addColumn<QRhiTexture::Format>("format");
const struct TestFile {
QString name;
QSize size;
QRhiTexture::Format format;
} testFiles [] = {
{ "o1_bc1.ktx", QSize(64, 64), QRhiTexture::BC1 },
{ "logo.pkm", QSize(256, 256), QRhiTexture::ETC2_RGB8 },
{ "qt4.astc", QSize(250, 200), QRhiTexture::ASTC_8x8 }
};
for (const TestFile &file : testFiles) {
for (int dpr = 1; dpr <= 4; ++dpr)
QTest::newRow(qPrintable(QString::fromLatin1("%1 DPR=%2").arg(file.name).arg(dpr))) << dpr << file.name << file.size << file.format;
}
}
void tst_qquickninepatchimage::hwCompressedImages()
{
QFETCH(int, dpr);
QFETCH(QString, file);
QFETCH(QSize, size);
QFETCH(QRhiTexture::Format, format);
QHighDpiScaling::setGlobalFactor(dpr);
QQuickView view(testFileUrl("ninepatchimage.qml"));
QCOMPARE(view.status(), QQuickView::Ready);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
if (!QSGRendererInterface::isApiRhiBased(view.rendererInterface()->graphicsApi()))
QSKIP("Skipping due to using software backend");
QRhi *rhi = static_cast<QRhi *>(view.rendererInterface()->getResource(&view, QSGRendererInterface::RhiResource));
if (!rhi->isTextureFormatSupported(format))
QSKIP(qPrintable(QString::fromLatin1("%1 not supported, skip").arg(format)));
QQuickImage *ninePatchImage = qobject_cast<QQuickImage *>(view.rootObject());
QVERIFY(ninePatchImage);
ninePatchImage->setSource(testFileUrl(file));
ninePatchImage->setSize(size);
QSignalSpy spy(&view, SIGNAL(afterSynchronizing()));
QTRY_VERIFY(spy.size() >= 1);
QQuickImagePrivate *ninePatchImagePrivate = static_cast<QQuickImagePrivate *>(QQuickItemPrivate::get(ninePatchImage));
QVERIFY(ninePatchImagePrivate->paintNode);
}
QTEST_MAIN(tst_qquickninepatchimage)
#include "tst_qquickninepatchimage.moc"