Accélération matérielle Java

J’ai passé un certain temps à examiner les fonctionnalités d’accélération matérielle de Java et je suis encore un peu confus, car aucun des sites que j’ai trouvés en ligne directement ne répondait clairement à certaines de mes questions. Voici donc les questions que j’ai sur l’accélération matérielle en Java:

1) Dans Eclipse version 3.6.0, avec la mise à jour Java la plus récente pour Mac OS X (1.6u10, je pense), l’accélération matérielle est-elle activée par défaut? Je lis quelque part que

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

est censé indiquer si l’accélération matérielle est activée ou non, et mon programme renvoie la valeur true lorsque celle-ci est exécutée sur mon instance principale de Canvas. Si mon accélération matérielle n’est pas activée maintenant ou par défaut, que devrais-je faire pour l’activer?

2) J’ai vu quelques articles ici et là sur la différence entre BufferedImage et VolatileImage, indiquant principalement que VolatileImage est l’image à accélération matérielle et est stockée dans la mémoire VRAM pour une copie rapide à partir d’une opération. Cependant, j’ai également constaté que BufferedImage était également accéléré matériellement. Le matériel BufferedImage est-il également accéléré dans mon environnement? Quel serait l’avantage d’utiliser VolatileImage si les deux types sont accélérés par le matériel? Ma principale hypothèse sur l’avantage d’avoir une VolatileImage dans le cas où les deux ont une accélération est que VolatileImage est capable de détecter le vidage de sa VRAM. Mais si BufferedImage supporte également l’accélération maintenant, n’aurait-il pas le même type de détection intégré, juste caché à l’utilisateur, au cas où la mémoire serait vidée?

3) Y at-il un avantage à utiliser

 someGraphicsConfiguration.getCompatibleImage/getCompatibleVolatileImage() 

par opposition à

 ImageIO.read() 

Dans un tutoriel, je lisais quelques concepts généraux sur la configuration correcte de la fenêtre de rendu ( tutorial ), qui utilise la méthode getCompatibleImage, qui, je crois, renvoie un BufferedImage, pour obtenir leurs images à “accélération matérielle” permettant un dessin rapide, ce qui est problématique. 2 sur si le matériel est accéléré.

4) C’est moins d’accélération matérielle, mais c’est quelque chose qui m’insortinggue: dois-je commander quels graphiques sont dessinés? Je sais que lorsque vous utilisez OpenGL via C / C ++, il est préférable de s’assurer que le même graphique est dessiné dans tous les emplacements à dessiner en même temps afin de réduire le nombre de changements de texture actuels. D’après ce que j’ai lu, il semble que Java s’en occupe pour moi et s’assure que les choses sont dessinées de la manière la plus optimale, mais encore une fois, rien de tel n’a été dit clairement.

5) Quelles classes AWT / Swing prennent en charge l’accélération matérielle et lesquelles doivent être utilisées? J’utilise actuellement une classe qui étend JFrame pour créer une fenêtre et y ajoute un canevas à partir duquel je crée une BufferStrategy. S’agit-il d’une bonne pratique ou existe-t-il un autre moyen de mettre cela en œuvre?

Merci beaucoup pour votre temps, et j’espère avoir fourni des questions claires et suffisamment d’informations pour que vous puissiez répondre à plusieurs de mes questions.

1) Jusqu’à présent, l’accélération matérielle n’est jamais activée par défaut et, à ma connaissance, elle n’a pas encore changé. Pour activer l’accélération de rendu, transmettez cet argument (-Dsun.java2d.opengl = true) au programme de lancement Java au démarrage du programme ou définissez-le avant d’utiliser une bibliothèque de rendu. System.setProperty("sun.java2d.opengl", "true"); C’est un paramètre optionnel.

2) Oui BufferedImage encapsule certains des détails de la gestion de la mémoire volatile, car lorsque cette BufferdImage est accélérée, une copie de celle-ci est stockée dans V-Ram en tant que VolatileImage .

L’intérêt d’une image BufferedImage est que tant que vous ne manipulez pas les pixels qu’elle contient, il suffit de les copier comme un appel à graphics.drawImage() . Ensuite, l’image BufferedImage sera accélérée après un certain nombre de copies non spécifiées et sera gérée. le VolatileImage pour vous.

L’inconvénient d’une image BufferedImage est que si vous modifiez les images en modifiant l’image BufferedImage , dans certains cas, vous aurez tendance à renoncer à l’accélérer. À ce stade, si vous recherchez un rendu performant pour votre édition, vous devez envisager de la gérer. votre propre VolatileImage . Je ne sais pas quelles opérations font que BufferedImage renonce à essayer d’accélérer le rendu pour vous.

3) L’avantage d’utiliser createCompatibleImage()/createCompatibleVolatileImage() est ImageIO.read() n’effectue aucune conversion en un modèle de données d’image pris en charge par défaut. Donc, si vous importez un fichier PNG, il le représentera dans le format créé par le lecteur PNG. Cela signifie que chaque fois qu’il est rendu par un GraphicsDevice il doit d’abord être converti en un modèle de données d’image 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() 

Le processus ci-dessus convertit une image lue avec l’image io api en une image BufferedImage comportant un modèle de données d’image compatible avec le périphérique d’écran par défaut, de sorte que la conversion ne doit pas nécessairement avoir lieu à chaque rendu. Les moments où cela est le plus avantageux sont ceux où vous allez rendre l’image très fréquemment.

4) Vous n’avez pas besoin de faire un effort pour regrouper votre rendu d’image, car Java essaiera de le faire pour vous. Il n’y a aucune raison pour que vous ne puissiez pas tenter cela, mais en général, il est préférable de profiler vos applications et de confirmer qu’il existe un goulot d’étranglement au niveau du code de rendu des images avant d’essayer de réaliser une optimisation des performances telle que celle-ci. Le principal inconvénient est qu’il est implémenté de manière légèrement différente dans chaque JVM et que les améliorations pourraient ne pas être utiles.

5) Au mieux de mes connaissances, la conception que vous avez décrite est l’une des meilleures stratégies disponibles lors de la double mise en mémoire tampon manuelle et du rendu actif d’une application. http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferStrategy.html Ce lien BufferStrategy une description de BufferStrategy . Dans la description, un BufferStrategy code est recommandé pour effectuer un rendu actif avec un object BufferStrategy . J’utilise cette technique particulière pour mon code de rendu actif. La seule différence majeure est que dans mon code. Comme vous, j’ai créé la BufferStrategy sur une instance de Canvas que je mets sur un JFrame .

À en juger par une documentation plus ancienne , vous pouvez déterminer sur les sun.java2d.opengl si l’accélération matérielle est sun.java2d.opengl ou non en vérifiant la propriété sun.java2d.opengl .

Malheureusement, je ne sais pas si cela s’applique à la JVM Apple.

Vous pouvez vérifier si une image individuelle est accélérée par le matériel en utilisant getCapabilities(GraphicsConfiguration).isAccelerated()

Ceci dit, toute la documentation que j’ai vue (y compris celle-ci ) implique que BufferedImage n’est pas accélérée matériellement. Swing a également été modifié pour utiliser VolatileImage s pour sa double mise en mémoire tampon pour cette raison même.