diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-06-04 10:24:46 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-06-04 10:28:48 +0200 |
commit | 9556f6d075b61fa95d6e1057f305e522a26f71d6 (patch) | |
tree | 53190472453390810c47b9b5a47b23188a00267e /src/quick/util/qquickpixmapcache.cpp | |
parent | 42ffe9b193a5bd958b0853233fd0d94170722bd1 (diff) | |
parent | 1fd0cdc6a2e01775d8a79c6614910cc5a2fbf2b3 (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts:
src/qml/jsruntime/qv4engine_p.h
src/quick/items/qquickitemsmodule.cpp
src/quick/items/qquicktext.cpp
src/quick/util/qquickpixmapcache.cpp
tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
Change-Id: I90ecaad6a4bfaa4f36149a7463f4d7141f4a516a
Diffstat (limited to 'src/quick/util/qquickpixmapcache.cpp')
-rw-r--r-- | src/quick/util/qquickpixmapcache.cpp | 104 |
1 files changed, 68 insertions, 36 deletions
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 810629cdb6..f36d06d00d 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -131,15 +131,17 @@ public: QUrl url; bool loading; + AutoTransform autoTransform; int redirectCount; class Event : public QEvent { public: - Event(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory); + Event(ReadError, const QString &, const QSize &, AutoTransform, QQuickTextureFactory *factory); ReadError error; QString errorString; QSize implicitSize; + AutoTransform autoTransform; QQuickTextureFactory *textureFactory; }; void postReply(ReadError, const QString &, const QSize &, QQuickTextureFactory *factory); @@ -193,7 +195,7 @@ protected: private: friend class QQuickPixmapReaderThreadObject; void processJobs(); - void processJob(QQuickPixmapReply *, const QUrl &, const QString &, QQuickImageProvider::ImageType, QQuickImageProvider *); + void processJob(QQuickPixmapReply *, const QUrl &, const QString &, AutoTransform, QQuickImageProvider::ImageType, QQuickImageProvider *); void networkRequestDone(QNetworkReply *); void asyncResponseFinished(QQuickImageResponse *); @@ -224,25 +226,32 @@ public: class QQuickPixmapData { public: - QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, const QString &e) + QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &s, AutoTransform transform, const QString &e) : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Error), - url(u), errorString(e), requestSize(s), textureFactory(0), reply(0), prevUnreferenced(0), + url(u), errorString(e), requestSize(s), + requestedTransform(transform), appliedTransform(UsePluginDefault), + textureFactory(0), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0), nextUnreferenced(0) { declarativePixmaps.insert(pixmap); } - QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r) + QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, const QSize &r, AutoTransform rTransform, AutoTransform aTransform) : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Loading), - url(u), requestSize(r), textureFactory(0), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0), + url(u), requestSize(r), + requestedTransform(rTransform), appliedTransform(aTransform), + textureFactory(0), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0), nextUnreferenced(0) { declarativePixmaps.insert(pixmap); } - QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture, const QSize &s, const QSize &r) + QQuickPixmapData(QQuickPixmap *pixmap, const QUrl &u, QQuickTextureFactory *texture, + const QSize &s, const QSize &r, AutoTransform rTransform, AutoTransform aTransform) : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready), - url(u), implicitSize(s), requestSize(r), textureFactory(texture), reply(0), prevUnreferenced(0), + url(u), implicitSize(s), requestSize(r), + requestedTransform(rTransform), appliedTransform(aTransform), + textureFactory(texture), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0), nextUnreferenced(0) { declarativePixmaps.insert(pixmap); @@ -250,6 +259,7 @@ public: QQuickPixmapData(QQuickPixmap *pixmap, QQuickTextureFactory *texture) : refCount(1), inCache(false), pixmapStatus(QQuickPixmap::Ready), + requestedTransform(UsePluginDefault), appliedTransform(UsePluginDefault), textureFactory(texture), reply(0), prevUnreferenced(0), prevUnreferencedPtr(0), nextUnreferenced(0) { @@ -283,6 +293,8 @@ public: QString errorString; QSize implicitSize; QSize requestSize; + AutoTransform requestedTransform; + AutoTransform appliedTransform; QQuickTextureFactory *textureFactory; @@ -311,11 +323,11 @@ void QQuickPixmapReply::postReply(ReadError error, const QString &errorString, const QSize &implicitSize, QQuickTextureFactory *factory) { loading = false; - QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, factory)); + QCoreApplication::postEvent(this, new Event(error, errorString, implicitSize, autoTransform, factory)); } -QQuickPixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSize, QQuickTextureFactory *factory) - : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), textureFactory(factory) +QQuickPixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSize, AutoTransform iTransformed, QQuickTextureFactory *factory) + : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), autoTransform(iTransformed), textureFactory(factory) { } @@ -352,9 +364,13 @@ static void maybeRemoveAlpha(QImage *image) } static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *errorString, QSize *impsize, - const QSize &requestSize) + const QSize &requestSize, AutoTransform &autoTransform) { QImageReader imgio(dev); + if (autoTransform != UsePluginDefault) + imgio.setAutoTransform(autoTransform == ApplyTransform); + else + autoTransform = imgio.autoTransform() ? ApplyTransform : DoNotApplyTransform; const bool force_scale = imgio.format() == "svg" || imgio.format() == "svgz"; @@ -464,7 +480,7 @@ void QQuickPixmapReader::networkRequestDone(QNetworkReply *reply) QByteArray all = reply->readAll(); QBuffer buff(&all); buff.open(QIODevice::ReadOnly); - if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, job->requestSize)) + if (!readImage(reply->url(), &buff, &image, &errorString, &readSize, job->requestSize, job->autoTransform)) error = QQuickPixmapReply::Decoding; } // send completion event to the QQuickPixmapReply @@ -599,8 +615,9 @@ void QQuickPixmapReader::processJobs() PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url)); + AutoTransform autoTransform = job->autoTransform; locker.unlock(); - processJob(job, url, localFile, imageType, provider); + processJob(job, url, localFile, autoTransform, imageType, provider); locker.relock(); } } @@ -612,7 +629,7 @@ void QQuickPixmapReader::processJobs() } void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &url, const QString &localFile, - QQuickImageProvider::ImageType imageType, QQuickImageProvider *provider) + AutoTransform autoTransform, QQuickImageProvider::ImageType imageType, QQuickImageProvider *provider) { // fetch if (url.scheme() == QLatin1String("image")) { @@ -701,7 +718,7 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u QFile f(localFile); QSize readSize; if (f.open(QIODevice::ReadOnly)) { - if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize)) + if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, autoTransform)) errorCode = QQuickPixmapReply::Loading; } else { errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString()); @@ -800,16 +817,17 @@ class QQuickPixmapKey public: const QUrl *url; const QSize *size; + AutoTransform autoTransform; }; inline bool operator==(const QQuickPixmapKey &lhs, const QQuickPixmapKey &rhs) { - return *lhs.size == *rhs.size && *lhs.url == *rhs.url; + return *lhs.size == *rhs.size && *lhs.url == *rhs.url && lhs.autoTransform == rhs.autoTransform; } inline uint qHash(const QQuickPixmapKey &key) { - return qHash(*key.url) ^ key.size->width() ^ key.size->height(); + return qHash(*key.url) ^ (key.size->width()*7) ^ (key.size->height()*17) ^ (key.autoTransform * 0x5c5c5c5c); } class QQuickPixmapStore : public QObject @@ -977,7 +995,7 @@ void QQuickPixmap::purgeCache() } QQuickPixmapReply::QQuickPixmapReply(QQuickPixmapData *d) -: data(d), engineForReader(0), requestSize(d->requestSize), url(d->url), loading(false), redirectCount(0) +: data(d), engineForReader(0), requestSize(d->requestSize), url(d->url), loading(false), autoTransform(d->appliedTransform), redirectCount(0) { if (finishedIndex == -1) { finishedIndex = QMetaMethod::fromSignal(&QQuickPixmapReply::finished).methodIndex(); @@ -1001,6 +1019,7 @@ bool QQuickPixmapReply::event(QEvent *event) if (data->pixmapStatus == QQuickPixmap::Ready) { data->textureFactory = de->textureFactory; data->implicitSize = de->implicitSize; + data->appliedTransform = de->autoTransform; PIXMAP_PROFILE(pixmapLoadingFinished(data->url, data->textureFactory != 0 && data->textureFactory->textureSize().isValid() ? data->textureFactory->textureSize() : @@ -1071,7 +1090,7 @@ void QQuickPixmapData::release() void QQuickPixmapData::addToCache() { if (!inCache) { - QQuickPixmapKey key = { &url, &requestSize }; + QQuickPixmapKey key = { &url, &requestSize, requestedTransform }; pixmapStore()->m_cache.insert(key, this); inCache = true; PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>( @@ -1082,7 +1101,7 @@ void QQuickPixmapData::addToCache() void QQuickPixmapData::removeFromCache() { if (inCache) { - QQuickPixmapKey key = { &url, &requestSize }; + QQuickPixmapKey key = { &url, &requestSize, requestedTransform }; pixmapStore()->m_cache.remove(key); inCache = false; PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>( @@ -1090,7 +1109,7 @@ void QQuickPixmapData::removeFromCache() } } -static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, bool *ok) +static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, QQmlEngine *engine, const QUrl &url, const QSize &requestSize, AutoTransform autoTransform, bool *ok) { if (url.scheme() == QLatin1String("image")) { QSize readSize; @@ -1102,14 +1121,14 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q switch (imageType) { case QQuickImageProvider::Invalid: - return new QQuickPixmapData(declarativePixmap, url, requestSize, + return new QQuickPixmapData(declarativePixmap, url, requestSize, autoTransform, QQuickPixmap::tr("Invalid image provider: %1").arg(url.toString())); case QQuickImageProvider::Texture: { QQuickTextureFactory *texture = provider->requestTexture(imageId(url), &readSize, requestSize); if (texture) { *ok = true; - return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize); + return new QQuickPixmapData(declarativePixmap, url, texture, readSize, requestSize, autoTransform, UsePluginDefault); } } @@ -1118,7 +1137,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q QImage image = provider->requestImage(imageId(url), &readSize, requestSize); if (!image.isNull()) { *ok = true; - return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize); + return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, UsePluginDefault); } } case QQuickImageProvider::Pixmap: @@ -1126,7 +1145,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q QPixmap pixmap = provider->requestPixmap(imageId(url), &readSize, requestSize); if (!pixmap.isNull()) { *ok = true; - return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize); + return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(pixmap.toImage()), readSize, requestSize, autoTransform, UsePluginDefault); } } case QQuickImageProvider::ImageResponse: @@ -1137,7 +1156,7 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q } // provider has bad image type, or provider returned null image - return new QQuickPixmapData(declarativePixmap, url, requestSize, + return new QQuickPixmapData(declarativePixmap, url, requestSize, autoTransform, QQuickPixmap::tr("Failed to get image from provider: %1").arg(url.toString())); } @@ -1151,17 +1170,17 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q if (f.open(QIODevice::ReadOnly)) { QImage image; - - if (readImage(url, &f, &image, &errorString, &readSize, requestSize)) { + AutoTransform appliedTransform = autoTransform; + if (readImage(url, &f, &image, &errorString, &readSize, requestSize, appliedTransform)) { *ok = true; - return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize); + return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, autoTransform, appliedTransform); } errorString = QQuickPixmap::tr("Invalid image data: %1").arg(url.toString()); } else { errorString = QQuickPixmap::tr("Cannot open: %1").arg(url.toString()); } - return new QQuickPixmapData(declarativePixmap, url, requestSize, errorString); + return new QQuickPixmapData(declarativePixmap, url, requestSize, autoTransform, errorString); } @@ -1190,7 +1209,7 @@ QQuickPixmap::QQuickPixmap(QQmlEngine *engine, const QUrl &url, const QSize &siz QQuickPixmap::QQuickPixmap(const QUrl &url, const QImage &image) { - d = new QQuickPixmapData(this, url, new QQuickDefaultTextureFactory(image), image.size(), QSize()); + d = new QQuickPixmapData(this, url, new QQuickDefaultTextureFactory(image), image.size(), QSize(), UsePluginDefault, UsePluginDefault); d->addToCache(); } @@ -1263,6 +1282,14 @@ const QSize &QQuickPixmap::requestSize() const return nullPixmap()->size; } +AutoTransform QQuickPixmap::autoTransform() const +{ + if (d) + return d->appliedTransform; + else + return UsePluginDefault; +} + QQuickTextureFactory *QQuickPixmap::textureFactory() const { if (d) @@ -1338,13 +1365,18 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &size) void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options) { + load(engine, url, requestSize, options, UsePluginDefault); +} + +void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &requestSize, QQuickPixmap::Options options, AutoTransform requestAutoTransform) +{ if (d) { d->declarativePixmaps.remove(this); d->release(); d = 0; } - QQuickPixmapKey key = { &url, &requestSize }; + QQuickPixmapKey key = { &url, &requestSize, requestAutoTransform }; QQuickPixmapStore *store = pixmapStore(); QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.end(); @@ -1370,7 +1402,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques if (!(options & QQuickPixmap::Asynchronous)) { bool ok = false; PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(url)); - d = createPixmapDataSync(this, engine, url, requestSize, &ok); + d = createPixmapDataSync(this, engine, url, requestSize, requestAutoTransform, &ok); if (ok) { PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height()))); if (options & QQuickPixmap::Cache) @@ -1386,7 +1418,7 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques if (!engine) return; - d = new QQuickPixmapData(this, url, requestSize); + d = new QQuickPixmapData(this, url, requestSize, requestAutoTransform, requestAutoTransform); if (options & QQuickPixmap::Cache) d->addToCache(); @@ -1422,7 +1454,7 @@ void QQuickPixmap::clear(QObject *obj) bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize) { - QQuickPixmapKey key = { &url, &requestSize }; + QQuickPixmapKey key = { &url, &requestSize, UsePluginDefault }; QQuickPixmapStore *store = pixmapStore(); return store->m_cache.contains(key); |