stopping gifs on history close, only one gif playing

This commit is contained in:
John Preston 2015-12-16 16:35:15 +03:00
parent 7f6f92ac85
commit 29a7c66e45
11 changed files with 48 additions and 46 deletions

View File

@ -2428,6 +2428,7 @@ namespace App {
}
void regGifItem(ClipReader *reader, HistoryItem *item) {
stopGifItems();
::gifItems.insert(reader, item);
}
@ -2439,6 +2440,16 @@ namespace App {
return ::gifItems;
}
void stopGifItems() {
while (!::gifItems.isEmpty()) {
if (HistoryItem *playing = ::gifItems.begin().value()) {
if (playing->getMedia() && playing->getMedia()->type() == MediaTypeGif) {
static_cast<HistoryGif*>(playing->getMedia())->stop(playing);
}
}
}
}
QString phoneFromSharedContact(int32 userId) {
SharedContactItems::const_iterator i = ::sharedContactItems.constFind(userId);
if (i != ::sharedContactItems.cend()) {

View File

@ -254,6 +254,7 @@ namespace App {
void regGifItem(ClipReader *reader, HistoryItem *item);
void unregGifItem(ClipReader *reader);
const GifItems &gifItems();
void stopGifItems();
void regMuted(PeerData *peer, int32 changeIn);
void unregMuted(PeerData *peer);

View File

@ -84,6 +84,7 @@ enum {
AnimationTimerDelta = 7,
ClipThreadsCount = 8,
AverageGifSize = 320 * 240,
SaveRecentEmojisTimeout = 3000, // 3 secs
SaveWindowPositionTimeout = 1000, // 1 sec

View File

@ -124,6 +124,8 @@ void AnimationManager::clipReinit(ClipReader *reader) {
if (it != items.cend()) {
it.value()->initDimensions();
if (App::main()) emit App::main()->itemResized(it.value(), true);
Notify::historyItemLayoutChanged(it.value());
}
}
@ -359,8 +361,9 @@ void ClipReader::start(int32 framew, int32 frameh, int32 outerw, int32 outerh, b
_clipManagers.at(_threadIndex)->start(this);
}
QPixmap ClipReader::current(int32 framew, int32 frameh, int32 outerw, int32 outerh) {
QPixmap ClipReader::current(int32 framew, int32 frameh, int32 outerw, int32 outerh, uint64 ms) {
_currentDisplayed.storeRelease(1);
_lastDisplayMs = ms;
int32 factor(cIntRetinaFactor());
QPixmap result(_current);
@ -491,7 +494,8 @@ public:
}
uint64 nextFrameDelay() {
return qMax(_reader->nextImageDelay(), 5);
int delay = _reader->nextImageDelay();
return qMax(delay, 5);
}
void swapBuffers(uint64 ms = 0) {
@ -636,6 +640,7 @@ ClipReadManager::ClipReadManager(QThread *thread) : _processingInThread(0) {
void ClipReadManager::append(ClipReader *reader, const FileLocation &location, const QByteArray &data) {
reader->_private = new ClipReaderPrivate(reader, location, data);
_loadLevel.fetchAndAddRelease(AverageGifSize);
update(reader);
}
@ -669,6 +674,9 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess
return false;
}
if (result == ClipProcessStarted) {
_loadLevel.fetchAndAddRelease(reader->_currentOriginal.width() * reader->_currentOriginal.height() - AverageGifSize);
}
if (result == ClipProcessReinit || result == ClipProcessRedraw || result == ClipProcessStarted) {
it.key()->_current = reader->_current;
it.key()->_currentOriginal = reader->_currentOriginal;
@ -684,6 +692,7 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess
ClipReadManager::ResultHandleState ClipReadManager::handleResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms) {
if (!handleProcessResult(reader, result)) {
_loadLevel.fetchAndAddRelease(-1 * (reader->_currentOriginal.isNull() ? AverageGifSize : reader->_currentOriginal.width() * reader->_currentOriginal.height()));
delete reader;
return ResultHandleRemove;
}

View File

@ -500,7 +500,7 @@ public:
ClipReader(const FileLocation &location, const QByteArray &data);
void start(int32 framew, int32 frameh, int32 outerw, int32 outerh, bool rounded);
QPixmap current(int32 framew, int32 frameh, int32 outerw, int32 outerh);
QPixmap current(int32 framew, int32 frameh, int32 outerw, int32 outerh, uint64 ms);
bool currentDisplayed() const {
return _currentDisplayed.loadAcquire() > 0;
}
@ -530,6 +530,7 @@ private:
QPixmap _current;
QImage _currentOriginal, _cacheForResize;
QAtomicInt _currentDisplayed;
uint64 _lastDisplayMs;
int32 _threadIndex;
friend class ClipReadManager;

View File

@ -152,30 +152,6 @@ void historyInit() {
_initTextOptions();
}
void startGif(HistoryItem *row, const FileLocation &file) {
if (row == animated.msg) {
stopGif();
} else {
animated.start(row, file);
}
}
void itemReplacedGif(HistoryItem *oldItem, HistoryItem *newItem) {
if (oldItem == animated.msg) {
animated.msg = newItem;
}
}
void itemRemovedGif(HistoryItem *item) {
if (item == animated.msg) {
animated.stop(true);
}
}
void stopGif() {
animated.stop();
}
void DialogRow::paint(Painter &p, int32 w, bool act, bool sel, bool onlyBackground) const {
QRect fullRect(0, 0, w, st::dlgHeight);
p.fillRect(fullRect, (act ? st::dlgActiveBG : (sel ? st::dlgHoverBG : st::dlgBG))->b);
@ -4571,7 +4547,7 @@ HistoryGif::HistoryGif(DocumentData *document) : HistoryFileMedia()
, _thumbw(1)
, _thumbh(1)
, _gif(0) {
setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data));
setLinks(new DocumentOpenLink(_data), new DocumentOpenLink(_data), new DocumentCancelLink(_data));
setStatusSize(FileStatusSizeReady);
@ -4651,7 +4627,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
QRect rthumb(rtlrect(skipx, skipy, width, height, w));
if (animating) {
p.drawPixmap(rthumb.topLeft(), _gif->current(_thumbw, _thumbh, width, height));
p.drawPixmap(rthumb.topLeft(), _gif->current(_thumbw, _thumbh, width, height, ms));
} else {
p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(_thumbw, _thumbh, width, height));
}
@ -4876,9 +4852,9 @@ void HistoryGif::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x,
}
if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height) {
if (_gif && _gif->started()) {
lnk = _openl;
lnk = _savel;
} else {
lnk = _data->already().isEmpty() ? (_data->loader ? _cancell : _savel) : _openl;
lnk = _data->already().isEmpty() ? (_data->loader ? _cancell : _savel) : _savel;
}
int32 fullRight = skipx + width, fullBottom = skipy + height;
@ -4900,15 +4876,23 @@ ImagePtr HistoryGif::replyPreview() {
void HistoryGif::play(HistoryItem *parent) {
if (_gif) {
App::unregGifItem(_gif);
delete _gif;
_gif = 0;
stop(parent);
} else {
_gif = new ClipReader(_data->location(), _data->data);
App::regGifItem(_gif, parent);
}
}
void HistoryGif::stop(HistoryItem *parent) {
App::unregGifItem(_gif);
delete _gif;
_gif = 0;
parent->initDimensions();
if (App::main()) emit App::main()->itemResized(parent);
Notify::historyItemLayoutChanged(parent);
}
HistoryGif::~HistoryGif() {
if (_gif) {
App::unregGifItem(_gif);
@ -6666,7 +6650,7 @@ void HistoryMessage::initMediaFromText(QString &currentText) {
void HistoryMessage::initMediaFromDocument(DocumentData *doc) {
if (doc->sticker()) {
_media = new HistorySticker(doc);
} else if (doc->type == AnimatedDocument) {
} else if (doc->type == AnimatedDocument || doc->mime.toLower() == qstr("image/gif")) {
_media = new HistoryGif(doc);
} else {
_media = new HistoryDocument(doc);

View File

@ -24,11 +24,6 @@ void historyInit();
class HistoryItem;
void startGif(HistoryItem *row, const FileLocation &file);
void itemRemovedGif(HistoryItem *item);
void itemReplacedGif(HistoryItem *oldItem, HistoryItem *newItem);
void stopGif();
static const uint32 FullItemSel = 0xFFFFFFFF;
typedef QMap<int32, HistoryItem*> SelectedItemSet;
@ -1606,6 +1601,8 @@ public:
}
void play(HistoryItem *parent);
void stop(HistoryItem *parent);
~HistoryGif();
protected:

View File

@ -3225,7 +3225,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
}
}
stopGif();
App::stopGifItems();
clearReplyReturns();
clearAllLoadRequests();

View File

@ -1454,7 +1454,6 @@ void MainWidget::itemRemoved(HistoryItem *item) {
if (overview && (overview->peer() == item->history()->peer || (overview->peer() && overview->peer() == item->history()->peer->migrateTo()))) {
overview->itemRemoved(item);
}
itemRemovedGif(item);
if (!_toForward.isEmpty()) {
SelectedItemSet::iterator i = _toForward.find(item->id);
if (i != _toForward.cend() && i.value() == item) {
@ -1476,7 +1475,6 @@ void MainWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
if (history.peer() == newItem->history()->peer || (history.peer() && history.peer() == newItem->history()->peer->migrateTo())) {
history.itemReplaced(oldItem, newItem);
}
itemReplacedGif(oldItem, newItem);
if (!_toForward.isEmpty()) {
SelectedItemSet::iterator i = _toForward.find(oldItem->id);
if (i != _toForward.cend() && i.value() == oldItem) {

View File

@ -2906,7 +2906,7 @@ int32 OverviewWidget::countBestScroll() const {
}
void OverviewWidget::fastShow(bool back, int32 lastScrollTop) {
stopGif();
App::stopGifItems();
resizeEvent(0);
_scrollSetAfterShow = (lastScrollTop < 0 ? countBestScroll() : lastScrollTop);
show();
@ -2919,7 +2919,7 @@ void OverviewWidget::fastShow(bool back, int32 lastScrollTop) {
void OverviewWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back, int32 lastScrollTop) {
if (App::app()) App::app()->mtpPause();
stopGif();
App::stopGifItems();
(back ? _cacheOver : _cacheUnder) = bgAnimCache;
(back ? _cacheTopBarOver : _cacheTopBarUnder) = bgAnimTopBarCache;

View File

@ -1832,7 +1832,7 @@ int32 ProfileWidget::lastScrollTop() const {
void ProfileWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back, int32 lastScrollTop) {
if (App::app()) App::app()->mtpPause();
stopGif();
App::stopGifItems();
(back ? _cacheOver : _cacheUnder) = bgAnimCache;
(back ? _cacheTopBarOver : _cacheTopBarUnder) = bgAnimTopBarCache;