Correctly unload heavy parts on quit.

This commit is contained in:
John Preston 2020-05-26 17:40:36 +04:00
parent 64cf0e1a44
commit 700d3db4cc
21 changed files with 87 additions and 63 deletions

View File

@ -607,8 +607,8 @@ auto Element::verticalRepaintRange() const -> VerticalRepaintRange {
} }
void Element::checkHeavyPart() { void Element::checkHeavyPart() {
if (_media) { if (_media && !_media->hasHeavyPart()) {
_media->checkHeavyPart(); history()->owner().unregisterHeavyViewPart(this);
} }
} }
@ -745,6 +745,8 @@ void Element::clickHandlerPressedChanged(
} }
Element::~Element() { Element::~Element() {
// Delete media while owner still exists.
_media = nullptr;
if (_data->mainView() == this) { if (_data->mainView() == this) {
_data->clearMainView(); _data->clearMainView();
} }

View File

@ -28,7 +28,9 @@ public:
void clearStickerLoopPlayed() override { void clearStickerLoopPlayed() override {
} }
void checkHeavyPart() override { bool hasHeavyPart() const override {
return (_start ? _start->hasHeavyPart() : false)
|| (_end ? _end->hasHeavyPart() : false);
} }
void unloadHeavyPart() override { void unloadHeavyPart() override {
if (_start) { if (_start) {

View File

@ -84,6 +84,13 @@ Document::Document(
} }
} }
Document::~Document() {
if (_dataMedia) {
_dataMedia = nullptr;
_parent->checkHeavyPart();
}
}
float64 Document::dataProgress() const { float64 Document::dataProgress() const {
ensureDataMediaCreated(); ensureDataMediaCreated();
return _dataMedia->progress(); return _dataMedia->progress();
@ -494,10 +501,8 @@ void Document::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti
} }
} }
void Document::checkHeavyPart() { bool Document::hasHeavyPart() const {
if (!_dataMedia) { return (_dataMedia != nullptr);
history()->owner().unregisterHeavyViewPart(_parent);
}
} }
void Document::unloadHeavyPart() { void Document::unloadHeavyPart() {

View File

@ -31,6 +31,7 @@ public:
Document( Document(
not_null<Element*> parent, not_null<Element*> parent,
not_null<DocumentData*> document); not_null<DocumentData*> document);
~Document();
void draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const override; void draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const override;
TextState textState(QPoint point, StateRequest request) const override; TextState textState(QPoint point, StateRequest request) const override;
@ -67,7 +68,7 @@ public:
void refreshParentId(not_null<HistoryItem*> realParent) override; void refreshParentId(not_null<HistoryItem*> realParent) override;
void parentTextUpdated() override; void parentTextUpdated() override;
void checkHeavyPart() override; bool hasHeavyPart() const override;
void unloadHeavyPart() override; void unloadHeavyPart() override;
protected: protected:

View File

@ -80,10 +80,8 @@ public:
void parentTextUpdated() override; void parentTextUpdated() override;
void checkHeavyPart() override { bool hasHeavyPart() const override {
if (_attach) { return _attach ? _attach->hasHeavyPart() : false;
_attach->checkHeavyPart();
}
} }
void unloadHeavyPart() override { void unloadHeavyPart() override {
if (_attach) { if (_attach) {

View File

@ -96,12 +96,14 @@ Gif::Gif(
} }
Gif::~Gif() { Gif::~Gif() {
if (_streamed || _dataMedia) {
if (_streamed) { if (_streamed) {
_data->owner().streaming().keepAlive(_data); _data->owner().streaming().keepAlive(_data);
setStreamed(nullptr); setStreamed(nullptr);
} }
_dataMedia = nullptr; _dataMedia = nullptr;
checkHeavyPart(); _parent->checkHeavyPart();
}
} }
QSize Gif::sizeForAspectRatio() const { 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) { if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
return result; return result;
} }
ensureDataMediaCreated();
auto paintx = 0, painty = 0, paintw = width(), painth = height(); auto paintx = 0, painty = 0, paintw = width(), painth = height();
auto bubble = _parent->hasBubble(); 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)) { if (QRect(usex + paintx, painty, usew, painth).contains(point)) {
ensureDataMediaCreated();
result.link = _data->uploading() result.link = _data->uploading()
? _cancell ? _cancell
: _realParent->isSending() : _realParent->isSending()
@ -1299,10 +1301,8 @@ void Gif::parentTextUpdated() {
} }
} }
void Gif::checkHeavyPart() { bool Gif::hasHeavyPart() const {
if (!_dataMedia && !_streamed) { return _streamed || _dataMedia;
history()->owner().unregisterHeavyViewPart(_parent);
}
} }
void Gif::unloadHeavyPart() { void Gif::unloadHeavyPart() {

View File

@ -104,7 +104,7 @@ public:
void parentTextUpdated() override; void parentTextUpdated() override;
void checkHeavyPart() override; bool hasHeavyPart() const override;
void unloadHeavyPart() override; void unloadHeavyPart() override;
void refreshParentId(not_null<HistoryItem*> realParent) override; void refreshParentId(not_null<HistoryItem*> realParent) override;

View File

@ -70,10 +70,8 @@ public:
return _attach.get(); return _attach.get();
} }
void checkHeavyPart() override { bool hasHeavyPart() const override {
if (_attach) { return _attach ? _attach->hasHeavyPart() : false;
_attach->checkHeavyPart();
}
} }
void unloadHeavyPart() override { void unloadHeavyPart() override {
if (_attach) { if (_attach) {

View File

@ -253,7 +253,8 @@ public:
crl::time ms) const { crl::time ms) const {
} }
virtual void checkHeavyPart() { virtual bool hasHeavyPart() const {
return false;
} }
virtual void unloadHeavyPart() { virtual void unloadHeavyPart() {
} }

View File

@ -61,6 +61,11 @@ GroupedMedia::GroupedMedia(
Ensures(result); Ensures(result);
} }
GroupedMedia::~GroupedMedia() {
// Destroy all parts while the media object is still not destroyed.
base::take(_parts).clear();
}
QSize GroupedMedia::countOptimalSize() { QSize GroupedMedia::countOptimalSize() {
if (_caption.hasSkipBlock()) { if (_caption.hasSkipBlock()) {
_caption.updateSkipBlock( _caption.updateSkipBlock(
@ -422,11 +427,14 @@ int GroupedMedia::checkAnimationCount() {
return result; return result;
} }
void GroupedMedia::checkHeavyPart() { bool GroupedMedia::hasHeavyPart() const {
for (auto &part : _parts) { for (auto &part : _parts) {
part.content->checkHeavyPart(); if (part.content->hasHeavyPart()) {
return true;
} }
} }
return false;
}
void GroupedMedia::unloadHeavyPart() { void GroupedMedia::unloadHeavyPart() {
for (auto &part : _parts) { for (auto &part : _parts) {

View File

@ -27,6 +27,7 @@ public:
GroupedMedia( GroupedMedia(
not_null<Element*> parent, not_null<Element*> parent,
const std::vector<not_null<HistoryItem*>> &items); const std::vector<not_null<HistoryItem*>> &items);
~GroupedMedia();
void refreshParentId(not_null<HistoryItem*> realParent) override; void refreshParentId(not_null<HistoryItem*> realParent) override;
@ -88,7 +89,7 @@ public:
void stopAnimation() override; void stopAnimation() override;
int checkAnimationCount() override; int checkAnimationCount() override;
void checkHeavyPart() override; bool hasHeavyPart() const override;
void unloadHeavyPart() override; void unloadHeavyPart() override;
void parentTextUpdated() override; void parentTextUpdated() override;

View File

@ -34,7 +34,8 @@ public:
} }
virtual void clearStickerLoopPlayed() { virtual void clearStickerLoopPlayed() {
} }
virtual void checkHeavyPart() { virtual bool hasHeavyPart() const {
return false;
} }
virtual void unloadHeavyPart() { virtual void unloadHeavyPart() {
} }
@ -84,8 +85,8 @@ public:
_content->clearStickerLoopPlayed(); _content->clearStickerLoopPlayed();
} }
void checkHeavyPart() override { bool hasHeavyPart() const override {
_content->checkHeavyPart(); return _content->hasHeavyPart();
} }
void unloadHeavyPart() override { void unloadHeavyPart() override {
_content->unloadHeavyPart(); _content->unloadHeavyPart();

View File

@ -52,7 +52,12 @@ Photo::Photo(
create(parent->data()->fullId(), chat); create(parent->data()->fullId(), chat);
} }
Photo::~Photo() = default; Photo::~Photo() {
if (_dataMedia) {
_dataMedia = nullptr;
_parent->checkHeavyPart();
}
}
void Photo::create(FullMsgId contextId, PeerData *chat) { void Photo::create(FullMsgId contextId, PeerData *chat) {
setLinks( setLinks(
@ -86,10 +91,8 @@ void Photo::dataMediaCreated() const {
history()->owner().registerHeavyViewPart(_parent); history()->owner().registerHeavyViewPart(_parent);
} }
void Photo::checkHeavyPart() { bool Photo::hasHeavyPart() const {
if (!_dataMedia) { return (_dataMedia != nullptr);
history()->owner().unregisterHeavyViewPart(_parent);
}
} }
void Photo::unloadHeavyPart() { void Photo::unloadHeavyPart() {

View File

@ -80,7 +80,7 @@ public:
void parentTextUpdated() override; void parentTextUpdated() override;
void checkHeavyPart() override; bool hasHeavyPart() const override;
void unloadHeavyPart() override; void unloadHeavyPart() override;
protected: protected:

View File

@ -65,9 +65,11 @@ Sticker::Sticker(
} }
Sticker::~Sticker() { Sticker::~Sticker() {
if (_lottie || _dataMedia) {
unloadLottie(); unloadLottie();
_dataMedia = nullptr; _dataMedia = nullptr;
checkHeavyPart(); _parent->checkHeavyPart();
}
} }
bool Sticker::isEmojiSticker() const { bool Sticker::isEmojiSticker() const {
@ -78,7 +80,9 @@ void Sticker::initSize() {
_size = _data->dimensions; _size = _data->dimensions;
if (isEmojiSticker() || _diceIndex >= 0) { if (isEmojiSticker() || _diceIndex >= 0) {
_size = GetAnimatedEmojiSize(&_data->session(), _size); _size = GetAnimatedEmojiSize(&_data->session(), _size);
if (_diceIndex > 0) {
[[maybe_unused]] bool result = readyToDrawLottie(); [[maybe_unused]] bool result = readyToDrawLottie();
}
} else { } else {
_size = DownscaledSize( _size = DownscaledSize(
_size, _size,
@ -292,10 +296,8 @@ void Sticker::setupLottie() {
}, _lifetime); }, _lifetime);
} }
void Sticker::checkHeavyPart() { bool Sticker::hasHeavyPart() const {
if (!_dataMedia && !_lottie) { return _lottie || _dataMedia;
_parent->history()->owner().unregisterHeavyViewPart(_parent);
}
} }
void Sticker::unloadHeavyPart() { void Sticker::unloadHeavyPart() {
@ -312,7 +314,7 @@ void Sticker::unloadLottie() {
_lottieOncePlayed = false; _lottieOncePlayed = false;
} }
_lottie = nullptr; _lottie = nullptr;
checkHeavyPart(); _parent->checkHeavyPart();
} }
} // namespace HistoryView } // namespace HistoryView

View File

@ -50,7 +50,7 @@ public:
_lottieOncePlayed = false; _lottieOncePlayed = false;
} }
void checkHeavyPart() override; bool hasHeavyPart() const override;
void unloadHeavyPart() override; void unloadHeavyPart() override;
void refreshLink() override; void refreshLink() override;

View File

@ -41,8 +41,10 @@ ThemeDocument::ThemeDocument(
} }
ThemeDocument::~ThemeDocument() { ThemeDocument::~ThemeDocument() {
if (_dataMedia) {
_dataMedia = nullptr; _dataMedia = nullptr;
checkHeavyPart(); _parent->checkHeavyPart();
}
} }
void ThemeDocument::fillPatternFieldsFrom(const QString &url) { void ThemeDocument::fillPatternFieldsFrom(const QString &url) {
@ -310,10 +312,8 @@ QString ThemeDocument::additionalInfoString() const {
return result; return result;
} }
void ThemeDocument::checkHeavyPart() { bool ThemeDocument::hasHeavyPart() const {
if (!_dataMedia) { return (_dataMedia != nullptr);
_parent->history()->owner().unregisterHeavyViewPart(_parent);
}
} }
void ThemeDocument::unloadHeavyPart() { void ThemeDocument::unloadHeavyPart() {

View File

@ -46,7 +46,7 @@ public:
bool isReadyForOpen() const override; bool isReadyForOpen() const override;
QString additionalInfoString() const override; QString additionalInfoString() const override;
void checkHeavyPart() override; bool hasHeavyPart() const override;
void unloadHeavyPart() override; void unloadHeavyPart() override;
protected: protected:

View File

@ -425,10 +425,8 @@ void WebPage::ensurePhotoMediaCreated() const {
history()->owner().registerHeavyViewPart(_parent); history()->owner().registerHeavyViewPart(_parent);
} }
void WebPage::checkHeavyPart() { bool WebPage::hasHeavyPart() const {
if (_attach) { return _photoMedia || (_attach ? _attach->hasHeavyPart() : false);
_attach->checkHeavyPart();
}
} }
void WebPage::unloadHeavyPart() { void WebPage::unloadHeavyPart() {
@ -821,6 +819,10 @@ QString WebPage::displayedSiteName() const {
WebPage::~WebPage() { WebPage::~WebPage() {
history()->owner().unregisterWebPageView(_data, _parent); history()->owner().unregisterWebPageView(_data, _parent);
if (_photoMedia) {
_photoMedia = nullptr;
_parent->checkHeavyPart();
}
} }
} // namespace HistoryView } // namespace HistoryView

View File

@ -86,7 +86,7 @@ public:
return _attach.get(); return _attach.get();
} }
void checkHeavyPart() override; bool hasHeavyPart() const override;
void unloadHeavyPart() override; void unloadHeavyPart() override;
~WebPage(); ~WebPage();

View File

@ -490,7 +490,7 @@ std::unique_ptr<FileLoader> CreateFileLoader(
size, size,
locationType, locationType,
toCache, toCache,
fromCloud, LoadFromCloudOrLocal,
autoLoading, autoLoading,
cacheTag); cacheTag);
}); });