SurfaceFlinger และ WindowManager

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

SurfaceFlinger

SurfaceFlinger ยอมรับบัฟเฟอร์ได้ 2 วิธี ได้แก่ ผ่าน BufferQueue และ SurfaceControl หรือผ่าน ASurfaceControl

วิธีที่ SurfaceFlinger ยอมรับบัฟเฟอร์คือผ่าน BufferQueue และ SurfaceControl เมื่อแอปปรากฏขึ้นที่เบื้องหน้า แอปจะขอบัฟเฟอร์จาก WindowManager จากนั้น WindowManager จะขอเลเยอร์จาก SurfaceFlinger เลเยอร์คือชุดค่าผสมของ surface ซึ่งมี BufferQueue และ SurfaceControl ซึ่งมีข้อมูลเมตาของเลเยอร์ เช่น เฟรมการแสดงผล SurfaceFlinger จะสร้างเลเยอร์และส่งไปยัง WindowManager จากนั้น WindowManager จะส่ง Surface ไปยังแอป แต่เก็บ SurfaceControl ไว้เพื่อควบคุมลักษณะที่ปรากฏของแอปบนหน้าจอ

Android 10 เพิ่ม ASurfaceControl ซึ่งเป็นอีกวิธีหนึ่งที่ SurfaceFlinger ยอมรับบัฟเฟอร์ ASurfaceControl จะรวมพื้นผิวและ SurfaceControl ไว้ในแพ็กเกจธุรกรรมเดียวที่ส่งไปยัง SurfaceFlinger ASurfaceControl จะเชื่อมโยงกับเลเยอร์ ซึ่งแอปจะอัปเดตผ่าน ASurfaceTransactions จากนั้นแอปจะได้รับข้อมูลเกี่ยวกับ ASurfaceTransactions ผ่านคอลแบ็กที่ส่ง ASurfaceTransactionStats ซึ่งมีข้อมูล เช่น เวลาแตะ เวลารับ เป็นต้น

ตารางต่อไปนี้มีรายละเอียดเพิ่มเติมเกี่ยวกับ ASurfaceControl และคอมโพเนนต์ที่เกี่ยวข้อง

ส่วนประกอบ คำอธิบาย
ASurfaceControl แพ็กเกจนี้จะรวม SurfaceControl และช่วยให้แอปสร้าง SurfaceControl ที่สอดคล้องกับเลเยอร์บนจอแสดงผลได้

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

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

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

หลังจาก SurfaceFlinger รวบรวมบัฟเฟอร์ทั้งหมดสําหรับเลเยอร์ที่มองเห็นแล้ว ก็จะถามเครื่องมือจัดองค์ประกอบฮาร์ดแวร์ (HWC) ว่าควรใช้การคอมโพสอย่างไร หาก HWC ระบุว่าประเภทการคอมโพสเลเยอร์เป็นการคอมโพสเลเยอร์ไคลเอ็นต์ SurfaceFlinger จะคอมโพสเลเยอร์เหล่านั้น จากนั้น SurfaceFlinger จะส่งบัฟเฟอร์เอาต์พุตไปยัง HWC

WindowManager

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

การหมุนเวียนล่วงหน้า

การวางซ้อนฮาร์ดแวร์จำนวนมากไม่รองรับการหมุน (และแม้ว่าจะรองรับ ก็ต้องใช้พลังงานในการประมวลผล) ทางออกคือการเปลี่ยนรูปแบบบัฟเฟอร์ก่อนที่จะส่งไปยัง SurfaceFlinger Android รองรับคำแนะนำการค้นหา (NATIVE_WINDOW_TRANSFORM_HINT) ใน ANativeWindow เพื่อแสดงการเปลี่ยนรูปแบบที่มีแนวโน้มมากที่สุดที่จะใช้กับบัฟเฟอร์โดย SurfaceFlinger ไดรเวอร์ GL สามารถใช้คำแนะนำนี้เพื่อเปลี่ยนรูปแบบบัฟเฟอร์ล่วงหน้าก่อนที่จะส่งไปยัง SurfaceFlinger เพื่อให้บัฟเฟอร์ได้รับการเปลี่ยนรูปแบบอย่างถูกต้องเมื่อมาถึง

เช่น เมื่อได้รับคำแนะนำให้หมุน 90 องศา ให้สร้างและใช้เมทริกซ์กับบัฟเฟอร์เพื่อป้องกันไม่ให้แสดงที่ด้านล่างของหน้า ดำเนินการนี้ก่อนการหมุนเพื่อประหยัดพลังงาน ดูรายละเอียดได้ที่อินเทอร์เฟซ ANativeWindow ที่กำหนดไว้ใน system/core/include/system/window.h