RenderScript เป็นเฟรมเวิร์กสำหรับการเรียกใช้การคำนวณอย่างหนัก งานที่มีประสิทธิภาพสูงใน Android ผลิตภัณฑ์นี้ออกแบบมาให้ใช้ร่วมกับ การประมวลผลข้อมูลคู่ขนาน แม้ว่าภาระงานแบบอนุกรมจะได้ประโยชน์ด้วยเช่นกัน รันไทม์ของ RenderScript ทำงานพร้อมกันได้ในโปรเซสเซอร์ที่ใช้ได้ใน เช่น CPU และ GPU แบบหลายแกน ทำให้นักพัฒนาซอฟต์แวร์มุ่งเน้นที่ เพื่อแสดงอัลกอริทึมมากกว่าการกำหนดเวลาทำงาน RenderScript โดยเฉพาะ มีประโยชน์สำหรับแอป ประมวลผลภาพ ประมวลผล ภาพถ่าย หรือคอมพิวเตอร์วิทัศน์
อุปกรณ์ที่ใช้ Android 8.0 ขึ้นไปใช้ RenderScript ต่อไปนี้ กรอบการทำงานและ HAL ของผู้ให้บริการ:
![](https://source.android.google.cn/docs/core/architecture/images/treble_rs_linking.png?authuser=19&hl=th)
รูปที่ 1 โค้ดผู้ให้บริการที่ลิงก์กับไลบรารีภายใน
ความแตกต่างจาก RenderScript ใน Android 7.x และต่ำกว่า ได้แก่
- ไลบรารีภายใน RenderScript 2 อินสแตนซ์ในโปรเซส ชุดหนึ่งมีไว้สำหรับ
เส้นทางสำรองของ CPU และมาจาก
/system/lib
โดยตรง อื่นๆ ที่ตั้งค่าไว้สำหรับเส้นทาง GPU และมาจาก/system/lib/vndk-sp
- ไลบรารีภายใน RS ใน
/system/lib
สร้างขึ้นโดยเป็นส่วนหนึ่งของ แพลตฟอร์มและได้รับการอัปเดตเมื่อsystem.img
ได้รับการอัปเกรด อย่างไรก็ตาม lib ใน/system/lib/vndk-sp
สร้างขึ้นสำหรับผู้ให้บริการ และไม่ใช่ อัปเดตเมื่อsystem.img
ได้รับการอัปเกรด (ในขณะที่อัปเดตได้ สำหรับการแก้ไขปัญหาด้านความปลอดภัย ABI ยังคงเหมือนเดิม) - รหัสตัวแทนจำหน่ายรายย่อย (RS HAL, ไดรเวอร์ RS และ
bcc plugin
) คือ ลิงก์กับคลังภายใน RenderScript ที่/system/lib/vndk-sp
และไม่สามารถเชื่อมโยงกับไลบรารีใน/system/lib
เนื่องจาก lib ในไดเรกทอรีนั้นสร้างขึ้นสำหรับ ซึ่งอาจทำให้ไม่สามารถใช้งานร่วมกับรหัสผู้ให้บริการ (เช่น สัญลักษณ์ อาจถูกนำออก) เนื่องจากจะทำให้ OTA ที่ใช้เฟรมเวิร์กเท่านั้นดำเนินการไม่ได้
การออกแบบ
ส่วนต่อไปนี้แสดงรายละเอียดการออกแบบ RenderScript ใน Android 8.0 ขึ้นไป
ไลบรารี RenderScript ที่พร้อมให้บริการแก่ผู้ให้บริการ
ส่วนนี้จะแสดงไลบรารี RenderScript (หรือเรียกว่า Vendor NDK สำหรับกระบวนการเดียวกัน) HAL หรือ VNDK-SP) ที่มีให้สำหรับรหัสผู้ให้บริการและที่สามารถลิงก์ได้ เทียบกับ นอกจากนี้ยังแสดงรายละเอียดไลบรารีเพิ่มเติมที่ไม่เกี่ยวข้องกับ RenderScript แต่จะมีให้กับโค้ดของผู้ให้บริการด้วย
แม้ว่ารายการไลบรารีต่อไปนี้อาจแตกต่างกันไปใน Android รุ่นต่างๆ
จะไม่สามารถเปลี่ยนแปลงได้สำหรับ Android บางรุ่น เพื่อดูรายการล่าสุด
ไลบรารีที่ใช้ได้ โปรดดูที่ /system/etc/ld.config.txt
คลัง RenderScript | ไลบรารีที่ไม่ใช่ RenderScript |
---|---|
|
|
การกำหนดค่าเนมสเปซของ Linker
ข้อจำกัดการลิงก์ที่ป้องกันไม่ให้มีการใช้งาน Lib ที่ไม่ได้อยู่ใน VNDK-SP โดย ระบบจะบังคับใช้โค้ดของผู้ให้บริการขณะรันไทม์โดยใช้เนมสเปซ Linker (โปรดดูรายละเอียด ดูการออกแบบของ VNDK งานนำเสนอ)
สำหรับอุปกรณ์ที่ใช้ Android 8.0 ขึ้นไป ต้องใช้ HAL กระบวนการเดียวกัน (SP-HAL) ทั้งหมด
ยกเว้น RenderScript จะโหลดภายในเนมสเปซของ Linker
sphal
RenderScript โหลดไปยัง RenderScript โดยเฉพาะ
Namespace rs
ซึ่งเป็นตำแหน่งที่ตั้งที่ช่วยให้ยกเว้นได้เล็กน้อย
การบังคับใช้สำหรับไลบรารี RenderScript เนื่องจากต้องโหลดการติดตั้งใช้งาน RS
บิตโค้ดที่คอมไพล์แล้ว /data/*/*.so
จะถูกเพิ่มลงในเส้นทางของ
เนมสเปซ rs
(ไม่อนุญาตให้ SP-HAL อื่นๆ โหลดไลบรารีจาก
พาร์ติชันข้อมูล)
นอกจากนี้เนมสเปซ rs
ยังอนุญาตให้มีไลบรารีมากกว่าที่ระบุสำหรับ
เนมสเปซอื่น libmediandk.so
และ libft2.so
แสดงกับเนมสเปซ rs
เนื่องจาก
libRS_internal.so
มีการขึ้นต่อกันภายในกับไลบรารีเหล่านี้
![](https://source.android.google.cn/docs/core/architecture/images/treble_rs_namespace.png?authuser=19&hl=th)
รูปที่ 2 การกำหนดค่าเนมสเปซสำหรับ Linker
โหลดไดรเวอร์
เส้นทางสำรองของ CPU
ขึ้นอยู่กับการมีอยู่ของบิต RS_CONTEXT_LOW_LATENCY
เมื่อสร้างบริบท RS ระบบจะเลือกเส้นทาง CPU หรือ GPU เมื่อ
เลือกเส้นทาง CPU แล้ว libRS_internal.so
(การใช้งานหลัก
ของเฟรมเวิร์ก RS) dlopen
มาจาก Linker เริ่มต้นโดยตรง
เนมสเปซที่ระบุเวอร์ชันแพลตฟอร์มของ RS Libs
ไม่มีการนำการติดตั้งใช้งาน RS HAL จากผู้ให้บริการมาใช้เลยเมื่อ CPU
มีการใช้เส้นทางสำรอง และมีการสร้างออบเจ็กต์ RsContext
ด้วย
null mVendorDriverName
libRSDriver.so
(โดย
ค่าเริ่มต้น) dlopen
และไลบรารีไดรเวอร์จะโหลดจาก
เนมสเปซ default
เนื่องจากผู้โทร
(libRS_internal.so
) ก็โหลดใน default
ด้วย
Namespace
![](https://source.android.google.cn/docs/core/architecture/images/treble_rs_cpu_fallback.png?authuser=19&hl=th)
รูปที่ 3 เส้นทางสำรองของ CPU
เส้นทาง GPU
สำหรับเส้นทาง GPU นั้น libRS_internal.so
จะโหลดต่างไปจากเดิม
อันดับแรก libRS.so
ใช้
android.hardware.renderscript@1.0.so
(และองค์ประกอบที่เกี่ยวข้อง
libhidltransport.so
) ที่จะโหลด
android.hardware.renderscript@1.0-impl.so
(ผู้ให้บริการ
RS HAL) ลงในเนมสเปซ Linker อื่นที่เรียกว่า
sphal
RS
HAL จากนั้น dlopen
ขึ้น libRS_internal.so
ในอีก
เนมสเปซ Linker ที่ชื่อว่า 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
อยู่ในเส้นทางการค้นหาของเนมสเปซ
![](https://source.android.google.cn/docs/core/architecture/images/treble_rs_gpu_fallback.png?authuser=19&hl=th)
รูปที่ 4 เส้นทางสำรองของ GPU
เมื่อเปลี่ยนจากเนมสเปซ default
ไปเป็น
เนมสเปซ sphal
libhidltransport.so
ใช้
android_load_sphal_library()
เพื่อเรียงลำดับฟังก์ชัน
Linker แบบไดนามิกเพื่อโหลดไลบรารี -impl.so
จาก
เนมสเปซ sphal
เมื่อเปลี่ยนจากเนมสเปซ sphal
ไปเป็น
Namespace rs
การโหลดจะเกิดขึ้นโดยอ้อมในบรรทัดต่อไปนี้ใน
/system/etc/ld.config.txt
:
namespace.sphal.link.rs.shared_libs = libRS_internal.so
บรรทัดนี้ระบุว่าตัวลิงก์แบบไดนามิกควรโหลด
libRS_internal.so
จากเนมสเปซ rs
เมื่อ lib
ไม่พบ/โหลดจากเนมสเปซ sphal
(ซึ่งก็คือ
กรณีนี้เนื่องจากเนมสเปซ sphal
ไม่สามารถค้นหา
/system/lib/vndk-sp
โดยที่ libRS_internal.so
อยู่) การกำหนดค่านี้จะทำให้การเรียก 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
และ
โหลด Lib โดยใช้ dlopen()
แบบง่ายโดย
libLLVM.so
ใน Android 8.0 ขึ้นไป จะมีการระบุไว้ในฟิลด์
-plugin
และ lib จะถูกโหลดโดย
bcc
เอง ตัวเลือกนี้จะเปิดใช้เส้นทางที่ไม่ใช่ Android โดยเฉพาะไปยัง
โครงการ LLVM แบบโอเพนซอร์ส
![](https://source.android.google.cn/docs/core/architecture/images/treble_rs_bcc_plugin_old.png?authuser=19&hl=th)
รูปที่ 5 กำลังโหลดปลั๊กอิน bcc, Android 7.x และต่ำกว่า
![](https://source.android.google.cn/docs/core/architecture/images/treble_rs_bcc_plugin_new.png?authuser=19&hl=th)
รูปที่ 6 กำลังโหลดปลั๊กอิน bcc, Android 8.0 ขึ้นไป
ค้นหาเส้นทางสำหรับ ld.mc
ขณะเรียกใช้ ld.mc
ไลบรารีรันไทม์บางส่วนของ RS จะระบุเป็นอินพุต
Linker บิตโค้ด 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 แบบ Passthrough- เพิ่ม
exec_types
ใหม่ทั้งหมดในพาร์ติชันvendor
แล้ว ผ่าน SEPolicy ของผู้ให้บริการต้องมีแอตทริบิวต์vendor_file_type
ซึ่งบังคับใช้ผ่านneverallows
- หลีกเลี่ยงการติดป้ายกำกับเพื่อไม่ให้เกิดความขัดแย้งกับการอัปเดตแพลตฟอร์ม/เฟรมเวิร์กในอนาคต
ไฟล์อื่นที่ไม่ใช่
exec_types
ในพาร์ติชันvendor
- ทรัพยากร Dependency ของไลบรารีทั้งหมดสำหรับ HAL ของกระบวนการเดียวกันที่ระบุ AOSP ต้องเป็น
ติดป้ายกำกับเป็น
same_process_hal_file
โปรดดูรายละเอียดนโยบาย SELinux ที่ Linux ที่เพิ่มประสิทธิภาพด้านความปลอดภัยใน Android
ความเข้ากันได้ของ ABI สำหรับบิตโค้ด
หากไม่ได้เพิ่ม API ใหม่ หมายความว่าเฟรมเวิร์ก RS จะไม่เพิ่มขึ้นตามเวอร์ชัน HAL จะใช้ไดรเวอร์ GPU (HAL 1.0) ที่มีอยู่ต่อไป
สำหรับการเปลี่ยนแปลง HAL เล็กน้อย (HAL 1.1) ซึ่งไม่ส่งผลต่อบิตโค้ด เฟรมเวิร์กควร ใช้ CPU สำรองสำหรับ API ที่เพิ่มเข้ามาใหม่และใช้ไดรเวอร์ GPU (HAL 1.0) ต่อไป ในที่อื่นๆ
สำหรับการเปลี่ยนแปลง HAL ที่สำคัญ (HAL 2.0) ที่มีผลต่อการคอมไพล์/การลิงก์บิตโค้ด RS ควรเลือกไม่โหลดไดรเวอร์ GPU ที่ผู้ให้บริการจัดหาให้ และ ใช้เส้นทาง CPU หรือ Vulkan สำหรับการเร่ง
การใช้บิตโค้ดใน RenderScript เป็น 3 ขั้นตอนดังนี้
ขั้น | รายละเอียด |
---|---|
คอมไพล์ |
|
ลิงก์ |
|
โหลด |
|
นอกจาก HAL แล้ว API รันไทม์และสัญลักษณ์ที่ส่งออกยัง อินเทอร์เฟซ อินเทอร์เฟซไม่ได้มีการเปลี่ยนแปลงตั้งแต่ Android 7.0 (API 24) และ เรายังไม่มีแผนที่จะเปลี่ยนแปลงฟีเจอร์นี้ใน Android 8.0 ขึ้นไป อย่างไรก็ตาม หาก มีการเปลี่ยนแปลง ส่วนเวอร์ชัน HAL ก็จะเพิ่มขึ้นด้วย
การติดตั้งใช้งานของผู้ให้บริการ
Android 8.0 ขึ้นไปต้องมีการเปลี่ยนแปลงไดรเวอร์ GPU บางอย่างเพื่อให้ไดรเวอร์ GPU เป็น ทำงานได้อย่างถูกต้อง
โมดูลไดรเวอร์
- โมดูลไดรเวอร์ต้องไม่ขึ้นอยู่กับไลบรารีระบบที่ไม่ได้อยู่ใน รายการ
- คนขับต้องระบุข้อมูลของตนเอง
android.hardware.renderscript@1.0-impl_{NAME}
หรือประกาศ การใช้งานเริ่มต้นandroid.hardware.renderscript@1.0-impl
เป็น การพึ่งพากัน - การใช้งาน CPU
libRSDriver.so
คือตัวอย่างที่ดีของวิธีการ นำทรัพยากร Dependency ที่ไม่ใช่ VNDK-SP ออก
คอมไพเลอร์บิตโค้ด
คุณคอมไพล์บิตโค้ด RenderScript สำหรับไดรเวอร์ของผู้ให้บริการได้ 2 วิธี ดังนี้
- เรียกใช้คอมไพเลอร์ RenderScript เฉพาะผู้ให้บริการใน
/vendor/bin/
(วิธีการคอมไพล์ GPU ที่แนะนำ) เช่นเดียวกับโมดูลไดรเวอร์อื่นๆ ไบนารีของคอมไพเลอร์ของผู้ให้บริการต้องไม่ขึ้นอยู่กับไลบรารีระบบใดๆ ที่ไม่ได้อยู่ในข้อมูล รายการ RenderScript lib พร้อมให้บริการแก่ผู้ให้บริการ - เรียกสำเนาลับของระบบ:
/system/bin/bcc
ที่ระบุโดยผู้ให้บริการbcc plugin
; ปลั๊กอินนี้ต้องไม่พึ่งไลบรารีระบบใดๆ ที่ ไม่อยู่ในรายชื่อ ไลบรารี RenderScript พร้อมใช้งาน แก่ผู้ให้บริการ
ผู้ให้บริการ bcc plugin
ต้องการแทรกแซง CPU หรือไม่
การคอมไพล์และการพึ่งพา libLLVM.so
ทำได้ยาก
ออก ผู้ให้บริการควรคัดลอก bcc
(และแท็กที่ไม่ใช่ LL-NDK ทั้งหมด
ทรัพยากร Dependency เช่น libLLVM.so
, libbcc.so
) ไปยัง
พาร์ติชัน /vendor
นอกจากนี้ ผู้ให้บริการต้องทำการเปลี่ยนแปลงต่อไปนี้
![](https://source.android.google.cn/docs/core/architecture/images/treble_rs_vendor_driver.png?authuser=19&hl=th)
รูปที่ 7 การเปลี่ยนแปลงไดรเวอร์ของผู้ให้บริการ
- คัดลอก
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
ไฟล์ปฏิบัติการของคอมไพเลอร์จะต้องสามารถเรียกใช้ได้ด้วยกระบวนการของแอป เช่นเดียวกับกรณีต่อไปนี้
สำเนาสำเนาลับ (/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
สำรองสำหรับเส้นทาง CPU
ดูข้อมูลเกี่ยวกับแรงจูงใจในการเลิกใช้งาน Renderscript ได้ในนักพัฒนาแอป Android บล็อก: Android GPU Compute Going Forward ข้อมูลแหล่งข้อมูลสำหรับการเลิกใช้งานนี้มีดังนี้
- ย้ายข้อมูลจาก Renderscript
- ตัวอย่าง RenderScriptMigration
- ชุดเครื่องมือทดแทนของ Intrinsics README
- การเปลี่ยน Intrinsics Toolkit.kt