Accélération Matérielle Java


J'ai passé du 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 n'a répondu directement et clairement à certaines des questions que j'ai. Voici donc les questions que j'ai pour l'accélération matérielle en Java:

1) Dans la version Eclipse 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? J'ai lu quelque part que

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

Est supposé pour donner une indication de si l'accélération matérielle est activée ou non, et mon programme renvoie true lorsque cela est exécuté sur mon instance principale de Canevas pour le dessin. 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 un BufferedImage et VolatileImage, disant principalement que VolatileImage est l'image accélérée par le matériel et est stockée dans VRAM pour une copie rapide opérations. Cependant, j'ai également trouvé des cas où BufferedImage est également accéléré par le matériel. BufferedImage est-il également accéléré dans mon environnement? Quel serait l'avantage d'utiliser un VolatileImage si les deux types sont accélérés par le matériel? Mon hypothèse principale pour l'avantage d'avoir une VolatileImage dans le cas des deux ayant une accélération est que VolatileImage est capable de détecter quand sa VRAM a été vidée. Mais si BufferedImage prend également en charge 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 a-t-il un avantage à utiliser

someGraphicsConfiguration.getCompatibleImage/getCompatibleVolatileImage()

, par opposition à

ImageIO.read()

Dans un tutoriel que j'ai lu pour quelques concepts généraux sur la configuration correcte de la fenêtre de rendu (tutorial), il utilise la méthode getCompatibleImage, qui, je crois, renvoie un BufferedImage, pour obtenir leurs images" accélérées matérielles " rapidement dessin, qui se lie à la question 2 à savoir si elle est accélérée par le matériel.

4) C'est moins d'accélération matérielle, mais c'est quelque chose qui m'a curieux: dois-je commander quels graphiques sont dessinés? Je sais que lors de l'utilisation d'OpenGL via C/C++, il est préférable de s'assurer que le même graphique est dessiné à tous les endroits où il doit être dessiné à la fois pour réduire le nombre de fois où la texture actuelle doit être commutée. D'après ce que j'ai lu, il semble que Java s'en occupe pour moi et assurez-vous que les choses sont dessinées de la manière la plus optimale, mais encore une fois, rien n'a jamais dit quelque chose comme ça 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. Est-ce une bonne pratique, ou y a-t-il un autre type de moyen que je devrais mettre 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 à mes nombreuses questions.

Author: Zixradoom, 2011-01-07

2 answers

1) La mesure de l'accélération matérielle n'est jamais activé par défaut, et à ma connaissance il n'a pas encore changé. Pour activer l'accélération du rendu, passez cet arg (- Dsun.java2d. opengl=true) au lanceur Java au démarrage du programme, ou définissez-le avant d'utiliser des bibliothèques de rendu. System.setProperty("sun.java2d.opengl", "true"); C'est un paramètre optionnel.

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

L'envers d'un BufferedImage est tant que vous ne jouez pas avec les pixels qu'il contient, il suffit de les copier comme un appel à graphics.drawImage(), puis le BufferedImage sera accéléré après un certain nombre non spécifié de copies et il gérera le VolatileImage pour vous.

L'inconvénient d'un BufferedImage est que si vous faites de l'édition d'image, en changeant les pixels dans le BufferedImage, dans certains cas, il renoncera à essayer de l'accélérer, à ce moment-là si vous recherchez un rendu performant pour votre édition vous devez envisager de gérer votre propre VolatileImage. Je ne sais pas quelles opérations font renoncer le BufferedImage à essayer d'accélérer le rendu pour vous.

3) L'avantage d'utiliser le createCompatibleImage()/createCompatibleVolatileImage() est-ce que ImageIO.read() ne fait aucune conversion vers un modèle de données d'image pris en charge par défaut. Donc, si vous importez un PNG, il le représentera dans le format construit par le lecteur PNG. Cela signifie que chaque fois qu'il est rendu par un GraphicsDevice, il doit d'abord être converti en données d'image compatibles Modèle.

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 convertira une image lue avec l'api image io en un BufferedImage qui a un Modèle de Données d'image compatible avec le périphérique d'écran par défaut afin que la conversion n'ait pas besoin d'avoir lieu quand elle est rendue. Les moments où cela est le plus avantageux est quand vous serez rendu l'image très fréquemment.

4) Vous n'avez pas besoin de faire un effort pour grouper votre rendu d'image car pour la plupart Java tentera de le faire pour vous. Il n'y a aucune raison pour laquelle vous ne pouvez pas essayer de le faire, 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 d'image avant de tenter d'effectuer une optimisation des performances telle que celle-ci. Le principal inconvénient est qu'il soit implémenté légèrement différemment dans chaque JVM et que les améliorations pourraient être sans valeur.

5) À ma connaissance la conception que vous avez décrite est l'une des meilleures stratégies disponibles lorsque vous effectuez une double mise en mémoire tampon manuellement et le rendu actif d'une application. http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferStrategy.html Sur ce lien, vous trouverez une description du BufferStrategy. Dans la description, il montre un extrait de code qui est la façon recommandée de faire un rendu actif avec un objet 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éé le {[16] } sur une instance de un Canvas que j'ai mis sur un JFrame.

 16
Author: Zixradoom, 2014-10-01 12:31:47

À en juger par une documentation plus ancienne, vous pouvez dire sur les JVM Sun si l'accélération matérielle est activée 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 Image ' s getCapabilities(GraphicsConfiguration).isAccelerated()

Cela dit, toute la documentation que j'ai vue (y compris celui-ci) implique que BufferedImageest pas accéléré par le matériel. Swing a a également été modifié pour utiliser VolatileImage s pour sa double mise en mémoire tampon pour cette raison même.

 2
Author: Powerlord, 2015-11-30 20:28:16