From cdd700404c15fc241cede1982105e4c7c7f37d3c Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 7 Oct 2019 13:41:04 +0200 Subject: [PATCH] Don't store transform reference in CachedIcon and LazyIcon, store transform modification count instead (IDEA-CR-53109) GitOrigin-RevId: b671242d3feada4474362411d3ae68214c9143f8 --- .../com/intellij/openapi/util/IconLoader.java | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/platform/util/ui/src/com/intellij/openapi/util/IconLoader.java b/platform/util/ui/src/com/intellij/openapi/util/IconLoader.java index a0dffeb3a3d3..cf08685d0c1a 100644 --- a/platform/util/ui/src/com/intellij/openapi/util/IconLoader.java +++ b/platform/util/ui/src/com/intellij/openapi/util/IconLoader.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.function.Supplier; @@ -66,6 +67,7 @@ public final class IconLoader { }; private static final AtomicReference ourTransform = new AtomicReference<>(IconTransform.getDefault()); + private static final AtomicInteger ourTransformModCount = new AtomicInteger(0); static { installPathPatcher(new DeprecatedDuplicatesIconPathPatcher()); @@ -104,12 +106,9 @@ public final class IconLoader { next = updater.apply(prev); } while (!ourTransform.compareAndSet(prev, next)); + ourTransformModCount.incrementAndGet(); if (prev != next) { - for (CachedImageIcon value : ourIconsCache.values()) { - value.myTransform = next; - } - ourIcon2DisabledIcon.clear(); //clears svg cache ImageDescriptor.clearCache(); @@ -564,7 +563,7 @@ public final class IconLoader { @Nullable private final String myOriginalPath; @NotNull private volatile IconUrlResolver myResolver; @Nullable("when not overridden") private final Boolean myDarkOverridden; - @NotNull private volatile IconTransform myTransform; + private int myTransformModCount; private final boolean myUseCacheOnLoad; @Nullable private final Supplier myLocalFilterSupplier; @@ -578,22 +577,20 @@ public final class IconLoader { this(new MyUrlResolver(url, null), null, useCacheOnLoad); } - private CachedImageIcon(@NotNull MyUrlResolver urlResolver, @Nullable String originalPath, boolean useCacheOnLoad) - { - this(originalPath, urlResolver, null, useCacheOnLoad, ourTransform.get(), null); + private CachedImageIcon(@NotNull MyUrlResolver urlResolver, @Nullable String originalPath, boolean useCacheOnLoad) { + this(originalPath, urlResolver, null, useCacheOnLoad, null); } private CachedImageIcon(@Nullable String originalPath, @NotNull IconUrlResolver resolver, @Nullable Boolean darkOverridden, boolean useCacheOnLoad, - @NotNull IconTransform transform, @Nullable Supplier localFilterSupplier) { myOriginalPath = originalPath; myResolver = resolver; myDarkOverridden = darkOverridden; myUseCacheOnLoad = useCacheOnLoad; - myTransform = transform; + myTransformModCount = ourTransformModCount.get(); myLocalFilterSupplier = localFilterSupplier; } @@ -622,12 +619,11 @@ public final class IconLoader { if (isLoaderDisabled()) return EMPTY_ICON; synchronized (myLock) { if (!isValid()) { - myTransform = ourTransform.get(); myResolver.resolve(); myRealIcon = null; myScaledIconsCache.clear(); if (myOriginalPath != null) { - myResolver = myResolver.patch(myOriginalPath, myTransform); + myResolver = myResolver.patch(myOriginalPath, ourTransform.get()); } } } @@ -650,7 +646,7 @@ public final class IconLoader { } private boolean isValid() { - return myTransform == ourTransform.get() && myResolver.isResolved(); + return ourTransformModCount.get() == myTransformModCount && myResolver.isResolved(); } @Override @@ -679,7 +675,7 @@ public final class IconLoader { @NotNull @Override public Icon getDarkIcon(boolean isDark) { - return new CachedImageIcon(myOriginalPath, myResolver, isDark, myUseCacheOnLoad, myTransform, myLocalFilterSupplier); + return new CachedImageIcon(myOriginalPath, myResolver, isDark, myUseCacheOnLoad, myLocalFilterSupplier); } @NotNull @@ -701,21 +697,21 @@ public final class IconLoader { @NotNull @Override public CachedImageIcon copy() { - return new CachedImageIcon(myOriginalPath, myResolver, myDarkOverridden, myUseCacheOnLoad, myTransform, myLocalFilterSupplier); + return new CachedImageIcon(myOriginalPath, myResolver, myDarkOverridden, myUseCacheOnLoad, myLocalFilterSupplier); } @NotNull private Icon createWithFilter(@NotNull Supplier filterSupplier) { - return new CachedImageIcon(myOriginalPath, myResolver, myDarkOverridden, myUseCacheOnLoad, myTransform, filterSupplier); + return new CachedImageIcon(myOriginalPath, myResolver, myDarkOverridden, myUseCacheOnLoad, filterSupplier); } private boolean isDark() { - return myDarkOverridden == null ? myTransform.isDark() : myDarkOverridden; + return myDarkOverridden == null ? ourTransform.get().isDark() : myDarkOverridden; } @Nullable private ImageFilter[] getFilters() { - ImageFilter global = myTransform.getFilter(); + ImageFilter global = ourTransform.get().getFilter(); ImageFilter local = myLocalFilterSupplier != null ? myLocalFilterSupplier.get() : null; if (global != null && local != null) { return new ImageFilter[] {global, local}; @@ -1044,7 +1040,7 @@ public final class IconLoader { public abstract static class LazyIcon extends ScaleContextSupport implements CopyableIcon, RetrievableIcon { private boolean myWasComputed; private volatile Icon myIcon; - private IconTransform myTransform = ourTransform.get(); + private int myTransformModCount = ourTransformModCount.get(); @Override public void paintIcon(Component c, Graphics g, int x, int y) { @@ -1069,10 +1065,10 @@ public final class IconLoader { @NotNull final synchronized Icon getOrComputeIcon() { - IconTransform currentTransform = ourTransform.get(); Icon icon = myIcon; - if (!myWasComputed || myTransform != currentTransform || icon == null) { - myTransform = currentTransform; + int newTransformModCount = ourTransformModCount.get(); + if (!myWasComputed || myTransformModCount != newTransformModCount || icon == null) { + myTransformModCount = newTransformModCount; myWasComputed = true; myIcon = icon = compute(); }