diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 366d372a03..1f18217bb7 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -23,24 +23,26 @@ import static com.android.launcher3.InvariantDeviceProfile.INDEX_TWO_PANEL_PORTR import static com.android.launcher3.Utilities.dpiFromPx; import static com.android.launcher3.Utilities.pxFromSp; import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR; +import static com.android.launcher3.icons.GraphicsUtils.getShapePath; import static com.android.launcher3.testing.shared.ResourceUtils.pxFromDp; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; -import android.graphics.Path; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.util.DisplayMetrics; +import android.util.SparseArray; import android.view.Surface; +import androidx.annotation.NonNull; + import com.android.launcher3.CellLayout.ContainerType; import com.android.launcher3.DevicePaddings.DevicePadding; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.DotRenderer; -import com.android.launcher3.icons.GraphicsUtils; import com.android.launcher3.icons.IconNormalizer; import com.android.launcher3.uioverrides.ApiWrapper; import com.android.launcher3.util.DisplayController; @@ -222,8 +224,8 @@ public class DeviceProfile { private boolean mIsSeascape; // Notification dots - public DotRenderer mDotRendererWorkSpace; - public DotRenderer mDotRendererAllApps; + public final DotRenderer mDotRendererWorkSpace; + public final DotRenderer mDotRendererAllApps; // Taskbar public boolean isTaskbarPresent; @@ -237,8 +239,8 @@ public class DeviceProfile { /** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */ DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds, - boolean isMultiWindowMode, boolean transposeLayoutWithOrientation, - boolean useTwoPanels, boolean isGestureMode) { + SparseArray dotRendererCache, boolean isMultiWindowMode, + boolean transposeLayoutWithOrientation, boolean useTwoPanels, boolean isGestureMode) { this.inv = inv; this.isLandscape = windowBounds.isLandscape(); @@ -469,10 +471,18 @@ public class DeviceProfile { R.dimen.drag_flingToDeleteMinVelocity); // This is done last, after iconSizePx is calculated above. - Path dotPath = GraphicsUtils.getShapePath(DEFAULT_DOT_SIZE); - mDotRendererWorkSpace = new DotRenderer(iconSizePx, dotPath, DEFAULT_DOT_SIZE); - mDotRendererAllApps = iconSizePx == allAppsIconSizePx ? mDotRendererWorkSpace : - new DotRenderer(allAppsIconSizePx, dotPath, DEFAULT_DOT_SIZE); + mDotRendererWorkSpace = createDotRenderer(iconSizePx, dotRendererCache); + mDotRendererAllApps = createDotRenderer(allAppsIconSizePx, dotRendererCache); + } + + private static DotRenderer createDotRenderer( + int size, @NonNull SparseArray cache) { + DotRenderer renderer = cache.get(size); + if (renderer == null) { + renderer = new DotRenderer(size, getShapePath(DEFAULT_DOT_SIZE), DEFAULT_DOT_SIZE); + cache.put(size, renderer); + } + return renderer; } /** @@ -566,10 +576,16 @@ public class DeviceProfile { widthPx, heightPx, availableWidthPx, availableHeightPx, rotationHint); bounds.bounds.offsetTo(windowX, windowY); bounds.insets.set(mInsets); + + SparseArray dotRendererCache = new SparseArray<>(); + dotRendererCache.put(iconSizePx, mDotRendererWorkSpace); + dotRendererCache.put(allAppsIconSizePx, mDotRendererAllApps); + return new Builder(context, inv, mInfo) .setWindowBounds(bounds) .setUseTwoPanels(isTwoPanels) .setMultiWindowMode(isMultiWindowMode) + .setDotRendererCache(dotRendererCache) .setGestureMode(isGestureMode); } @@ -1474,6 +1490,8 @@ public class DeviceProfile { private Boolean mTransposeLayoutWithOrientation; private Boolean mIsGestureMode; + private SparseArray mDotRendererCache; + public Builder(Context context, InvariantDeviceProfile inv, Info info) { mContext = context; mInv = inv; @@ -1490,6 +1508,10 @@ public class DeviceProfile { return this; } + public Builder setDotRendererCache(SparseArray dotRendererCache) { + mDotRendererCache = dotRendererCache; + return this; + } public Builder setWindowBounds(WindowBounds bounds) { mWindowBounds = bounds; @@ -1516,8 +1538,12 @@ public class DeviceProfile { if (mIsGestureMode == null) { mIsGestureMode = DisplayController.getNavigationMode(mContext).hasGestures; } - return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mIsMultiWindowMode, - mTransposeLayoutWithOrientation, mUseTwoPanels, mIsGestureMode); + if (mDotRendererCache == null) { + mDotRendererCache = new SparseArray<>(); + } + return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mDotRendererCache, + mIsMultiWindowMode, mTransposeLayoutWithOrientation, mUseTwoPanels, + mIsGestureMode); } } diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 9b017342f4..67620e3ef9 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -48,6 +48,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.content.res.ResourcesCompat; +import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.model.DeviceGridState; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.testing.shared.ResourceUtils; @@ -396,10 +397,12 @@ public class InvariantDeviceProfile { final List localSupportedProfiles = new ArrayList<>(); defaultWallpaperSize = new Point(displayInfo.currentSize); + SparseArray dotRendererCache = new SparseArray<>(); for (WindowBounds bounds : displayInfo.supportedBounds) { localSupportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo) .setUseTwoPanels(deviceType == TYPE_MULTI_DISPLAY) .setWindowBounds(bounds) + .setDotRendererCache(dotRendererCache) .build()); // Wallpaper size should be the maximum of the all possible sizes Launcher expects diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt index 4732fc1f31..7046782ecf 100644 --- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt +++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt @@ -18,6 +18,7 @@ package com.android.launcher3 import android.content.Context import android.graphics.PointF import android.graphics.Rect +import android.util.SparseArray import androidx.test.core.app.ApplicationProvider import com.android.launcher3.util.DisplayController.Info import com.android.launcher3.util.WindowBounds @@ -56,6 +57,7 @@ abstract class DeviceProfileBaseTest { inv, info, windowBounds, + SparseArray(), isMultiWindowMode, transposeLayoutWithOrientation, useTwoPanels,