เฟรมเวิร์กการซิงค์จะอธิบายทรัพยากร Dependency ระหว่าง การทำงานไม่พร้อมกันต่างๆ ในระบบกราฟิกของ Android เฟรมเวิร์ก ให้ API ที่ช่วยให้คอมโพเนนต์สามารถระบุเมื่อมีการปล่อยบัฟเฟอร์ นอกจากนี้ อนุญาตให้ส่งผ่านค่าพื้นฐานของการซิงค์ระหว่างไดรเวอร์จากเคอร์เนล กับพื้นที่ผู้ใช้ และระหว่างการประมวลผลข้อมูลของผู้ใช้เอง
ตัวอย่างเช่น แอปพลิเคชันอาจจัดคิวงานที่ต้องทำใน GPU GPU จะเริ่มวาดรูปนั้น แม้ว่าจะยังไม่ได้วาดรูปภาพ ลงในหน่วยความจำ แล้วส่งบัฟเฟอร์ตัวชี้ไปยังหน้าต่าง compositor พร้อมกับรั้วที่ระบุว่า GPU จะทำงานเมื่อใด เสร็จสิ้น เครื่องมือประกอบหน้าต่างจะเริ่มประมวลผลล่วงหน้าและ เพื่อส่งข้อมูลงานไปยังตัวควบคุมจอแสดงผล ในทำนองเดียวกัน การทำงานของ CPU เสร็จล่วงหน้า เมื่อ GPU เสร็จสิ้น ตัวควบคุมการแสดงผล แสดงรูปภาพได้ทันที
เฟรมเวิร์กการซิงค์ยังช่วยให้ผู้ติดตั้งใช้งานสามารถใช้ประโยชน์จาก ทรัพยากรในการซิงค์ข้อมูลในคอมโพเนนต์ของฮาร์ดแวร์ของตัวเอง สุดท้าย ทำให้มองเห็นไปป์ไลน์กราฟิกเพื่อ การแก้ไขข้อบกพร่อง
การซิงค์ที่ชัดเจน
การซิงค์ข้อมูลที่ชัดเจนจะช่วยให้ผู้ผลิตและผู้บริโภคบัฟเฟอร์กราฟิก เพื่อส่งสัญญาณแจ้งเมื่อใช้บัฟเฟอร์เสร็จแล้ว การซิงค์อย่างชัดเจนคือ ใน Kernel-Space
ประโยชน์ของการซิงค์ข้อมูลอย่างชัดเจนมีดังนี้
- ความแปรผันของลักษณะการทำงานระหว่างอุปกรณ์น้อยลง
- รองรับการแก้ไขข้อบกพร่องที่ดียิ่งขึ้น
- เมตริกการทดสอบที่ปรับปรุงใหม่
เฟรมเวิร์กการซิงค์มีออบเจ็กต์ 3 ประเภทดังนี้
sync_timeline
sync_pt
sync_fence
ไทม์ไลน์การซิงค์
sync_timeline
เป็นไทม์ไลน์ที่เพิ่มขึ้นเรื่อยๆ
ผู้ให้บริการควรใช้สำหรับอินสแตนซ์ไดรเวอร์แต่ละรายการ เช่น บริบท GL
ตัวควบคุมการแสดงผล หรือบลิตเตอร์แบบ 2 มิติ จำนวน sync_timeline
รายการ
งานที่ส่งไปยังเคอร์เนลสำหรับฮาร์ดแวร์หนึ่งๆ
sync_timeline
ให้การรับประกันเกี่ยวกับลำดับการดำเนินการ
และเปิดใช้การใช้งานเฉพาะฮาร์ดแวร์
ทำตามหลักเกณฑ์ต่อไปนี้เมื่อติดตั้งใช้งาน sync_timeline
- ระบุชื่อที่เป็นประโยชน์สำหรับคนขับ ไทม์ไลน์ และรั้วทั้งหมดเพื่อลดความซับซ้อน การแก้ไขข้อบกพร่อง
- นำ
timeline_value_str
และpt_value_str
ไปใช้ ในไทม์ไลน์เพื่อให้ผลการแก้ไขข้อบกพร่องอ่านง่ายขึ้น - ใช้
driver_data
แบบเต็มเพื่อมอบไลบรารีพื้นที่ผู้ใช้ เช่น ไลบรารี GL เข้าถึงข้อมูลไทม์ไลน์ส่วนตัว หากต้องการdata_driver
ช่วยให้ผู้ให้บริการส่งต่อข้อมูลเกี่ยวกับการเปลี่ยนแปลงไม่ได้sync_fence
และsync_pts
เพื่อสร้างบรรทัดคำสั่ง โดยอิงจากพวกเขา - ไม่อนุญาตให้ผู้ใช้สร้างหรือส่งสัญญาณรั้วอย่างชัดแจ้ง ชัดเจน การสร้างสัญญาณ/รั้วจะทำให้เกิดการโจมตีแบบปฏิเสธการให้บริการ หยุดฟังก์ชันการทำงานของไปป์ไลน์
- ไม่เข้าถึง
sync_timeline
,sync_pt
หรือsync_fence
องค์ประกอบอย่างชัดเจน API มีข้อมูลที่จำเป็นทั้งหมด
ซิงค์_พอยต์
sync_pt
เป็นค่าเดียวหรือคะแนน
sync_timeline
คะแนน
มี 3 สถานะ ได้แก่ ใช้งานอยู่ ได้รับสัญญาณ และมีข้อผิดพลาด คะแนนจะเริ่มในสถานะใช้งานอยู่
และเปลี่ยนเป็นสถานะที่มีสัญญาณหรือข้อผิดพลาด เช่น เมื่อรูปภาพ
ผู้บริโภคไม่ต้องการบัฟเฟอร์อีกต่อไป โดยจะมีสัญญาณ sync_pt
เพื่อให้ผู้ผลิตภาพรู้ว่าสามารถเขียนลงในบัฟเฟอร์ได้อีกครั้ง
รั้วซิงค์
sync_fence
คือคอลเล็กชันที่มี sync_pt
ค่า
บ่อยครั้ง
มีผู้เผยแพร่โฆษณาหลัก sync_timeline
ที่แตกต่างกัน (เช่น สำหรับเครือข่ายดิสเพลย์
ตัวควบคุมและ GPU) sync_fence
, sync_pt
และ
sync_timeline
คือค่าพื้นฐานหลักๆ ที่ไดรเวอร์และพื้นที่ผู้ใช้
ใช้สื่อสารทรัพยากร Dependency ได้ เมื่อมีสัญญาณรั้ว
คำสั่งที่ออกก่อนการกำหนดรั้วมีการรับประกันว่าจะเสร็จสมบูรณ์เนื่องจาก
ไดรเวอร์เคอร์เนลหรือบล็อกฮาร์ดแวร์จะดำเนินการตามคำสั่งตามลำดับ
เฟรมเวิร์กการซิงค์ช่วยให้ผู้บริโภคหรือผู้ผลิตหลายรายสามารถส่งสัญญาณ
ใช้บัฟเฟอร์เสร็จ โดยสื่อสารข้อมูลทรัพยากร Dependency ด้วยฟังก์ชันเดียว
พารามิเตอร์ รั้วได้รับการสนับสนุนโดยข้อบ่งชี้ไฟล์และส่งมาจาก
พื้นที่เคอร์เนลไปยังพื้นที่ผู้ใช้ เช่น รั้วอาจมี
ค่า sync_pt
ที่บ่งบอกเวลาเสร็จสิ้นการใช้รูปภาพ 2 รูป
การอ่านบัฟเฟอร์ เมื่อมีสัญญาณรั้วแล้ว ผู้ผลิตรูปภาพจะทราบว่า
ผู้บริโภคนั้นบริโภคเนื้อหาในอินเทอร์เน็ต
รั้ว เช่น ค่า sync_pt
จะเริ่มต้นใช้งานอยู่และเปลี่ยนสถานะตาม
สถานะคะแนน หากค่า sync_pt
ทั้งหมดได้รับสัญญาณ ค่า
sync_fence
ได้รับสัญญาณ หากมี sync_pt
ตก
สถานะข้อผิดพลาด sync_fence
ทั้งหมดจะมีสถานะเป็นข้อผิดพลาด
การเป็นสมาชิกใน sync_fence
จะเปลี่ยนแปลงไม่ได้หลังจากที่มีสิทธิ์
สร้าง แล้ว หากต้องการได้มากกว่าหนึ่งจุดในรั้ว การผสานจะเท่ากับ
โดยมีการเพิ่มคะแนนจาก 2 รั้วที่แตกต่างกันไปยังรั้วที่ 3
หากจุดใดจุดหนึ่งได้รับสัญญาณในรั้วต้นทาง แต่อีกจุดหนึ่งไม่มีสัญญาณ
รั้วที่สามจะไม่อยู่ในสถานะส่งสัญญาณด้วย
ในการใช้การซิงค์ข้อมูลอย่างชัดเจน โปรดระบุข้อมูลต่อไปนี้
- ระบบย่อยของ Kernel Space ที่ใช้เฟรมเวิร์กการซิงค์
สำหรับไดรเวอร์ฮาร์ดแวร์เฉพาะ คนขับที่ต้องระวังรั้ว
โดยทั่วไปแล้วทุกสิ่งที่เข้าถึงหรือสื่อสารกับฮาร์ดแวร์คอมโพสเซอร์
ไฟล์หลักมีดังนี้
- การใช้งานหลัก
kernel/common/include/linux/sync.h
kernel/common/drivers/base/sync.c
- เอกสารประกอบที่
kernel/common/Documentation/sync.txt
- ไลบรารีสำหรับสื่อสารกับพื้นที่ของเคอร์เนลใน
platform/system/core/libsync
- การใช้งานหลัก
- ผู้ให้บริการต้องระบุการซิงค์ข้อมูลที่เหมาะสม
เป็นพารามิเตอร์ให้กับ
validateDisplay()
และpresentDisplay()
ฟังก์ชันใน HAL - ส่วนขยาย GL ที่เกี่ยวข้องกับรั้ว 2 รายการ (
EGL_ANDROID_native_fence_sync
และEGL_ANDROID_wait_sync
) และการรองรับรั้วในกราฟิก คนขับ
กรณีศึกษา: ใช้ไดรเวอร์จอแสดงผล
หากต้องการใช้ API ที่รองรับฟังก์ชันการซิงค์
พัฒนาไดรเวอร์จอแสดงผลที่มีฟังก์ชันบัฟเฟอร์จอแสดงผล ก่อนการเปลี่ยนแปลง
มีเฟรมเวิร์กการซิงค์อยู่แล้ว ฟังก์ชันนี้จะได้รับ dma-buf
วางบัฟเฟอร์เหล่านั้นบนจอแสดงผล และบล็อกขณะที่เห็นบัฟเฟอร์ สำหรับ
ตัวอย่าง:
/* * assumes buffer is ready to be displayed. returns when buffer is no longer on * screen. */ void display_buffer(struct dma_buf *buffer);
เมื่อใช้เฟรมเวิร์กการซิงค์ ฟังก์ชัน display_buffer
นั้นจะมีความซับซ้อนมากขึ้น ขณะวางบัฟเฟอร์บนจอแสดงผล ระบบจะเชื่อมโยงบัฟเฟอร์
พร้อมด้วยรั้วที่บอกว่าบัฟเฟอร์จะพร้อมใช้งานเมื่อใด คุณจัดคิวได้
และเริ่มตกแต่ง
หลังจากที่ตัดรั้วออกแล้ว
การจัดคิวและเริ่มต้นงานหลังจากเคลียร์รั้วแล้วจะไม่บล็อกอะไรเลย คุณจะต้องคืนรั้วของตัวเองทันที ซึ่งรับประกันได้ว่าจะมีการบัฟเฟอร์ จะอยู่นอกจอแสดงผล เมื่อคุณจัดคิวบัฟเฟอร์ เคอร์เนลจะแสดงรายการ ทรัพยากร Dependency ด้วยเฟรมเวิร์กการซิงค์
/* * displays buffer when fence is signaled. returns immediately with a fence * that signals when buffer is no longer displayed. */ struct sync_fence* display_buffer(struct dma_buf *buffer, struct sync_fence *fence);
การผสานรวมการซิงค์
ส่วนนี้จะอธิบายวิธีผสานรวมเฟรมเวิร์กการซิงค์พื้นที่เคอร์เนลกับ ส่วนของพื้นที่ผู้ใช้ของเฟรมเวิร์ก Android และไดรเวอร์ที่ต้องสื่อสาร ให้กันและกัน ออบเจ็กต์ช่องว่างของเคอร์เนลแสดงเป็นข้อบ่งชี้ไฟล์ใน พื้นที่ผู้ใช้
แบบแผนการรวม
ปฏิบัติตามข้อกำหนดของอินเทอร์เฟซ HAL ของ Android ดังนี้
- หาก API มีข้อบ่งชี้ไฟล์ที่อ้างถึง
sync_pt
ไดรเวอร์ของผู้ให้บริการหรือ HAL ที่ใช้ API ต้องปิดข้อบ่งชี้ไฟล์ - หากไดรเวอร์ของผู้ให้บริการหรือ HAL ส่งข้อบ่งชี้ไฟล์ที่มี
sync_pt
ไปยังฟังก์ชัน API ไดรเวอร์ของผู้ให้บริการหรือ HAL ต้องไม่ ปิดข้อบ่งชี้ไฟล์ - หากต้องการใช้ข้อบ่งชี้ไฟล์ fence, ไดรเวอร์ของผู้ให้บริการ หรือ HAL ต้องทำซ้ำข้อบ่งชี้
ระบบจะเปลี่ยนชื่อออบเจ็กต์รั้วทุกครั้งที่ผ่าน BufferQueue
การรองรับรั้วเคอร์เนลช่วยให้ fences มีสตริงสำหรับตั้งชื่อ ดังนั้นการซิงค์
เฟรมเวิร์กใช้ชื่อหน้าต่างและดัชนีบัฟเฟอร์ที่อยู่ในคิวเพื่อตั้งชื่อ
รั้ว เช่น SurfaceView:0
ช่วงเวลานี้
มีประโยชน์ในการแก้ไขข้อบกพร่องเพื่อระบุแหล่งที่มาของการติดตายเมื่อชื่อปรากฏขึ้น
ในเอาต์พุตของ /d/sync
และรายงานข้อบกพร่อง
การผสานรวม ANativeWindow
A NativeWindow จะคำนึงถึงระดับรั้ว dequeueBuffer
,
queueBuffer
และ cancelBuffer
มีพารามิเตอร์รั้ว
การผสานรวม OpenGL ES
การผสานรวมการซิงค์ OpenGL ES ต้องใช้ส่วนขยาย EGL 2 รายการดังนี้
EGL_ANDROID_native_fence_sync
มีวิธีให้ รวมหรือสร้างข้อบ่งชี้ไฟล์รั้ว Android แบบเนทีฟในEGLSyncKHR
ออบเจ็กต์EGL_ANDROID_wait_sync
อนุญาตคอลัมน์ฝั่ง GPU แทนที่จะเป็นฝั่ง CPU ทำให้ GPU รอEGLSyncKHR
ส่วนขยายEGL_ANDROID_wait_sync
เหมือนกับ ส่วนขยายEGL_KHR_wait_sync
หากต้องการใช้ส่วนขยายเหล่านี้แยกต่างหาก ให้ใช้
ส่วนขยาย EGL_ANDROID_native_fence_sync
รายการพร้อมด้วยส่วนขยายที่เกี่ยวข้อง
การสนับสนุนเคอร์เนล ต่อไป ให้เปิดใช้ EGL_ANDROID_wait_sync
ในไดรเวอร์ของคุณ EGL_ANDROID_native_fence_sync
ส่วนขยายประกอบด้วยออบเจ็กต์ EGLSyncKHR
สำหรับ Fence ดั้งเดิมที่แตกต่างกัน
ประเภท ด้วยเหตุนี้ ส่วนขยายที่ใช้กับ EGLSyncKHR
ที่มีอยู่
ไม่จำเป็นต้องใช้ประเภทออบเจ็กต์กับ EGL_ANDROID_native_fence
เพื่อหลีกเลี่ยงการโต้ตอบที่ไม่ต้องการ
ส่วนขยาย EGL_ANDROID_native_fence_sync
ใช้โฆษณาเนทีฟที่เกี่ยวข้อง
แอตทริบิวต์ข้อบ่งชี้ไฟล์ fence ที่ตั้งค่าได้เฉพาะตอนที่สร้างและ
คุณจะค้นหาจากออบเจ็กต์การซิงค์ที่มีอยู่โดยตรงไม่ได้อีกต่อไป แอตทริบิวต์นี้
สามารถตั้งค่าเป็น 1 ใน 2 โหมดต่อไปนี้
- ข้อบ่งชี้ไฟล์รั้วที่ถูกต้องรวมโฆษณาเนทีฟที่มีอยู่
ข้อบ่งชี้ไฟล์ fence ของ Android ในออบเจ็กต์
EGLSyncKHR
- -1 สร้างข้อบ่งชี้ไฟล์ค่าเริ่มต้นของ Android Fence จาก
ออบเจ็กต์
EGLSyncKHR
รายการ
ใช้การเรียกฟังก์ชัน DupNativeFenceFD()
เพื่อดึงข้อมูล
EGLSyncKHR
จากข้อบ่งชี้ไฟล์ Fence แบบดั้งเดิมของ Android
ซึ่งได้ผลลัพธ์เหมือนกับการค้นหาแอตทริบิวต์ set แต่จะเป็นไปตาม
แบบแผนว่าผู้รับปิดรั้ว (ดังนั้นจึงสำเนา
การดำเนินการ) สุดท้าย การทำลายออบเจ็กต์ EGLSyncKHR
จะปิด
แอตทริบิวต์ fence ภายใน
การผสานรวมฮาร์ดแวร์คอมโพสเซอร์
ฮาร์ดแวร์คอมโพสเซอร์จะจัดการกับประเภทการซิงค์ 3 ประเภทดังนี้
- มองหารั้วจะส่งไปพร้อมกับบัฟเฟอร์อินพุตไปยัง
สายจาก
setLayerBuffer
และsetClientTarget
ซึ่งแสดงถึงการเขียนที่รอดำเนินการลงในบัฟเฟอร์และต้องส่งสัญญาณก่อน SurfaceFlinger หรือ HWC พยายามอ่านจากบัฟเฟอร์ที่เกี่ยวข้องไปยัง ทำการเรียบเรียง - มีการเรียกรั้วกั้นหลังการโทรเพื่อ
presentDisplay
โดยใช้การโทรgetReleaseFences
ค่าเหล่านี้แสดงถึงการอ่านที่รอดำเนินการจากบัฟเฟอร์ก่อนหน้าในเลเยอร์เดียวกัน ต ปล่อยสัญญาณรั้วเมื่อ HWC ไม่ใช้บัฟเฟอร์ก่อนหน้านี้อีกต่อไป เนื่องจากบัฟเฟอร์ปัจจุบันได้มาแทนที่บัฟเฟอร์ก่อนหน้าในจอแสดงผล ระบบจะส่งคืนรั้วสำหรับปล่อยกลับไปยังแอปพร้อมกับบัฟเฟอร์ก่อนหน้านี้ที่ จะถูกแทนที่ในระหว่างการแต่งปัจจุบัน โดยแอปจะต้องรอจนกว่า ปล่อยสัญญาณรั้วก่อนที่จะเขียนเนื้อหาใหม่ลงในบัฟเฟอร์ คืนให้ - รั้วปัจจุบันจะแสดงแบบ 1 รายการต่อเฟรม ซึ่งเป็นส่วนหนึ่งของ
การโทรไปยัง
presentDisplay
รั้วนำเสนอแสดงให้เห็นว่า องค์ประกอบของเฟรมนี้เสร็จสมบูรณ์ หรือในบางกรณี ไม่จำเป็นต้องใช้ผลลัพธ์องค์ประกอบของเฟรมก่อนหน้าแล้ว สำหรับจับต้องได้presentDisplay
จะแสดงผลรั้วปัจจุบันเมื่อ เฟรมปัจจุบันจะปรากฏขึ้นบนหน้าจอ หลังจากการล้อมรั้วปัจจุบันแล้ว สามารถเขียนไปยังบัฟเฟอร์เป้าหมายของ SurfaceFlinger อีกครั้งได้ หาก ที่เกี่ยวข้อง สำหรับจอแสดงผลเสมือน ระบบจะส่งคืนรั้วปัจจุบันเมื่อ เหมาะสำหรับการอ่านจากบัฟเฟอร์เอาต์พุต