หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

SurfaceFlinger และ WindowManager

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

SurfaceFlinger

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

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

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

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

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

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

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

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

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

WindowManager

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

ก่อนการหมุน

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

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