From 700d3db4cca67d04879f0ca90ef18c8705937106 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 26 May 2020 17:40:36 +0400 Subject: [PATCH] Correctly unload heavy parts on quit. --- .../history/view/history_view_element.cpp | 6 ++++-- .../history/view/media/history_view_dice.h | 4 +++- .../view/media/history_view_document.cpp | 13 ++++++++---- .../view/media/history_view_document.h | 3 ++- .../history/view/media/history_view_game.h | 6 ++---- .../history/view/media/history_view_gif.cpp | 20 +++++++++---------- .../history/view/media/history_view_gif.h | 2 +- .../history/view/media/history_view_invoice.h | 6 ++---- .../history/view/media/history_view_media.h | 3 ++- .../view/media/history_view_media_grouped.cpp | 12 +++++++++-- .../view/media/history_view_media_grouped.h | 3 ++- .../view/media/history_view_media_unwrapped.h | 7 ++++--- .../history/view/media/history_view_photo.cpp | 13 +++++++----- .../history/view/media/history_view_photo.h | 2 +- .../view/media/history_view_sticker.cpp | 20 ++++++++++--------- .../history/view/media/history_view_sticker.h | 2 +- .../media/history_view_theme_document.cpp | 12 +++++------ .../view/media/history_view_theme_document.h | 2 +- .../view/media/history_view_web_page.cpp | 10 ++++++---- .../view/media/history_view_web_page.h | 2 +- .../SourceFiles/storage/file_download.cpp | 2 +- 21 files changed, 87 insertions(+), 63 deletions(-) diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 1d7e5fe29a..d017865c06 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -607,8 +607,8 @@ auto Element::verticalRepaintRange() const -> VerticalRepaintRange { } void Element::checkHeavyPart() { - if (_media) { - _media->checkHeavyPart(); + if (_media && !_media->hasHeavyPart()) { + history()->owner().unregisterHeavyViewPart(this); } } @@ -745,6 +745,8 @@ void Element::clickHandlerPressedChanged( } Element::~Element() { + // Delete media while owner still exists. + _media = nullptr; if (_data->mainView() == this) { _data->clearMainView(); } diff --git a/Telegram/SourceFiles/history/view/media/history_view_dice.h b/Telegram/SourceFiles/history/view/media/history_view_dice.h index a256fb26ce..8022352ca6 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_dice.h +++ b/Telegram/SourceFiles/history/view/media/history_view_dice.h @@ -28,7 +28,9 @@ public: void clearStickerLoopPlayed() override { } - void checkHeavyPart() override { + bool hasHeavyPart() const override { + return (_start ? _start->hasHeavyPart() : false) + || (_end ? _end->hasHeavyPart() : false); } void unloadHeavyPart() override { if (_start) { diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 4ec79f4e7e..6084b7bfe1 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -84,6 +84,13 @@ Document::Document( } } +Document::~Document() { + if (_dataMedia) { + _dataMedia = nullptr; + _parent->checkHeavyPart(); + } +} + float64 Document::dataProgress() const { ensureDataMediaCreated(); return _dataMedia->progress(); @@ -494,10 +501,8 @@ void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti } } -void Document::checkHeavyPart() { - if (!_dataMedia) { - history()->owner().unregisterHeavyViewPart(_parent); - } +bool Document::hasHeavyPart() const { + return (_dataMedia != nullptr); } void Document::unloadHeavyPart() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.h b/Telegram/SourceFiles/history/view/media/history_view_document.h index 23a08118ce..c024d04c87 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.h +++ b/Telegram/SourceFiles/history/view/media/history_view_document.h @@ -31,6 +31,7 @@ public: Document( not_null parent, not_null document); + ~Document(); void draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const override; TextState textState(QPoint point, StateRequest request) const override; @@ -67,7 +68,7 @@ public: void refreshParentId(not_null realParent) override; void parentTextUpdated() override; - void checkHeavyPart() override; + bool hasHeavyPart() const override; void unloadHeavyPart() override; protected: diff --git a/Telegram/SourceFiles/history/view/media/history_view_game.h b/Telegram/SourceFiles/history/view/media/history_view_game.h index be21390f13..892609b48c 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_game.h +++ b/Telegram/SourceFiles/history/view/media/history_view_game.h @@ -80,10 +80,8 @@ public: void parentTextUpdated() override; - void checkHeavyPart() override { - if (_attach) { - _attach->checkHeavyPart(); - } + bool hasHeavyPart() const override { + return _attach ? _attach->hasHeavyPart() : false; } void unloadHeavyPart() override { if (_attach) { diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index 7084be9f92..777dde4129 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -96,12 +96,14 @@ Gif::Gif( } Gif::~Gif() { - if (_streamed) { - _data->owner().streaming().keepAlive(_data); - setStreamed(nullptr); + if (_streamed || _dataMedia) { + if (_streamed) { + _data->owner().streaming().keepAlive(_data); + setStreamed(nullptr); + } + _dataMedia = nullptr; + _parent->checkHeavyPart(); } - _dataMedia = nullptr; - checkHeavyPart(); } QSize Gif::sizeForAspectRatio() const { @@ -728,7 +730,6 @@ TextState Gif::textState(QPoint point, StateRequest request) const { if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) { return result; } - ensureDataMediaCreated(); auto paintx = 0, painty = 0, paintw = width(), painth = height(); auto bubble = _parent->hasBubble(); @@ -827,6 +828,7 @@ TextState Gif::textState(QPoint point, StateRequest request) const { } } if (QRect(usex + paintx, painty, usew, painth).contains(point)) { + ensureDataMediaCreated(); result.link = _data->uploading() ? _cancell : _realParent->isSending() @@ -1299,10 +1301,8 @@ void Gif::parentTextUpdated() { } } -void Gif::checkHeavyPart() { - if (!_dataMedia && !_streamed) { - history()->owner().unregisterHeavyViewPart(_parent); - } +bool Gif::hasHeavyPart() const { + return _streamed || _dataMedia; } void Gif::unloadHeavyPart() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.h b/Telegram/SourceFiles/history/view/media/history_view_gif.h index d71b9941bd..9a489cb7eb 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.h +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.h @@ -104,7 +104,7 @@ public: void parentTextUpdated() override; - void checkHeavyPart() override; + bool hasHeavyPart() const override; void unloadHeavyPart() override; void refreshParentId(not_null realParent) override; diff --git a/Telegram/SourceFiles/history/view/media/history_view_invoice.h b/Telegram/SourceFiles/history/view/media/history_view_invoice.h index 9a0b5d6657..1ccc13e1a4 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_invoice.h +++ b/Telegram/SourceFiles/history/view/media/history_view_invoice.h @@ -70,10 +70,8 @@ public: return _attach.get(); } - void checkHeavyPart() override { - if (_attach) { - _attach->checkHeavyPart(); - } + bool hasHeavyPart() const override { + return _attach ? _attach->hasHeavyPart() : false; } void unloadHeavyPart() override { if (_attach) { diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.h b/Telegram/SourceFiles/history/view/media/history_view_media.h index fd61228eb6..179e3f35e7 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media.h @@ -253,7 +253,8 @@ public: crl::time ms) const { } - virtual void checkHeavyPart() { + virtual bool hasHeavyPart() const { + return false; } virtual void unloadHeavyPart() { } diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp index b4f65ce989..d6c7760ee0 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp @@ -61,6 +61,11 @@ GroupedMedia::GroupedMedia( Ensures(result); } +GroupedMedia::~GroupedMedia() { + // Destroy all parts while the media object is still not destroyed. + base::take(_parts).clear(); +} + QSize GroupedMedia::countOptimalSize() { if (_caption.hasSkipBlock()) { _caption.updateSkipBlock( @@ -422,10 +427,13 @@ int GroupedMedia::checkAnimationCount() { return result; } -void GroupedMedia::checkHeavyPart() { +bool GroupedMedia::hasHeavyPart() const { for (auto &part : _parts) { - part.content->checkHeavyPart(); + if (part.content->hasHeavyPart()) { + return true; + } } + return false; } void GroupedMedia::unloadHeavyPart() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h index 897cfa1c54..769e6ab7ce 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h @@ -27,6 +27,7 @@ public: GroupedMedia( not_null parent, const std::vector> &items); + ~GroupedMedia(); void refreshParentId(not_null realParent) override; @@ -88,7 +89,7 @@ public: void stopAnimation() override; int checkAnimationCount() override; - void checkHeavyPart() override; + bool hasHeavyPart() const override; void unloadHeavyPart() override; void parentTextUpdated() override; diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h index 17fe8fe1e3..ea56b0ec54 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media_unwrapped.h @@ -34,7 +34,8 @@ public: } virtual void clearStickerLoopPlayed() { } - virtual void checkHeavyPart() { + virtual bool hasHeavyPart() const { + return false; } virtual void unloadHeavyPart() { } @@ -84,8 +85,8 @@ public: _content->clearStickerLoopPlayed(); } - void checkHeavyPart() override { - _content->checkHeavyPart(); + bool hasHeavyPart() const override { + return _content->hasHeavyPart(); } void unloadHeavyPart() override { _content->unloadHeavyPart(); diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp index 50f493a269..737105f060 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp @@ -52,7 +52,12 @@ Photo::Photo( create(parent->data()->fullId(), chat); } -Photo::~Photo() = default; +Photo::~Photo() { + if (_dataMedia) { + _dataMedia = nullptr; + _parent->checkHeavyPart(); + } +} void Photo::create(FullMsgId contextId, PeerData *chat) { setLinks( @@ -86,10 +91,8 @@ void Photo::dataMediaCreated() const { history()->owner().registerHeavyViewPart(_parent); } -void Photo::checkHeavyPart() { - if (!_dataMedia) { - history()->owner().unregisterHeavyViewPart(_parent); - } +bool Photo::hasHeavyPart() const { + return (_dataMedia != nullptr); } void Photo::unloadHeavyPart() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.h b/Telegram/SourceFiles/history/view/media/history_view_photo.h index 4e80d9c4f3..679fe2c0b9 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.h +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.h @@ -80,7 +80,7 @@ public: void parentTextUpdated() override; - void checkHeavyPart() override; + bool hasHeavyPart() const override; void unloadHeavyPart() override; protected: diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp index fe99b7ba2b..85bc420f78 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp @@ -65,9 +65,11 @@ Sticker::Sticker( } Sticker::~Sticker() { - unloadLottie(); - _dataMedia = nullptr; - checkHeavyPart(); + if (_lottie || _dataMedia) { + unloadLottie(); + _dataMedia = nullptr; + _parent->checkHeavyPart(); + } } bool Sticker::isEmojiSticker() const { @@ -78,7 +80,9 @@ void Sticker::initSize() { _size = _data->dimensions; if (isEmojiSticker() || _diceIndex >= 0) { _size = GetAnimatedEmojiSize(&_data->session(), _size); - [[maybe_unused]] bool result = readyToDrawLottie(); + if (_diceIndex > 0) { + [[maybe_unused]] bool result = readyToDrawLottie(); + } } else { _size = DownscaledSize( _size, @@ -292,10 +296,8 @@ void Sticker::setupLottie() { }, _lifetime); } -void Sticker::checkHeavyPart() { - if (!_dataMedia && !_lottie) { - _parent->history()->owner().unregisterHeavyViewPart(_parent); - } +bool Sticker::hasHeavyPart() const { + return _lottie || _dataMedia; } void Sticker::unloadHeavyPart() { @@ -312,7 +314,7 @@ void Sticker::unloadLottie() { _lottieOncePlayed = false; } _lottie = nullptr; - checkHeavyPart(); + _parent->checkHeavyPart(); } } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.h b/Telegram/SourceFiles/history/view/media/history_view_sticker.h index 1ae3217e9a..7c874d6ee1 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.h +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.h @@ -50,7 +50,7 @@ public: _lottieOncePlayed = false; } - void checkHeavyPart() override; + bool hasHeavyPart() const override; void unloadHeavyPart() override; void refreshLink() override; diff --git a/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp index aca5d7ddb9..3840b7c7c3 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp @@ -41,8 +41,10 @@ ThemeDocument::ThemeDocument( } ThemeDocument::~ThemeDocument() { - _dataMedia = nullptr; - checkHeavyPart(); + if (_dataMedia) { + _dataMedia = nullptr; + _parent->checkHeavyPart(); + } } void ThemeDocument::fillPatternFieldsFrom(const QString &url) { @@ -310,10 +312,8 @@ QString ThemeDocument::additionalInfoString() const { return result; } -void ThemeDocument::checkHeavyPart() { - if (!_dataMedia) { - _parent->history()->owner().unregisterHeavyViewPart(_parent); - } +bool ThemeDocument::hasHeavyPart() const { + return (_dataMedia != nullptr); } void ThemeDocument::unloadHeavyPart() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_theme_document.h b/Telegram/SourceFiles/history/view/media/history_view_theme_document.h index 3fa517b470..3253bce9b2 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_theme_document.h +++ b/Telegram/SourceFiles/history/view/media/history_view_theme_document.h @@ -46,7 +46,7 @@ public: bool isReadyForOpen() const override; QString additionalInfoString() const override; - void checkHeavyPart() override; + bool hasHeavyPart() const override; void unloadHeavyPart() override; protected: diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp index 04c33aee52..7f12c2c00e 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.cpp @@ -425,10 +425,8 @@ void WebPage::ensurePhotoMediaCreated() const { history()->owner().registerHeavyViewPart(_parent); } -void WebPage::checkHeavyPart() { - if (_attach) { - _attach->checkHeavyPart(); - } +bool WebPage::hasHeavyPart() const { + return _photoMedia || (_attach ? _attach->hasHeavyPart() : false); } void WebPage::unloadHeavyPart() { @@ -821,6 +819,10 @@ QString WebPage::displayedSiteName() const { WebPage::~WebPage() { history()->owner().unregisterWebPageView(_data, _parent); + if (_photoMedia) { + _photoMedia = nullptr; + _parent->checkHeavyPart(); + } } } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/media/history_view_web_page.h b/Telegram/SourceFiles/history/view/media/history_view_web_page.h index c3d9ab429a..c04cf192cc 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_web_page.h +++ b/Telegram/SourceFiles/history/view/media/history_view_web_page.h @@ -86,7 +86,7 @@ public: return _attach.get(); } - void checkHeavyPart() override; + bool hasHeavyPart() const override; void unloadHeavyPart() override; ~WebPage(); diff --git a/Telegram/SourceFiles/storage/file_download.cpp b/Telegram/SourceFiles/storage/file_download.cpp index 4ccce49d69..bdd118328a 100644 --- a/Telegram/SourceFiles/storage/file_download.cpp +++ b/Telegram/SourceFiles/storage/file_download.cpp @@ -490,7 +490,7 @@ std::unique_ptr CreateFileLoader( size, locationType, toCache, - fromCloud, + LoadFromCloudOrLocal, autoLoading, cacheTag); });