SurfaceFlinger ยอมรับ สร้าง และส่งบัฟเฟอร์ไปยังจอแสดงผล WindowManager จะให้บัฟเฟอร์และข้อมูลเมตาของหน้าต่างแก่ SurfaceFlinger ซึ่ง SurfaceFlinger จะใช้ข้อมูลดังกล่าวเพื่อสร้างพื้นผิวแบบผสมไปยังจอแสดงผล
SurfaceFlinger
SurfaceFlinger ยอมรับบัฟเฟอร์ได้ 2 วิธี ได้แก่ ผ่าน BufferQueue และ
SurfaceControl หรือผ่าน ASurfaceControl
วิธีหนึ่งที่ SurfaceFlinger ยอมรับบัฟเฟอร์คือผ่าน BufferQueue และ SurfaceControl เมื่อแอปมาอยู่เบื้องหน้า แอปจะขอบัฟเฟอร์จาก
WindowManager จากนั้น WindowManager จะขอเลเยอร์จาก SurfaceFlinger เลเยอร์คือการรวมกันของพื้นผิวที่มี BufferQueue และ
อินสแตนซ์ SurfaceControl ที่
มีข้อมูลเมตาของเลเยอร์ เช่น เฟรมจอแสดงผล
SurfaceFlinger จะสร้างเลเยอร์และส่งไปยัง WindowManager จากนั้น WindowManager จะส่งพื้นผิวไปยังแอป แต่เก็บอินสแตนซ์ SurfaceControl ไว้เพื่อจัดการลักษณะที่ปรากฏของแอปบนหน้าจอ
ASurfaceControl มีวิธีอื่นให้ SurfaceFlinger ยอมรับบัฟเฟอร์ได้ตั้งแต่ Android 10 เป็นต้นไป ASurfaceControl จะรวมพื้นผิว
และอินสแตนซ์ SurfaceControl ไว้ในแพ็กเกจธุรกรรมเดียวที่ SurfaceFlinger ได้รับ ASurfaceControl เชื่อมโยงกับเลเยอร์ที่แอปอัปเดตผ่านอินสแตนซ์ ASurfaceTransaction จากนั้นแอปจะได้รับข้อมูลเกี่ยวกับ
ASurfaceTransaction อินสแตนซ์ผ่านการเรียกกลับที่ส่ง ASurfaceTransactionStats
ซึ่งมีข้อมูล เช่น เวลาในการล็อก เวลาในการรับ เป็นต้น
ตารางต่อไปนี้อธิบาย ASurfaceControl และคอมโพเนนต์ที่เกี่ยวข้อง
| คอมโพเนนต์ | คำอธิบาย |
|---|---|
ASurfaceControl |
ห่อหุ้ม SurfaceControl และช่วยให้แอปสร้างอินสแตนซ์ SurfaceControl ที่
สอดคล้องกับเลเยอร์บนจอแสดงผลสามารถสร้างเป็นองค์ประกอบย่อยของ ANativeWindow หรือเป็นองค์ประกอบย่อยของอินสแตนซ์ ASurfaceControl อื่น |
ASurfaceTransaction |
ห่อหุ้ม Transaction เพื่อให้ไคลเอ็นต์แก้ไขพร็อพเพอร์ตี้เชิงอธิบายของเลเยอร์ เช่น รูปทรงเรขาคณิต และส่งบัฟเฟอร์ที่อัปเดตไปยัง SurfaceFlinger |
ASurfaceTransactionStats |
ส่งข้อมูลเกี่ยวกับธุรกรรมที่แสดง เช่น เวลาในการล็อก เวลาในการรับ และรั้วการเผยแพร่ก่อนหน้า ไปยังแอปผ่านการเรียกกลับที่ลงทะเบียนไว้ล่วงหน้า |
แม้ว่าแอปจะส่งบัฟเฟอร์ได้ทุกเมื่อ แต่ SurfaceFlinger จะทำงานเพื่อยอมรับบัฟเฟอร์ระหว่างการรีเฟรชจอแสดงผลเท่านั้น ซึ่งอาจแตกต่างกันไปตามอุปกรณ์ วิธีนี้จะช่วยลดการใช้งานหน่วยความจำและหลีกเลี่ยงการฉีกขาดที่มองเห็นได้บนหน้าจอ ซึ่งอาจเกิดขึ้นเมื่ออัปเดตจอแสดงผลระหว่างการรีเฟรช
เมื่อจอแสดงผลอยู่ระหว่างการรีเฟรช จอแสดงผลจะส่งสัญญาณ VSync ไปยัง SurfaceFlinger สัญญาณ VSync บ่งชี้ว่าจอแสดงผลสามารถรีเฟรชได้โดยไม่เกิดการฉีกขาด เมื่อ SurfaceFlinger ได้รับสัญญาณ VSync ระบบจะตรวจสอบรายการเลเยอร์เพื่อหาบัฟเฟอร์ใหม่ หากพบบัฟเฟอร์ใหม่ SurfaceFlinger จะรับบัฟเฟอร์ดังกล่าว หากไม่พบ ระบบจะใช้บัฟเฟอร์ที่รับก่อนหน้านี้ต่อไป SurfaceFlinger ต้องแสดงบางสิ่งบางอย่างเสมอ จึงจะเก็บบัฟเฟอร์ไว้ 1 รายการ หากไม่มีการส่งบัฟเฟอร์ในเลเยอร์ SurfaceFlinger จะไม่สนใจเลเยอร์นั้น
หลังจากที่ SurfaceFlinger รวบรวมบัฟเฟอร์ทั้งหมดสำหรับเลเยอร์ที่มองเห็นได้แล้ว ระบบจะถาม Hardware Composer (HWC) ว่าควรทำการสร้างแบบผสมอย่างไร หาก HWC ทำเครื่องหมายประเภทการสร้างแบบผสมของเลเยอร์เป็นการสร้างแบบผสมของไคลเอ็นต์ SurfaceFlinger จะสร้างแบบผสมเลเยอร์เหล่านั้น จากนั้น SurfaceFlinger จะส่งบัฟเฟอร์เอาต์พุตไปยัง HWC
WindowManager
WindowManager ควบคุมออบเจ็กต์ Window ซึ่งเป็นคอนเทนเนอร์สำหรับออบเจ็กต์ View ออบเจ็กต์ Window จะได้รับการสนับสนุนจาก
Surface ออบเจ็กต์เสมอ
WindowManager ดูแลวงจรการทำงาน เหตุการณ์อินพุตและโฟกัส การวางแนวหน้าจอ การเปลี่ยนภาพ ภาพเคลื่อนไหว ตำแหน่ง การแปลง Z-order และหน้าต่างอื่นๆ อีกมากมาย WindowManager จะส่งข้อมูลเมตาของหน้าต่างทั้งหมดไปยัง SurfaceFlinger เพื่อให้ SurfaceFlinger ใช้ข้อมูลดังกล่าวในการสร้างพื้นผิวแบบผสมบนจอแสดงผล
การหมุนก่อนแสดง
การซ้อนทับฮาร์ดแวร์จำนวนมากไม่รองรับการหมุน (และแม้ว่าจะรองรับก็ต้องใช้พลังการประมวลผล) โซลูชันคือการแปลงบัฟเฟอร์ก่อนที่จะส่งไปยัง SurfaceFlinger Android รองรับคำแนะนำการค้นหา (NATIVE_WINDOW_TRANSFORM_HINT) ใน ANativeWindow เพื่อแสดงการแปลงที่มีแนวโน้มมากที่สุดที่ SurfaceFlinger จะใช้กับบัฟเฟอร์
ไดรเวอร์ GL สามารถใช้คำแนะนำนี้เพื่อแปลงบัฟเฟอร์ล่วงหน้าก่อนที่จะส่งไปยัง SurfaceFlinger เพื่อให้บัฟเฟอร์ได้รับการแปลงอย่างถูกต้องเมื่อมาถึง
ตัวอย่างเช่น เมื่อได้รับคำแนะนำให้หมุน 90 องศา ให้สร้างและใช้เมทริกซ์กับบัฟเฟอร์เพื่อป้องกันไม่ให้บัฟเฟอร์หลุดออกจากท้ายหน้า ให้ทำการหมุนก่อนแสดงนี้เพื่อประหยัดพลังงาน ดูรายละเอียดได้ที่อินเทอร์เฟซ ANativeWindow ที่กำหนดไว้ใน system/core/include/system/window.h