38 votes

Bitmap.Config.HARDWARE vs Bitmap.Config.RGB_565

API 26 ajoute une nouvelle option Bitmap.Config.HARDWARE:

Configuration spéciale, lors de la bitmap est uniquement stockée dans la mémoire graphique. Les Bitmaps dans cette configuration sont toujours immuable. Il est optimal pour cas, lorsque la seule opération avec l'image bitmap est de le dessiner sur une de l'écran.

Des Questions qui ne sont pas expliqué dans les docs:

  1. Faut-il TOUJOURS préfèrent désormais Bitmap.Config.HARDWAREplus Bitmap.Config.RGB_565 lorsque la vitesse est prioritaire et la qualité et la mutabilité ne le sont pas (par exemple pour les miniatures, etc)?
  2. N'des données de pixels d'après le décodage de l'utilisation de cette option en fait PAS consommer TOUTE la mémoire du tas et qui réside dans la mémoire GPU seulement? Si oui, cela semble pour enfin être un soulagement pour OutOfMemoryException de l'inquiétude quand travailler avec des images.
  3. Quelle est la qualité par rapport à RGB_565, RGBA_F16 ou ARGB_8888 doit-on s'attendre à partir de cette option?
  4. Est la vitesse de décodage lui-même le même/mieux/valeur par rapport à décodage avec RGB_565?
  5. (Merci @CommonsWare pour indiquer dans les commentaires) Ce serait passerait-il si nous dépasser GPU, de la mémoire lors du décodage d'une image à l'aide de cette option? Serait une exception est levée (peut-être le même OutOfMemoryException :)?

22voto

uval Points 2127

La Documentation et les public le code source n'est pas poussé encore Google git. Donc ma recherche est basée uniquement sur des informations partielles, certaines expériences, et sur ma propre expérience de portage de la JVM de différents appareils.

Mon test a créé une grande mutable Bitmap et copié dans un nouveau MATÉRIEL Bitmap sur un clic d'un bouton, l'ajouter dans une image de la liste. J'ai réussi à créer plusieurs instances de la grande bitmaps avant, il s'est écrasé.

J'ai été capable de le trouver dans la android-o-extrait-4 git push:

+struct AHardwareBuffer;
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer);
+#else
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROID) (const struct AHardwareBuffer *buffer);

Et la recherche de la documentation de AHardwareBuffer, sous le capot c'est la création d'un EGLClientBuffer soutenu par ANativeWindowBuffer (graphique natif tampon) dans Android de mémoire partagée ("ashmem"). Mais la mise en œuvre effective peut varier au niveau de l'équipement.

Pour les questions:

  1. Faut-il TOUJOURS préférer maintenant Bitmap.Config.MATÉRIEL au fil du Bitmap.Config.RGB_565...?

Pour SDK >= 26, HARDWARE configuration peut améliorer le faible niveau de dessin bitmap par la prévention de la nécessité de copier les données de pixel pour le GPU à chaque fois la même image bitmap retourne à l'écran. Je pense que ça peut éviter de perdre des images lorsqu'une image est ajoutée à l'écran.

La mémoire n'est pas comptée dans votre application, et mon test l'a confirmé.

Le natif de la bibliothèque de docs disent qu'il sera de retour null si l'allocation de mémoire a échoué. Sans le code source, il n'est pas clair ce que l'implémentation de Java (l'API réalisateurs) de le faire dans ce cas - il peut décider de jeter OutOfMemoryException ou de secours à un autre type d'allocation.

Mise à jour: Expérience révèle qu'aucune exception OutOfMemoryException est levée. Alors que la répartition est couronnée de succès - tout fonctionne bien. Lors de l'échec de l'allocation - l'émulateur s'est écrasé (passé). En d'autres occasions, j'ai un étrange NullPointerException lors de l'attribution de Bitmap en application de la mémoire.

En raison de l'imprévisibilité de la stabilité, je vous déconseille d'utiliser cette nouvelle API en production actuellement. Au moins pas sans de nombreux essais.

  1. N'des données de pixels d'après le décodage de l'utilisation de cette option fait de ne PAS consommer TOUTE la mémoire du tas et qui réside dans la mémoire GPU seulement? Si oui, c' semble finalement être un soulagement pour OutOfMemoryException de l'inquiétude quand travailler avec des images.

Les données de Pixel sera dans la mémoire partagée (probablement la texture de la mémoire), mais il y a toujours une petite Bitmap objet en Java référence (si "TOUT" est inexact).

Chaque vendeur peut décider de mettre en œuvre l'allocation différemment, ce n'est pas une API publique, ils sont tenus de. Donc, OutOfMemoryException peut encore être un problème. Je ne suis pas sûr de savoir comment il peut être manipulé correctement.

  1. Quelle est la qualité par rapport à RGB_565/ARGB_8888?

L' HARDWARE drapeau n'est pas le sujet de la qualité, mais sur les pixels emplacement de stockage. Depuis les options de configuration ne peut pas être OR-ed, je suppose que la valeur par défaut (ARGB_8888) est utilisé pour le décodage.

(En fait, l' HARDWARE enum sembler comme un hack pour moi).

  1. Est la vitesse de décodage lui-même le même/mieux/pire...?

HARDWARE drapeau semblent sans rapport avec le décodage, donc, le même que ARGB_8888.

  1. Qu'arriverait-il si nous dépassons la mémoire GPU?

Le résultat de mon test dans de très mauvaises choses, quand la mémoire est en cours d'exécution. L'émulateur s'est écrasé horriblement parfois, et j'ai inattendu sans rapport avec NPE à d'autres occasions. Aucune exception OutOfMemoryException eu lieu, et il était impossible de dire quand le GPU, la mémoire est en cours d'exécution, donc aucun moyen de prévoir ce.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X