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