From 2a28bebdc8548c1171a3f255651edafe685da003 Mon Sep 17 00:00:00 2001 From: Daiwei Li Date: Fri, 27 Feb 2015 23:56:12 -0800 Subject: Implement cache property for QQuickAnimatedImage Some longer and larger .gifs can consume a lot of memory if every decoded frame is cached. Just as the backing QMovie provides the ability to not cache frame, so should AnimatedImage. This also allows a workaround for some animated image types that can contain loops that aren't handled correctly (QTBUG-24869) to not leak memory. Change-Id: I0639461d75bb2c758917893e7a6ae5c215fffa9d Task-number: QTBUG-44447 Task-number: QTBUG-24869 Task-number: QTBUG-28844 Reviewed-by: Alan Alpert --- src/quick/items/qquickanimatedimage.cpp | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'src/quick/items/qquickanimatedimage.cpp') diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index a989e81176..49fef12467 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -104,7 +104,13 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine about its state, such as the current frame and total number of frames. The result is an animated image with a simple progress indicator underneath it. - \b Note: Unlike images, animated images are not cached or shared internally. + \b Note: When animated images are cached, every frame of the animation will be cached. + + Set cache to false if you are playing a long or large animation and you + want to conserve memory. + + If the image data comes from a sequential device (e.g. a socket), + AnimatedImage can only loop if cache is set to true. \clearfloat \snippet qml/animatedimage.qml document @@ -126,6 +132,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine QQuickAnimatedImage::QQuickAnimatedImage(QQuickItem *parent) : QQuickImage(*(new QQuickAnimatedImagePrivate), parent) { + QObject::connect(this, &QQuickImageBase::cacheChanged, this, &QQuickAnimatedImage::onCacheChanged); } QQuickAnimatedImage::~QQuickAnimatedImage() @@ -372,7 +379,8 @@ void QQuickAnimatedImage::movieRequestFinished() this, SLOT(playingStatusChanged())); connect(d->_movie, SIGNAL(frameChanged(int)), this, SLOT(movieUpdate())); - d->_movie->setCacheMode(QMovie::CacheAll); + if (d->cache) + d->_movie->setCacheMode(QMovie::CacheAll); d->status = Ready; emit statusChanged(d->status); @@ -406,6 +414,11 @@ void QQuickAnimatedImage::movieUpdate() { Q_D(QQuickAnimatedImage); + if (!d->cache) { + qDeleteAll(d->frameMap); + d->frameMap.clear(); + } + if (d->_movie) { d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this))); emit frameChanged(); @@ -426,6 +439,22 @@ void QQuickAnimatedImage::playingStatusChanged() } } +void QQuickAnimatedImage::onCacheChanged() +{ + Q_D(QQuickAnimatedImage); + if (!cache()) { + qDeleteAll(d->frameMap); + d->frameMap.clear(); + if (d->_movie) { + d->_movie->setCacheMode(QMovie::CacheNone); + } + } else { + if (d->_movie) { + d->_movie->setCacheMode(QMovie::CacheAll); + } + } +} + QSize QQuickAnimatedImage::sourceSize() { Q_D(QQuickAnimatedImage); -- cgit v1.2.3