การจัดการเฟรมบัฟเฟอร์ไคลเอ็นต์

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

การจัดการบัฟเฟอร์เฟรมระหว่างสวิตช์ความละเอียด

การเปลี่ยนแปลงความละเอียดเกิดขึ้นเนื่องจากหนึ่งในสองสถานการณ์ต่อไปนี้:

  • เหตุการณ์ฮอตปลั๊ก เริ่มต้นโดย Hardware Composer (HWC) ซึ่งเกิดขึ้นเมื่อสลับจากจอแสดงผลภายนอกหนึ่งไปยังจอแสดงผลภายนอกอื่นที่มีความละเอียดเริ่มต้นที่แตกต่างกัน

    ในระหว่างเหตุการณ์ฮอตปลั๊ก หมายเลขอ้างอิงของ framebuffers เก่าจะถูกปล่อยออกมาเมื่อมีการจัดสรรข้อมูลการแสดงผลเก่า

  • สวิตช์โหมดการแสดงผลที่ริเริ่มโดย SurfaceFlinger ซึ่งเกิดขึ้นเมื่อผู้ใช้เปลี่ยนความละเอียดด้วย การตั้งค่าของผู้ใช้ หรือแอปเปลี่ยนความ preferredDisplayModeId ด้วย

    ในระหว่างการสลับโหมดการแสดงผล หมายเลขอ้างอิงของบัฟเฟอร์เฟรมไคลเอ็นต์ที่มีอยู่จะถูกปล่อยโดย SurfaceFlinger ก่อนที่จะเรียกใช้ setActiveConfig หรือ setActiveConfigWithConstraints

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

  • สำหรับเหตุการณ์ hotplug ทันทีก่อนที่จะเรียก onHotplug

  • สำหรับสวิตช์โหมด ทันทีหลังจากการเรียก setActiveConfig หรือ setActiveConfigWithConstraints

การปล่อยจุดจับจะทำให้หน่วยความจำ framebuffer ได้รับการจัดสรรคืนทั้งหมดก่อนที่จะมีการจัดสรร framebuffer ใหม่ที่ SurfaceFlinger ดำเนินการในระหว่างรอบ ที่ไม่ถูกต้อง ครั้งถัดไป

คำแนะนำสำหรับการจัดการเฟรมบัฟเฟอร์

ถ้า HWC ไม่ปล่อยหมายเลขอ้างอิงให้กับ framebuffer เก่าทันเวลา การจัดสรร framebuffer ใหม่จะเกิดขึ้นก่อนการจัดสรรคืน framebuffer เก่า ซึ่งอาจทำให้เกิดปัญหาร้ายแรงเมื่อการจัดสรรใหม่ล้มเหลวเนื่องจากการกระจายตัวหรือปัญหาอื่นๆ ที่แย่ไปกว่านั้น ถ้า HWC ไม่ปล่อยจุดจับเหล่านี้เลย หน่วยความจำรั่วอาจเกิดขึ้นได้

เพื่อหลีกเลี่ยงความล้มเหลวในการจัดสรรที่เป็นภัยพิบัติ ให้ทำตามคำแนะนำเหล่านี้:

  • ถ้า HWC จำเป็นต้องใช้ framebuffer ของไคลเอ็นต์เก่าต่อไปจนกว่าจะมีการจัดหา framebuffer ของไคลเอ็นต์ใหม่ ดังนั้น จึงจำเป็นอย่างยิ่งที่จะต้องสำรองหน่วยความจำให้เพียงพอสำหรับทั้ง framebuffer ทั้งเก่าและใหม่ และอาจเรียกใช้อัลกอริทึมการจัดเรียงข้อมูลบนพื้นที่หน่วยความจำ framebuffer

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

ทดสอบการจัดการบัฟเฟอร์เฟรม

แนะนำให้ OEM ทดสอบการจัดการหน่วยความจำบัฟเฟอร์เฟรมไคลเอ็นต์ที่เหมาะสมกับสวิตช์ความละเอียดสำหรับอุปกรณ์ของตน โดยมีคำอธิบายดังนี้:

  • สำหรับเหตุการณ์ฮอตปลั๊ก เพียงถอดปลั๊กและเชื่อมต่อจอแสดงผลสองจอที่มีความละเอียดต่างกันอีกครั้ง

  • สำหรับสวิตช์โหมด ให้ใช้การทดสอบ ModeSwitchingTestActivity CTS Verifier เพื่อเริ่มต้นสวิตช์โหมดสำหรับทดสอบพฤติกรรมของหน่วยความจำบัฟเฟอร์เฟรม การทดสอบนี้สามารถระบุปัญหาด้วยสายตาซึ่งยากต่อการตรวจจับโดยทางโปรแกรม