optimisation: number of repaint events reduced

This commit is contained in:
Alexey Kudravtsev
2015-09-17 14:35:36 +03:00
parent fc1514c834
commit d6ff7e141f
4 changed files with 51 additions and 19 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
package com.intellij.ui;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
@@ -32,4 +33,7 @@ public abstract class IconDeferrer {
public abstract <T> Icon defer(Icon base, T param, @NotNull Function<T, Icon> f);
public abstract <T> Icon deferAutoUpdatable(Icon base, T param, @NotNull Function<T, Icon> f);
public boolean equalIcons(Icon icon1, Icon icon2) {
return Comparing.equal(icon1, icon2);
}
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.util.ProgressIndicatorUtils;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.tabs.impl.TabLabel;
import com.intellij.util.Alarm;
@@ -48,14 +49,14 @@ public class DeferredIconImpl<T> implements DeferredIcon {
@NotNull
private volatile Icon myDelegateIcon;
private Function<T, Icon> myEvaluator;
private volatile boolean myIsScheduled = false;
private volatile boolean myIsScheduled;
private T myParam;
private static final Icon EMPTY_ICON = JBUI.emptyIcon(16);
private final boolean myNeedReadAction;
private boolean myDone;
private final boolean myAutoUpdatable;
private long myLastCalcTime = 0L;
private long myLastTimeSpent = 0L;
private long myLastCalcTime;
private long myLastTimeSpent;
private static final ThreadPoolExecutor ourIconsCalculatingExecutor = ConcurrencyUtil.newSingleThreadExecutor("Icons");
@@ -85,7 +86,7 @@ public class DeferredIconImpl<T> implements DeferredIcon {
}
@Override
public void paintIcon(final Component c, final Graphics g, final int x, final int y) {
public void paintIcon(@NotNull final Component c, @NotNull final Graphics g, final int x, final int y) {
if (!(myDelegateIcon instanceof DeferredIconImpl && ((DeferredIconImpl)myDelegateIcon).myDelegateIcon instanceof DeferredIconImpl)) {
myDelegateIcon.paintIcon(c, g, x, y); //SOE protection
}
@@ -165,7 +166,7 @@ public class DeferredIconImpl<T> implements DeferredIcon {
if (actualTarget == null) return;
if (shouldRevalidate) {
// revalidate will not work: jtree caches size of nodes
// revalidate will not work: JTree caches size of nodes
if (actualTarget instanceof JTree) {
final TreeUI ui = ((JTree)actualTarget).getUI();
if (ui instanceof BasicTreeUI) {
@@ -283,7 +284,7 @@ public class DeferredIconImpl<T> implements DeferredIcon {
}
public boolean isDone() {
if (myAutoUpdatable && myDone && myLastCalcTime > 0 && (System.currentTimeMillis() - myLastCalcTime) > Math.max(MIN_AUTO_UPDATE_MILLIS, 10 * myLastTimeSpent)) {
if (myAutoUpdatable && myDone && myLastCalcTime > 0 && System.currentTimeMillis() - myLastCalcTime > Math.max(MIN_AUTO_UPDATE_MILLIS, 10 * myLastTimeSpent)) {
myDone = false;
myIsScheduled = false;
}
@@ -294,7 +295,7 @@ public class DeferredIconImpl<T> implements DeferredIcon {
private final Alarm myAlarm = new Alarm();
private final Set<RepaintRequest> myQueue = new LinkedHashSet<RepaintRequest>();
public void pushDirtyComponent(@NotNull Component c, final Rectangle rec) {
private void pushDirtyComponent(@NotNull Component c, final Rectangle rec) {
ApplicationManager.getApplication().assertIsDispatchThread(); // assert myQueue accessed from EDT only
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@@ -336,7 +337,17 @@ public class DeferredIconImpl<T> implements DeferredIcon {
}
}
public interface IconListener<T> {
interface IconListener<T> {
void evalDone(DeferredIconImpl<T> source, T key, @NotNull Icon result);
}
public static boolean equalIcons(Icon icon1, Icon icon2) {
if (icon1 instanceof DeferredIconImpl) {
icon1 = ((DeferredIconImpl)icon1).myDelegateIcon;
}
if (icon2 instanceof DeferredIconImpl) {
icon2 = ((DeferredIconImpl)icon2).myDelegateIcon;
}
return Comparing.equal(icon1, icon2);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -125,4 +125,9 @@ public class IconDeferrerImpl extends IconDeferrer {
myEvaluationIsInProgress.set(Boolean.FALSE);
}
}
@Override
public boolean equalIcons(Icon icon1, Icon icon2) {
return DeferredIconImpl.equalIcons(icon1, icon2);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,9 @@ package com.intellij.ui.tabs;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.ui.Queryable;
import com.intellij.openapi.util.Comparing;
import com.intellij.reference.SoftReference;
import com.intellij.ui.IconDeferrer;
import com.intellij.ui.PlaceProvider;
import com.intellij.ui.SimpleColoredText;
import com.intellij.ui.SimpleTextAttributes;
@@ -103,8 +105,10 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
}
public TabInfo setText(String text) {
clearText(false);
append(text, getDefaultAttributes());
if (!myText.toString().equals(text)) {
clearText(false);
append(text, getDefaultAttributes());
}
return this;
}
@@ -135,8 +139,10 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
public TabInfo setIcon(Icon icon) {
Icon old = myIcon;
myIcon = icon;
myChangeSupport.firePropertyChange(ICON, old, icon);
if (!IconDeferrer.getInstance().equalIcons(old, icon)) {
myIcon = icon;
myChangeSupport.firePropertyChange(ICON, old, icon);
}
return this;
}
@@ -168,6 +174,7 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
return myIcon;
}
@Override
public String getPlace() {
return myPlace;
}
@@ -339,8 +346,10 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
public TabInfo setTooltipText(final String text) {
String old = myTooltipText;
myTooltipText = text;
myChangeSupport.firePropertyChange(TEXT, old, myTooltipText);
if (!Comparing.equal(old, text)) {
myTooltipText = text;
myChangeSupport.firePropertyChange(TEXT, old, myTooltipText);
}
return this;
}
@@ -350,8 +359,10 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
public TabInfo setTabColor(Color color) {
Color old = myTabColor;
myTabColor = color;
myChangeSupport.firePropertyChange(TAB_COLOR, old, color);
if (!Comparing.equal(color, old)) {
myTabColor = color;
myChangeSupport.firePropertyChange(TAB_COLOR, old, color);
}
return this;
}
@@ -364,6 +375,7 @@ public final class TabInfo implements Queryable, PlaceProvider<String> {
return this;
}
@Override
public void putInfo(@NotNull Map<String, String> info) {
if (myQueryable != null) {
myQueryable.putInfo(info);