aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlengine.cpp10
-rw-r--r--src/qml/qml/qqmlengine.h7
-rw-r--r--src/quick/util/qquickimageprovider.cpp18
-rw-r--r--src/quick/util/qquickimageprovider.h3
-rw-r--r--src/quick/util/qquickpixmapcache.cpp11
-rw-r--r--tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp25
6 files changed, 64 insertions, 10 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 13344f0710..b6a306085e 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -204,6 +204,16 @@ void QQmlEnginePrivate::defineModule()
The QQuickImageProvider::requestTexture() method will be called for all image requests. \omitvalue
*/
+/*!
+ \enum QQmlImageProviderBase::Flag
+
+ Defines specific requirements or features of this image provider.
+
+ \value ForceAsynchronousImageLoading Ensures that image requests to the provider are
+ run in a separate thread, which allows the provider to spend as much time as needed
+ on producing the image without blocking the main thread.
+*/
+
/*! \internal */
QQmlImageProviderBase::QQmlImageProviderBase()
{
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h
index 8d250ed209..8640f1acad 100644
--- a/src/qml/qml/qqmlengine.h
+++ b/src/qml/qml/qqmlengine.h
@@ -64,14 +64,21 @@ public:
Invalid
};
+ enum Flag {
+ ForceAsynchronousImageLoading = 0x01
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
virtual ~QQmlImageProviderBase();
virtual ImageType imageType() const = 0;
+ virtual Flags flags() const = 0;
private:
friend class QQuickImageProvider;
QQmlImageProviderBase();
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlImageProviderBase::Flags)
class QQmlComponent;
class QQmlEnginePrivate;
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index b306ab3419..5ded343195 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -47,6 +47,7 @@ class QQuickImageProviderPrivate
{
public:
QQuickImageProvider::ImageType type;
+ QQuickImageProvider::Flags flags;
};
/*!
@@ -203,6 +204,12 @@ QImage QQuickTextureFactory::image() const
allowing image loading to be executed in the background, and reducing the
performance impact on the user interface.
+ To force asynchronous image loading, even for image sources that do not
+ have the \c asynchronous property set to \c true, you may pass the
+ \c QQuickImageProvider::ForceAsynchronousImageLoading flag to the image
+ provider constructor. This ensures that all image requests for the
+ provider are handled in a separate thread.
+
Asynchronous loading is not supported for image providers that provide
QPixmap rather than QImage values, as pixmaps can only be created in the
main thread. In this case, if \l {Image::}{asynchronous} is set to
@@ -228,10 +235,11 @@ QImage QQuickTextureFactory::image() const
/*!
Creates an image provider that will provide images of the given \a type.
*/
-QQuickImageProvider::QQuickImageProvider(ImageType type)
+QQuickImageProvider::QQuickImageProvider(ImageType type, Flags flags)
: d(new QQuickImageProviderPrivate)
{
d->type = type;
+ d->flags = flags;
}
/*!
@@ -253,6 +261,14 @@ QQuickImageProvider::ImageType QQuickImageProvider::imageType() const
}
/*!
+ Returns the flags set for this provider.
+*/
+QQuickImageProvider::Flags QQuickImageProvider::flags() const
+{
+ return d->flags;
+}
+
+/*!
Implement this method to return the image with \a id. The default
implementation returns an empty image.
diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h
index 252d57b1d6..459b3ea48d 100644
--- a/src/quick/util/qquickimageprovider.h
+++ b/src/quick/util/qquickimageprovider.h
@@ -71,10 +71,11 @@ public:
class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase
{
public:
- QQuickImageProvider(ImageType type);
+ QQuickImageProvider(ImageType type, Flags flags = 0);
virtual ~QQuickImageProvider();
ImageType imageType() const;
+ Flags flags() const;
virtual QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize);
virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize);
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 0400c9580c..2ef95a5959 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -1168,12 +1168,13 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques
QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.find(key);
if (iter == store->m_cache.end()) {
- if (options & QQuickPixmap::Asynchronous) {
- // pixmaps can only be loaded synchronously
- if (url.scheme() == QLatin1String("image")) {
- QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url)));
- if (provider && provider->imageType() == QQuickImageProvider::Pixmap) {
+ if (url.scheme() == QLatin1String("image")) {
+ if (QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url)))) {
+ if (provider->imageType() == QQuickImageProvider::Pixmap) {
+ // pixmaps can only be loaded synchronously
options &= ~QQuickPixmap::Asynchronous;
+ } else if (provider->flags() & QQuickImageProvider::ForceAsynchronousImageLoading) {
+ options |= QQuickPixmap::Asynchronous;
}
}
}
diff --git a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp
index 7f9a0efb33..b44fbfe0fc 100644
--- a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp
+++ b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp
@@ -61,6 +61,8 @@ private slots:
void requestImage_sync();
void requestImage_async_data();
void requestImage_async();
+ void requestImage_async_forced_data();
+ void requestImage_async_forced();
void requestPixmap_sync_data();
void requestPixmap_sync();
@@ -81,8 +83,9 @@ private:
class TestQImageProvider : public QQuickImageProvider
{
public:
- TestQImageProvider(bool *deleteWatch = 0)
- : QQuickImageProvider(Image), deleteWatch(deleteWatch)
+ TestQImageProvider(bool *deleteWatch = 0, bool forceAsync = false)
+ : QQuickImageProvider(Image, (forceAsync ? ForceAsynchronousImageLoading : Flags()))
+ , deleteWatch(deleteWatch)
{
}
@@ -231,7 +234,11 @@ void tst_qquickimageprovider::runTest(bool async, QQuickImageProvider *provider)
QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
QVERIFY(obj != 0);
- if (async)
+ // From this point on, treat forced async providers as async behaviour-wise
+ if (engine.imageProvider(QUrl(source).host()) == provider)
+ async |= provider->flags() & QQuickImageProvider::ForceAsynchronousImageLoading;
+
+ if (async)
QTRY_VERIFY(obj->status() == QQuickImage::Loading);
QCOMPARE(obj->source(), QUrl(source));
@@ -284,6 +291,18 @@ void tst_qquickimageprovider::requestImage_async()
QVERIFY(deleteWatch);
}
+void tst_qquickimageprovider::requestImage_async_forced_data()
+{
+ fillRequestTestsData("qimage|async_forced");
+}
+
+void tst_qquickimageprovider::requestImage_async_forced()
+{
+ bool deleteWatch = false;
+ runTest(false, new TestQImageProvider(&deleteWatch, true));
+ QVERIFY(deleteWatch);
+}
+
void tst_qquickimageprovider::requestPixmap_sync_data()
{
fillRequestTestsData("qpixmap");