英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论