aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorLouis du Verdier <louis.du.verdier@free.fr>2014-06-05 08:44:16 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-06-05 14:09:31 +0200
commit468a65c89eebeeb8c02cb83fe8ffd37c3e8937d2 (patch)
tree5fb2ece74d4323b17a6500b74fe8573980f69b7e /src/quick
parent8a71e2bd031230777dcfbb482af40a03b8d91507 (diff)
Optimize the way AnimatedImage display its content
Since QtQuick2, the AnimatedImage component is less efficient than it was with QtQuick1, using more CPU and RAM. This commit makes it upload when required each animation frame as a cached texture (using QQuickPixmapCache) to speed up the component. Task-number: QTBUG-38921 Change-Id: I7ab0b5f47ecec6cb3cdded0dd219d6acc1bc4148 Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/qquickanimatedimage.cpp40
-rw-r--r--src/quick/items/qquickanimatedimage_p_p.h3
-rw-r--r--src/quick/items/qquickimage.cpp11
-rw-r--r--src/quick/items/qquickimage_p_p.h1
-rw-r--r--src/quick/util/qquickpixmapcache.cpp19
-rw-r--r--src/quick/util/qquickpixmapcache_p.h2
6 files changed, 74 insertions, 2 deletions
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index 3f31884cd3..19c6d13b2a 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -52,6 +52,36 @@
#include <QtNetwork/qnetworkreply.h>
QT_BEGIN_NAMESPACE
+
+QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine)
+{
+ if (!_movie)
+ return 0;
+
+ int current = _movie->currentFrameNumber();
+ if (!frameMap.contains(current)) {
+ QUrl requestedUrl;
+ QQuickPixmap *pixmap = 0;
+ if (engine && !_movie->fileName().isEmpty()) {
+ requestedUrl.setUrl(QString::fromUtf8("quickanimatedimage://%1#%2")
+ .arg(_movie->fileName())
+ .arg(current));
+ }
+ if (!requestedUrl.isEmpty()) {
+ if (QQuickPixmap::isCached(requestedUrl, QSize()))
+ pixmap = new QQuickPixmap(engine, requestedUrl);
+ else
+ pixmap = new QQuickPixmap(requestedUrl, _movie->currentImage());
+ } else {
+ pixmap = new QQuickPixmap;
+ pixmap->setImage(_movie->currentImage());
+ }
+ frameMap.insert(current, pixmap);
+ }
+
+ return frameMap.value(current);
+}
+
/*!
\qmltype AnimatedImage
\instantiates QQuickAnimatedImage
@@ -111,6 +141,8 @@ QQuickAnimatedImage::~QQuickAnimatedImage()
if (d->reply)
d->reply->deleteLater();
delete d->_movie;
+ qDeleteAll(d->frameMap);
+ d->frameMap.clear();
}
/*!
@@ -231,6 +263,10 @@ void QQuickAnimatedImage::setSource(const QUrl &url)
d->reply = 0;
}
+ d->setImage(QImage());
+ qDeleteAll(d->frameMap);
+ d->frameMap.clear();
+
d->oldPlaying = isPlaying();
if (d->_movie) {
delete d->_movie;
@@ -357,7 +393,7 @@ void QQuickAnimatedImage::movieRequestFinished()
d->_movie->jumpToFrame(d->preset_currentframe);
d->preset_currentframe = 0;
}
- d->setImage(d->_movie->currentPixmap().toImage());
+ d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this)));
if (isPlaying() != d->oldPlaying)
emit playingChanged();
@@ -372,7 +408,7 @@ void QQuickAnimatedImage::movieUpdate()
Q_D(QQuickAnimatedImage);
if (d->_movie) {
- d->setImage(d->_movie->currentPixmap().toImage());
+ d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this)));
emit frameChanged();
}
}
diff --git a/src/quick/items/qquickanimatedimage_p_p.h b/src/quick/items/qquickanimatedimage_p_p.h
index 21b891eadd..0be24dece5 100644
--- a/src/quick/items/qquickanimatedimage_p_p.h
+++ b/src/quick/items/qquickanimatedimage_p_p.h
@@ -72,6 +72,8 @@ public:
{
}
+ QQuickPixmap *infoForCurrentFrame(QQmlEngine *engine);
+
bool playing;
bool paused;
int preset_currentframe;
@@ -79,6 +81,7 @@ public:
QNetworkReply *reply;
int redirectCount;
bool oldPlaying;
+ QMap<int, QQuickPixmap *> frameMap;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index d7527742dc..f8323a6bc3 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -184,6 +184,17 @@ void QQuickImagePrivate::setImage(const QImage &image)
q->update();
}
+void QQuickImagePrivate::setPixmap(const QQuickPixmap &pixmap)
+{
+ Q_Q(QQuickImage);
+ pix.setPixmap(pixmap);
+
+ q->pixmapChange();
+ status = pix.isNull() ? QQuickImageBase::Null : QQuickImageBase::Ready;
+
+ q->update();
+}
+
/*!
\qmlproperty enumeration QtQuick::Image::fillMode
diff --git a/src/quick/items/qquickimage_p_p.h b/src/quick/items/qquickimage_p_p.h
index de88662ab8..7ed0a6b989 100644
--- a/src/quick/items/qquickimage_p_p.h
+++ b/src/quick/items/qquickimage_p_p.h
@@ -71,6 +71,7 @@ public:
qreal paintedWidth;
qreal paintedHeight;
void setImage(const QImage &img);
+ void setPixmap(const QQuickPixmap &pixmap);
bool pixmapChanged : 1;
bool mipmap : 1;
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 0a5b26281a..95b3ac5b21 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -1182,6 +1182,17 @@ void QQuickPixmap::setImage(const QImage &p)
d = new QQuickPixmapData(this, textureFactoryForImage(p));
}
+void QQuickPixmap::setPixmap(const QQuickPixmap &other)
+{
+ clear();
+
+ if (other.d) {
+ d = other.d;
+ d->addref();
+ d->declarativePixmaps.insert(this);
+ }
+}
+
int QQuickPixmap::width() const
{
if (d && d->textureFactory)
@@ -1305,6 +1316,14 @@ void QQuickPixmap::clear(QObject *obj)
}
}
+bool QQuickPixmap::isCached(const QUrl &url, const QSize &requestSize)
+{
+ QQuickPixmapKey key = { &url, &requestSize };
+ QQuickPixmapStore *store = pixmapStore();
+
+ return store->m_cache.contains(key);
+}
+
bool QQuickPixmap::connectFinished(QObject *object, const char *method)
{
if (!d || !d->reply) {
diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h
index 6ab1ff6482..76bbf6d341 100644
--- a/src/quick/util/qquickpixmapcache_p.h
+++ b/src/quick/util/qquickpixmapcache_p.h
@@ -101,6 +101,7 @@ public:
const QSize &requestSize() const;
QImage image() const;
void setImage(const QImage &);
+ void setPixmap(const QQuickPixmap &other);
QQuickTextureFactory *textureFactory() const;
@@ -122,6 +123,7 @@ public:
bool connectDownloadProgress(QObject *, int);
static void purgeCache();
+ static bool isCached(const QUrl &url, const QSize &requestSize);
private:
Q_DISABLE_COPY(QQuickPixmap)