From: Albert Astals Cid Date: Fri, 23 Nov 2012 11:44:16 +0000 (+0100) Subject: Support requestPixmap if platform has ThreadedPixmaps feature X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=597df98c542601ff2d286c79a8002a9ae995c98b;p=profile%2Fivi%2Fqtdeclarative.git Support requestPixmap if platform has ThreadedPixmaps feature As discussed with Samuel enable the use of requestPixmap in a thread for async requests if the platform support ThreadedPixmaps Task-number: 28138 Change-Id: I106cf0123430115464b0a75071c7e6129a98d22b Reviewed-by: Samuel Rødal --- diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp index 94a753f..3c5610f 100644 --- a/src/quick/util/qquickimageprovider.cpp +++ b/src/quick/util/qquickimageprovider.cpp @@ -136,7 +136,7 @@ QImage QQuickTextureFactory::image() const \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 @@ -211,7 +211,7 @@ QImage QQuickTextureFactory::image() const \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, @@ -225,11 +225,11 @@ QImage QQuickTextureFactory::image() const 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 @@ -328,6 +328,9 @@ QImage QQuickImageProvider::requestImage(const QString &id, QSize *size, const Q 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) { diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 1649e33..3d6a8d0 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -47,6 +47,9 @@ #include #include +#include +#include + #include #include @@ -539,6 +542,18 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u 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; @@ -1176,7 +1191,8 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques if (iter == store->m_cache.end()) { if (url.scheme() == QLatin1String("image")) { if (QQuickImageProvider *provider = static_cast(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) {