我写了以下演示程序。 每个包含一个Text节点的四个HBox将添加到根(组)中。第一个和最后一个是动画的时间轴,以交换他们的位置。 所有的HBox都具有相同的CSS风格。
结果是“每秒帧数”非常低的动画。 我有一个双核E7400 2.8Ghz Cpu。一个核心100%使用。我期望计算在GPU中完成。 删除大部分CSS(特别是阴影效果)后,动画变得更加平滑。 在我有更好的表现的同时,为了保持视觉效果,我能做些什么吗? 使用css来装饰要设置动画的节点是不是一种不好的做法?
我还使用-Dprism.verbose = true来检查硬件加速是否打开。一切似乎都没问题
Prism pipeline init order: d3d sw
Using platform text rasterizer
Using native-based Pisces rasterizer
Using dirty region optimizations
Not using texture mask for primitives
Not forcing power of 2 sizes for textures
Using hardware CLAMP_TO_ZERO mode
Opting in for HiDPI pixel scaling
Prism pipeline name = com.sun.prism.d3d.D3DPipeline
Loading D3D native library ...
succeeded.
D3DPipelineManager: Created D3D9 device
Direct3D initialization succeeded
(X) Got class = class com.sun.prism.d3d.D3DPipeline
Initialized prism pipeline: com.sun.prism.d3d.D3DPipeline
Maximum supported texture size: 8192
Maximum texture size clamped to 4096
OS Information:
Windows 7 build 7601
D3D Driver Information:
ATI Radeon HD 4800 Series
\\.\DISPLAY1
Driver aticfx32.dll, version 8.17.10.1129
Pixel Shader version 3.0
Device : ven_1002, dev_9440, subsys_0502174B
Max Multisamples supported: 4
vsync: true vpipe: true
Loading Prism common native library ...
succeeded.
这是程序
public class Sample extends Application{
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
Card card1 = new Card(1);
Card card2 = new Card(2);
Card card3 = new Card(3);
Card card4 = new Card(3);
card1.relocate(100, 200);
card2.relocate(250, 200);
card3.relocate(400, 200);
card4.relocate(550, 200);
root.getChildren().add(card1);
root.getChildren().add(card2);
root.getChildren().add(card3);
root.getChildren().add(card4);
primaryStage.setScene(new Scene(root , 800, 600, Color.DARKSLATEGREY));
primaryStage.show();
Timeline tl = new Timeline(new KeyFrame(
Duration.millis(500),
new KeyValue(card1.layoutXProperty(), card4.getLayoutX()),
new KeyValue(card4.layoutXProperty(), card1.getLayoutX())
));
tl.setAutoReverse(true);
tl.setCycleCount(Timeline.INDEFINITE);
tl.play();
}
class Card extends HBox{
private static final String textStyle =
"-fx-fill: linear-gradient(BROWN, WHITE);"+
"-fx-font-size: 100px;"+
"-fx-font-weight: BOLD;"+
"-fx-stroke-type: outside;"+
"-fx-stroke-width: 3;"+
"-fx-stroke: linear-gradient(WHITE, BROWN);"+
"-fx-blend-mode: hard-light;";
boolean active;
public final Text text;
public Card(int number) {
setStyle("-fx-effect: dropshadow(one-pass-box, black, 30, 0, 10, 20);");
text = new Text(""+number);
text.setStyle(textStyle);
getChildren().add(text);
}
}
public static void main(String[] args) {
launch(args);
}
}
答案 0 :(得分:12)
缓存节点(使用您的示例执行此操作会将CPU使用率从核心的100%降至1%)。
setCache(true);
setCacheShape(true);
setCacheHint(CacheHint.SPEED);
在样式表中定义CSS规则而不是内联样式(如果我记得由于JavaFX中CSS实现的性质而更有效)。
在open-jfx wiki上查看performance tips and tricks。
阅读相关问题:
我希望计算在GPU中完成。
JavaFX将在GPU上进行大量计算,但它会做出权衡 - 在CPU上更好地完成一些计算,而JavaFX将使用CPU进行这些类型的计算。您的问题不是在GPU或CPU上进行计算。您的问题是进行了太多计算,因为没有向JavaFX系统提供适当的缓存提示。
使用css来装饰要设置动画的节点是不是一种不好的做法?
内联css样式通常是不好的做法 - 将css放在样式表中。对于大多数用例,在动画节点上使用CSS是合适的。
确实设置setCache(true)和setCacheHint(CacheHint.SPEED)改进了动画,但它仍然是滞后的。
动画并没有落后于我的机器,但之后它并没有真正的可比性,因为我的机器中的硬件和软件是从2014年开始,而不是2008年。
也许尝试更新图形驱动程序并将JavaFX更新为latest development build。
此外,减慢动画速度(例如,给它持续五秒而不是半秒)。当动画移动得非常快时,很难在视觉上检测动画的平滑度。
在JavaFX issue tracker中记录错误报告 - JavaFX开发人员应该能够提供有关如何启用详细JavaFX性能跟踪的其他信息,该跟踪记录JavaFX管道中的呈现步骤并测量其在逐帧(我不知道如何做)。