Java硬件加速 [英] Java Hardware Acceleration

查看:152
本文介绍了Java硬件加速的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了一些时间研究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。这是一种很好的做法,还是有其他一些我应该实施的方式?



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

解决方案

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

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



的副本 BufferedImage 只要你没有搞乱它包含的像素,只需像调用 graphics.drawImage(),那么 BufferedImage 会在某个非指定数量的副本之后加速,并且会为您管理 VolatileImage $ b

对于 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)
据我所知,当您手动执行Double Buffering并主动渲染应用程序时,您所概述的设计是更好的策略之一。
http://docs.oracle.com/javase/ 7 / docs / api / java / awt / image / BufferStrategy.html
在此链接中,您可以找到 BufferStrategy 的说明。在描述中,它显示了一个代码片段,它是使用 BufferStrategy 对象进行主动渲染的推荐方式。我将这种特殊技术用于我的主动渲染代码。唯一的主要区别是在我的代码中。像你一样,我已经在一个 Canvas 的实例上创建了 BufferStrategy ,并在 JFrame


I have been spending some time looking into the hardware acceleration features of Java, and I am still a bit confused as none of the sites that I found online directly and clearly answered some of the questions I have. So here are the questions I have for hardware acceleration in Java:

1) In Eclipse version 3.6.0, with the most recent Java update for Mac OS X (1.6u10 I think), is hardware acceleration enabled by default? I read somewhere that

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

is supposed to give an indication of whether or not hardware acceleration is enabled, and my program reports back true when that is run on my main Canvas instance for drawing to. If my hardware acceleration is not enabled now, or by default, what would I have to do to enable it?

2) I have seen a couple articles here and there about the difference between a BufferedImage and VolatileImage, mainly saying that VolatileImage is the hardware accelerated image and is stored in VRAM for fast copy-from operations. However, I have also found some instances where BufferedImage is said to be hardware accelerated as well. Is BufferedImage hardware accelerated as well in my environment? What would be the advantage of using a VolatileImage if both types are hardware accelerated? My main assumption for the advantage of having a VolatileImage in the case of both having acceleration is that VolatileImage is able to detect when its VRAM has been dumped. But if BufferedImage also support acceleration now, would it not have the same kind of detection built into it as well, just hidden from the user, in case that the memory is dumped?

3) Is there any advantage to using

someGraphicsConfiguration.getCompatibleImage/getCompatibleVolatileImage()

as opposed to

ImageIO.read()

In a tutorial I have been reading for some general concepts about setting up the rendering window properly (tutorial) it uses the getCompatibleImage method, which I believe returns a BufferedImage, to get their "hardware accelerated" images for fast drawing, which ties into question 2 about if it is hardware accelerated.

4) This is less hardware acceleration, but it is something I have been curious about: do I need to order which graphics get drawn? I know that when using OpenGL via C/C++ it is best to make sure that the same graphic is drawn in all the locations it needs to be drawn at once to reduce the number of times the current texture needs to be switch. From what I have read, it seems as if Java will take care of this for me and make sure things are drawn in the most optimal fashion, but again, nothing has ever said anything like this clearly.

5) What AWT/Swing classes support hardware acceleration, and which ones should be used? I am currently using a class that extends JFrame to create a window, and adding a Canvas to it from which I create a BufferStrategy. Is this good practice, or is there some other type of way I should be implementing this?

Thank you very much for your time, and I hope I provided clear questions and enough information for you to answer my several questions.

解决方案

1) So far hardware acceleration is never enabled by default, and to my knowledge it has not changed yet. To activate rendering acceleration pass this arg (-Dsun.java2d.opengl=true) to the Java launcher at program start up, or set it before using any rendering libraries. System.setProperty("sun.java2d.opengl", "true"); It is an optional parameter.

2) Yes BufferedImage encapsulates some of the details of managing the Volatile Memory because, when the BufferdImage is accelerated a copy of it is stored in V-Ram as a VolatileImage.

The upside to a BufferedImage is as long as you are not messing with the pixels it contains, just copying them like a call to graphics.drawImage(), then the BufferedImage will be accelerated after a certain non specified number of copies and it will manage the VolatileImage for you.

The downside to a BufferedImage is if you are doing image editing, changing the pixels in the BufferedImage, in some cases it will give up trying to accelerate it, at that point if you are looking for performant rendering for your editing you need to consider managing your own VolatileImage. I do not know which operations make the BufferedImage give up on trying to accelerate rendering for you.

3) The advantage of using the createCompatibleImage()/createCompatibleVolatileImage() is that ImageIO.read() does not do any conversion to a default supported Image Data Model. So if you import a PNG it will represent it in the format built by the PNG reader. This means that every time it is rendered by a GraphicsDevice it must first be converted to a compatible Image Data Model.

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

The above process will convert an image read in with the image io api to a BufferedImage that has a Image Data Model compatible with the default screen device so that conversion does not need to take place when ever it is rendered. The times when this is most advantageous is when you will be rendering the image very frequently.

4) You do not need to make an effort to batch your image rendering because for the most part Java will attempt to do this for you. There is no reason why you cant attempt to do this but in general it is better to profile your applications and confirm that there is a bottleneck at the image rendering code before you attempt to carry out a performance optimization such as this. The main disadvantage is that it my be implemented slightly differently in each JVM and then the enhancements might be worthless.

5) To the best of my knowledge the design you have outlined is one of the better strategies out there when doing Double Buffering manually and actively rendering an application. http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferStrategy.html At this link you will find a description of the BufferStrategy. In the description it shows a code snippet that is the recommended way to do active rendering with a BufferStrategy object. I use this particular technique for my active rendering code. The only major difference is that in my code. like you, I have created the BufferStrategy on an instance of a Canvas which I put on a JFrame.

这篇关于Java硬件加速的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆