Java Graphics2D flicker only when using nvidia-* drivers (Ubuntu)

huangapple go评论76阅读模式
英文:

Java Graphics2D flicker only when using nvidia-* drivers (Ubuntu)

问题

使用Java的Graphics2D绘制到屏幕时,我在我的JFrame内部随机地得到一个全黑的窗口。当我尝试移动我正在绘制的图像时,这种情况发生得更频繁。我曾经使用一个JPanel并重写了PaintComponent,然后切换到了带有缓冲策略的Canvas。无论在哪种情况下,我都会出现闪烁。缓冲策略设置为2。我使用SwingTimer每40毫秒绘制一次,我尝试了限制它,但没有任何区别,即使将延迟设置为非常高,比如4秒。只有在Ubuntu 20.04上使用任何专有的NVIDIA驱动程序时才会发生这种情况,配备了GTX 1050 ti。我尝试过卸载并重新安装驱动程序,我尝试过所有可用的附加驱动程序,以及从NVIDIA的网站安装驱动程序。如果我使用APU的集成图形,就不会出现这个问题,在测试嵌有Radeon图形的笔记本电脑上也不会出现这个问题。以下是我的绘图方式:

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

do {
    try {

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

        //绘制加载
        if (c.getLoading()) {
            drawLoading(g);
        }

        //绘制登录界面
        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),在测试的两台机器上都是这个版本。

英文:

When using java Graphics2D to draw to the screen I am getting an all black window inside my JFrame randomly. It happens more often when I try moving the images I am drawing. I was using a JPanel and overriding PaintComponent and switched to a Canvas with a buffer strategy. I get flicker in either situation. BufferStrategy is set to 2. I am drawing using a SwingTimer every 40ms, I tried throttling this it makes no difference, even if set to a really high delay such as 4 seconds. This only happens when using any of the proprietary nvidia drivers on Ubuntu 20.04 with a GTX 1050 ti. I tried purging and reinstalling the drivers I tried all the available ones under additional drivers as well as installing from nvidia's site. If I use my APUs embedded graphics this issue doesn't arise, This issue also does not occur when testing on a laptop with embedded radeon graphics. Here is how I am drawing:

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

I tried changing power levels and openGL performance under nvidia-settings application with no luck.

[Edit] By the way java: openjdk 11.0.8 2020-07-14 on both machines tested.

答案1

得分: 1

我感觉相当傻,我查看了BufferStrategy的JavaDoc,看看是否有什么明显的遗漏。他们包含了一个示例,其中有一个内部的do-while循环,用于检查缓冲区内容是否已恢复,所以我将我的渲染循环更改为:

bf = getBufferStrategy();

do {

    do {

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

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

        //绘制加载
        if(c.getLoading()){
            drawLoading(g);
        }

        //绘制登录界面
        if(c.getShowLogin()){
            drawLogin(g);
        }

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

        g.dispose();

    } while (bf.contentsRestored());

    bf.show();

} while (bf.contentsLost());

到目前为止还没有闪烁。Java文档:BufferStrategy

[编辑] 我说得太早了... 我仍然会偶尔出现闪烁。如果有帮助的话,这些是我的虚拟机选项:-Dsun.java2d.opengl=True -Xms256m -Xmx2048m。没有设置opengl=True的话,闪烁非常严重。

在关闭Chrome并从IntelliJ IDEA分离游戏的服务器端之后,我就不再看到闪烁。我把这归因于我的环境,可能不是可重复的(客户端最多使用30%的CPU,平均使用15%),希望是这样的。

英文:

I feel pretty silly, I looked over the JavaDoc for BufferStrategy to see if I was missing something obvious. They include an example which has an inner do-while loop that checks if the buffer contents are restored so I changed my rendering loop to:

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

So far no flickering.
Java Doc: BufferStrategy

[Edit] I spoke to soon.. I am still receiving intermittent flicker. If it helps these are my VM options: -Dsun.java2d.opengl=True -Xms256m -Xmx2048m
Without opengl=True its really bad constant flickering.

After closing Chrome, and detaching the Server side of the game from intellij idea I don't see flicker. I am chalking this up as my environment and not repeatable (Client is pulling 30% cpu max average 15%), hopefully.

huangapple
  • 本文由 发表于 2020年10月6日 05:48:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/64216664.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定