RenderScript — это платформа для выполнения ресурсоемких задач с высокой производительностью на Android. Он предназначен для использования с параллельными вычислениями данных, хотя последовательные рабочие нагрузки также могут быть полезны. Среда выполнения RenderScript распараллеливает работу между процессорами, доступными на устройстве, такими как многоядерные ЦП и ГП, что позволяет разработчикам сосредоточиться на выражении алгоритмов, а не на планировании работы. RenderScript особенно полезен для приложений, выполняющих обработку изображений, вычислительную фотографию или компьютерное зрение.
Устройства под управлением Android 8.0 и более поздних версий используют следующую платформу RenderScript и HAL поставщиков:
Отличия от RenderScript в Android 7.x и ниже включают:
- Два экземпляра внутренних библиотек RenderScript в процессе. Один набор предназначен для резервного пути ЦП и находится непосредственно в
/system/lib
; другой набор предназначен для пути к графическому процессору и взят из/system/lib/vndk-sp
. - Внутренние библиотеки RS в
/system/lib
создаются как часть платформы и обновляются по мере обновленияsystem.img
. Однако библиотеки в/system/lib/vndk-sp
создаются для производителя и не обновляются при обновленииsystem.img
(хотя их можно обновить для исправления безопасности, их ABI остается прежним). - Код поставщика (RS HAL, драйвер RS и
bcc plugin
) связан с внутренними библиотеками RenderScript, расположенными в/system/lib/vndk-sp
. Они не могут ссылаться на библиотеки в/system/lib
, потому что библиотеки в этом каталоге созданы для платформы и, следовательно, могут быть несовместимы с кодом поставщика (т. е. символы могут быть удалены). Это сделало бы OTA только для фреймворка невозможным.
Дизайн
В следующих разделах подробно описывается дизайн RenderScript в Android 8.0 и более поздних версиях.
Библиотеки RenderScript, доступные поставщикам
В этом разделе перечислены библиотеки RenderScript (известные как Vendor NDK для HAL того же процесса или VNDK-SP), которые доступны для кода поставщика и с которыми можно связать. В нем также подробно описаны дополнительные библиотеки, которые не связаны с RenderScript, но также предоставляются в коде поставщика.
Хотя следующий список библиотек может различаться в разных версиях Android, он неизменен для конкретной версии Android; актуальный список доступных библиотек см. в /system/etc/ld.config.txt
.
Библиотеки RenderScript | Библиотеки без RenderScript |
---|---|
|
|
Конфигурация пространства имен компоновщика
Ограничение связывания, которое предотвращает использование библиотек, не входящих в VNDK-SP, кодом поставщика, применяется во время выполнения с использованием пространства имен компоновщика. (Подробности см. в презентации VNDK Design .)
На устройстве под управлением Android 8.0 и выше все HAL того же процесса (SP-HAL), кроме RenderScript , загружаются внутри пространства имен компоновщика sphal
. RenderScript загружается в специфичное для RenderScript пространство имен rs
, место, которое позволяет немного слабее применять библиотеки RenderScript. Поскольку реализации RS необходимо загрузить скомпилированный битовый код, /data/*/*.so
добавляется к пути пространства имен rs
(другим SP-HAL не разрешено загружать библиотеки из раздела данных).
Кроме того, пространство имен rs
позволяет использовать больше библиотек, чем предусмотрено другими пространствами имен. libmediandk.so
и libft2.so
доступны пространству имен rs
, поскольку libRS_internal.so
имеет внутреннюю зависимость от этих библиотек.
Загрузка драйверов
Резервный путь процессора
В зависимости от наличия бита RS_CONTEXT_LOW_LATENCY
при создании контекста RS выбирается путь CPU или GPU. Когда выбран путь ЦП, libRS_internal.so
(основная реализация инфраструктуры RS) напрямую dlopen
из пространства имен компоновщика по умолчанию, где предоставляется версия библиотеки RS для платформы.
Реализация RS HAL от поставщика вообще не используется, когда используется резервный путь ЦП, а объект RsContext
создается с нулевым mVendorDriverName
. libRSDriver.so
(по умолчанию) dlopen
, а библиотека драйверов загружается из пространства имен по default
, поскольку вызывающая программа ( libRS_internal.so
) также загружается в пространство имен по default
.
Путь графического процессора
Для пути GPU libRS_internal.so
загружается иначе. Во-первых, libRS.so
использует android.hardware.renderscript@1.0.so
(и лежащий в его основе libhidltransport.so
) для загрузки android.hardware.renderscript@1.0-impl.so
(реализация RS HAL от поставщика) в другое пространство имен компоновщика, называемое sphal
. Затем RS HAL libRS_internal.so
dlopen
другом пространстве имен компоновщика с именем rs
.
Поставщики могут предоставить свой собственный драйвер RS, установив флаг времени сборки OVERRIDE_RS_DRIVER
, встроенный в реализацию RS HAL ( hardware/interfaces/renderscript/1.0/default/Context.cpp
). Это имя драйвера затем dlopen
для контекста RS для пути GPU.
Создание объекта RsContext
делегировано реализации RS HAL. HAL обращается к платформе RS, используя rsContextCreateVendor()
с именем драйвера для использования в качестве аргумента. Затем платформа RS загружает указанный драйвер при инициализации RsContext
. В этом случае библиотека драйверов загружается в пространство имен rs
, поскольку объект RsContext
создается внутри пространства имен rs
, а /vendor/lib
находится в пути поиска пространства имен.
При переходе от пространства имен по default
к пространству имен sphal
libhidltransport.so
использует android_load_sphal_library()
, чтобы явно приказать динамическому компоновщику загрузить библиотеку -impl.so
из пространства имен sphal
.
При переходе из пространства имен sphal
в пространство имен rs
загрузка выполняется косвенно с помощью следующей строки в /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
Эта строка указывает, что динамический компоновщик должен загружать libRS_internal.so
из пространства имен rs
, когда библиотека не может быть найдена/загружена из пространства имен sphal
(что всегда имеет место, поскольку пространство имен sphal
не ищет /system/lib/vndk-sp
где libRS_internal.so
находится). В этой конфигурации достаточно простого вызова dlopen dlopen()
для libRS_internal.so
, чтобы выполнить переход пространства имен.
Загрузка плагина скрытой копии
bcc plugin
— это предоставляемая поставщиком библиотека, загружаемая в компилятор bcc
. Поскольку bcc
— это системный процесс в каталоге /system/bin
, библиотеку bcc plugin
можно рассматривать как SP-HAL (т. е. поставщик HAL, который можно напрямую загрузить в системный процесс без привязки). В качестве SP-HAL библиотека bcc-plugin
:
- Нельзя связываться с библиотеками только для фреймворка, такими как
libLLVM.so
. - Может связываться только с библиотеками VNDK-SP, доступными поставщику.
Это ограничение применяется путем загрузки bcc plugin
в пространство имен sphal
с помощью функции android_sphal_load_library()
. В предыдущих версиях Android имя плагина указывалось с помощью параметра -load
, а библиотека загружалась с помощью простого dlopen()
от libLLVM.so
. В Android 8.0 и более поздних версиях это указывается в параметре -plugin
, и библиотека загружается непосредственно самой bcc
. Этот параметр включает путь, не зависящий от Android, к проекту LLVM с открытым исходным кодом.
Пути поиска для ld.mc
При выполнении ld.mc
некоторые библиотеки времени выполнения RS передаются в качестве входных данных компоновщику. Бит-код RS из приложения связывается с библиотеками времени выполнения, и когда преобразованный бит-код загружается в процесс приложения, библиотеки времени выполнения снова динамически связываются с преобразованным бит-кодом.
Библиотеки времени выполнения включают:
-
libcompiler_rt.so
-
libm.so
-
libc.so
- Драйвер RS (либо
libRSDriver.so
либоOVERRIDE_RS_DRIVER
)
При загрузке скомпилированного битового кода в процесс приложения укажите точно такую же библиотеку, которая использовалась ld.mc
В противном случае скомпилированный биткод может не найти символ, который был доступен при компоновке.
Для этого платформа RS использует разные пути поиска для библиотек среды выполнения при выполнении ld.mc
в зависимости от того, загружается ли сама структура RS из /system/lib
или из /system/lib/vndk-sp
. Это можно определить, прочитав адрес произвольного символа библиотеки фреймворка RS и используя dladdr()
, чтобы сопоставить путь к файлу с адресом.
Политика SELinux
В результате изменений политики SELinux в Android 8.0 и более поздних версиях вы должны следовать определенным правилам (обеспечиваемым через neverallows
) при маркировке дополнительных файлов в разделе vendor
:
-
vendor_file
должен быть меткой по умолчанию для всех файлов в разделеvendor
. Политика платформы требует этого для доступа к сквозным реализациям HAL. - Все новые
exec_types
добавляемые в разделvendor
через SEPolicy поставщика, должны иметь атрибутvendor_file_type
. Это обеспечивается черезneverallows
. - Чтобы избежать конфликтов с будущими обновлениями платформы/фреймворка, избегайте маркировки файлов, отличных от
exec_types
, в разделеvendor
. - Все зависимости библиотек для HAL одного и того же процесса, идентифицируемые AOSP, должны быть помечены как
same_process_hal_file
.
Дополнительные сведения о политике SELinux см. в разделе Linux с улучшенной безопасностью в Android .
Совместимость с ABI для биткода
Если новые API-интерфейсы не добавляются, что означает отсутствие изменения версии HAL, платформы RS будут продолжать использовать существующий драйвер графического процессора (HAL 1.0).
Для незначительных изменений HAL (HAL 1.1), не влияющих на битовый код, фреймворки должны отступать от ЦП для этих недавно добавленных API и продолжать использовать драйвер графического процессора (HAL 1.0) в другом месте.
Для серьезных изменений HAL (HAL 2.0), влияющих на компиляцию/компоновку битового кода, платформам RS следует отказаться от загрузки предоставленных поставщиком драйверов графического процессора, а вместо этого использовать путь ЦП или Vulkan для ускорения.
Использование битового кода RenderScript происходит в три этапа:
стадия | Подробности |
---|---|
Компиляция |
|
Связь |
|
Нагрузка |
|
В дополнение к HAL интерфейсами также являются API среды выполнения и экспортируемые символы. Ни один из интерфейсов не изменился со времен Android 7.0 (API 24), и в ближайшем будущем не планируется менять его в Android 8.0 и более поздних версиях. Однако, если интерфейс изменится, версия HAL также увеличится.
Реализации поставщиков
Android 8.0 и более поздние версии требуют некоторых изменений драйвера графического процессора для правильной работы драйвера графического процессора.
Модули драйверов
- Модули драйверов не должны зависеть ни от каких системных библиотек, которых нет в списке .
- Драйвер должен предоставить свой собственный
android.hardware.renderscript@1.0-impl_{NAME}
или объявить реализацию по умолчаниюandroid.hardware.renderscript@1.0-impl
в качестве своей зависимости. - Реализация процессора
libRSDriver.so
— хороший пример того, как удалить зависимости, отличные от VNDK-SP.
Компилятор битового кода
Вы можете скомпилировать битовый код RenderScript для драйвера поставщика двумя способами:
- Запустите компилятор RenderScript конкретного поставщика в
/vendor/bin/
(предпочтительный метод компиляции GPU). Подобно другим модулям драйверов, двоичный файл компилятора поставщика не может зависеть ни от какой системной библиотеки, которой нет в списке библиотек RenderScript, доступных поставщикам . - Вызов системы bcc:
/system/bin/bcc
с помощьюbcc plugin
, предоставленного поставщиком; этот плагин не может зависеть ни от какой системной библиотеки, которой нет в списке библиотек RenderScript, доступных для поставщиков .
Если bcc plugin
должен мешать компиляции ЦП и его зависимость от libLLVM.so
не может быть легко удалена, поставщик должен скопировать bcc
(и все зависимости, не относящиеся к LL-NDK, включая libLLVM.so
, libbcc.so
) в /vendor
раздел.
Кроме того, поставщикам необходимо внести следующие изменения:
- Скопируйте
libclcore.bc
в раздел/vendor
. Это обеспечиваетlibclcore.bc
,libLLVM.so
иlibbcc.so
. - Измените путь к исполняемому файлу
bcc
копии, задавRsdCpuScriptImpl::BCC_EXE_PATH
из реализации RS HAL.
Политика SELinux
Политика SELinux влияет как на драйвер, так и на исполняемые файлы компилятора. Все модули драйверов должны быть помечены как same_process_hal_file
в file_contexts
устройства. Например:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
Исполняемый файл компилятора должен иметь возможность вызываться процессом приложения, как и копия поставщика bcc ( /vendor/bin/bcc
). Например:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Устаревшие устройства
Устаревшие устройства — это те, которые удовлетворяют следующим условиям:
- PRODUCT_SHIPPING_API_LEVEL ниже 26.
- PRODUCT_FULL_TREBLE_OVERRIDE не определен.
Для устаревших устройств ограничения не применяются при обновлении до Android 8.0 и выше, что означает, что драйверы могут продолжать ссылаться на библиотеки в /system/lib[64]
. Однако из-за изменения архитектуры, связанного с OVERRIDE_RS_DRIVER
, android.hardware.renderscript@1.0-impl
необходимо установить в раздел /vendor
; в противном случае среда выполнения RenderScript переключается на путь ЦП.
Информацию о причинах прекращения поддержки Renderscript см. в блоге разработчиков Android: Android GPU Compute Going Forward . Информация о ресурсах для этого устаревания включает следующее:
- Миграция с рендерскрипта
- Образец RenderScriptMigration
- README набора инструментов для замены внутренних компонентов
- Набор инструментов для замены внутренних компонентов.kt