mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Optimize sets stickers / gifs panel repainting.
This commit is contained in:
parent
1a3a0fb124
commit
51fef843f0
3 changed files with 93 additions and 14 deletions
|
@ -46,7 +46,7 @@ namespace {
|
|||
constexpr auto kSearchRequestDelay = 400;
|
||||
constexpr auto kInlineItemsMaxPerRow = 5;
|
||||
constexpr auto kSearchBotUsername = "gif"_cs;
|
||||
constexpr auto kMinRepaintDelay = crl::time(16);
|
||||
constexpr auto kMinRepaintDelay = crl::time(33);
|
||||
constexpr auto kMinAfterScrollDelay = crl::time(33);
|
||||
|
||||
} // namespace
|
||||
|
@ -175,9 +175,7 @@ GifsListWidget::GifsListWidget(
|
|||
, _mosaic(st::emojiPanWidth - st::inlineResultsLeft)
|
||||
, _previewTimer([=] { showPreview(); }) {
|
||||
setMouseTracking(true);
|
||||
|
||||
// Otherwise our optimization on repainting is too aggressive.
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
||||
_inlineRequestTimer.setSingleShot(true);
|
||||
connect(
|
||||
|
@ -193,14 +191,14 @@ GifsListWidget::GifsListWidget(
|
|||
|
||||
controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
updateInlineItems();
|
||||
}, lifetime());
|
||||
|
||||
controller->gifPauseLevelChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (!controller->isGifPausedAtLeastFor(
|
||||
Window::GifPauseReason::SavedGifs)) {
|
||||
update();
|
||||
updateInlineItems();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
|
@ -240,10 +238,11 @@ object_ptr<TabbedSelector::InnerFooter> GifsListWidget::createFooter() {
|
|||
void GifsListWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
auto top = getVisibleTop();
|
||||
const auto top = getVisibleTop();
|
||||
Inner::visibleTopBottomUpdated(visibleTop, visibleBottom);
|
||||
if (top != getVisibleTop()) {
|
||||
_lastScrolledAt = crl::now();
|
||||
update();
|
||||
}
|
||||
checkLoadMore();
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ constexpr auto kSearchRequestDelay = 400;
|
|||
constexpr auto kRecentDisplayLimit = 20;
|
||||
constexpr auto kPreloadOfficialPages = 4;
|
||||
constexpr auto kOfficialLoadLimit = 40;
|
||||
constexpr auto kMinRepaintDelay = crl::time(33);
|
||||
constexpr auto kMinAfterScrollDelay = crl::time(33);
|
||||
|
||||
using Data::StickersSet;
|
||||
using Data::StickersPack;
|
||||
|
@ -968,6 +970,8 @@ StickersListWidget::StickersListWidget(
|
|||
, _api(&controller->session().mtp())
|
||||
, _section(Section::Stickers)
|
||||
, _isMasks(masks)
|
||||
, _updateItemsTimer([=] { updateItems(); })
|
||||
, _updateSetsTimer([=] { updateSets(); })
|
||||
, _pathGradient(std::make_unique<Ui::PathShiftGradient>(
|
||||
st::windowBgRipple,
|
||||
st::windowBgOver,
|
||||
|
@ -991,7 +995,7 @@ StickersListWidget::StickersListWidget(
|
|||
session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (isVisible()) {
|
||||
repaintItems();
|
||||
updateItems();
|
||||
readVisibleFeatured(getVisibleTop(), getVisibleBottom());
|
||||
}
|
||||
}, lifetime());
|
||||
|
@ -1065,7 +1069,13 @@ object_ptr<TabbedSelector::InnerFooter> StickersListWidget::createFooter() {
|
|||
void StickersListWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
const auto top = getVisibleTop();
|
||||
Inner::visibleTopBottomUpdated(visibleTop, visibleBottom);
|
||||
if (top != getVisibleTop()) {
|
||||
_lastScrolledAt = crl::now();
|
||||
_repaintSetsIds.clear();
|
||||
update();
|
||||
}
|
||||
if (_section == Section::Featured) {
|
||||
checkVisibleFeatured(visibleTop, visibleBottom);
|
||||
} else {
|
||||
|
@ -1925,7 +1935,7 @@ void StickersListWidget::ensureLottiePlayer(Set &set) {
|
|||
if (sets[info.section].lottiePlayer.get() != raw) {
|
||||
return true;
|
||||
}
|
||||
repaintItems(info);
|
||||
updateSet(info);
|
||||
return false;
|
||||
});
|
||||
}, set.lottieLifetime);
|
||||
|
@ -2000,7 +2010,7 @@ void StickersListWidget::clipCallback(
|
|||
case Notification::Repaint: break;
|
||||
}
|
||||
|
||||
repaintItems(info);
|
||||
updateSet(info);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
@ -2016,16 +2026,73 @@ bool StickersListWidget::itemVisible(
|
|||
return (visibleTop < bottom) && (visibleBottom > top);
|
||||
}
|
||||
|
||||
void StickersListWidget::repaintItems(const SectionInfo &info) {
|
||||
void StickersListWidget::updateSets() {
|
||||
if (_repaintSetsIds.empty()) {
|
||||
return;
|
||||
}
|
||||
auto repaint = base::take(_repaintSetsIds);
|
||||
auto &sets = shownSets();
|
||||
enumerateSections([&](const SectionInfo &info) {
|
||||
if (repaint.contains(sets[info.section].id)) {
|
||||
updateSet(info);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void StickersListWidget::updateSet(const SectionInfo &info) {
|
||||
auto &set = shownSets()[info.section];
|
||||
|
||||
const auto now = crl::now();
|
||||
const auto delay = std::max(
|
||||
_lastScrolledAt + kMinAfterScrollDelay - now,
|
||||
set.lastUpdateTime + kMinRepaintDelay - now);
|
||||
if (delay <= 0) {
|
||||
repaintItems(info, now);
|
||||
} else {
|
||||
_repaintSetsIds.emplace(set.id);
|
||||
if (!_updateSetsTimer.isActive()
|
||||
|| _updateSetsTimer.remainingTime() > kMinRepaintDelay) {
|
||||
_updateSetsTimer.callOnce(std::max(delay, kMinRepaintDelay));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StickersListWidget::repaintItems(
|
||||
const SectionInfo &info,
|
||||
crl::time now) {
|
||||
update(
|
||||
0,
|
||||
info.rowsTop,
|
||||
width(),
|
||||
info.rowsBottom - info.rowsTop);
|
||||
auto &set = shownSets()[info.section];
|
||||
set.lastUpdateTime = now;
|
||||
}
|
||||
|
||||
void StickersListWidget::repaintItems() {
|
||||
void StickersListWidget::updateItems() {
|
||||
const auto now = crl::now();
|
||||
const auto delay = std::max(
|
||||
_lastScrolledAt + kMinAfterScrollDelay - now,
|
||||
_lastFullUpdatedAt + kMinRepaintDelay - now);
|
||||
if (delay <= 0) {
|
||||
repaintItems(now);
|
||||
} else if (!_updateItemsTimer.isActive()
|
||||
|| _updateItemsTimer.remainingTime() > kMinRepaintDelay) {
|
||||
_updateItemsTimer.callOnce(std::max(delay, kMinRepaintDelay));
|
||||
}
|
||||
}
|
||||
|
||||
void StickersListWidget::repaintItems(crl::time now) {
|
||||
update();
|
||||
_repaintSetsIds.clear();
|
||||
if (!now) {
|
||||
now = crl::now();
|
||||
}
|
||||
_lastFullUpdatedAt = now;
|
||||
for (auto &set : shownSets()) {
|
||||
set.lastUpdateTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
QSize StickersListWidget::boundingBoxSize() const {
|
||||
|
|
|
@ -205,6 +205,7 @@ private:
|
|||
QString shortName;
|
||||
std::vector<Sticker> stickers;
|
||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||
crl::time lastUpdateTime = 0;
|
||||
|
||||
std::unique_ptr<Lottie::MultiPlayer> lottiePlayer;
|
||||
rpl::lifetime lottieLifetime;
|
||||
|
@ -305,8 +306,13 @@ private:
|
|||
void takeHeavyData(Sticker &to, Sticker &from);
|
||||
void clearHeavyIn(Set &set, bool clearSavedFrames = true);
|
||||
void clearHeavyData();
|
||||
void repaintItems();
|
||||
void repaintItems(const SectionInfo &info);
|
||||
void updateItems();
|
||||
void updateSets();
|
||||
void repaintItems(crl::time now = 0);
|
||||
void updateSet(const SectionInfo &info);
|
||||
void repaintItems(
|
||||
const SectionInfo &info,
|
||||
crl::time now);
|
||||
|
||||
int stickersRight() const;
|
||||
bool featuredHasAddButton(int index) const;
|
||||
|
@ -364,12 +370,19 @@ private:
|
|||
base::flat_set<not_null<DocumentData*>> _favedStickersMap;
|
||||
std::weak_ptr<Lottie::FrameRenderer> _lottieRenderer;
|
||||
|
||||
crl::time _lastScrolledAt = 0;
|
||||
crl::time _lastFullUpdatedAt = 0;
|
||||
|
||||
mtpRequestId _officialRequestId = 0;
|
||||
int _officialOffset = 0;
|
||||
|
||||
Section _section = Section::Stickers;
|
||||
const bool _isMasks;
|
||||
|
||||
base::Timer _updateItemsTimer;
|
||||
base::Timer _updateSetsTimer;
|
||||
base::flat_set<uint64> _repaintSetsIds;
|
||||
|
||||
bool _displayingSet = false;
|
||||
uint64 _removingSetId = 0;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue