Java硬件加速

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (19)

我花了一些时间研究Java的硬件加速功能,而且我仍然有点困惑,因为我没有直接在网上找到的网站,并且明确地回答了我的一些问题。所以下面是我在Java中使用硬件加速的问题:

1)在Eclipse 3.6.0版本中,最新的Mac OS X(1.6u10我认为)的Java更新默认启用了硬件加速功能?我在某处读过

someCanvas.getGraphicsConfiguration().getBufferCapabilities().isPageFlipping()

应该显示是否启用了硬件加速,并且当我的主Canvas实例上运行该程序以进行绘制时,我的程序将返回true。如果我的硬件加速现在还没有启用,或者默认情况下,我需要做些什么来启用它?

2)我在这里和那里看到了一些有关BufferedImage和VolatileImage之间区别的文章,主要是说VolatileImage是硬件加速映像,并存储在VRAM中用于快速复制操作。但是,我也发现了一些BufferedImage也被称为硬件加速的例子。BufferedImage硬件是否也在我的环境中加速?如果两种类型都是硬件加速,那么使用VolatileImage会有什么好处?我在拥有加速度的情况下拥有VolatileImage的优势的主要假设是,VolatileImage能够检测其VRAM已被转储的时间。但是,如果BufferedImage现在也支持加速,那么它是否也没有内置相同类型的检测,只是在用户隐藏的情况下,以防内存被转储?

3)使用有什么好处

someGraphicsConfiguration.getCompatibleImage/getCompatibleVolatileImage()

而不是

ImageIO.read()

在教程中,我一直在阅读关于正确设置渲染窗口的一些常规概念,它使用了getCompatibleImage方法(我相信这会返回一个BufferedImage),以获得用于快速绘制的“硬件加速”图像, 2关于是否硬件加速。

4)硬件加速比较少,但我一直很好奇:我是否需要订购绘制哪些图形?我知道当通过C / C ++使用OpenGL时,最好确保同一图形在所有需要同时绘制的位置绘制,以减少当前纹理需要切换的次数。从我所读的内容来看,似乎Java会为我照顾这件事,并确保以最优化的方式绘制事物,但是再一次,没有任何事情可以清楚地说明这一点。

5)什么AWT / Swing类支持硬件加速,哪些应该使用?我目前正在使用一个扩展JFrame的类来创建一个窗口,并在其中添加一个Canvas,从中创建一个BufferStrategy。这是好的做法吗,还是有其他一些我应该实施的方式?

非常感谢你的时间,并且我希望我提供了明确的问题和足够的信息来回答我的几个问题。

提问于
用户回答回答于

1)到目前为止,硬件加速从未默认启用,据我所知它还没有改变。激活渲染加速在程序启动时将此arg(-Dsun.java2d.opengl = true)传递给Java启动程序,或者在使用任何渲染库之前将其设置。System.setProperty("sun.java2d.opengl", "true");它是一个可选参数。

2)是BufferedImage封装了一些管理易失性存储器的细节,因为当BufferdImage它加速时,它的一个副本作为一个存储在V-Ram中VolatileImage

a的好处BufferedImage是,只要你没有搞乱它包含的像素,只是像打电话一样拷贝它们graphics.drawImage(),那么在BufferedImage一定数量的非拷贝之后,它会加速,并且它会VolatileImage为你管理。

a的缺点BufferedImage是,如果您正在进行图像编辑,更改像素BufferedImage,在某些情况下,它会放弃尝试加速它,此时,如果您正在寻找用于编辑的高性能渲染,则需要考虑管理自己的图像VolatileImage。我不知道哪些操作会BufferedImage放弃尝试为您加速渲染。

3)使用的优点createCompatibleImage()/createCompatibleVolatileImage()ImageIO.read()不会对默认支持的图像数据模型进行任何转换。所以如果你导入一个PNG,它将以PNG阅读器的格式表示它。这意味着每次渲染GraphicsDevice时都必须先将其转换为兼容的图像数据模型。

BufferedImage image = ImageIO.read ( url );
BufferedImage convertedImage = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment ();
GraphicsDevice gd = ge.getDefaultScreenDevice ();
GraphicsConfiguration gc = gd.getDefaultConfiguration ();
convertedImage = gc.createCompatibleImage (image.getWidth (), 
                                           image.getHeight (), 
                                           image.getTransparency () );
Graphics2D g2d = convertedImage.createGraphics ();
g2d.drawImage ( image, 0, 0, image.getWidth (), image.getHeight (), null );
g2d.dispose()

上述过程将把图像io api读入的图像转换为具有与默认屏幕设备兼容的图像数据模型的BufferedImage,以便在渲染时不需要进行转换。这种情况最有利的时候是你会非常频繁地渲染图像。

4)你不需要努力批量渲染图像,因为大多数情况下Java会尝试为你做这件事。没有理由不尝试这样做,但总的来说,在尝试执行性能优化之前,最好对应用程序进行配置并确认图像渲染代码存在瓶颈。主要的缺点是它在每个JVM中稍微有点不同,然后增强可能毫无价值。

5)据我所知,你所概述的设计是手动执行双缓冲和主动渲染应用程序时更好的策略之一。 http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferStrategy.html 在这个链接,你会发现一个描述BufferStrategy。在说明中,它显示了一个代码片段,这是推荐使用BufferStrategy对象进行主动渲染的方式。我将这种特殊技术用于我的主动渲染代码。唯一的主要区别是在我的代码中。和你一样,我创建了BufferStrategy上的一个实例Canvas,我穿上了JFrame

用户回答回答于

扫码关注云+社区