Skip to content

Commit

Permalink
8169922: SwingMark/TextArea: 2-7% regression on Linux, Mac, Windows i…
Browse files Browse the repository at this point in the history
…n 9-b143

Reviewed-by: flar, serb
  • Loading branch information
Alexander Scherbatiy committed Dec 22, 2016
1 parent 4c934b1 commit 4d06c5d
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@
import sun.swing.SwingUtilities2;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.swing.JPasswordField;
import static javax.swing.text.PlainView.isFPMethodOverriden;

/**
* Implements a View suitable for use in JPasswordField
Expand Down Expand Up @@ -332,22 +329,6 @@ public float getPreferredSpan(int axis) {

static char[] ONE = new char[1];

private final boolean drawEchoCharacterOverridden;

{
final Class<?> CLS = getClass();
final Class<?> INT = Integer.TYPE;
final Class<?> FP = Float.TYPE;
final Class<?> CHAR = Character.TYPE;

drawEchoCharacterOverridden = AccessController
.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
Class<?>[] intTypes = {Graphics.class, INT, INT, CHAR};
Class<?>[] fpTypes = {Graphics2D.class, FP, FP, CHAR};
return isFPMethodOverriden("drawEchoCharacter", CLS, intTypes, fpTypes);
}
});
}
private final boolean drawEchoCharacterOverridden =
getFPMethodOverridden(getClass(), "drawEchoCharacter", FPMethodArgs.GNNC);
}
147 changes: 101 additions & 46 deletions jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import java.util.Objects;
import javax.swing.event.*;
import java.lang.reflect.Module;
import java.lang.ref.SoftReference;
import java.util.HashMap;

/**
* Implements View interface for a simple multi-line text view
Expand Down Expand Up @@ -818,10 +820,45 @@ private int getLineWidth(Element line) {
return w;
}

static boolean isFPMethodOverriden(String method,
Class<?> cls,
Class<?>[] intTypes,
Class<?>[] fpTypes)
static boolean getFPMethodOverridden(Class<?> cls, String method,
FPMethodArgs methodArgs) {
HashMap<FPMethodItem, Boolean> map = null;
boolean initialized = methodsOverriddenMapRef != null
&& (map = methodsOverriddenMapRef.get()) != null;

if (!initialized) {
map = new HashMap<>();
methodsOverriddenMapRef = new SoftReference<>(map);
}

FPMethodItem key = new FPMethodItem(cls, method);
Boolean isFPMethodOverridden = map.get(key);
if (isFPMethodOverridden == null) {
isFPMethodOverridden = checkFPMethodOverridden(cls, method, methodArgs);
map.put(key, isFPMethodOverridden);
}
return isFPMethodOverridden;
}

private static boolean checkFPMethodOverridden(final Class<?> className,
final String methodName,
final FPMethodArgs methodArgs) {

return AccessController
.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return isFPMethodOverridden(methodName, className,
methodArgs.getMethodArguments(false),
methodArgs.getMethodArguments(true));
}
});
}

private static boolean isFPMethodOverridden(String method,
Class<?> cls,
Class<?>[] intTypes,
Class<?>[] fpTypes)
{
Module thisModule = PlainView.class.getModule();
while (!thisModule.equals(cls.getModule())) {
Expand All @@ -840,6 +877,57 @@ static boolean isFPMethodOverriden(String method,
return true;
}

enum FPMethodArgs {

IGNN,
IIGNN,
GNNII,
GNNC;

public Class<?>[] getMethodArguments(boolean isFPType) {
Class<?> N = (isFPType) ? Float.TYPE : Integer.TYPE;
Class<?> G = (isFPType) ? Graphics2D.class : Graphics.class;
switch (this) {
case IGNN:
return new Class<?>[]{Integer.TYPE, G, N, N};
case IIGNN:
return new Class<?>[]{Integer.TYPE, Integer.TYPE, G, N, N};
case GNNII:
return new Class<?>[]{G, N, N, Integer.TYPE, Integer.TYPE};
case GNNC:
return new Class<?>[]{G, N, N, Character.TYPE};
default:
throw new RuntimeException("Unknown method arguments!");
}
}
}

private static class FPMethodItem {

final Class<?> className;
final String methodName;

public FPMethodItem(Class<?> className, String methodName) {
this.className = className;
this.methodName = methodName;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof FPMethodItem) {
FPMethodItem that = (FPMethodItem) obj;
return this.className.equals(that.className)
&& this.methodName.equals(that.methodName);
}
return false;
}

@Override
public int hashCode() {
return 31 * methodName.hashCode() + className.hashCode();
}
}

// --- member variables -----------------------------------------------

/**
Expand Down Expand Up @@ -878,46 +966,13 @@ static boolean isFPMethodOverriden(String method,
*/
int firstLineOffset;

final boolean drawLineOverridden;
final boolean drawSelectedTextOverridden;
final boolean drawUnselectedTextOverridden;
final boolean useFloatingPointAPI;

{
final Class<?> CLS = getClass();
final Class<?> INT = Integer.TYPE;
final Class<?> FP = Float.TYPE;

drawLineOverridden = AccessController
.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
Class<?>[] intTypes = {INT, Graphics.class, INT, INT};
Class<?>[] fpTypes = {INT, Graphics2D.class, FP, FP};
return isFPMethodOverriden("drawLine", CLS, intTypes, fpTypes);
}
});

drawUnselectedTextOverridden = AccessController
.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
return isFPMethodOverriden("drawUnselectedText", CLS, intTypes, fpTypes);
}
});

drawSelectedTextOverridden = AccessController
.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
return isFPMethodOverriden("drawSelectedText", CLS, intTypes, fpTypes);
}
});

useFloatingPointAPI = drawUnselectedTextOverridden || drawSelectedTextOverridden;
}
private static SoftReference<HashMap<FPMethodItem, Boolean>> methodsOverriddenMapRef;
final boolean drawLineOverridden =
getFPMethodOverridden(getClass(), "drawLine", FPMethodArgs.IGNN);
final boolean drawSelectedTextOverridden =
getFPMethodOverridden(getClass(), "drawSelectedText", FPMethodArgs.GNNII);
final boolean drawUnselectedTextOverridden =
getFPMethodOverridden(getClass(), "drawUnselectedText", FPMethodArgs.GNNII);
final boolean useFloatingPointAPI =
drawUnselectedTextOverridden || drawSelectedTextOverridden;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.lang.ref.SoftReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.swing.event.*;
import static javax.swing.text.PlainView.isFPMethodOverriden;
import static javax.swing.text.PlainView.FPMethodArgs.*;
import static javax.swing.text.PlainView.getFPMethodOverridden;

/**
* View of plain text (text with only one font and color)
Expand Down Expand Up @@ -989,46 +988,12 @@ private int findLine(int[] array, int offset, int min, int max) {
SoftReference<int[]> lineCache = null;
}

private final boolean drawLineOverridden;
private final boolean drawSelectedTextOverridden;
private final boolean drawUnselectedTextOverridden;
private final boolean useFloatingPointAPI;

{
final Class<?> CLS = getClass();
final Class<?> INT = Integer.TYPE;
final Class<?> FP = Float.TYPE;

drawLineOverridden = AccessController
.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
Class<?>[] intTypes = {INT, INT, Graphics.class, INT, INT};
Class<?>[] fpTypes = {INT, INT, Graphics2D.class, FP, FP};
return isFPMethodOverriden("drawLine", CLS, intTypes, fpTypes);
}
});

drawUnselectedTextOverridden = AccessController
.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
return isFPMethodOverriden("drawUnselectedText", CLS, intTypes, fpTypes);
}
});

drawSelectedTextOverridden = AccessController
.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
return isFPMethodOverriden("drawSelectedText", CLS, intTypes, fpTypes);
}
});

useFloatingPointAPI = drawUnselectedTextOverridden || drawSelectedTextOverridden;
}
private final boolean drawLineOverridden =
getFPMethodOverridden(getClass(), "drawLine", IIGNN);
private final boolean drawSelectedTextOverridden =
getFPMethodOverridden(getClass(), "drawSelectedText", GNNII);
private final boolean drawUnselectedTextOverridden =
getFPMethodOverridden(getClass(), "drawUnselectedText", GNNII);
private final boolean useFloatingPointAPI =
drawUnselectedTextOverridden || drawSelectedTextOverridden;
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

/**
* @test
* @bug 8156217
* @bug 8156217 8169922
* @key headful
* @summary Selected text is shifted on HiDPI display
* @run main FPMethodCalledTest
Expand Down

0 comments on commit 4d06c5d

Please sign in to comment.