iconGrid: Cache max size of children

We call this._getChildrenMaxSize() from the allocate() vfunc of
IconGridLayout. Since the function is quite expensive, it slows the
layout process down a lot, so instead of re-calculating it on every
relayout, cache the max size of children.

This makes the average time spent in vfunc_allocate() of the iconGrid go
down from 2.3 ms to 1.6 ms.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1713>
This commit is contained in:
Jonas Dreßler 2021-02-23 19:47:45 +01:00 committed by Marge Bot
parent 0a144ee54f
commit b3c46a33c0

View File

@ -369,6 +369,8 @@ var IconGridLayout = GObject.registerClass({
this._resolveOnIdleId = 0; this._resolveOnIdleId = 0;
this._iconSizeUpdateResolveCbs = []; this._iconSizeUpdateResolveCbs = [];
this._childrenMaxSize = -1;
} }
_findBestIconSize() { _findBestIconSize() {
@ -414,21 +416,25 @@ var IconGridLayout = GObject.registerClass({
} }
_getChildrenMaxSize() { _getChildrenMaxSize() {
let minWidth = 0; if (this._childrenMaxSize === -1) {
let minHeight = 0; let minWidth = 0;
let minHeight = 0;
for (const child of this._container) { for (const child of this._container) {
if (!child.visible) if (!child.visible)
continue; continue;
const [childMinHeight] = child.get_preferred_height(-1); const [childMinHeight] = child.get_preferred_height(-1);
const [childMinWidth] = child.get_preferred_width(-1); const [childMinWidth] = child.get_preferred_width(-1);
minWidth = Math.max(minWidth, childMinWidth); minWidth = Math.max(minWidth, childMinWidth);
minHeight = Math.max(minHeight, childMinHeight); minHeight = Math.max(minHeight, childMinHeight);
}
this._childrenMaxSize = Math.max(minWidth, minHeight);
} }
return Math.max(minWidth, minHeight); return this._childrenMaxSize;
} }
_getVisibleChildrenForPage(pageIndex) { _getVisibleChildrenForPage(pageIndex) {
@ -445,6 +451,7 @@ var IconGridLayout = GObject.registerClass({
item.disconnect(itemData.destroyId); item.disconnect(itemData.destroyId);
item.disconnect(itemData.visibleId); item.disconnect(itemData.visibleId);
item.disconnect(itemData.queueRelayoutId);
this._items.delete(item); this._items.delete(item);
} }
@ -557,6 +564,9 @@ var IconGridLayout = GObject.registerClass({
else if (!this.allowIncompletePages) else if (!this.allowIncompletePages)
this._fillItemVacancies(itemData.pageIndex); this._fillItemVacancies(itemData.pageIndex);
}), }),
queueRelayoutId: item.connect('queue-relayout', () => {
this._childrenMaxSize = -1;
}),
}); });
item.icon.setIconSize(this._iconSize); item.icon.setIconSize(this._iconSize);