Java硬件加速

我花了一些时间研究Java的硬件加速function,我仍然有点困惑,因为我没有直接在网上找到的网站,并清楚地回答了我的一些问题。 以下是我对Java硬件加速的问题:

1)在Eclipse版本3.6.0中,使用最新的Mac OS X Java更新(我认为1.6u10),默认情况下是否启用了硬件加速? 我读到了某个地方

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加速时,它的副本作为VolatileImage存储在V-Ram中。

BufferedImage的好处就在于你没有弄乱它所包含的像素,只是像调用graphics.drawImage()一样复制它们,然后BufferedImage将在一定的非指定数量的副本之后加速并且它将管理VolatileImage适合你。

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中的实现方式略有不同,然后增强function可能毫无价值。

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

从一些较旧的文档判断,您可以通过检查sun.java2d.opengl属性来判断Sun JVM是否启用了硬件加速。

不幸的是,我不知道这是否适用于Apple JVM。

您可以使用ImagegetCapabilities(GraphicsConfiguration).isAccelerated()来检查单个图像是否是硬件加速的getCapabilities(GraphicsConfiguration).isAccelerated()

说完这一切之后,我见过的所有文档(包括这一篇 )都暗示BufferedImage 不是硬件加速的。 由于这个原因,Swing也被改为使用VolatileImage进行双缓冲。