ใช้งาน HAL ของฮาร์ดแวร์คอมโพสเซอร์

เลเยอร์คอมโพสิต HAL ของฮาร์ดแวร์คอมโพสิต (HWC) ที่ได้รับจาก SurfaceFlinger ซึ่งจะลดปริมาณองค์ประกอบ OpenGL ES (GLES) และ GPU

HWC นำวัตถุต่างๆ เช่น การวางซ้อนและคลิตเตอร์ 2 มิติมาใช้ในการประกอบ พื้นผิวและสื่อสารกับฮาร์ดแวร์การจัดวางหน้าต่างแบบพิเศษเพื่อ หน้าต่างผสม ใช้ HWC เพื่อทำการผสมหน้าต่างแทน วัสดุผสม SurfaceFlinger กับ GPU GPU ส่วนใหญ่ไม่ได้เพิ่มประสิทธิภาพเพื่อ และเมื่อ GPU เขียนเลเยอร์จาก แพลตฟอร์ม SurfaceFlinger แอปจะใช้ GPU เพื่อแสดงผลของตนเองไม่ได้

การติดตั้งใช้งาน HWC ควรรองรับสิ่งต่อไปนี้

  • การวางซ้อนอย่างน้อย 4 รายการ:
    • แถบสถานะ
    • แถบระบบ
    • แอป
    • วอลเปเปอร์/พื้นหลัง
  • เลเยอร์ที่ใหญ่กว่าจอแสดงผล (เช่น วอลเปเปอร์)
  • การผสมอัลฟ่าแบบคูณต่อพิกเซลและต่อระนาบ การผสมอัลฟ่า
  • เส้นทางฮาร์ดแวร์สำหรับการเล่นวิดีโอที่มีการปกป้อง
  • ลำดับการแพ็ก RGBA, รูปแบบ YUV และพร็อพเพอร์ตี้การแบ่งส่วน การเรียงสับเปลี่ยน และระยะก้าว

วิธีใช้ HWC

  1. ใช้ HWC แบบไม่ดำเนินการและส่งงานการเรียบเรียงทั้งหมดไปที่ GLES
  2. ใช้อัลกอริทึมเพื่อมอบสิทธิ์การคอมโพสให้กับ HWC ทีละรายการ เช่น มอบสิทธิ์เฉพาะ 3 หรือ 4 พื้นผิวแรกให้กับการวางซ้อน ฮาร์ดแวร์ของ HWC
  3. เพิ่มประสิทธิภาพ HWC ซึ่งอาจรวมถึงสิ่งต่างๆ ต่อไปนี้
    • เลือกแพลตฟอร์มที่เพิ่มโหลดสูงสุดที่ได้จาก GPU และ ส่งไปยัง HWC
    • กำลังตรวจจับว่าหน้าจอกำลังอัปเดตหรือไม่ หากไม่ใช่ ให้มอบสิทธิ์ องค์ประกอบนี้เป็น GLES แทน HWC เพื่อประหยัดพลังงาน เมื่อหน้าจอ แล้วอัปเดตอีกครั้ง ส่งองค์ประกอบไปยัง HWC ต่อไป
    • การเตรียมพร้อมสำหรับ Use Case ทั่วไป เช่น
      • หน้าจอหลัก ซึ่งรวมถึงแถบสถานะ แถบระบบ และแอป หน้าต่าง และวอลเปเปอร์เคลื่อนไหว
      • เกมแบบเต็มหน้าจอในโหมดแนวตั้งและแนวนอน
      • วิดีโอแบบเต็มหน้าจอพร้อมคำบรรยายและการเล่น การควบคุม
      • การเล่นวิดีโอที่มีการคุ้มครอง
      • แยกหน้าจอหลายหน้าต่าง

HWC แบบเดิม

HWC มีตัวเลือกพื้นฐาน 2 แบบ ได้แก่ เลเยอร์และจอแสดงผล แสดงถึงงานประพันธ์เพลงและการโต้ตอบกับฮาร์ดแวร์แสดงผล HWC ยังมอบการควบคุม VSYNC และการเรียกกลับไปยัง SurfaceFlinger ด้วย เพื่อแจ้งเตือนเมื่อมีเหตุการณ์ VSYNC เกิดขึ้น

อินเทอร์เฟซ HIDL

Android 8.0 ขึ้นไปใช้อินเทอร์เฟซ HIDL ที่เรียกว่า Composer HAL สำหรับ IPC แบบ Binderized ระหว่าง HWC กับ SurfaceFlinger HAL ของคอมโพสเซอร์จะแทนที่ฟังก์ชัน อินเทอร์เฟซเดิมของ hwcomposer2.h กรณีที่ผู้ให้บริการมี HAL ของ Composer ติดตั้งใช้งาน HWC แล้ว Composer HAL จะยอมรับการเรียกใช้ HIDL โดยตรงจาก SurfaceFlinger หากผู้ให้บริการมีการติดตั้งใช้งาน HWC แบบเดิม Composer HAL จะโหลดเคอร์เซอร์ฟังก์ชันจาก hwcomposer2.h การส่งต่อการเรียกใช้ HIDL ไปยังการเรียกเคอร์เซอร์ฟังก์ชัน

HWC มีฟังก์ชันสำหรับระบุคุณสมบัติของจอแสดงผลหนึ่งๆ ถึง สลับระหว่างการกำหนดค่าการแสดงผลต่างๆ (เช่น 4K หรือ 1080p ความละเอียด) และโหมดสี (เช่น สีดั้งเดิมหรือ sRGB จริง) และเปลี่ยน หน้าจอจะเปิดหรือปิด หรือเข้าสู่โหมดใช้พลังงานต่ำ (หากรองรับ)

ตัวชี้ฟังก์ชัน

หากผู้ให้บริการใช้ HAL ของ Composer โดยตรง SurfaceFlinger จะเรียกใช้ฟังก์ชันของ Composer โดยตรง ผ่าน HIDL IPC ตัวอย่างเช่น หากต้องการสร้างเลเยอร์ จะเรียก SurfaceFlinger createLayer() ใน HAL ของ Composer

หากผู้ให้บริการใช้อินเทอร์เฟซ hwcomposer2.h แล้ว Composer HAL เข้าสู่เคอร์เซอร์ฟังก์ชัน hwcomposer2.h ในความคิดเห็น hwcomposer2.h ระบบจะอ้างอิงฟังก์ชันอินเทอร์เฟซ HWC ด้วยชื่อรูปแบบ lowerCamelCase ซึ่งไม่มีอยู่ในอินเทอร์เฟซเป็นช่องที่มีชื่อ โดยระบบจะโหลดฟังก์ชันเกือบทั้งหมดโดยส่งคำขอ ตัวชี้ฟังก์ชันที่ใช้ getFunction จัดเตรียมโดย hwc2_device_t เช่น ฟังก์ชัน createLayer เป็นตัวชี้ฟังก์ชันประเภท HWC2_PFN_CREATE_LAYER ซึ่งก็คือ แสดงผลเมื่อค่าที่แจกแจง HWC2_FUNCTION_CREATE_LAYER คือ ส่งผ่านไปยัง getFunction

หากต้องการดูเอกสารประกอบโดยละเอียดเกี่ยวกับฟังก์ชัน HAL ของ Composer และการส่งผ่านของฟังก์ชัน HWC โปรดดู composer หากต้องการดูเอกสารโดยละเอียดเกี่ยวกับ ตัวชี้ฟังก์ชัน HWC โปรดดู hwcomposer2.h

แฮนเดิลเลเยอร์และแฮนเดิล

เลเยอร์และจอแสดงผลได้รับการจัดการโดยแฮนเดิลที่ HWC สร้างขึ้น แฮนเดิลของ SurfaceFlinger จะทึบแสง

เมื่อ SurfaceFlinger สร้างเลเยอร์ใหม่ ระบบจะเรียก createLayer ซึ่งแสดงผลประเภท Layer สำหรับการเข้าชมโดยตรง หรือ hwc2_layer_t สำหรับการใช้งาน Passthrough วันและเวลา SurfaceFlinger จะแก้ไขพร็อพเพอร์ตี้ของเลเยอร์นั้น ซึ่ง SurfaceFlinger จะส่ง ค่า hwc2_layer_t ลงในฟังก์ชันการแก้ไขที่เหมาะสม พร้อมด้วยข้อมูลอื่นๆ ที่จําเป็นในการทําการแก้ไข hwc2_layer_t ประเภทมีขนาดใหญ่พอที่จะเก็บตัวชี้หรือ ดัชนี

จอแสดงผลที่จับต้องได้สร้างขึ้นด้วยการ Hotplugged เมื่อจอแสดงผล HWC จะสร้างแฮนเดิล และส่งไปยัง SurfaceFlinger ผ่าน HotPlug Callback จอแสดงผลเสมือนสร้างขึ้นโดย SurfaceFlinger กำลังโทรหา createVirtualDisplay() เพื่อขอจอแสดงผล หาก HWCรองรับการคอมโพสิชันการแสดงผลเสมือนจริง ระบบจะแสดงผลแฮนเดิล จากนั้น SurfaceFlinger มอบสิทธิ์องค์ประกอบของจอแสดงผลให้กับ HWC หาก HWC ไม่รองรับการสนับสนุนทางออนไลน์ การจัดวางองค์ประกอบการแสดงผล SurfaceFlinger จะสร้างแฮนเดิลและประกอบการแสดงผล

การดำเนินการจัดองค์ประกอบจอแสดงผล

1 ครั้งต่อ VSYNC, SurfaceFlinger จะปลุกระบบหากมีเนื้อหาใหม่ไปยัง การผสม เนื้อหาใหม่นี้อาจเป็นบัฟเฟอร์รูปภาพใหม่จากแอป หรือ การเปลี่ยนแปลงคุณสมบัติของเลเยอร์หนึ่งเลเยอร์ขึ้นไป เมื่อ SurfaceFlinger ตื่นขึ้นมา

  1. จัดการธุรกรรม หากมี
  2. สลักบัฟเฟอร์กราฟิกใหม่ หากมี
  3. ดำเนินการจัดองค์ประกอบใหม่ หากขั้นตอนที่ 1 หรือ 2 ส่งผลให้มีการเปลี่ยนแปลงเนื้อหาที่แสดง

สำหรับการจัดองค์ประกอบใหม่ SurfaceFlinger จะสร้างและ ทำลายเลเยอร์หรือแก้ไขสถานะของเลเยอร์ตามความเหมาะสม และยังเป็นการอัปเดต กับเนื้อหาปัจจุบันด้วยการเรียก เช่น setLayerBuffer หรือ setLayerColor หลังจากที่ทุกเลเยอร์ อัปเดต SurfaceFlinger โทรหา validateDisplay ซึ่งบอก HWC เพื่อตรวจสอบสถานะของเลเยอร์และระบุว่า การจัดวางองค์ประกอบ ดำเนินการต่อ โดยค่าเริ่มต้น SurfaceFlinger จะพยายามกำหนดค่าทุกเลเยอร์ เพื่อให้เลเยอร์ได้รับการประกอบขึ้นโดย HWC แต่ในบางที่ SurfaceFlinger จะทำการผสมเลเยอร์โดยใช้ GPU สำรอง

หลังจากการเรียก validateDisplay แล้ว SurfaceFlinger จะเรียก getChangedCompositionTypes เพื่อดูว่า HWC ต้องการเปลี่ยนประเภทการคอมโพสิชันเลเยอร์ใดๆ ก่อนที่จะทำการคอมโพสิชันหรือไม่ หากต้องการยอมรับการเปลี่ยนแปลง ให้ SurfaceFlinger เรียกใช้ acceptDisplayChanges

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

สุดท้าย SurfaceFlinger จะเรียก presentDisplay เพื่อบอกให้ HWC ดำเนินการตามกระบวนการคอมโพสิชันให้เสร็จสมบูรณ์และแสดงผลลัพธ์สุดท้าย

ดิสเพลย์หลายรายการ

Android 10 รองรับหน้าจอจริงหลายชิ้น เมื่อออกแบบการใช้งาน HWC เพื่อใช้กับ Android 7.0 และ สูงกว่า มีข้อจำกัดบางประการที่ไม่มีอยู่ในคำจำกัดความของ HWC ดังนี้

  • ระบบจะถือว่ามีจอแสดงผลภายในเพียง 1 จอ ภายใน คือการแสดงผลที่ฮ็อตปลั๊กเริ่มต้นรายงานในระหว่าง Boot หลังจากใช้งานแบบ Hotplugged กับจอแสดงผลภายในแล้ว ถูกตัดการเชื่อมต่อ
  • นอกจากจอแสดงผลภายในแล้ว อาจเสียบปลั๊กจอแสดงผลภายนอกกี่จอก็ได้ ระหว่างการทำงานตามปกติของอุปกรณ์ เฟรมเวิร์กนี้จะถือว่า ปลั๊กฮอตหลังจากจอแสดงผลภายในเครื่องแรกเป็นจอแสดงผลภายนอก ดังนั้นหากมี จอแสดงผลภายในเพิ่มเข้ามา ซึ่งได้รับการจัดหมวดหมู่ไม่ถูกต้องตาม Display.TYPE_HDMI แทนที่จะเป็น Display.TYPE_BUILT_IN

แม้ว่าการดำเนินการ SurfaceFlinger ที่อธิบายไว้ข้างต้นจะดำเนินการต่อจอแสดงผลแต่ละจอ แต่การดำเนินการดังกล่าวจะดำเนินการตามลำดับสำหรับจอแสดงผลที่ใช้งานอยู่ทั้งหมด แม้ว่าจะมีการอัปเดตเนื้อหาของจอแสดงผลเพียงจอเดียวก็ตาม

เช่น หากอัปเดตจอแสดงผลภายนอก ลำดับจะเป็นดังนี้

// In Android 9 and lower:

// Update state for internal display
// Update state for external display
validateDisplay(<internal display>)
validateDisplay(<external display>)
presentDisplay(<internal display>)
presentDisplay(<external display>)

// In Android 10 and higher:

// Update state for internal display
// Update state for external display
validateInternal(<internal display>)
presentInternal(<internal display>)
validateExternal(<external display>)
presentExternal(<external display>)

องค์ประกอบของจอแสดงผลเสมือน

องค์ประกอบของจอแสดงผลเสมือนคล้ายกับจอแสดงผลภายนอก องค์ประกอบ ความแตกต่างระหว่างองค์ประกอบของการแสดงผลแบบเสมือนกับลักษณะทางกายภาพ การจัดวางองค์ประกอบการแสดงผล คือการที่จอแสดงผลเสมือนจะส่งเอาต์พุตไปยังบัฟเฟอร์ Gralloc แทนหน้าจอ ฮาร์ดแวร์คอมโพสเซอร์ (HWC) จะเขียนเอาต์พุตไปยังบัฟเฟอร์ ให้รั้วที่สมบูรณ์ และส่งบัฟเฟอร์ไปยังผู้บริโภค (เช่น โปรแกรมเปลี่ยนไฟล์วิดีโอ, GPU, CPU และอื่นๆ) จอแสดงผลเสมือนสามารถใช้แบบ 2 มิติ/ทลิตเตอร์หรือ ซ้อนทับ หากไปป์ไลน์การแสดงผลเขียนไปยังหน่วยความจำ

โหมด

แต่ละเฟรมจะอยู่ใน 1 ใน 3 โหมดหลังจากที่ SurfaceFlinger เรียกใช้ฟังก์ชัน validateDisplay() เมธอด HWC:

  • GLES — GPU ทำการผสมเลเยอร์ทั้งหมด กำลังเขียน ไปยังบัฟเฟอร์เอาต์พุตโดยตรง HWC ไม่เกี่ยวข้องกับการเรียบเรียง
  • ผสม — GPU ทำการผสมบางเลเยอร์กับ เฟรมบัฟเฟอร์และ HWC รวมเฟรมบัฟเฟอร์และเลเยอร์ที่เหลือ การเขียนไปยังบัฟเฟอร์เอาต์พุตโดยตรง
  • HWC — HWC จะคอมโพสิตเลเยอร์ทั้งหมดและเขียนโดยตรง ไปยังบัฟเฟอร์เอาต์พุต

รูปแบบเอาต์พุต

รูปแบบเอาต์พุตบัฟเฟอร์การแสดงผลเสมือนจริงจะขึ้นอยู่กับโหมดของบัฟเฟอร์

  • โหมด GLES — ไดรเวอร์ EGL จะตั้งค่ารูปแบบบัฟเฟอร์เอาต์พุตใน dequeueBuffer() ซึ่งโดยปกติจะเป็น RGBA_8888 ผู้บริโภคต้องยอมรับรูปแบบเอาต์พุตที่ไดรเวอร์กำหนด มิฉะนั้นระบบจะอ่านบัฟเฟอร์ไม่ได้
  • โหมด MIXED และ HWC - หากผู้บริโภคต้องการ CPU การเข้าถึง ผู้บริโภคจะเป็นผู้กำหนดรูปแบบเอง หากไม่มี รูปแบบคือ IMPLEMENTATION_DEFINED และ Gralloc ตั้งค่ารูปแบบที่ดีที่สุดตาม การแจ้งเตือนการใช้งาน ตัวอย่างเช่น Gralloc ตั้งค่ารูปแบบ YCbCr หากผู้บริโภค โปรแกรมเปลี่ยนไฟล์วิดีโอและ HWC สามารถเขียนรูปแบบได้อย่างมีประสิทธิภาพ

รั้วสำหรับซิงค์

การซิงค์ (Sync) รั้วเป็นมุมมองที่สำคัญในกราฟิก Android ระบบ รั้วช่วยให้ CPU ทำงานได้อย่างอิสระจากการทำงานของ GPU พร้อมกัน บล็อกเฉพาะเมื่อมีทรัพยากร Dependency ที่แท้จริงเท่านั้น

ตัวอย่างเช่น เมื่อแอปส่งบัฟเฟอร์ที่เกิดขึ้นบน GPU จะส่งอ็อบเจ็กต์ Sync Fence ด้วย รั้วนี้จะส่งสัญญาณเมื่อ GPU เขียนลงในบัฟเฟอร์เสร็จแล้ว

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

โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับรั้วการซิงค์ที่หัวข้อเครื่องมือเขียนฮาร์ดแวร์ การผสานรวม