使用大画布时javafx中的java空指针

vdzxcuhz  于 2021-06-27  发布在  Java
关注(0)|答案(0)|浏览(349)

我在应用程序中使用canvas对象,确切地说,在stackpane中有两个大小相同的对象。当这些对象变大时,javafx在尝试绘制/渲染时开始崩溃:

java.lang.NullPointerException: Cannot invoke "com.sun.prism.RTTexture.createGraphics()" because "<local9>" is null
at javafx.graphics/com.sun.javafx.sg.prism.NGCanvas$RenderBuf.validate(NGCanvas.java:214)
at javafx.graphics/com.sun.javafx.sg.prism.NGCanvas.initCanvas(NGCanvas.java:644)
at javafx.graphics/com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:607)
at javafx.graphics/com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2072)
(...)

和类似的(都与javafx.graphics/com.sun.javafx.sg.prism.ngcanvas相关)。现在,在过去(例如这里)已经有一些关于这类东西的讨论,并且有一半的互联网基本上只是通过关闭硬件加速来回答这个问题,这就是flags所喜欢的 -Dprism.order=sw 去吧。
我认为这不是答案。
我的图形硬件支持16384x16384纹理(至少在opengl驱动程序中)和8gb的vram。我甚至编写了一个小的测试程序来验证这是“真正的”支持,并工作,因为我在过去被一些劣质的集成笔记本电脑的图形设备烧毁了,这些设备声称支持opengl-v3兼容,但当有人试图分配一个8k+纹理时崩溃了。我的电脑里只有一个显卡,所以javafx应用程序不可能使用错误的设备。
当我将画布对象从4156x4156调整到8252x8252时,我的应用程序崩溃。即使我们接受,它将使用两个大小的下一个更高的权力来渲染这些东西,我声称,我的硬件应该能够处理这个设置。即使是多个16384x16384纹理也可以很容易地与其他东西一起放入内存。
我在windows10上,在版本15.0.1中使用openjdk和javafx,尽管canvas很旧,这应该不是问题。
有人知道这里到底发生了什么吗?
编辑:正如评论中所建议的,我做了一些更精确的测试。对这两个画布对象使用硬编码大小进行进一步的手动测试,结果如下:
将两者都设置为4096x4096和4097x4097都有效。记住,后者应该在内部使用纹理8192x8192,因为这是图形卡的工作方式。内部是指在显卡上,而不是其他任何地方。
不过,这里很有趣:
将两个画布对象中的一个设置为8192x8192(另一个设置为2x2)也可以正常工作。将两者都设置为8192x8192不起作用,从而导致上述空值问题。
这表明这毕竟是一个记忆问题,可能与分配有关。不过,如前所述,图形设备应该能够处理这个问题,而且似乎也能够处理,考虑到将两者都设置为4097x4097是可行的。我怀疑这是java方面的问题,可能与堆栈窗格有关。有人知道stackpane是否有某种内部像素阵列或其他机制吗?可能检测到变化?显然,这将是非常不幸的,因为它与硬件加速纹理的使用背道而驰。
此外,我还使用 -Dprism.order=sw . 从4156x4156到8252x8252的转换确实在该模式下工作。当进一步推进(仅用于实验目的)时,最终会出现完全相同的问题,再次表明内存问题。
我可以选择只使用一个画布,并在其中更经常地重新绘制,以减少内存占用(猜测性能权衡在这里是好的),但我想首先了解到底是什么是在这里非常错误的。。。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题