redroid11 integrated nvidia gpu hals

Foreword

In this article, nvidia related aosp library and 510.155_Android_R_aarch64_release file are used to provide basic information from the original factory, which can be used for the basic ideas of aosp transplant library.
This article records the practice of integrating nvidia gpu driver library and nvidia_omx driver library in redroid11 (aosp11) for memo.

1>. Apply the patch to Android R code then trigger the build.

2>. Change ro.board.platform=nv-streaming for build.prop in build output, or rename the gralloc.nv-streaming.so in step #3,
corresponding to your platform name. eg: TARGET_BOARD_PLATFORM:=nv-streaming or rename gralloc.nv-streaming.so gralloc.redroid.so
Add the following content to the file @build/make/tools/buildinfo.sh.

if [ -z "$TARGET_BOARD_PLATFORM" ];then
echo "##"
echo "## Add ro.board.platform"
echo "##"
echo "ro.board.platform=nv-streaming"
#echo "ro.board.platform=AMD"
#echo "ro.hardware.gralloc=dri"
#echo "ro.hardware.vulkan=amd"
#echo "ro.hardware.egl=AMD"
echo ""
fi

3>. Copy the graphics lib files in Android_aarch64_release.tar to the corresponding directory
under system/vendor/ . Remove other files under vendor/lib(64)/egl/ of your build output.

4>. Ensure hwcomposer process in the container has permission for /tmp/display_pipe.
For example, change the bindinit.sh file:
cpp chown system system /tmp chmod 777 /tmp
4.1> del umount /etc/* in bindinit.sh
cpp # umount /etc/* # rm -rf /etc # ln -s /system/etc /etc

5>. Add related property in redroid.common.rc By default the graphics will use 720p 30fps,

 setprop persist.sys.display.resolution 720x1080
setprop persist.sys.display.refresh 30

6>. If you want to run container in different GPU,set below property

setprop persist.vendor.nvidia.gpu.index $index

docker run input parament: persist.vendor.nvidia.gpu.index=0/1/2…’

7>.hwcomposer2.1 which use HIDL interface
7.1> Add below part in your product manifest.xml which define hidl interface:

 <hal format="hidl">
<name>android.hardware.graphics.composer</name>
<transport>hwbinder</transport>
<version>2.1</version>
<interface>
<name>IComposer</name>
<instance>default</instance>
</interface>
</hal>
<!--nvidia begin-->
<hal format="hidl">
<name>vendor.nvidia.hardware.graphics.composer</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>INvComposer</name>
<instance>default</instance>
</interface>
</hal>
<hal format="hidl">
<name>vendor.nvidia.hardware.graphics.display</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>INvDisplay</name>
<instance>default</instance>
</interface>
</hal>
<!--nvidia end-->
</code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">

7.2> rewrite compatibility_matrices
${TOP}/hardware/interfaces/compatibility_matrices/compatibility_matrix.5.xml

<!--nvidia begin-->
    <hal format="hidl" optional="false">
        <name>vendor.nvidia.hardware.graphics.composer</name>
        <version>1.0</version>
        <interface>
            <name>INvComposer</name>
            <instance>default</instance>
        </interface>
    </hal>
    <hal format="hidl" optional="false">
        <name>vendor.nvidia.hardware.graphics.display</name>
        <version>1.0</version>
        <interface>
            <name>INvDisplay</name>
            <instance>default</instance>
        </interface>
    </hal>
<!--nvidia end-->
</code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">

7.3> Remove [email protected] service

## gpu render
PRODUCT_PACKAGES + = \
    [email protected] \
    [email protected] \
    [email protected] \
    [email protected] \
    
    #[email protected] \
    #[email protected] \

8> graphics composer

8.1> Add [email protected] which under system\vendor\bin\hw to your image.

8.2> ensure it’s init rc [email protected] and lib dependency
are included.

8.3> For internal build related reason, NVIDIA graphics lib will depend on libc++ _nv_build.so
instead of libc++ .so, so need copy /system/lib(64)/libc++ .so to /system/lib(64)/libc++ _nv_build.so for graphics lib to use.

Because there is no libc++ _nv_build.so library file in the 510.155_Android_R_aarch64_release.tar file, extract libc++ _nv_build.so from the android-arm-r.tar.gz file and
Copy it to the redroid11 compiled image.

8.4> Need ensure libhidltransport/libhwbinder are included in container build
redroid11 manual compilation libhidl

mmm system/libhidl/
##mmm external/selinux
mmm external/libdrm
mmm system/libhwbinder

8.5>. Diff in system/linkerconfig to allow hwcomposer service load required library:

diff --git a/contents/namespace/systemdefault.cc b/contents/namespace/systemdefault.cc
index a9bfdb1..7b7c647 100644
--- a/contents/namespace/systemdefault.cc
 + + + b/contents/namespace/systemdefault.cc
@@ -14,6 + 14,19 @@
* limitations under the License.
*/
 + // Not a contribution
 + // Changes made by NVIDIA CORPORATION
 + // NVIDIA-proprietary are not a contribution and subject to the following terms and conditions:
 + //
 + // Copyright (C) 2022 NVIDIA CORPORATION. All Rights Reserved.
 + //
 + // NVIDIA CORPORATION and its licensors retain all intellectual property
 + // and proprietary rights in and to this software, related documentation
 + // and any modifications thereto. Any use, reproduction, disclosure or
 + // distribution of this software and related documentation is governed by
 + // the NVIDIA Pre-Release License Agreement between NVIDIA CORPORATION and
 + // the licensee. All other uses are strictly forbidden.
 +
// Framework-side code runs in this namespace. Libs from /vendor partition can't
// be loaded in this namespace.
@@ -81,6 + 94,8 @@ Namespace BuildSystemDefaultNamespace([[maybe_unused]] const
Context & ctx) {<!-- -->
"/system/vendor/framework",
"/system/vendor/app",
"/system/vendor/priv-app",
 + "/system/vendor/${LIB}/egl",
 + "/system/vendor/${LIB}/hw",
"/odm/framework",
"/odm/app",
"/odm/priv-app",
@@ -101,6 + 116,10 @@ Namespace BuildSystemDefaultNamespace([[maybe_unused]] const
Context & ctx) {<!-- -->
ns.AddPermittedPath(product + "/${LIB}", AsanPath::SAME_PATH);
}
}
 + ns.AddPermittedPath("/system/vendor/${LIB}/egl", AsanPath::NONE);
 + ns.AddPermittedPath("/system/vendor/${LIB}/hw", AsanPath::NONE);
 + ns.AddSearchPath("/system/vendor/${LIB}/egl", AsanPath::NONE);
 + ns.AddSearchPath("/system/vendor/${LIB}/hw", AsanPath::NONE);
ns.AddRequires(std::vector{<!-- -->
// Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
</code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">

8.6> linkerconfig adds libc++_nv_build.so and libui.so
Added @system/linkerconfig/contents/common/system_links.cc in the file

void AddStandardSystemLinks(const Context & amp; ctx, Section* section) {<!-- -->
  const bool debuggable = android::base::GetBoolProperty("ro.debuggable", false);
  const std::string system_ns_name = ctx.GetSystemNamespaceName();
  const bool is_section_vndk_enabled = ctx.IsSectionVndkEnabled();
  section->ForEachNamespaces([ & amp;](Namespace & amp; ns) {<!-- -->
    if (ns.GetName() != system_ns_name) {<!-- -->
      ns.GetLink(system_ns_name).AddSharedLib(kBionicLibs);
      if (!is_section_vndk_enabled || ns.GetName() != "default") {<!-- -->
        ns.GetLink(system_ns_name)
            .AddSharedLib(Var("SANITIZER_RUNTIME_LIBRARIES"));
      }
      if (debuggable) {<!-- -->
        // Library on the system image that can be dlopened for debugging purposes.
        ns.GetLink(system_ns_name).AddSharedLib("libfdtrack.so");
      }
      //>for nvidia
      ns.GetLink(system_ns_name).AddSharedLib("libc + + _nv_build.so");
      ns.GetLink(system_ns_name).AddSharedLib("libui.so");
      ns.GetLink(system_ns_name).AddSharedLib("libstagefright.so");
      //>nvidia end
    }
  });
}
</code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">

8.7> Modify [email protected]
Close [email protected]::IComposer default content to resolve reference errors.

service hwcomposer-1-0 /vendor/bin/hw/[email protected]
    class hal animation
    user system
    group graphics drmrpc
    capabilitiesSYS_NICE
    onrestart restart surfaceflinger
    #interface [email protected]::IComposer default
    interface [email protected]::IComposer default
    interface [email protected]::INvComposer default
    interface [email protected]::INvDisplay default

8.8> Add media_codecs_nvidia
nvidia_omx transplantation basis patch file: omx.patch.

@hardware/redroid/omx/media_codecs.xml adds nvidia configuration content.

<MediaCodecs>
    <Encoders>
        <MediaCodec name="OMX.redroid.h264.encoder" type="video/avc" />
    </Encoders>

    <Include href="media_codecs_nvidia.xml" />

    <Include href="media_codecs_google_audio.xml" />
    <Include href="media_codecs_google_telphony.xml" />
    <Include href="media_codecs_google_video.xml" />
</MediaCodecs>

Copy the file to the vendor path
PRODUCT_COPY_FILES + =
vendor/nvidia/Android_R/nvidia_omx/media_codecs_nvidia.xml:

(

T

A

R

G

E

T

C

O

P

Y

O

U

T

V

E

N

D

O

R

)

/

e

t

c

/

m

e

d

i

a

c

o

d

e

c

s

n

v

i

d

i

a

.

x

m

l

v

e

n

d

o

r

/

n

v

i

d

i

a

/

A

n

d

r

o

i

d

R

/

n

v

i

d

i

a

o

m

x

/

l

i

b

/

l

i

b

n

v

i

d

i

a

o

m

x

.

s

o

:

(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_nvidia.xml \ vendor/nvidia/Android_R/nvidia_omx/lib/libnvidia_omx.so:

(TARGETC?OPYO?UTV?ENDOR)/etc/mediac?odecsn?vidia.xml vendor/nvidia/AndroidR?/nvidiao?mx/lib/libnvidiao?mx.so:(TARGET_COPY_OUT_VENDOR)/lib/libnvidia_omx.so
vendor/nvidia/Android_R/nvidia_omx/lib64/libnvidia_omx.so:$(TARGET_COPY_OUT_VENDOR)/lib64/libnvidia_omx.so \

8.9> Add libnvidia_omx.so
@framework/av/media/libstragefright/omx/OMXMaster.cpp Add library

void OMXMaster::addVendorPlugin() {<!-- -->
    addPlugin("libstagefrighthw.so");
    addPlugin("libstagefrighthw_inno.so");
    addPlugin("libnvidia_omx.so");
}

8.10> Solve cpuset cgroup controller is not mounted! error

10-20 05:24:35.935 0 0 E init : cpuset cgroup controller is not mounted!
10-20 05:24:35.936 0 0 I init : processing action (init.svc.audioserver=running) from (/system/etc/init/audioserver.rc:35)
10-20 05:24:35.941 0 0 I init : starting service 'vendor.audio-hal'...
10-20 05:24:35.944 0 0 E init : cpuset cgroup controller is not mounted!

Modify the source code: @system/core/libprocessgroup/setup/cgroup_map_write.cpp file content is as follows:

bool CgroupSetup() {<!-- -->
    using namespace android::cgrouprc;

    std::map<std::string, CgroupDescriptor> descriptors;

    if (getpid() != 1) {<!-- -->
        LOG(ERROR) << "Cgroup setup can be done only by init process";
        //return false; Close pid! = 1 exit with error
    }

    // Make sure we do this only one time. No need for std::call_once because
    // init is a single-threaded process
    if (access(CGROUPS_RC_PATH, F_OK) == 0) {<!-- -->
        LOG(WARNING) << "Attempt to call SetupCgroups more than once";
        return true;
    }
    ...
}
</code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">

9>. Package your container image from the modified output.

Test system integration results

scrcpy client startup parameter configuration:
C:\\
V-GPU\istream-v1.24>
start “R3” /b scrcpy.exe –tcpip=192.168.31.25:21002
–window-title=3 –window-x=640 –window-y=30 –window-width=320 –window-height=180 –always-on-top
–encoder=OMX.nvidia.h264.encoder –stay-awake -V debug
–rotation=1 –lock-video-orientation=0
–max-fps=30 –bit-rate=3000000
–codec-options=minQP:int=8,maxQP:int=35,frameCount:int=-1,isUseVBR:int=1,isSaveFile:int=0,
verbose:int=0,isSaveYuv:int=0,qp:int=25,gopSize=600,gopPreset=0,
keyPeriod=600,keyRefreshMode:int=0,keyRefreshArg:int=10,keyFrameIndex:int=-1,
isScale:int=0,scaleWith:int=1280,scaleHeight:int=720,isUseCrop:int=0,cropTopOffset:int=0,cropBottomOffset:int=0,cropLeftOffset:int=0,cropRightOffset:int=0,isUseROI= 0,
roiFrameIndex=0,isUseSEI=0,seiFrameIndex=0,byPassFlages:int=255,
interval:int=60,pushStreamTimeout:int=10,bufferType:int=0,captureMode:int=5,
encoderName:string=OMX.nvidia.h264.encoder –stay-awake -V debug