เฟรมเวิร์กการซิงค์

เฟรมเวิร์กการซิงค์จะอธิบายทรัพยากร 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 อีกครั้งได้ หาก ที่เกี่ยวข้อง สำหรับจอแสดงผลเสมือน ระบบจะส่งคืนรั้วปัจจุบันเมื่อ เหมาะสำหรับการอ่านจากบัฟเฟอร์เอาต์พุต