SurfaceFlinger และ WindowManager

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 Wraps SurfaceControl และช่วยให้แอปสร้างอินสแตนซ์ SurfaceControl ที่ สอดคล้องกับเลเยอร์บนจอแสดงผล

สามารถสร้างเป็นองค์ประกอบย่อยของ ANativeWindow หรือเป็นองค์ประกอบย่อยของอินสแตนซ์ ASurfaceControl อื่น
ASurfaceTransaction Wraps Transaction เพื่อให้ไคลเอ็นต์แก้ไขพร็อพเพอร์ตี้เชิงอธิบายของเลเยอร์ได้ เช่น เรขาคณิต และส่งบัฟเฟอร์ที่อัปเดตไปยัง SurfaceFlinger
ASurfaceTransactionStats ส่งข้อมูลเกี่ยวกับธุรกรรมที่แสดง เช่น เวลาที่ล็อก เวลาที่ได้ และรั้วการเผยแพร่ก่อนหน้า ไปยังแอปผ่าน การเรียกกลับที่ลงทะเบียนล่วงหน้า

แม้ว่าแอปจะส่งบัฟเฟอร์ได้ทุกเมื่อ แต่ SurfaceFlinger จะทำงานเพื่อยอมรับบัฟเฟอร์ระหว่างการรีเฟรชจอแสดงผลเท่านั้น ซึ่งอาจแตกต่างกันไปตามอุปกรณ์ ซึ่งจะช่วยลดการใช้หน่วยความจำและหลีกเลี่ยงการฉีกขาดที่มองเห็นได้บน หน้าจอ ซึ่งอาจเกิดขึ้นเมื่ออัปเดตการแสดงผลกลางการรีเฟรช

เมื่อจอแสดงผลอยู่ระหว่างการรีเฟรช จอแสดงผลจะส่งสัญญาณ VSync ไปยัง SurfaceFlinger สัญญาณ VSync แสดงว่าจอแสดงผลสามารถ รีเฟรชได้โดยไม่มีภาพขาด เมื่อ SurfaceFlinger ได้รับสัญญาณ VSync, SurfaceFlinger จะตรวจสอบรายการเลเยอร์เพื่อหาบัฟเฟอร์ใหม่ หาก SurfaceFlinger พบ บัฟเฟอร์ใหม่ 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