aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util/qquickpixmapcache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/util/qquickpixmapcache.cpp')
-rw-r--r--src/quick/util/qquickpixmapcache.cpp114
1 files changed, 85 insertions, 29 deletions
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index f403615d83..9ecdbc1846 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -328,6 +328,7 @@ public:
QQuickImageProviderOptions::AutoTransform appliedTransform;
QColorSpace targetColorSpace;
+ QIODevice *specialDevice = nullptr;
QQuickTextureFactory *textureFactory;
QIntrusiveList<QQuickPixmap, &QQuickPixmap::dataListNode> declarativePixmaps;
@@ -895,40 +896,54 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
QImage image;
QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
QString errorStr;
- QFile f(existingImageFileForPath(localFile));
QSize readSize;
- if (f.open(QIODevice::ReadOnly)) {
- QSGTextureReader texReader(&f, localFile);
- if (backendSupport()->hasOpenGL && texReader.isTexture()) {
- QQuickTextureFactory *factory = texReader.read();
- if (factory) {
- readSize = factory->textureSize();
+
+ if (runningJob->data && runningJob->data->specialDevice) {
+ int frameCount;
+ int const frame = runningJob->data ? runningJob->data->frame : 0;
+ if (!readImage(url, runningJob->data->specialDevice, &image, &errorStr, &readSize, &frameCount,
+ runningJob->requestRegion, runningJob->requestSize,
+ runningJob->providerOptions, nullptr, frame)) {
+ errorCode = QQuickPixmapReply::Loading;
+ } else if (runningJob->data) {
+ runningJob->data->frameCount = frameCount;
+ }
+ } else {
+ QFile f(existingImageFileForPath(localFile));
+ if (f.open(QIODevice::ReadOnly)) {
+ QSGTextureReader texReader(&f, localFile);
+ if (backendSupport()->hasOpenGL && texReader.isTexture()) {
+ QQuickTextureFactory *factory = texReader.read();
+ if (factory) {
+ readSize = factory->textureSize();
+ } else {
+ errorStr = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
+ if (f.fileName() != localFile)
+ errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
+ errorCode = QQuickPixmapReply::Decoding;
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, factory);
+ mutex.unlock();
+ return;
} else {
- errorStr = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
- if (f.fileName() != localFile)
- errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
- errorCode = QQuickPixmapReply::Decoding;
+ int frameCount;
+ int const frame = runningJob->data ? runningJob->data->frame : 0;
+ if (!readImage(url, &f, &image, &errorStr, &readSize, &frameCount,
+ runningJob->requestRegion, runningJob->requestSize,
+ runningJob->providerOptions, nullptr, frame)) {
+ errorCode = QQuickPixmapReply::Loading;
+ if (f.fileName() != localFile)
+ errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
+ } else if (runningJob->data) {
+ runningJob->data->frameCount = frameCount;
+ }
}
- mutex.lock();
- if (!cancelled.contains(runningJob))
- runningJob->postReply(errorCode, errorStr, readSize, factory);
- mutex.unlock();
- return;
} else {
- int frameCount;
- int const frame = runningJob->data ? runningJob->data->frame : 0;
- if (!readImage(url, &f, &image, &errorStr, &readSize, &frameCount, runningJob->requestRegion, runningJob->requestSize,
- runningJob->providerOptions, nullptr, frame)) {
- errorCode = QQuickPixmapReply::Loading;
- if (f.fileName() != localFile)
- errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
- } else if (runningJob->data) {
- runningJob->data->frameCount = frameCount;
- }
+ errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
+ errorCode = QQuickPixmapReply::Loading;
}
- } else {
- errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
- errorCode = QQuickPixmapReply::Loading;
}
mutex.lock();
if (!cancelled.contains(runningJob))
@@ -1738,6 +1753,47 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QRect &reques
}
}
+/*! \internal
+ Attempts to load an image from the given \a url via the given \a device.
+ This is for special cases when the QImageIOHandler can benefit from reusing
+ the I/O device, or from something extra that a subclass of QIODevice
+ carries with it. So far, this code doesn't support loading anything other
+ than a QImage, for example compressed textures. It can be added if needed.
+*/
+void QQuickPixmap::loadImageFromDevice(QQmlEngine *engine, QIODevice *device, const QUrl &url,
+ const QRect &requestRegion, const QSize &requestSize,
+ const QQuickImageProviderOptions &providerOptions, int frame, int frameCount)
+{
+ auto oldD = d;
+ QQuickPixmapKey key = { &url, &requestRegion, &requestSize, frame, providerOptions };
+ QQuickPixmapStore *store = pixmapStore();
+ QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.end();
+ iter = store->m_cache.find(key);
+ if (iter == store->m_cache.end()) {
+ if (!engine)
+ return;
+
+ d = new QQuickPixmapData(this, url, requestRegion, requestSize, providerOptions,
+ QQuickImageProviderOptions::UsePluginDefaultTransform, frame, frameCount);
+ d->specialDevice = device;
+ d->addToCache();
+
+ QQuickPixmapReader::readerMutex.lock();
+ d->reply = QQuickPixmapReader::instance(engine)->getImage(d);
+ if (oldD) {
+ QObject::connect(d->reply, &QQuickPixmapReply::finished, [oldD, this]() {
+ oldD->declarativePixmaps.remove(this);
+ oldD->release();
+ });
+ }
+ QQuickPixmapReader::readerMutex.unlock();
+ } else {
+ d = *iter;
+ d->addref();
+ d->declarativePixmaps.insert(this);
+ }
+}
+
void QQuickPixmap::clear()
{
if (d) {