\list
\li Loaded using QPixmaps rather than actual image files
- \li Loaded asynchronously in a separate thread, if imageType() is \l{QQuickImageProvider::ImageType}{ImageType::Image}
+ \li Loaded asynchronously in a separate thread
\endlist
To specify that an image should be loaded by an image provider, use the
\section2 Asynchronous image loading
- Image providers that support QImage loading automatically include support
+ Image providers that support QImage or Texture loading automatically include support
for asychronous loading of images. To enable asynchronous loading for an
image source, set the \c asynchronous property to \c true for the relevant
\l Image, \l BorderImage or \l AnimatedImage object. When this is enabled,
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
- \c true, the value is ignored and the image is loaded
- synchronously.
+ Asynchronous loading for image providers that provide QPixmap is only supported
+ in platforms that have the ThreadedPixmaps feature, in platforms where
+ pixmaps can only be created in the main thread (i.e. ThreadedPixmaps is not supported)
+ if \l {Image::}{asynchronous} is set to \c true, the value is ignored
+ and the image is loaded synchronously.
\section2 Image caching
In all cases, \a size must be set to the original size of the image. This
is used to set the \l {Item::}{width} and \l {Item::}{height} of the
relevant \l Image if these values have not been set explicitly.
+
+ \note this method may be called by multiple threads, so ensure the
+ implementation of this method is reentrant.
*/
QPixmap QQuickImageProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize)
{
#include <private/qqmlglobal_p.h>
#include <private/qqmlengine_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+
#include <QtQuick/private/qsgtexture_p.h>
#include <QtQuick/private/qsgcontext_p.h>
if (!cancelled.contains(runningJob))
runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(image));
mutex.unlock();
+ } else if (imageType == QQuickImageProvider::Pixmap) {
+ const QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize);
+ QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
+ QString errorStr;
+ if (pixmap.isNull()) {
+ errorCode = QQuickPixmapReply::Loading;
+ errorStr = QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString());
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, textureFactoryForImage(pixmap.toImage()));
+ mutex.unlock();
} else {
QQuickTextureFactory *t = provider->requestTexture(imageId(url), &readSize, requestSize);
QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
if (iter == store->m_cache.end()) {
if (url.scheme() == QLatin1String("image")) {
if (QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url)))) {
- if (provider->imageType() == QQuickImageProvider::Pixmap) {
+ const bool threadedPixmaps = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps);
+ if (!threadedPixmaps && provider->imageType() == QQuickImageProvider::Pixmap) {
// pixmaps can only be loaded synchronously
options &= ~QQuickPixmap::Asynchronous;
} else if (provider->flags() & QQuickImageProvider::ForceAsynchronousImageLoading) {