Ответ 1
Документация и открытый исходный код еще не нажаты Google git. Поэтому мои исследования основаны только на частичной информации, некоторых экспериментах и на собственном опыте переноса JVM на различные устройства.
Мой тест создал большой измененный битмап и скопировал его в новый растровый рисунок HARDWARE одним нажатием кнопки, добавив его в список растровых изображений. Мне удалось создать несколько экземпляров больших растровых изображений, прежде чем он разбился.
Я смог найти это в 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);
И ища документацию AHardwareBuffer, под капотом создается EGLClientBuffer
под ANativeWindowBuffer
(собственный графический буфер) в общей памяти Android ( "ashmem" ). Но фактическая реализация может различаться в зависимости от оборудования.
Что касается вопросов:
- Должны ли мы ВСЕГДА выбрать сейчас Bitmap.Config.HARDWARE через Bitmap.Config.RGB_565...?
Для конфигурации SDK >= 26, HARDWARE
можно улучшить рисунок растрового изображения низкого уровня, предотвращая необходимость копирования пиксельных данных на GPU каждый раз, когда одна и та же растровая карта возвращается к экрану. Я думаю, это может предотвратить потерю некоторых кадров, когда растровое изображение добавляется на экран.
Память не учитывается в вашем приложении, и мой тест подтвердил это.
Собственная библиотека docs говорит, что она вернет null
, если распределение памяти не увенчалось успехом.
Без исходного кода неясно, что будет делать реализация Java (разработчики API) в этом случае - она может решить бросить OutOfMemoryException
или вернуться к другому типу распределения.
Обновление: Эксперимент показывает, что не выбрано исключение OutOfMemoryException. Хотя распределение успешно - все работает нормально. После неудачного выделения - эмулятор разбился (просто исчез). В других случаях у меня есть странный NullPointerException
при распределении Bitmap в памяти приложения.
Из-за непредсказуемой стабильности я бы не рекомендовал использовать этот новый API в настоящее время. По крайней мере, не без тщательного тестирования.
- Получают ли пиксельные данные после декодирования с использованием этой опции, фактически НЕ потребляют ЛЮБАЯ кучную память и находятся только в памяти GPU? Если это так, представляется, наконец, облегчением для беспокойства
OutOfMemoryException
, когда работа с изображениями.
Пиксельные данные будут находиться в общей памяти (возможно, в памяти текстур), но все еще есть небольшой объект Bitmap
в Java, ссылающийся на него (так что "ЛЮБОЙ" является неточным).
Каждый поставщик может решить реализовать фактическое распределение по-разному, это не публичный API, к которому они привязаны.
Так что OutOfMemoryException
все еще может быть проблемой. Я не уверен, как можно корректно обрабатывать.
- Какое качество по сравнению с RGB_565/ARGB_8888?
Флаг HARDWARE
не относится к качеству, а относится к местоположению хранения пикселей. Поскольку флаги конфигурации не могут быть OR
-ed, я полагаю, что для декодирования используется значение по умолчанию (ARGB_8888
).
(На самом деле, перечисление HARDWARE
кажется мне взломанным).
Флаг
- Является ли скорость декодирования тем же/лучше/хуже...?
HARDWARE
кажется не связанным с декодированием, так же, как ARGB_8888
.
- Что произойдет, если мы превысим память GPU?
Мой результат теста очень плох, когда память заканчивается. Иногда эмулятор разбивался ужасно, и в других случаях у меня был неожиданный несвязанный NPE. Отсутствие OutOfMemoryException произошло, и также не было возможности сказать, когда заканчивается память GPU, поэтому невозможно предвидеть это.