API 26 ajoute une nouvelle optionBitmap.Config.HARDWARE
:
Configuration spéciale, lorsque le bitmap est stocké uniquement dans la mémoire graphique. Les bitmaps de cette configuration sont toujours immuables. Il est optimal pour les cas où la seule opération avec le bitmap est de le dessiner sur un écran.
Questions qui ne sont pas expliquées dans les documents:
Bitmap.Config.HARDWARE
plus de Bitmap.Config.RGB_565
lorsque la vitesse est prioritaire et que la qualité et la mutabilité ne le sont pas (par exemple pour les miniatures, etc.)?OutOfMemoryException
lorsque vous travaillez avec des images.OutOfMemoryException
:)?La documentation et le code source public ne sont pas encore poussés à git de Google . Donc, mes recherches ne sont basées que sur des informations partielles, quelques expériences et sur ma propre expérience de portage de JVM vers divers périphériques.
Mon test a créé un grand bitmap mutable et l'a copié dans un nouveau bitmap HARDWARE en un clic sur un bouton, l'ajoutant à une liste bitmap. J'ai réussi à créer plusieurs instances des grands bitmaps avant qu'il ne plante.
J'ai pu le trouver dans le Android-o-preview-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 en recherchant documentation de AHardwareBuffer , sous le capot, il crée un EGLClientBuffer
soutenu par ANativeWindowBuffer
(tampon graphique natif) dans = Android mémoire partagée ("ashmem"). Mais l'implémentation réelle peut varier d'un matériel à l'autre.
Pour les questions:
- Faut-il TOUJOURS préférer maintenant Bitmap.Config.HARDWARE à Bitmap.Config.RGB_565 ...?
Pour le SDK> = 26, la configuration HARDWARE
peut améliorer le dessin bitmap de bas niveau en évitant d'avoir à copier les données de pixels sur le GPU chaque fois que le même bitmap revient à l'écran. Je suppose que cela peut empêcher de perdre certaines images lorsqu'un bitmap est ajouté à l'écran.
La mémoire n'est pas prise en compte dans votre application, et mon test l'a confirmé.
Les documents de la bibliothèque native indiquent qu'il renverra null
si l'allocation de mémoire a échoué. Sans le code source, il n'est pas clair ce que l'implémentation Java (les implémenteurs d'API) fera dans ce cas - il pourrait décider de jeter OutOfMemoryException
ou de retomber dans un autre type d'allocation.
Mise à jour: L'expérience révèle qu'aucune exception OutOfMemoryException n'est levée. Bien que l'allocation soit réussie - tout fonctionne bien. En cas d'échec de l'allocation - l'émulateur s'est écrasé (il vient de disparaître). À d'autres occasions, j'ai un NullPointerException
étrange lors de l'allocation de Bitmap dans la mémoire de l'application.
En raison de la stabilité imprévisible, je ne recommanderais pas d'utiliser cette nouvelle API en production actuellement . Du moins pas sans tests approfondis.
- Les données de pixels après décodage à l'aide de cette option ne consomment-elles AUCUNE mémoire de tas et résident-elles uniquement dans la mémoire GPU? Si tel est le cas, cela semble enfin être un soulagement pour
OutOfMemoryException
lorsque vous travaillez avec des images.
Les données de pixels seront dans la mémoire partagée (probablement la mémoire de texture), mais il y aura toujours un petit objet Bitmap
dans Java le référençant (donc "ANY" est inexact)).
Chaque fournisseur peut décider d'implémenter l'allocation réelle différemment, ce n'est pas une API publique à laquelle il est lié. OutOfMemoryException
peut donc toujours poser problème. Je ne sais pas comment cela peut être géré correctement.
- Quelle qualité par rapport à RGB_565/ARGB_8888?
L'indicateur HARDWARE
ne concerne pas la qualité, mais l'emplacement de stockage des pixels. Étant donné que les drapeaux de configuration ne peuvent pas être OR
- ed, je suppose que la valeur par défaut (ARGB_8888
) est utilisé pour le décodage.
(En fait, l'énumération HARDWARE
me semble être un hack).
- La vitesse de décodage est-elle la même/meilleure/pire ...?
HARDWARE
flag ne semble pas lié au décodage, donc identique à ARGB_8888
.
- Que se passerait-il si nous dépassions la mémoire GPU?
Mon test donne de très mauvaises choses lorsque la mémoire est épuisée. L'émulateur s'est écrasé horriblement parfois, et j'ai eu NPE inattendu sans rapport à d'autres occasions. Aucune OutOfMemoryException ne s'est produite et il n'y avait également aucun moyen de savoir quand la mémoire du GPU s'épuisait, donc aucun moyen de le prévoir.