From 59b97a30958663c2beefc29800e8ce8f7b107f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= Date: Thu, 25 Feb 2021 17:20:42 +0100 Subject: [PATCH] workspace: Use Util.lerp() instead of actor box for interpolating Instead of interpolating our workspace and layout boxes for each child using clutter_actor_box_interpolate(), use our Util.lerp() function and stay in JS land instead. This is quite a large performance improvement since it avoids heap-allocating a new ClutterActorBox for every child. With this, we're finally at a duration of 1.0 ms to allocate the Workspace with 20 windows. Part-of: --- js/ui/workspace.js | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/js/ui/workspace.js b/js/ui/workspace.js index f11f546f1..1a5bd0227 100644 --- a/js/ui/workspace.js +++ b/js/ui/workspace.js @@ -616,8 +616,7 @@ var WorkspaceLayout = GObject.registerClass({ const allocationScale = containerBox.get_width() / workareaWidth; - const workspaceBox = new Clutter.ActorBox(); - const layoutBox = new Clutter.ActorBox(); + const childBox = new Clutter.ActorBox(); const { ControlsState } = OverviewControls; const inSessionTransition = @@ -625,44 +624,46 @@ var WorkspaceLayout = GObject.registerClass({ const nSlots = this._windowSlots.length; for (let i = 0; i < nSlots; i++) { - const [x, y, width, height, child] = this._windowSlots[i]; + let [x, y, width, height, child] = this._windowSlots[i]; if (!child.visible) continue; const windowInfo = this._windows.get(child); + let workspaceBoxX, workspaceBoxY; + let workspaceBoxWidth, workspaceBoxHeight; + if (windowInfo.metaWindow.showing_on_its_workspace()) { - workspaceBox.set_origin( - child.boundingBox.x - workareaX, - child.boundingBox.y - workareaY); - workspaceBox.set_size( - child.boundingBox.width, - child.boundingBox.height); + workspaceBoxX = (child.boundingBox.x - workareaX) * allocationScale; + workspaceBoxY = (child.boundingBox.y - workareaY) * allocationScale; + workspaceBoxWidth = child.boundingBox.width * allocationScale; + workspaceBoxHeight = child.boundingBox.height * allocationScale; } else { - workspaceBox.set_origin(workareaX, workareaY); - workspaceBox.set_size(0, 0); + workspaceBoxX = workareaX * allocationScale; + workspaceBoxY = workareaY * allocationScale; + workspaceBoxWidth = 0; + workspaceBoxHeight = 0; child.opacity = stateAdjustementValue * 255; } - workspaceBox.scale(allocationScale); - // Don't allow the scaled floating size to drop below // the target layout size. // We only want to apply this when the scaled floating size is // actually larger than the target layout size, that is while // animating between the session and the window picker. if (inSessionTransition) { - workspaceBox.set_size( - Math.max(workspaceBox.get_width(), width), - Math.max(workspaceBox.get_height(), height)); + workspaceBoxWidth = Math.max(workspaceBoxWidth, width); + workspaceBoxHeight = Math.max(workspaceBoxHeight, height); } - layoutBox.set_origin(x, y); - layoutBox.set_size(width, height); + x = Util.lerp(workspaceBoxX, x, stateAdjustementValue); + y = Util.lerp(workspaceBoxY, y, stateAdjustementValue); + width = Util.lerp(workspaceBoxWidth, width, stateAdjustementValue); + height = Util.lerp(workspaceBoxHeight, height, stateAdjustementValue); - const childBox = workspaceBox.interpolate(layoutBox, - stateAdjustementValue); + childBox.set_origin(x, y); + childBox.set_size(width, height); if (windowInfo.currentTransition) { windowInfo.currentTransition.get_interval().set_final(childBox);