เลเยอร์และจอแสดงผล

เลเยอร์และจอแสดงผลเป็นองค์ประกอบพื้นฐาน 2 อย่างที่ใช้แสดงการคอมโพสและการทำงานร่วมกับฮาร์ดแวร์ของจอแสดงผล

เลเยอร์

เลเยอร์คือหน่วยองค์ประกอบที่สำคัญที่สุด เลเยอร์คือพื้นผิวที่รวมกับอินสแตนซ์ของ SurfaceControl เลเยอร์แต่ละเลเยอร์จะมีชุดพร็อพเพอร์ตี้ที่กำหนดวิธีโต้ตอบกับเลเยอร์อื่นๆ ตารางต่อไปนี้อธิบายพร็อพเพอร์ตี้ของเลเยอร์

พร็อพเพอร์ตี้ คำอธิบาย
ตำแหน่ง กำหนดตำแหน่งที่เลเยอร์จะปรากฏบนจอแสดงผล มีข้อมูล เช่น ตำแหน่งของขอบเลเยอร์และลําดับ Z ของเลเยอร์นั้นๆ เมื่อเทียบกับเลเยอร์อื่นๆ (ควรอยู่ข้างหน้าหรือหลังเลเยอร์อื่นๆ)
เนื้อหา กําหนดวิธีนำเสนอเนื้อหาที่แสดงในเลเยอร์ภายในขอบเขตที่กําหนดโดยพร็อพเพอร์ตี้ตำแหน่ง มีข้อมูล เช่น ครอบตัด (เพื่อขยายเนื้อหาบางส่วนให้เต็มขอบเขตของเลเยอร์) และการเปลี่ยนรูปแบบ (เพื่อแสดงเนื้อหาที่พลิกหรือหมุน)
การเรียบเรียง กำหนดวิธีคอมโพสเลเยอร์กับเลเยอร์อื่นๆ มีข้อมูล เช่น โหมดการผสมและค่าอัลฟาทั้งเลเยอร์สําหรับการคอมโพสอัลฟา
การเพิ่มประสิทธิภาพ ให้ข้อมูลที่ไม่ใช่ข้อมูลที่จำเป็นอย่างยิ่งในการคอมโพสเลเยอร์อย่างถูกต้อง แต่อุปกรณ์เครื่องมือแต่งภาพฮาร์ดแวร์ (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 ช่วยให้แอประบุข้อมูลเป็นไบต์ดิบในบัฟเฟอร์ หรือผ่านแพลตฟอร์ม เมื่อ screenrecord ขอสิทธิ์เข้าถึงโปรแกรมเปลี่ยนไฟล์วิดีโอ กระบวนการ mediaserver จะสร้าง BufferQueue, เชื่อมต่อกับฝั่งผู้บริโภค จากนั้นส่งฝั่งผู้ผลิตกลับไปให้ screenrecord เป็นแพลตฟอร์ม

จากนั้นยูทิลิตี screenrecord จะขอให้ SurfaceFlinger สร้างจอแสดงผลเสมือนจริงที่มิเรอร์จอแสดงผลหลัก (กล่าวคือมีเลเยอร์เดียวกันทั้งหมด) และสั่งให้ส่งเอาต์พุตไปยังพื้นผิวที่มาจากกระบวนการ mediaserver ในกรณีนี้ SurfaceFlinger จะเป็นผู้ผลิตบัฟเฟอร์ ไม่ใช่ผู้บริโภค

หลังจากการกําหนดค่าเสร็จสมบูรณ์แล้ว screenrecord จะทริกเกอร์เมื่อข้อมูลที่เข้ารหัสปรากฏขึ้น เมื่อแอปวาดภาพ บัฟเฟอร์จะส่งไปยัง SurfaceFlinger ซึ่งจะคอมโพสให้เป็นบัฟเฟอร์เดียวที่ส่งไปยังโปรแกรมเปลี่ยนรหัสวิดีโอโดยตรงในกระบวนการ mediaserver กระบวนการ screenrecord จะไม่ได้เห็นเฟรมแบบเต็ม ภายในนั้น กระบวนการ mediaserver มีวิธีของตัวเองในการย้ายบัฟเฟอร์ไปรอบๆ ซึ่งจะส่งข้อมูลด้วยแฮนเดิลด้วย เพื่อลดค่าใช้จ่ายเพิ่มเติม

กรณีศึกษา: จำลองจอแสดงผลรอง

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

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