RenderScript เป็นเฟรมเวิร์กสำหรับการรันงานที่เน้นการประมวลผลและประสิทธิภาพสูงบน Android ได้รับการออกแบบมาเพื่อใช้กับการคำนวณข้อมูลแบบคู่ขนาน แม้ว่าปริมาณงานแบบอนุกรมจะได้รับประโยชน์เช่นกัน รันไทม์ RenderScript ทำงานแบบขนานระหว่างโปรเซสเซอร์ที่มีอยู่ในอุปกรณ์ เช่น CPU และ GPU แบบมัลติคอร์ ช่วยให้นักพัฒนามุ่งเน้นไปที่การแสดงอัลกอริธึมแทนที่จะจัดตารางเวลางาน RenderScript มีประโยชน์อย่างยิ่งสำหรับแอพพลิเคชั่นที่ประมวลผลภาพ การถ่ายภาพด้วยคอมพิวเตอร์ หรือคอมพิวเตอร์วิทัศน์
อุปกรณ์ที่ใช้ Android 8.0 และสูงกว่าใช้เฟรมเวิร์ก RenderScript และ HAL ของผู้จำหน่ายต่อไปนี้:
ความแตกต่างจาก RenderScript ใน Android 7.x และต่ำกว่า ได้แก่:
- libs ภายใน RenderScript สองอินสแตนซ์อยู่ในกระบวนการ ชุดหนึ่งสำหรับเส้นทางสำรองของ CPU และมาจากโดยตรงที่
/system/lib
; อีกชุดหนึ่งสำหรับเส้นทาง GPU และมาจาก/system/lib/vndk-sp
- libs ภายใน RS ใน
/system/lib
ถูกสร้างขึ้นโดยเป็นส่วนหนึ่งของแพลตฟอร์มและได้รับการอัปเดตเมื่อsystem.img
ได้รับการอัปเกรด อย่างไรก็ตาม libs ใน/system/lib/vndk-sp
ถูกสร้างขึ้นสำหรับผู้จำหน่ายและจะไม่อัปเดตเมื่อมีการอัปเกรดsystem.img
(แม้ว่าจะสามารถอัปเดตเพื่อแก้ไขปัญหาด้านความปลอดภัยได้ แต่ ABI จะยังคงเหมือนเดิม) - รหัสผู้ขาย (RS HAL, ไดรเวอร์ RS และ
bcc plugin
) เชื่อมโยงกับ libs ภายใน RenderScript ซึ่งอยู่ที่/system/lib/vndk-sp
ไม่สามารถเชื่อมโยงกับ libs ใน/system/lib
ได้ เนื่องจาก libs ในไดเร็กทอรีนั้นถูกสร้างขึ้นสำหรับแพลตฟอร์ม และอาจเข้ากันไม่ได้กับโค้ดของผู้จำหน่าย (กล่าวคือ สัญลักษณ์อาจถูกลบออก) การทำเช่นนี้จะทำให้ OTA เฉพาะเฟรมเวิร์กเป็นไปไม่ได้
ออกแบบ
ส่วนต่อไปนี้ให้รายละเอียดเกี่ยวกับการออกแบบ RenderScript ใน Android 8.0 และสูงกว่า
RenderScript libs พร้อมใช้งานสำหรับผู้ขาย
ส่วนนี้แสดงรายการ RenderScript libs (เรียกว่า Vendor NDK สำหรับ Same-Process HAL หรือ VNDK-SP) ที่พร้อมใช้งานสำหรับโค้ดผู้จำหน่ายและสามารถเชื่อมโยงได้ นอกจากนี้ยังมีรายละเอียดไลบรารีเพิ่มเติมที่ไม่เกี่ยวข้องกับ RenderScript แต่มีให้กับรหัสผู้ขายด้วย
แม้ว่ารายการไลบรารีต่อไปนี้อาจแตกต่างกันระหว่าง Android รุ่นต่างๆ แต่ก็ไม่เปลี่ยนแปลงสำหรับ Android รุ่นใดรุ่นหนึ่ง สำหรับรายการไลบรารีที่มีอยู่ล่าสุด โปรดดูที่ /system/etc/ld.config.txt
RenderScript Libs | Libs ที่ไม่ใช่ RenderScript |
---|---|
|
|
การกำหนดค่าเนมสเปซของลิงก์เกอร์
ข้อจำกัดในการลิงก์ที่ป้องกันไม่ให้ libs ที่ไม่ได้อยู่ใน VNDK-SP ถูกใช้โดยรหัสผู้จำหน่ายนั้นถูกบังคับใช้ในขณะรันไทม์โดยใช้เนมสเปซของตัวเชื่อมโยง (สำหรับรายละเอียด โปรดดูการนำเสนอของ VNDK Design )
บนอุปกรณ์ที่ใช้ Android 8.0 และสูงกว่า Same-Process HALs (SP-HAL) ทั้งหมด ยกเว้น RenderScript จะถูกโหลดภายใน sphal
สเปซตัวเชื่อมโยง RenderScript ถูกโหลดลงในเนมสเปซเฉพาะของ RenderScript rs
ซึ่งเป็นตำแหน่งที่ทำให้การบังคับใช้ RenderScript libs ลดลงเล็กน้อย เนื่องจากการใช้งาน RS จำเป็นต้องโหลดบิตโค้ดที่คอมไพล์แล้ว /data/*/*.so
จะถูกเพิ่มไปยังพาธของเนมสเปซ rs
(SP-HAL อื่นๆ ไม่ได้รับอนุญาตให้โหลด libs จากพาร์ติชันข้อมูล)
นอกจากนี้ เนมสเปซ rs
ยังอนุญาตให้มี libs มากกว่าที่เนมสเปซอื่นๆ ระบุไว้ libmediandk.so
และ libft2.so
ถูกเปิดเผยต่อเนมสเปซ rs
เนื่องจาก libRS_internal.so
มีการพึ่งพาภายในกับไลบรารีเหล่านี้
กำลังโหลดไดรเวอร์
เส้นทางสำรองของ CPU
ขึ้นอยู่กับการมีอยู่ของบิต RS_CONTEXT_LOW_LATENCY
เมื่อสร้างบริบท RS จะมีการเลือกเส้นทาง CPU หรือ GPU เมื่อเลือกเส้นทาง CPU แล้ว libRS_internal.so
(การใช้งานหลักของเฟรมเวิร์ก RS) จะ dlopen
ed โดยตรงจากเนมสเปซตัวเชื่อมโยงเริ่มต้นซึ่งมีเวอร์ชันแพลตฟอร์มของ RS libs ไว้
การใช้งาน RS HAL จากผู้จัดจำหน่ายจะไม่ถูกใช้เลยเมื่อมีการใช้เส้นทางสำรองของ CPU และวัตถุ RsContext
ถูกสร้างขึ้นด้วยค่า null mVendorDriverName
libRSDriver.so
คือ (โดยค่าเริ่มต้น) dlopen
ed และไดรเวอร์ lib ถูกโหลดจากเนมสเปซ default
เนื่องจากผู้เรียก ( libRS_internal.so
) ก็ถูกโหลดในเนมสเปซ default
เช่นกัน
เส้นทาง GPU
สำหรับเส้นทาง 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 จากนั้น dlopen
s libRS_internal.so
ในเนมสเปซตัวเชื่อมโยงอื่นที่เรียกว่า rs
ผู้จำหน่ายสามารถจัดเตรียมไดรเวอร์ RS ของตนเองได้โดยตั้งค่าแฟล็กเวลาบิลด์ OVERRIDE_RS_DRIVER
ซึ่งฝังอยู่ในการใช้งาน RS HAL ( hardware/interfaces/renderscript/1.0/default/Context.cpp
) จากนั้นชื่อไดรเวอร์นี้จะถูก dlopen
ed สำหรับบริบท 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
เมื่อไม่พบ/โหลด lib จากเนมสเปซ sphal
(ซึ่งเป็นกรณีเสมอเนื่องจากเนมสเปซ sphal
ไม่ได้ค้นหา /system/lib/vndk-sp
โดยที่ libRS_internal.so
อยู่) ด้วยการกำหนดค่านี้ การเรียก dlopen()
แบบธรรมดาไปยัง libRS_internal.so
ก็เพียงพอแล้วสำหรับการเปลี่ยนแปลงเนมสเปซ
กำลังโหลดปลั๊กอิน bcc
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 โอเพ่นซอร์ส
ค้นหาเส้นทางสำหรับ ld.mc
เมื่อดำเนินการ ld.mc
libs รันไทม์ RS บางส่วนจะได้รับเป็นอินพุตไปยังตัวเชื่อมโยง บิตโค้ด RS จากแอปเชื่อมโยงกับรันไทม์ libs และเมื่อมีการโหลดบิตโค้ดที่แปลงแล้วลงในกระบวนการของแอป libs รันไทม์จะถูกลิงก์แบบไดนามิกอีกครั้งจากบิตโค้ดที่แปลงแล้ว
libs รันไทม์ประกอบด้วย:
-
libcompiler_rt.so
-
libm.so
-
libc.so
- ไดรเวอร์ RS (อย่างใดอย่างหนึ่ง
libRSDriver.so
หรือOVERRIDE_RS_DRIVER
)
เมื่อโหลดบิตโค้ดที่คอมไพล์แล้วลงในกระบวนการของแอป ให้จัดเตรียมไลบรารีเดียวกันกับที่ ld.mc
ใช้ มิฉะนั้น บิตโค้ดที่คอมไพล์แล้วอาจไม่พบสัญลักษณ์ที่พร้อมใช้งานเมื่อมีการเชื่อมโยง
ในการทำเช่นนั้น เฟรมเวิร์ก RS จะใช้พาธการค้นหาที่แตกต่างกันสำหรับรันไทม์ libs เมื่อดำเนินการ ld.mc
ขึ้นอยู่กับว่าเฟรมเวิร์ก RS นั้นถูกโหลดจาก /system/lib
หรือจาก /system/lib/vndk-sp
ซึ่งสามารถกำหนดได้โดยการอ่านที่อยู่ของสัญลักษณ์ที่กำหนดเองของ RS framework lib และใช้ 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 โปรดดู Security-Enhanced Linux ใน Android
ความเข้ากันได้ของ ABI สำหรับบิตโค้ด
หากไม่มีการเพิ่ม API ใหม่ ซึ่งหมายความว่าไม่มีการชนเวอร์ชัน HAL เฟรมเวิร์ก RS จะใช้ไดรเวอร์ GPU ที่มีอยู่ (HAL 1.0) ต่อไป
สำหรับการเปลี่ยนแปลง HAL เล็กน้อย (HAL 1.1) ที่ไม่ส่งผลกระทบต่อบิตโค้ด เฟรมเวิร์กควรถอยกลับไปใช้ CPU สำหรับ API ที่เพิ่มใหม่เหล่านี้ และใช้ไดรเวอร์ GPU (HAL 1.0) ต่อไป
สำหรับการเปลี่ยนแปลง HAL ที่สำคัญ (HAL 2.0) ที่ส่งผลต่อการคอมไพล์/การลิงก์บิตโค้ด เฟรมเวิร์ก RS ควรเลือกที่จะไม่โหลดไดรเวอร์ GPU ที่ผู้จำหน่ายจัดหาให้ และใช้เส้นทาง CPU หรือ Vulkan แทนเพื่อเร่งความเร็ว
การใช้บิตโค้ด RenderScript เกิดขึ้นในสามขั้นตอน:
เวที | รายละเอียด |
---|---|
รวบรวม |
|
ลิงค์ |
|
โหลด |
|
นอกจาก HAL แล้ว runtime 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
เป็นตัวอย่างที่ดีของวิธีลบการพึ่งพาที่ไม่ใช่ VNDK-SP
คอมไพเลอร์ Bitcode
คุณสามารถคอมไพล์บิตโค้ด RenderScript สำหรับไดรเวอร์ของผู้จำหน่ายได้สองวิธี:
- เรียกใช้คอมไพเลอร์ RenderScript เฉพาะผู้จำหน่ายใน
/vendor/bin/
(วิธีที่แนะนำในการคอมไพล์ GPU) เช่นเดียวกับโมดูลไดรเวอร์อื่นๆ ไบนารีของคอมไพเลอร์ของผู้จำหน่ายไม่สามารถขึ้นอยู่กับไลบรารีระบบใดๆ ที่ไม่ได้อยู่ในรายการ RenderScript libs ที่ผู้จำหน่ายสามารถใช้ได้ - เรียกใช้ระบบ bcc:
/system/bin/bcc
ด้วยbcc plugin
ที่ผู้ขายจัดเตรียมให้ ; ปลั๊กอินนี้ไม่สามารถขึ้นอยู่กับไลบรารีระบบใดๆ ที่ไม่ได้อยู่ในรายการ RenderScript libs ที่ผู้จำหน่ายสามารถใช้ได้
หาก bcc plugin
ของผู้จำหน่ายจำเป็นต้องรบกวนการคอมไพล์ CPU และการพึ่งพา 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 ไปยังเส้นทาง CPU
สำหรับข้อมูลเกี่ยวกับแรงจูงใจในการเลิกใช้งาน Renderscript โปรดดูบล็อกของนักพัฒนา Android: Android GPU Compute Going Forward ข้อมูลทรัพยากรสำหรับการเลิกใช้งานนี้มีดังต่อไปนี้:
- ย้ายข้อมูลจาก Renderscript
- ตัวอย่าง RenderScriptMigration
- ชุดเครื่องมือทดแทนภายใน README
- Intrinsics Replacement Toolkit.kt