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

เลเยอร์และจอแสดงผลเป็นสองสิ่งพื้นฐานที่แสดงถึงงานองค์ประกอบและการโต้ตอบกับฮาร์ดแวร์จอแสดงผล

เลเยอร์

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

คุณสมบัติ คำอธิบาย
ตำแหน่ง กำหนดตำแหน่งที่เลเยอร์จะปรากฏบนจอแสดงผล รวมข้อมูล เช่น ตำแหน่งของขอบของเลเยอร์และ ลำดับ Z ที่สัมพันธ์กับเลเยอร์อื่นๆ (ไม่ว่าควรจะอยู่ด้านหน้าหรือด้านหลังเลเยอร์อื่นๆ)
เนื้อหา กำหนดวิธีการนำเสนอเนื้อหาที่แสดงบนเลเยอร์ภายในขอบเขตที่กำหนดโดยคุณสมบัติตำแหน่ง รวมข้อมูลเช่นการครอบตัด (เพื่อขยายส่วนหนึ่งของเนื้อหาเพื่อเติมเต็มขอบเขตของเลเยอร์) และการแปลง (เพื่อแสดงเนื้อหาที่หมุนหรือพลิก)
องค์ประกอบ กำหนดวิธีการรวมเลเยอร์กับเลเยอร์อื่น รวมข้อมูล เช่น โหมดการผสมและค่าอัลฟ่าทั้งเลเยอร์สำหรับ การผสมอัลฟ่า
การเพิ่มประสิทธิภาพ ให้ข้อมูลที่ไม่จำเป็นอย่างเคร่งครัดในการประกอบเลเยอร์อย่างถูกต้อง แต่อุปกรณ์ Hardware Composer (HWC) สามารถใช้เพื่อเพิ่มประสิทธิภาพวิธีการจัดองค์ประกอบ รวมข้อมูล เช่น ขอบเขตที่มองเห็นได้ของเลเยอร์ และส่วนใดของเลเยอร์ที่ได้รับการอัปเดตตั้งแต่เฟรมที่แล้ว

จอแสดงผล

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

การแสดงเสมือนจริง

SurfaceFlinger รองรับจอแสดงผลภายใน (มีอยู่ในโทรศัพท์หรือแท็บเล็ต), จอแสดงผลภายนอก (เช่น โทรทัศน์ที่เชื่อมต่อผ่าน HDMI) และจอแสดงผลเสมือนอย่างน้อยหนึ่งจอที่ทำให้เอาต์พุตแบบคอมโพสิตพร้อมใช้งานภายในระบบ จอแสดงผลเสมือนสามารถใช้เพื่อบันทึกหน้าจอหรือส่งหน้าจอผ่านเครือข่ายได้ เฟรมที่สร้างขึ้นสำหรับการแสดงผลเสมือนจะถูกเขียนลงใน BufferQueue

จอแสดงผลเสมือนอาจใช้ชุดเลเยอร์เดียวกันกับจอแสดงผลหลัก (เลเยอร์สแต็ก) หรือมีชุดของตัวเอง ไม่มี VSYNC สำหรับจอแสดงผลเสมือน ดังนั้น VSYNC สำหรับจอแสดงผลภายในจะทริกเกอร์การจัดองค์ประกอบสำหรับจอแสดงผลทั้งหมด

ในการใช้งาน HWC ที่รองรับ จอแสดงผลเสมือนสามารถประกอบเข้ากับ OpenGL ES (GLES), HWC หรือทั้ง GLES และ HWC ในการใช้งานที่ไม่รองรับ จอแสดงผลเสมือนจะถูกจัดองค์ประกอบโดยใช้ GLES เสมอ

กรณีศึกษา: บันทึกหน้าจอ

คำสั่ง 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 เพื่อจับภาพการเปิดใช้งานจอแสดงผล จากนั้นเล่นทีละเฟรม