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() {
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();
}

View File

@ -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) {

View File

@ -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() {

View File

@ -31,6 +31,7 @@ public:
Document(
not_null<Element*> parent,
not_null<DocumentData*> 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<HistoryItem*> realParent) override;
void parentTextUpdated() override;
void checkHeavyPart() override;
bool hasHeavyPart() const override;
void unloadHeavyPart() override;
protected:

View File

@ -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) {

View File

@ -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() {

View File

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

View File

@ -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) {

View File

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

View File

@ -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() {

View File

@ -27,6 +27,7 @@ public:
GroupedMedia(
not_null<Element*> parent,
const std::vector<not_null<HistoryItem*>> &items);
~GroupedMedia();
void refreshParentId(not_null<HistoryItem*> 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;

View File

@ -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();

View File

@ -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() {

View File

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

View File

@ -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

View File

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

View File

@ -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() {

View File

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

View File

@ -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

View File

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

View File

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