RenderScript is a framework for running computationally intensive tasks at high performance on Android. It is designed for use with data-parallel computation, although serial workloads can benefit as well. The RenderScript runtime parallelizes work across processors available on a device, such as multi-core CPUs and GPUs, enabling developers to focus on expressing algorithms rather than scheduling work. RenderScript is especially useful for apps performing image processing, computational photography, or computer vision.
Devices running Android 8.0 and higher use the following RenderScript framework and vendor HALs:

Figure 1. Vendor code linking to internal libs.
Differences from RenderScript in Android 7.x and lower include:
- Two instances of RenderScript internal libs in a process. One set is for CPU fallback path and is from directly at
/system/lib
; the other set is for GPU path and is from/system/lib/vndk-sp
. - RS internal libs in
/system/lib
are built as part of the platform and are updated assystem.img
is upgraded. However, libs in/system/lib/vndk-sp
are built for the vendor and are not updated whensystem.img
is upgraded (while they can be updated for a security fix, their ABI remains the same). - Vendor code (RS HAL, RS driver, and the
bcc plugin
) are linked against the RenderScript internal libs located at/system/lib/vndk-sp
. They cannot link against libs in/system/lib
because libs in that directory are built for the platform and thus may not be compatible with the vendor code (i.e., symbols may be removed). Doing so would make a framework-only OTA impossible.
Design
The following sections detail RenderScript design in Android 8.0 and higher.
RenderScript libs available to vendors
This section lists the RenderScript libs (known as Vendor NDK for Same-Process HALs or VNDK-SP) that are available to vendor code and which can be linked against. It also details additional libraries that are unrelated to RenderScript but which are also provided to vendor code.
While the following list of libraries might differ between Android releases, it is immutable for a specific Android release; for an up-to-date list of available libraries, refer to /system/etc/ld.config.txt
.
RenderScript Libs | Non-RenderScript Libs |
---|---|
|
|
Linker namespace configuration
The linking restriction that prevents libs not in VNDK-SP from being used by vendor code is enforced at runtime using the linker namespace. (For details, refer to the VNDK Design presentation.)
On a device running Android 8.0 and higher, all Same-Process HALs (SP-HALs) except RenderScript are loaded inside the linker namespace sphal
. RenderScript is loaded into the RenderScript-specific namespace rs
, a location that enables a slightly looser enforcement for RenderScript libs. Because the RS implementation needs to load the compiled bitcode, /data/*/*.so
is added to the path of the rs
namespace (other SP-HALs are not allowed to load libs from the data partition).
In addition, the rs
namespace allows more libs than provided for by other namespaces. libmediandk.so
and libft2.so
are exposed to the rs
namespace because libRS_internal.so
has an internal dependency to these libraries.

Figure 2. Namespace configuration for linker.
Load drivers
CPU fallback path
Depending on the existence of the RS_CONTEXT_LOW_LATENCY
bit when creating an RS context, either the CPU or GPU path is selected. When the CPU path is selected, libRS_internal.so
(the main implementation of the RS framework) is directly dlopen
ed from the default linker namespace where the platform version of RS libs are provided.
The RS HAL implementation from the vendor is not used at all when the CPU fallback path is taken, and an RsContext
object is created with null mVendorDriverName
. libRSDriver.so
is (by default) dlopen
ed and the driver lib is loaded from the default
namespace because the caller (libRS_internal.so
) is also loaded in the default
namespace.

Figure 3. CPU fallback path.
GPU path
For the GPU path, the libRS_internal.so
is loaded differently. First, libRS.so
uses [email protected]
(and its underlying libhidltransport.so
) to load [email protected]
(a vendor implementation of RS HAL) into a different linker namespace called sphal
. The RS HAL then dlopen
s libRS_internal.so
in a another linker namespace called rs
.
Vendors can provide their own RS driver by setting the build time flag OVERRIDE_RS_DRIVER
, which is embedded into the RS HAL implementation (hardware/interfaces/renderscript/1.0/default/Context.cpp
). This driver name is then dlopen
ed for the RS context for the GPU path.
The creation of the RsContext
object is delegated to the RS HAL implementation. The HAL calls back to the RS framework using rsContextCreateVendor()
function with the name of the driver to use as an argument. The RS framework then loads the specified driver when the RsContext
is initialized. In this case, the driver library is loaded into the rs
namespace because the RsContext
object is created inside the rs
namespace and /vendor/lib
is in the search path of the namespace.

Figure 4. GPU fallback path.
When transitioning from the default
namespace to the sphal
namespace, libhidltransport.so
uses the android_load_sphal_library()
function to explicitly order the dynamic linker to load the -impl.so
library from the sphal
namespace.
When transitioning from the sphal
namespace to the rs
namespace, loading is done indirectly by the following line in /system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
This line specifies the dynamic linker should load libRS_internal.so
from the rs
namespace when the lib can't be found/loaded from the sphal
namespace (which is always the case because sphal
namespace does not search /system/lib/vndk-sp
where libRS_internal.so
resides). With this configuration, a simple dlopen()
call to libRS_internal.so
is enough to make the namespace transition.
Load bcc plugin
bcc plugin
is a vendor-provided library loaded into the bcc
compiler. Because bcc
is a system process in the /system/bin
directory, the bcc plugin
library can be considered an SP-HAL (i.e., a vendor HAL that can be directly loaded into the system process without being binderized). As an SP-HAL, the bcc-plugin
library:
- Cannot link against framework-only libraries such as
libLLVM.so
. - Can link against only the VNDK-SP libraries available to the vendor.
This restriction is enforced by loading the bcc plugin
into the sphal
namespace using the android_sphal_load_library()
function. In previous versions of Android, the plugin name was specified using the -load
option and the lib was loaded using the simple dlopen()
by libLLVM.so
. In Android 8.0 and higher, this is specified in the -plugin
option and the lib is directly loaded by the bcc
itself. This option enables a non-Android-specific path to the open source LLVM project.

Figure 5. Loading bcc plugin, Android 7.x and lower.

Figure 6. Loading bcc plugin, Android 8.0 and higher.
Search paths for ld.mc
When executing ld.mc
, some RS runtime libs are given as inputs to the linker. The RS bitcode from the app is linked against the runtime libs and when the converted bitcode is loaded into an app process, the runtime libs are again dynamically linked from the converted bitcode.
Runtime libs include:
libcompiler_rt.so
libm.so
libc.so
- RS driver (either
libRSDriver.so
orOVERRIDE_RS_DRIVER
)
When loading the compiled bitcode into the app process, provide the exact same library that was used by ld.mc
. Otherwise, the compiled bitcode may not find a symbol which was available when it was linked.
To do so, RS framework uses different search paths for the runtime libs when executing ld.mc
, depending on whether the RS framework itself is loaded from /system/lib
or from /system/lib/vndk-sp
. This can be determined by reading the address of an arbitrary symbol of a RS framework lib and using dladdr()
to get the file path mapped to the address.
SELinux policy
As a result of the SELinux policy changes in Android 8.0 and higher, you must follow specific rules (enforced through neverallows
) when labelling additional files in vendor
partition:
vendor_file
must be the default label in for all files invendor
partition. The platform policy requires this to access passthrough HAL implementations.- All new
exec_types
added invendor
partition through vendor SEPolicy must havevendor_file_type
attribute. This is enforced throughneverallows
. - To avoid conflicts with future platform/framework updates, avoid labelling files other than
exec_types
invendor
partition. - All library dependencies for AOSP-identified same process HALs must be labelled as
same_process_hal_file
.
For details on SELinux policy, see Security-Enhanced Linux in Android.
ABI compatibility for bitcode
If no new APIs are added, which means no HAL version bump, the RS frameworks will keep using the existing GPU (HAL 1.0) driver.
For minor HAL changes (HAL 1.1) not affecting bitcode, the frameworks should fallback to CPU for these newly added APIs and keep using GPU (HAL 1.0) driver elsewhere.
For major HAL changes (HAL 2.0) affecting bitcode compilation/linking, RS frameworks should choose not to load vendor-provided GPU drivers and instead use the CPU or Vulkan path for acceleration.
Consuming RenderScript bitcode occurs in three stages:
Stage | Details |
---|---|
Compile |
|
Link |
|
Load |
|
In addition to the HAL, runtime APIs and the exported symbols are also interfaces. Neither interface has changed since Android 7.0 (API 24) and there are no immediate plans to change it in Android 8.0 and beyond. However, if the interface does change, the HAL version will also increment.
Vendor implementations
Android 8.0 and higher requires some GPU driver changes for the GPU driver to work correctly.
Driver modules
- Driver modules must not depend on any system libraries that are not in the list.
- Driver must provide its own
[email protected]_{NAME}
, or declare the default implementation[email protected]
as its dependency. - CPU implementation
libRSDriver.so
is a good example of how to remove non-VNDK-SP dependencies.
Bitcode compiler
You can compile RenderScript bitcode for the vendor driver in two ways:
- Invoke vendor-specific RenderScript compiler in
/vendor/bin/
(preferred method of GPU compilation). Similar to other driver modules, the vendor compiler binary cannot depend on any system library that is not in the list of RenderScript libs available to vendors. - Invoke system bcc:
/system/bin/bcc
with a vendor-providedbcc plugin
; this plugin cannot depend on any system library that is not in the list of RenderScript libs available to vendors.
If the vendor bcc plugin
needs to interfere with the CPU compilation and its dependency on libLLVM.so
cannot be easily removed, the vendor should copy bcc
(and all the non-LL-NDK dependencies, including libLLVM.so
, libbcc.so
) into /vendor
partition.
In addition, vendors need to make the following changes:

Figure 7. Changes to vendor driver.
- Copy
libclcore.bc
to/vendor
partition. This ensureslibclcore.bc
,libLLVM.so
, andlibbcc.so
are in sync. - Change the path to the
bcc
executable by settingRsdCpuScriptImpl::BCC_EXE_PATH
from the RS HAL implementation.
SELinux policy
SELinux policy affects both the driver and the compiler executables. All driver modules must be labeled same_process_hal_file
in the device's file_contexts
. For example:
/vendor/lib(64)?/libRSDriver_EXAMPLE\.so u:object_r:same_process_hal_file:s0
The compiler executable must be able to be invoked by an app process, as does the vendor copy of bcc (/vendor/bin/bcc
). For example:
device/vendor_foo/device_bar/sepolicy/file_contexts: /vendor/bin/bcc u:object_r:same_process_hal_file:s0
Legacy devices
Legacy devices are those that satisfy the following conditions:
- PRODUCT_SHIPPING_API_LEVEL is lower than 26.
- PRODUCT_FULL_TREBLE_OVERRIDE is not defined.
For legacy devices, the restrictions are not enforced when upgrading to Android 8.0 and higher, meaning the drivers can continue to link to libraries in /system/lib[64]
. However, because of the architecture change related to OVERRIDE_RS_DRIVER
, [email protected]
must be installed to /vendor
partition; failing to do so forces RenderScript runtime fallback to CPU path.
For information about the motivation for the Renderscript deprecation, see the Android Developers Blog: Android GPU Compute Going Forward. Resource information for this deprecation includes the following:
- Migrate from Renderscript
- RenderScriptMigration Sample
- Intrinsics Replacement Toolkit README
- Intrinsics ReplacementToolkit.kt