2011-01-07 38 views
17

He estado estudiando las características de aceleración de hardware de Java, y todavía estoy un poco confundido ya que ninguno de los sitios que encontré en línea respondió claramente algunas de las preguntas que tengo. Así que aquí están las preguntas que tengo para la aceleración de hardware en Java:Java Hardware Acceleration

1) En Eclipse versión 3.6.0, con la actualización más reciente de Java para Mac OS X (creo que 1.6u10), ¿la aceleración de hardware está habilitada por defecto? He leído en alguna parte que

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

se supone que dará una indicación de si es o no la aceleración de hardware está habilitado, y mis informes del programa posterior cierto cuando que se ejecuta en mi caso principal lienzo para dibujar a. Si mi aceleración de hardware no está habilitada ahora, o de manera predeterminada, ¿qué tendría que hacer para habilitarla?

2) He visto un par de artículos aquí y allá sobre la diferencia entre una Imagen Buffered y VolatileImage, principalmente diciendo que VolatileImage es la imagen acelerada por hardware y se almacena en VRAM para operaciones de copia rápida. Sin embargo, también encontré algunas instancias donde se dice que BufferedImage también está acelerado por hardware. ¿El hardware de BufferedImage también se acelera en mi entorno? ¿Cuál sería la ventaja de usar una imagen volátil si ambos tipos están acelerados por hardware? Mi principal supuesto para la ventaja de tener una imagen volátil en el caso de que ambos tengan aceleración es que VolatileImage es capaz de detectar cuándo se ha abandonado su VRAM. Pero si BufferedImage también es compatible con la aceleración ahora, ¿no tendría también el mismo tipo de detección incorporada, simplemente oculto para el usuario, en caso de que la memoria se descargue?

3) ¿Hay alguna ventaja de utilizar

someGraphicsConfiguration.getCompatibleImage/getCompatibleVolatileImage() 

en contraposición a

ImageIO.read() 

En un tutorial que he estado leyendo para algunos conceptos generales sobre la configuración de la ventana de renderizado correctamente (tutorial) usa el método getCompatibleImage, que creo que devuelve una imagen Buffered, para obtener sus imágenes "aceleradas por hardware" para el dibujo rápido, que se relaciona con la pregunta 2 acerca de si es hardware acelerado.

4) Esto es menos aceleración de hardware, pero es algo que me ha llamado la atención: ¿necesito pedir qué gráficos se dibujan? Sé que al usar OpenGL a través de C/C++ es mejor asegurarse de que se dibuje el mismo gráfico en todas las ubicaciones que necesita dibujar de una vez para reducir el número de veces que la textura actual necesita ser cambiada. Por lo que he leído, parece que Java se ocupará de esto para mí y se asegurará de que las cosas se dibujen de la manera más óptima, pero una vez más, nada ha dicho algo como esto claramente.

5) ¿Qué clases de AWT/Swing admiten la aceleración de hardware, y cuáles deberían usarse? Actualmente estoy usando una clase que amplía JFrame para crear una ventana y agregarle un lienzo desde el cual creo una estrategia BufferStrategy. ¿Es esta una buena práctica, o hay algún otro tipo de forma en que debería implementar esto?

Muchas gracias por su tiempo, y espero haberles proporcionado preguntas claras y suficiente información para poder responder a mis varias preguntas.

Respuesta

16

1) Hasta ahora, la aceleración de hardware nunca está habilitada de forma predeterminada, y que yo sepa, no ha cambiado todavía. Para activar la aceleración de representación, pase esta arg (-Dsun.java2d.opengl = true) al iniciador de Java al iniciar el programa, o configúrelo antes de usar cualquier biblioteca de renderizado. System.setProperty("sun.java2d.opengl", "true"); Es un parámetro opcional.

2) Sí BufferedImage encapsula algunos de los detalles de la gestión de la memoria volátil, ya que, cuando el BufferdImage se acelera una copia del mismo se almacena en V-RAM como VolatileImage.

La ventaja de un BufferedImage es todo el tiempo que no está ensuciando con los píxeles que contiene, simplemente copiarlos como una llamada a graphics.drawImage(), entonces el BufferedImage se aceleró después de un cierto no se especifica el número de copias y se gestionará el VolatileImage para usted.

La desventaja de un BufferedImage es si usted está haciendo la edición de imágenes, cambiar los píxeles de la BufferedImage, en algunos casos, se dará por vencido tratando de acelerarlo, en ese momento si usted está buscando para la representación performant para su edición que necesita considerar administrar su propio VolatileImage. No sé qué operaciones hacen que el BufferedImage se rinda al tratar de acelerar el procesamiento por usted.

3) La ventaja de utilizar el createCompatibleImage()/createCompatibleVolatileImage() es que ImageIO.read() no hace ninguna conversión a una imagen de modelo de datos soportados por omisión. Por lo tanto, si importa un PNG, lo representará en el formato creado por el lector de PNG. Esto significa que cada vez que es procesada por un GraphicsDevice primero debe convertirse a un Modelo de Datos de Imagen compatible.

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

El proceso anterior se convertir una imagen leída con la imagen io API a una BufferedImage que tiene un modelo de datos de imagen compatible con el dispositivo de pantalla por defecto por lo que la conversión no tiene por qué tener lugar cuando cada vez que se hace . Los momentos en que esto es más ventajoso es cuando va a renderizar la imagen con mucha frecuencia.

4) No necesita hacer un esfuerzo para agrupar el procesamiento de su imagen porque, en su mayor parte, Java intentará hacer esto por usted. No hay ninguna razón por la cual no pueda intentar hacer esto, pero en general es mejor perfilar sus aplicaciones y confirmar que hay un cuello de botella en el código de representación de la imagen antes de intentar llevar a cabo una optimización del rendimiento como esta. La principal desventaja es que se puede implementar de forma ligeramente diferente en cada JVM y, a continuación, las mejoras pueden ser inútiles.

5) Según mi leal saber y entender, el diseño que ha descrito es una de las mejores estrategias que existe cuando se realiza Double Buffering de forma manual y se representa activamente una aplicación. http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferStrategy.html En este enlace encontrará una descripción del BufferStrategy.En la descripción, muestra un fragmento de código que es la forma recomendada de hacer una representación activa con un objeto BufferStrategy. Utilizo esta técnica particular para mi código de renderizado activo. La única diferencia importante es eso en mi código. como usted, he creado el BufferStrategy en una instancia de Canvas que puse en JFrame.

+0

¿Hay alguna razón en particular por la que la mayoría de los ejemplos usen un JFrame para almacenar el lienzo? Por lo que entendí, Swing es bastante terrible. ¿Por qué no usarías un Marco? Tengo un código que hace exactamente eso, y parece que no es más difícil de crear que un JFrame. Además, ¿cómo se habilita la aceleración de hardware si no es por defecto? – Freezerburn

+0

@FreezerBurn No sé por qué la mayoría de los ejemplos usan JFrame vs Frame. Me imagino que se hace con un JFrame porque eso es lo que se conoce más comúnmente. Esto es solo una especulación, pero supongo que la renderización manual en Java con solo un contenedor de nivel superior (JFrame, Frame, etc.) y un lienzo, hay poca diferencia entre cuál elegir. Para activar la aceleración de representación pase este arg (-Dsun.java2d.opengl = true) al iniciador de Java al iniciar el programa, o para configurarlo antes de usar cualquier biblioteca de renderizado. (System.setProperty ("sun.java2d.opengl", "true");) Es un parámetro opcional. – Zixradoom

+0

JFrame es Swing donde Frame/Canvas es AWT. Swing es la biblioteca de componentes más nueva y AWT es la antigua biblioteca obsoleta. Swing utiliza componentes livianos donde AWT son componentes nativos. JFrame prefería los componentes AWT más antiguos. – chubbsondubs

2

A juzgar por algunos older documentation, puede indicar en las JVM de Sun si la aceleración de hardware está activada o no marcando la propiedad sun.java2d.opengl.

Lamentablemente, no sé si esto se aplica a Apple JVM.

se puede comprobar si una imagen individual es acelerado por hardware usando Image 's getCapabilities(GraphicsConfiguration).isAccelerated()

Una vez dicho todo esto, toda la documentación que he visto (incluyendo this one) implica que BufferedImage es no acelerada por hardware. Swing también se ha cambiado para usar VolatileImage s para su doble buffer por esta misma razón.

+0

¿Dónde encontraría la propiedad sun.java2d.opengl? Lo he visto mencionar, pero nunca supe dónde buscarlo o ponerlo para asegurarme de que esté habilitado en Mac/Eclipse. Además: http://download.oracle.com/javase/1.5.0/docs/guide/2d/new_features.html dice que las imágenes Buffered se administran en 1.5.0 y se almacenan en la memoria de video. – Freezerburn

+0

Veamos ... Creo que es 'System.getProperty (" sun.java2d.opengl ")' para obtener el valor de la propiedad. En cuanto a 'BufferedImage', dijo que se puede almacenar en la memoria de video pero no dice nada acerca de realmente manipularlo más allá de eso. – Powerlord

+0

Imprimir la salida de getProperty me da "nulo" a la consola. Por lo que entiendo acerca de cómo funciona la aceleración en Java, ¿estaría BufferedImage en la memoria de video permitiendo la rápida copia que se supone que tiene VolatileImage? Supongo que sería el caso si usa copia de video a video. – Freezerburn

Cuestiones relacionadas