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

เลเยอร์และจอแสดงผลเป็น 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

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