20

我一直在研究 Java 的硬件加速特性,但我仍然有点困惑,因为我在网上找到的网站都没有直接明确回答我的一些问题。以下是我对 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。这是一种很好的做法,还是我应该以其他方式来实现它?

非常感谢您抽出宝贵时间,我希望我提供了明确的问题和足够的信息,以便您回答我的几个问题。

4

2 回答 2

18

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

2) YesBufferedImage封装了管理易失性内存的一些细节,因为当BufferdImage加速时,它的副本作为VolatileImage.

a 的好处BufferedImage是,只要您不弄乱它包含的像素,只需像调用 那样复制它们graphics.drawImage(),然后在BufferedImage一定数量的非指定副本后加速,它会VolatileImage为您管理。

a 的缺点BufferedImage是,如果您正在进行图像编辑,更改BufferedImage. VolatileImage. 我不知道哪些操作让BufferedImage你放弃了为你加速渲染的尝试。

3) 使用的优点createCompatibleImage()/createCompatibleVolatileImage()ImageIO.read()不会对默认支持的图像数据模型进行任何转换。因此,如果您导入 PNG,它将以 PNG 阅读器构建的格式表示。这意味着每次由 a 渲染时,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对象进行主动渲染的推荐方法。我将这种特殊技术用于我的活动渲染代码。唯一的主要区别是在我的代码中。像你一样,我创建了一个我放在 a 上的 aBufferStrategy实例。CanvasJFrame

于 2012-12-12T04:30:20.857 回答
2

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

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

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

说了这么多,我看到的所有文档(包括这个)都暗示它BufferedImage不是硬件加速的。出于这个原因, Swing 也已更改为使用VolatileImages 进行双缓冲。

于 2011-01-07T16:02:35.333 回答