เลเยอร์และจอแสดงผลเป็น 2 องค์ประกอบพื้นฐานที่แสดงถึงการทำงานขององค์ประกอบ และการโต้ตอบกับฮาร์ดแวร์จอแสดงผล
เลเยอร์
เลเยอร์เป็นหน่วยการคอมโพสิตที่สำคัญที่สุด เลเยอร์คือ
การรวมกันของพื้นผิวและอินสแตนซ์ของ
SurfaceControl
เลเยอร์แต่ละรายการมีชุดพร็อพเพอร์ตี้ที่กำหนดวิธีโต้ตอบกับเลเยอร์อื่นๆ คุณสมบัติเลเยอร์
มีคำอธิบายในตารางต่อไปนี้
พร็อพเพอร์ตี้ | คำอธิบาย |
---|---|
ตามตำแหน่ง | กำหนดตำแหน่งที่เลเยอร์ปรากฏบนจอแสดงผล ประกอบด้วยข้อมูล เช่น ตำแหน่งของขอบเลเยอร์และลำดับ Z ที่สัมพันธ์กับเลเยอร์อื่นๆ (ควรอยู่ด้านหน้าหรือด้านหลัง เลเยอร์อื่นๆ) |
เนื้อหา | กำหนดวิธีแสดงเนื้อหาที่แสดงในเลเยอร์ภายในขอบเขตที่กำหนดโดยพร็อพเพอร์ตี้ตำแหน่ง รวมถึงข้อมูลต่างๆ เช่น ครอบตัด (เพื่อขยายส่วนของเนื้อหาให้เต็มขอบเขตของเลเยอร์) และเปลี่ยนรูป (เพื่อแสดงเนื้อหาที่หมุนหรือพลิก) |
การเรียบเรียง | กำหนดวิธีซ้อนเลเยอร์กับเลเยอร์อื่นๆ ประกอบด้วย ข้อมูล เช่น โหมดการผสมและค่าอัลฟ่าทั้งเลเยอร์สำหรับการคอมโพสิตอัลฟ่า |
การเพิ่มประสิทธิภาพ | ให้ข้อมูลที่ไม่จำเป็นอย่างเคร่งครัดในการคอมโพสิตเลเยอร์อย่างถูกต้อง แต่สามารถใช้โดยอุปกรณ์ Hardware Composer (HWC) เพื่อเพิ่มประสิทธิภาพวิธีการคอมโพสิต รวมถึงข้อมูลต่างๆ เช่น ภูมิภาคที่มองเห็นของเลเยอร์และส่วนใดของเลเยอร์ที่ ได้รับการอัปเดตนับตั้งแต่เฟรมก่อนหน้า |
จอแสดงผล
การแสดงผลเป็นอีกหน่วยการจัดวางที่สำคัญ ระบบสามารถ มีจอแสดงผลหลายจอ และ เพิ่มหรือนำจอแสดงผลออกได้ในระหว่างการทำงานของระบบตามปกติ การแสดงผลจะ เพิ่มหรือนำออกตามคำขอของ HWC หรือตามคำขอของเฟรมเวิร์ก อุปกรณ์ HWC จะขอให้เพิ่มหรือนำจอแสดงผลออกเมื่อมีการเชื่อมต่อหรือยกเลิกการเชื่อมต่อจอแสดงผลภายนอกกับอุปกรณ์ ซึ่งเรียกว่าการเสียบร้อน ไคลเอ็นต์จะขอจอแสดงผลเสมือน ซึ่งเนื้อหา จะได้รับการแสดงผลในบัฟเฟอร์นอกหน้าจอแทนที่จะเป็นจอแสดงผลจริง
จอแสดงผลเสมือน
SurfaceFlinger รองรับจอแสดงผลภายใน (ติดตั้งในโทรศัพท์หรือแท็บเล็ต), จอแสดงผลภายนอก (เช่น โทรทัศน์ที่เชื่อมต่อผ่าน HDMI) และจอแสดงผลเสมือนอย่างน้อย 1 จอ ซึ่งทำให้เอาต์พุตที่คอมโพสิตพร้อมใช้งานภายในระบบ คุณใช้จอแสดงผลเสมือนเพื่อบันทึกหน้าจอหรือส่งหน้าจอผ่านเครือข่ายได้ เฟรมที่สร้างขึ้น สำหรับจอแสดงผลเสมือนจะเขียนลงใน BufferQueue
จอแสดงผลเสมือนอาจใช้ชุดเลเยอร์เดียวกันกับจอแสดงผลหลัก (สแต็กเลเยอร์) หรือมีชุดเลเยอร์ของตัวเอง ไม่มี VSync สำหรับจอแสดงผลเสมือน ดังนั้น VSync สำหรับจอแสดงผลภายในจึงทริกเกอร์การจัดองค์ประกอบสำหรับจอแสดงผลทั้งหมด
ในการใช้งาน HWC ที่รองรับ จอแสดงผลเสมือน สามารถคอมโพสิตกับ OpenGL ES (GLES), HWC หรือทั้ง GLES และ HWC ในการใช้งานที่ไม่รองรับ จอแสดงผลเสมือนจะได้รับการคอมโพสิตโดยใช้ GLES เสมอ
กรณีศึกษา: screenrecord
คำสั่ง screenrecord
อนุญาตให้ผู้ใช้บันทึกทุกอย่างที่ปรากฏบนหน้าจอเป็นไฟล์ MP4 ในดิสก์
หากต้องการใช้ฟีเจอร์นี้ ระบบจะรับเฟรมที่คอมโพสจาก
SurfaceFlinger เขียนเฟรมเหล่านั้นลงในตัวเข้ารหัสวิดีโอ แล้วเขียนข้อมูลวิดีโอที่เข้ารหัส
ลงในไฟล์ ตัวแปลงรหัสวิดีโอได้รับการจัดการโดยกระบวนการแยกต่างหาก
(mediaserver
) ดังนั้นบัฟเฟอร์กราฟิกขนาดใหญ่จึงต้องย้ายไปมาใน
ระบบ และเพื่อเพิ่มความท้าทาย เป้าหมายคือการบันทึกวิดีโอ 60 FPS ที่
ความละเอียดเต็ม กุญแจสำคัญที่ทำให้การทำงานนี้มีประสิทธิภาพคือ BufferQueue
คลาส MediaCodec
ช่วยให้แอปสามารถระบุข้อมูลเป็นไบต์ดิบในบัฟเฟอร์
หรือผ่าน Surface เมื่อ screenrecord
ขอสิทธิ์เข้าถึงตัวเข้ารหัสวิดีโอ
กระบวนการ mediaserver
จะสร้าง BufferQueue เชื่อมต่อ
ตัวเองกับฝั่งผู้ใช้ แล้วส่งฝั่งผู้ผลิตกลับไปให้
screenrecord
เป็น Surface
จากนั้นยูทิลิตี screenrecord
จะขอให้ SurfaceFlinger สร้าง
จอแสดงผลเสมือนที่จำลองจอแสดงผลหลัก (กล่าวคือ มีเลเยอร์ทั้งหมดเหมือนกัน)
และสั่งให้ส่งเอาต์พุตไปยัง Surface ที่มาจากกระบวนการ mediaserver
ในกรณีนี้ SurfaceFlinger เป็นผู้ผลิต
บัฟเฟอร์ ไม่ใช่ผู้ใช้
หลังจากกำหนดค่าเสร็จแล้ว screenrecord
จะทริกเกอร์เมื่อ
ข้อมูลที่เข้ารหัสปรากฏขึ้น เมื่อแอปวาดภาพ บัฟเฟอร์ของแอปจะเดินทางไปยัง SurfaceFlinger
ซึ่งจะรวมบัฟเฟอร์เหล่านั้นเป็นบัฟเฟอร์เดียวที่ส่งไปยังตัวเข้ารหัสวิดีโอโดยตรงในmediaserver
กระบวนการ กระบวนการ screenrecord
จะไม่เห็นเฟรมเต็ม ภายใน mediaserver
มีวิธีของตัวเองในการย้ายบัฟเฟอร์ไปมา ซึ่งจะส่งข้อมูลโดยใช้แฮนเดิลด้วยเพื่อลดค่าใช้จ่าย
กรณีศึกษา: จำลองจอแสดงผลที่สอง
WindowManager สามารถขอให้ SurfaceFlinger สร้างเลเยอร์ที่มองเห็นได้ ซึ่ง SurfaceFlinger จะทำหน้าที่เป็นผู้ใช้ BufferQueue นอกจากนี้ คุณยังขอให้ SurfaceFlinger สร้างจอแสดงผลเสมือนได้ด้วย ซึ่ง SurfaceFlinger จะทำหน้าที่เป็น ผู้ผลิต BufferQueue
หากเชื่อมต่อจอแสดงผลเสมือนกับเลเยอร์ที่มองเห็นได้ ระบบจะสร้างลูปปิด
ซึ่งหน้าจอที่คอมโพสิตจะปรากฏในหน้าต่าง ตอนนี้หน้าต่างดังกล่าวเป็นส่วนหนึ่งของ
เอาต์พุตที่คอมโพสิตแล้ว ดังนั้นในการรีเฟรชครั้งถัดไป รูปภาพที่คอมโพสิตแล้วภายในหน้าต่าง
จะแสดงเนื้อหาของหน้าต่างด้วย หากต้องการดูการทำงานของฟีเจอร์นี้ ให้เปิดตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ในการตั้งค่า เลือกจำลองจอแสดงผลรอง แล้วเปิดใช้หน้าต่าง หากต้องการดู
จอแสดงผลรองที่ทำงานอยู่ ให้ใช้ screenrecord
เพื่อบันทึกการ
เปิดใช้จอแสดงผล แล้วเล่นซ้ำทีละเฟรม