Windows 7 WebView Text Rendering
Hello, I am using Java 8u66 on Windows 7 and the text rendering in a WebView is super blurry. For comparison purposes, I created a simple test that shows a WebView displaying a paragraph and next to it a standard Label showing the same paragraph. http://imgur.com/36RYvf8 (Sorry I don't have a better place to upload the screenshot). The page I am displaying is the following: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sed blandit magna, ut mattis ligula. Donec vestibulum ut neque id condimentum. Cras blandit erat ac tincidunt bibendum. Nulla dapibus arcu risus, at tincidunt leo facilisis sit amet. Donec imperdiet lectus diam, nec egestas sapien luctus nec. Praesent auctor ligula sed sem dictum venenatis. Donec non dapibus turpis. Aliquam dictum euismod sapien id bibendum. Quisque at accumsan eros. Quisque eleifend maximus justo at tempor. Curabitur ut mi ut justo auctor malesuada non at mi. Integer augue neque, ultrices sit amet augue a, interdum ultricies nibh. Sed imperdiet diam et eros maximus ultrices. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. The Java code I am using to create the WebView is: WebView webView = new WebView(); webView.setPrefSize(410, 620); webView.getEngine().load(getClass().getResource("/web/test.html").toExternalForm()); Essentially, a incredibly bare-bones example. This text rendering happens on every page I have tried to load (e.g. actual websites). System info: OS Name: Microsoft Windows 7 Ultimate OS Version:6.1.7601 Service Pack 1 Build 7601 java version "1.8.0_66" Java(TM) SE Runtime Environment (build 1.8.0_66-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode) Although this is not a functionality breaking issue (e.g. not a showstopper), it really is a serious issue in my eyes because of just how qualities are of the rendered texts. Thanks very much, -- Michael Ennen
[9] review request: JDK-8147410 Crash with long selector list
Hi Alexander, kevin, Please review the fix for below issue : JIRA: https://bugs.openjdk.java.net/browse/JDK-8147410 Webrev: http://cr.openjdk.java.net/~mbilla/8147410/ Issue: This crash is webkit regression in 8u60 and fixed in JDK 9 version. Thanks, Murali
Re: [PATCH] Decrease Toolkit.firePulse allocation rate
How often are listeners added and removed? It might make more sense to make them copy-on-write instead...? ...jim On 1/14/16 4:52 AM, Doswald Michael wrote: While profiling a JavaFX application that runs on embedded hardware, I have found that the Toolkit.firePulse method creates more garbage than necessary. In an application that simply animates an object without doing much else, I see that the firePulse method allocates a fair amount of objects (compared to the overall number of allocated objects). I have written a small patch that decreases the allocation rate in said method. Since I'm not sure if such tweaks are desired in the JavaFX codebase, I didn't open a JIRA issue. I'm happy to do so if they are. The following small application animates a single circle on screen. The allocation rate of the 'JavaFX Application Thread' is as follows (measured with jvisualvm): openjfx 8u HEAD:~ 65 KB/s after start, ~ 49 KB/s after JIT compilation kicked in with patch:~ 25 KB/s, doesn't seem to change when JIT kicks in public class AllocateApp extends Application { public static void main(String... args) { Application.launch(args); } @Override public void start(Stage primaryStage) throws Exception { Circle circle = new Circle(10, 25, 10); Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(2), new KeyValue(circle.centerXProperty(), 490))); timeline.setCycleCount(Timeline.INDEFINITE); timeline.setAutoReverse(true); timeline.play(); primaryStage.setScene(new Scene(new Pane(circle), 500, 50)); primaryStage.show(); } } The patch below only creates a single List object instead of three WeakHashMaps to make a local copy of the TKPulseListeners. It also uses the number of listeners in the maps to estimate the size of the list. The patch uses WeakReference objects in the list, which I doubt is necessary, but it emulates the previous behaviour more accurately. I believe it would be possible to change that to a strong reference for the following reasons: a) The list is local and the strong references would only be there for the time the firePulse method is run b) The code would become more readable (less generics parameters, null-guard not necessary in loop) c) Getting rid of the WeakReference objects would decrease garbage generation even more (down to ~ 21 KB/s) Regards Michael diff -r f1c3eb85af4d modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java --- a/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.javaFri Jan 08 08:11:51 2016 -0800 +++ b/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.javaWed Jan 13 10:43:27 2016 +0100 @@ -51,7 +51,6 @@ import javafx.scene.shape.StrokeType; import javafx.stage.FileChooser.ExtensionFilter; import javafx.stage.Modality; -import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.stage.Window; import java.io.File; @@ -94,6 +93,8 @@ import com.sun.scenario.effect.Color4f; import com.sun.scenario.effect.FilterContext; import com.sun.scenario.effect.Filterable; +import java.lang.ref.WeakReference; +import javafx.util.Pair; public abstract class Toolkit { @@ -362,32 +363,36 @@ // and those changes propogated to scene before it gets its pulse to update // Copy of listener map -final Map stagePulseList = -new WeakHashMap(); -final Map scenePulseList = -new WeakHashMap(); -final Map postScenePulseList = -new WeakHashMap(); +final List,AccessControlContext>> listenersList; synchronized (this) { -stagePulseList.putAll(stagePulseListeners); -scenePulseList.putAll(scenePulseListeners); -postScenePulseList.putAll(postScenePulseListeners); + listenersList = new ArrayList<>(stagePulseListeners.size()+scenePulseListeners.size()+postScenePulseListeners.size()); + copyListeners(stagePulseListeners, listenersList); + copyListeners(scenePulseListeners, listenersList); + copyListeners(postScenePulseListeners, listenersList); } -for (Map.Entry entry : stagePulseList.entrySet()) { -runPulse(entry.getKey(), entry.getValue()); -} -for (Map.Entry entry : scenePulseList.entrySet()) { -runPulse(entry.getKey(), entry.getValue()); -} -for (Map.Entry entry : postScenePulseList.entrySet()) { -runPulse(entry.getKey(), entry.getValue()); + +for (int idx = 0, max = listenersList.size(); idx < max; idx++) { + Pair, AccessControlContext> listenerEntry = listenersList.get(idx); + TKPulseListener pulseListener = listenerEntry.getKey().get(); + if (pulseListener != null) { +runPulse(pulseListener, listenerEntry.getValue()); + }
review: Refactor swing Tests to match the rest of the tests
Refactor swing Tests to match the rest of the tests https://bugs.openjdk.java.net/browse/JDK-8147416 http://cr.openjdk.java.net/~ddhill/8147416/ -- David Hill Java Embedded Development "A man's feet should be planted in his country, but his eyes should survey the world." -- George Santayana (1863 - 1952)
review: Move systemTest shims to proper module
Missed this in the previous systemTests rework: https://bugs.openjdk.java.net/browse/JDK-8147398 http://cr.openjdk.java.net/~ddhill/8147398/ Will submit to 9-dev though it really only affects Jake. -- David Hill Java Embedded Development "A man's feet should be planted in his country, but his eyes should survey the world." -- George Santayana (1863 - 1952)
Re: [PATCH] Decrease Toolkit.firePulse allocation rate
Hi Michael, If you would like to file an RFE, that would be fine. Before you do, please see the following page on contributing to an OpenJDK project such as OpenJFX: http://openjdk.java.net/contribute/ In particular, we need a signed Oracle Contributor Agreement (OCA) from you before we can evaluate your patch. As part of this, we will also need tests to verify that there is no functional regression, and a way to measure the improvement. Thanks! -- Kevin Doswald Michael wrote: While profiling a JavaFX application that runs on embedded hardware, I have found that the Toolkit.firePulse method creates more garbage than necessary. In an application that simply animates an object without doing much else, I see that the firePulse method allocates a fair amount of objects (compared to the overall number of allocated objects). I have written a small patch that decreases the allocation rate in said method. Since I'm not sure if such tweaks are desired in the JavaFX codebase, I didn't open a JIRA issue. I'm happy to do so if they are. The following small application animates a single circle on screen. The allocation rate of the 'JavaFX Application Thread' is as follows (measured with jvisualvm): openjfx 8u HEAD:~ 65 KB/s after start, ~ 49 KB/s after JIT compilation kicked in with patch:~ 25 KB/s, doesn't seem to change when JIT kicks in public class AllocateApp extends Application { public static void main(String... args) { Application.launch(args); } @Override public void start(Stage primaryStage) throws Exception { Circle circle = new Circle(10, 25, 10); Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(2), new KeyValue(circle.centerXProperty(), 490))); timeline.setCycleCount(Timeline.INDEFINITE); timeline.setAutoReverse(true); timeline.play(); primaryStage.setScene(new Scene(new Pane(circle), 500, 50)); primaryStage.show(); } } The patch below only creates a single List object instead of three WeakHashMaps to make a local copy of the TKPulseListeners. It also uses the number of listeners in the maps to estimate the size of the list. The patch uses WeakReference objects in the list, which I doubt is necessary, but it emulates the previous behaviour more accurately. I believe it would be possible to change that to a strong reference for the following reasons: a) The list is local and the strong references would only be there for the time the firePulse method is run b) The code would become more readable (less generics parameters, null-guard not necessary in loop) c) Getting rid of the WeakReference objects would decrease garbage generation even more (down to ~ 21 KB/s) Regards Michael diff -r f1c3eb85af4d modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java --- a/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.javaFri Jan 08 08:11:51 2016 -0800 +++ b/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.javaWed Jan 13 10:43:27 2016 +0100 @@ -51,7 +51,6 @@ import javafx.scene.shape.StrokeType; import javafx.stage.FileChooser.ExtensionFilter; import javafx.stage.Modality; -import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.stage.Window; import java.io.File; @@ -94,6 +93,8 @@ import com.sun.scenario.effect.Color4f; import com.sun.scenario.effect.FilterContext; import com.sun.scenario.effect.Filterable; +import java.lang.ref.WeakReference; +import javafx.util.Pair; public abstract class Toolkit { @@ -362,32 +363,36 @@ // and those changes propogated to scene before it gets its pulse to update // Copy of listener map -final Map stagePulseList = -new WeakHashMap(); -final Map scenePulseList = -new WeakHashMap(); -final Map postScenePulseList = -new WeakHashMap(); +final List,AccessControlContext>> listenersList; synchronized (this) { -stagePulseList.putAll(stagePulseListeners); -scenePulseList.putAll(scenePulseListeners); -postScenePulseList.putAll(postScenePulseListeners); + listenersList = new ArrayList<>(stagePulseListeners.size()+scenePulseListeners.size()+postScenePulseListeners.size()); + copyListeners(stagePulseListeners, listenersList); + copyListeners(scenePulseListeners, listenersList); + copyListeners(postScenePulseListeners, listenersList); } -for (Map.Entry entry : stagePulseList.entrySet()) { -runPulse(entry.getKey(), entry.getValue()); -} -for (Map.Entry entry : scenePulseList.entrySet()) { -runPulse(entry.getKey(), entry.getValue()); -} -for (Map.Entry entry : postScenePulseList.entrySet()) { -runPulse(entry.getKey(), entry.getValue()); + +for (int idx = 0, max = listenersList.size(); idx <
[PATCH] Decrease Toolkit.firePulse allocation rate
While profiling a JavaFX application that runs on embedded hardware, I have found that the Toolkit.firePulse method creates more garbage than necessary. In an application that simply animates an object without doing much else, I see that the firePulse method allocates a fair amount of objects (compared to the overall number of allocated objects). I have written a small patch that decreases the allocation rate in said method. Since I'm not sure if such tweaks are desired in the JavaFX codebase, I didn't open a JIRA issue. I'm happy to do so if they are. The following small application animates a single circle on screen. The allocation rate of the 'JavaFX Application Thread' is as follows (measured with jvisualvm): openjfx 8u HEAD:~ 65 KB/s after start, ~ 49 KB/s after JIT compilation kicked in with patch:~ 25 KB/s, doesn't seem to change when JIT kicks in public class AllocateApp extends Application { public static void main(String... args) { Application.launch(args); } @Override public void start(Stage primaryStage) throws Exception { Circle circle = new Circle(10, 25, 10); Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(2), new KeyValue(circle.centerXProperty(), 490))); timeline.setCycleCount(Timeline.INDEFINITE); timeline.setAutoReverse(true); timeline.play(); primaryStage.setScene(new Scene(new Pane(circle), 500, 50)); primaryStage.show(); } } The patch below only creates a single List object instead of three WeakHashMaps to make a local copy of the TKPulseListeners. It also uses the number of listeners in the maps to estimate the size of the list. The patch uses WeakReference objects in the list, which I doubt is necessary, but it emulates the previous behaviour more accurately. I believe it would be possible to change that to a strong reference for the following reasons: a) The list is local and the strong references would only be there for the time the firePulse method is run b) The code would become more readable (less generics parameters, null-guard not necessary in loop) c) Getting rid of the WeakReference objects would decrease garbage generation even more (down to ~ 21 KB/s) Regards Michael diff -r f1c3eb85af4d modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java --- a/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java Fri Jan 08 08:11:51 2016 -0800 +++ b/modules/graphics/src/main/java/com/sun/javafx/tk/Toolkit.java Wed Jan 13 10:43:27 2016 +0100 @@ -51,7 +51,6 @@ import javafx.scene.shape.StrokeType; import javafx.stage.FileChooser.ExtensionFilter; import javafx.stage.Modality; -import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.stage.Window; import java.io.File; @@ -94,6 +93,8 @@ import com.sun.scenario.effect.Color4f; import com.sun.scenario.effect.FilterContext; import com.sun.scenario.effect.Filterable; +import java.lang.ref.WeakReference; +import javafx.util.Pair; public abstract class Toolkit { @@ -362,32 +363,36 @@ // and those changes propogated to scene before it gets its pulse to update // Copy of listener map - final Map stagePulseList = - new WeakHashMap(); - final Map scenePulseList = - new WeakHashMap(); - final Map postScenePulseList = - new WeakHashMap(); + final List,AccessControlContext>> listenersList; synchronized (this) { - stagePulseList.putAll(stagePulseListeners); - scenePulseList.putAll(scenePulseListeners); - postScenePulseList.putAll(postScenePulseListeners); + listenersList = new ArrayList<>(stagePulseListeners.size()+scenePulseListeners.size()+postScenePulseListeners.size()); + copyListeners(stagePulseListeners, listenersList); + copyListeners(scenePulseListeners, listenersList); + copyListeners(postScenePulseListeners, listenersList); } - for (Map.Entry entry : stagePulseList.entrySet()) { - runPulse(entry.getKey(), entry.getValue()); - } - for (Map.Entry entry : scenePulseList.entrySet()) { - runPulse(entry.getKey(), entry.getValue()); - } - for (Map.Entry entry : postScenePulseList.entrySet()) { - runPulse(entry.getKey(), entry.getValue()); + + for (int idx = 0, max = listenersList.size(); idx < max; idx++) { + Pair, AccessControlContext> listenerEntry = listenersList.get(idx); + TKPulseListener pulseListener = listenerEntry.getKey().get(); + if (pulseListener != null) { + runPulse(pulseListener, listenerEntry.getValue()); + } } if (lastTkPulseListener != null) { runPulse(lastTkPulseListener, lastTkPulseAcc); } } + + private void copyListeners(Map listenerMap, List,AccessControlContext>> l