首页 > 解决方案 > Java Graphics2D 仅在使用 nvidia-* 驱动程序时闪烁 (Ubuntu)

问题描述

当使用 java Graphics2D 绘制到屏幕上时,我的 JFrame 内随机出现一个全黑窗口。当我尝试移动我正在绘制的图像时,它会更频繁地发生。我正在使用 JPanel 并覆盖 PaintComponent 并切换到具有缓冲策略的 Canvas。我在任何一种情况下都会闪烁。BufferStrategy 设置为 2。我每 40 毫秒使用一次 SwingTimer 绘图,我尝试对此进行节流,即使设置为非常高的延迟(例如 4 秒)也没有什么区别。只有在带有 GTX 1050 ti 的 Ubuntu 20.04 上使用任何专有的 nvidia 驱动程序时才会发生这种情况。我尝试清除并重新安装驱动程序我尝试了其他驱动程序下的所有可用驱动程序以及从 nvidia 的站点安装。如果我使用我的 APU 嵌入式图形,则不会出现此问题,在具有嵌入式 radeon 图形的笔记本电脑上进行测试时,也不会出现此问题。这是我的绘图方式:

 bf = getBufferStrategy();
        Graphics2D g = (Graphics2D) bf.getDrawGraphics();

        do {
            try{

                g.clearRect(0,0,getWidth(),getHeight());

                //Drawing Loading
                if(c.getLoading()){
                    drawLoading(g);
                }

                //Draw Login
                if(c.getShowLogin()){
                    drawLogin(g);
                }

                if(c.drawGame()){
                    drawGame(g);
                }


            } finally {
                g.dispose();
            }
            bf.show();
        } while (bf.contentsLost());

我尝试在 nvidia-settings 应用程序下更改功率级别和 openGL 性能,但没有成功。

[编辑] 顺便说一句 java: openjdk 11.0.8 2020-07-14 在两台机器上测试过。

标签: java

解决方案


我觉得很傻,我查看了 BufferStrategy 的 JavaDoc,看看我是否遗漏了一些明显的东西。它们包括一个示例,该示例具有一个内部 do-while 循环,该循环检查缓冲区内容是否已恢复,因此我将渲染循环更改为:

bf = getBufferStrategy();

do {
    
    do {

        Graphics2D g = (Graphics2D) bf.getDrawGraphics();

        g.clearRect(0,0,getWidth(),getHeight());

        //Drawing Loading
        if(c.getLoading()){
            drawLoading(g);
        }

        //Draw Login
        if(c.getShowLogin()){
            drawLogin(g);
        }

        if(c.drawGame()){
            drawGame(g);
        }

        g.dispose();

    } while (bf.contentsRestored());

    bf.show();
    
} while (bf.contentsLost());

到目前为止没有闪烁。Java 文档:缓冲区策略

[编辑] 我很快就和我谈过了。我仍然收到间歇性闪烁。如果有帮助,这些是我的虚拟机选项: -Dsun.java2d.opengl=True -Xms256m -Xmx2048m 没有 opengl=True 它真的很糟糕,不断闪烁。

关闭 Chrome 并将游戏的服务器端与 intellij idea 分离后,我看不到闪烁。我将其归结为我的环境并且不可重复(客户端正在拉 30% cpu 最大平均 15%),希望如此。


推荐阅读