diff options
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.h | 7 | ||||
-rw-r--r-- | src/quick/util/qquickimageprovider.cpp | 18 | ||||
-rw-r--r-- | src/quick/util/qquickimageprovider.h | 3 | ||||
-rw-r--r-- | src/quick/util/qquickpixmapcache.cpp | 11 | ||||
-rw-r--r-- | tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp | 25 |
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"); |