JavaFx的动画表现不佳,占用我所有的CPU [英] JavaFx animation poor performance, consumes all my CPU

查看:925
本文介绍了JavaFx的动画表现不佳,占用我所有的CPU的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了下面的演示程序。
四HBox中(多个)包含每一个文本节点,被添加到根目录(组)。第一个和最后用一个时间轴动画交换自己的立场。
所有的HBox(S)具有相同的CSS样式。

结果是amimation一个非常低的帧每秒。
我有一个双核E7400的2.8GHz的CPU。在一个芯被用于100%。我预计在GPU做的计算来代替。
删除的CSS大多数(尤其是阴影效果)动画后去平滑。
有什么我可以为了做preserve的视觉效果,而我有更好的表现?
它是被认为是不好的做法,用css来装饰这将要动画节点?

我还使用了-Dprism.verbose = true来检查硬件accelaration上。一切似乎确定

 棱镜管道的init命令:D3D SW
使用平台文本光栅化
使用基于原生双鱼座光栅
使用脏区优化
不使用质地面膜元
不强迫2种尺寸的电源纹理
使用硬件CLAMP_TO_ZERO模式
选择加入了HiDPI像素缩放
棱镜管道名称= com.sun.prism.d3d.D3DPipeline
D3D加载本地库...
        成功了。
D3DPipelineManager:创建D3D9设备
Direct3D的初始化成功
(X)得到了类=类com.sun.prism.d3d.D3DPipeline
初始化棱镜管道:com.sun.prism.d3d.D3DPipeline
支持的最大纹理大小:8192
最大纹理尺寸钳位到4096
操作系统信息:
        Windows 7的版本7601
D3D驱动程序信息:
    的ATI Radeon HD 4800系列
    \\\\。\\ DISPLAY1
    驱动aticfx32.dll,版本8.17.10.1129
    像素着色器3.0版
    设备:VEN_1002,dev_9440,subsys_0502174B
    最大支持多重采样:4
 VSYNC:真vpipe:真
加载棱镜常见的本地库...
        成功了。

和这里的程序

 公共类样品扩展应用{公共无效启动(阶段primaryStage)抛出异常{
    组root =新集团();
    卡卡1 =新卡(1);
    卡卡2 =新卡(2);
    卡card3 =新卡(3);
    卡card4 =新卡(3);
    card1.relocate(100,200);
    card2.relocate(250,200);
    card3.relocate(400,200);
    card4.relocate(550,200);
    。root.getChildren()加(卡1);
    。root.getChildren()加(卡2);
    。root.getChildren()加(card3);
    。root.getChildren()加(card4);
    primaryStage.setScene(新场景(根,800,600,Color.DARKSLATEGREY));
    primaryStage.show();    时间轴TL =新的时间线(新的关键帧(
            Duration.millis(500),
            新KEYVALUE(card1.layoutXProperty(),card4.getLayoutX()),
            新的键值(card4.layoutXProperty(),card1.getLayoutX())
            ));
    tl.setAutoReverse(真);
    tl.setCycleCount(Timeline.INDEFINITE);
    tl.play();
}班卡扩展的HBox {    私有静态最后弦乐TEXTSTYLE =
            -fx填充:线性渐变(棕色,白色);+
            -fx-字体大小:100像素;+
            -fx-字体重量:BOLD;+
            -fx冲程型:外;+
            -fx冲程宽度:3;+
            -fx行程:线性渐变(白,棕);+
            -fx-混合模式:硬轻;    布尔活跃;    公共最后文本文字;    市民卡(INT编号){
        的setStyle( - FX-效果:阴影效果(一传递箱,黑色,30,0,10,20););
        文本=新文本(+号);
        text.setStyle(文本样式);
        。的getChildren()添加(文字);
    }
}公共静态无效的主要(字串[] args){
    启动(参数);
}

}


解决方案

  1. 缓存节点(这样做与样品的下降,从一个核心的100%的CPU使用率1%)。

      setCache(真);
    setCacheShape(真);
    setCacheHint(CacheHint.SPEED);


  2. 阅读节点缓存的j​​avadoc


  3. 定义你的CSS规则的样式表,而不是内联样式(如果我记得那是更有效的,由于JavaFX中的CSS实现的本质)。


  4. 看看性能的技巧和窍门的上开放式JFX维基。


  5. 阅读相关的问题:



  

我预计在GPU做的计算来代替。


的JavaFX将会做大量的GPU上计算的,但它的权衡 - 一些计算是在CPU上做得更好和JavaFX将使用CPU为这些类型的计算。你的问题是没有在GPU或CPU进行运算之一。你的问题是因为有相应的提示缓存没有被提供给JavaFX的系统做过多的计算。


  

时,它认为一个不好的做法,用css来装饰这将要动画节点?


内联CSS样式一般不好的做法 - 把CSS样式表中。动画节点上使用CSS是适合大多数用例。


  

事实上设置setCache(真)和setCacheHint(CacheHint.SPEED)改进了动画,但它仍然是laggy。


动画不落后我的机器上,但它是不是真的比较,因为在我的机器的硬件和软件是从2014年,2008年没有

也许尝试更新您的显卡驱动程序和更新的JavaFX到最新开发版本

此外,动画慢下来(例如给它五秒钟时间,而不是半秒)。它可以是很难直观地发现动画的平滑度时,动作非常迅速。

在日志中 JavaFX的问题跟踪 bug报告 - JavaFX的开发者应该能够提供关于如何做其他信息打开详细的JavaFX的性能跟踪其记录在JavaFX的管道渲染的步骤和措施逐帧对他们的表现(我不知道如何做到这一点)。

I have written the following demonstration program. Four HBox(s) containing one Text node each, are added to the root (Group). The first and last are animated with a timeline to swap their positions. All the HBox(s) have the same css style.

The result is a very low 'frames per second' amimation. I have an dual core E7400 2.8Ghz Cpu. The one core was used 100%. I expected the computations to be done in GPU instead. After removing most of the css (especially the shadow effect) the animation went smoother. Is there something I can do in order to preserve the visual effects while I have a better performance? Is it considered a bad practice to use css to decorate nodes that are going to be animated?

I also used the -Dprism.verbose=true to check if the hardware accelaration is on. Everything seems ok

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.

and here is the program

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);
}

}

解决方案

  1. Cache the node (doing this with your sample dropped the CPU usage from 100% of a core to 1%).

    setCache(true);
    setCacheShape(true);
    setCacheHint(CacheHint.SPEED);
    

  2. Read the javadoc on node caching.

  3. Define your CSS rules in a stylesheet and not inline styles (if I recall that is more efficient due to the nature of the CSS implementation in JavaFX).

  4. Take a look at performance tips and tricks on the open-jfx wiki.

  5. Read related questions:

I expected the computations to be done in GPU instead.

JavaFX will do lots of computations on the GPU, however it does a tradeoff - some computations are better done on a CPU and JavaFX will use the CPU for these kinds of computations. Your issue is not one of having computations done on the GPU or CPU. Your issue is having too many computations done because appropriate caching hints have not been provided to the JavaFX system.

Is it considered a bad practice to use css to decorate nodes that are going to be animated?

Inline css styles are bad practice in general - put the css in a stylesheet. Using CSS on animated nodes is fine for most use cases.

Indeed setting setCache(true) and setCacheHint(CacheHint.SPEED) improved the animation but it is still laggy.

The animation does not lag on my machine, but then it is not really comparable because the hardware and software in my machine is from 2014, not 2008.

Perhaps try updating your graphics drivers and updating JavaFX to the latest development build.

Also, slow down the animation (e.g. give it a duration of five seconds rather than half a second). It can be hard to visually detect the smoothness of an animation when it moves very quickly.

Log a bug report in the JavaFX issue tracker - the JavaFX developers should be able to supply additional information on how to do turn on detailed JavaFX performance tracking which logs the rendering steps in the JavaFX pipeline and measures their performance on a frame by frame basis (I don't know how to do this).

这篇关于JavaFx的动画表现不佳,占用我所有的CPU的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆