เลเยอร์คอมโพสิต HAL ของฮาร์ดแวร์คอมโพสิต (HWC) ที่ได้รับจาก SurfaceFlinger ซึ่งจะลดปริมาณองค์ประกอบ OpenGL ES (GLES) และ GPU
HWC นำวัตถุต่างๆ เช่น การวางซ้อนและคลิตเตอร์ 2 มิติมาใช้ในการประกอบ พื้นผิวและสื่อสารกับฮาร์ดแวร์การจัดวางหน้าต่างแบบพิเศษเพื่อ หน้าต่างผสม ใช้ HWC เพื่อทำการผสมหน้าต่างแทน วัสดุผสม SurfaceFlinger กับ GPU GPU ส่วนใหญ่ไม่ได้เพิ่มประสิทธิภาพเพื่อ และเมื่อ GPU เขียนเลเยอร์จาก แพลตฟอร์ม SurfaceFlinger แอปจะใช้ GPU เพื่อแสดงผลของตนเองไม่ได้
การติดตั้งใช้งาน HWC ควรรองรับสิ่งต่อไปนี้
- การวางซ้อนอย่างน้อย 4 รายการ:
- แถบสถานะ
- แถบระบบ
- แอป
- วอลเปเปอร์/พื้นหลัง
- เลเยอร์ที่ใหญ่กว่าจอแสดงผล (เช่น วอลเปเปอร์)
- การผสมอัลฟ่าแบบคูณต่อพิกเซลและต่อระนาบ การผสมอัลฟ่า
- เส้นทางฮาร์ดแวร์สำหรับการเล่นวิดีโอที่มีการปกป้อง
- ลำดับการแพ็ก RGBA, รูปแบบ YUV และพร็อพเพอร์ตี้การแบ่งส่วน การเรียงสับเปลี่ยน และระยะก้าว
วิธีใช้ HWC
- ใช้ HWC แบบไม่ดำเนินการและส่งงานการเรียบเรียงทั้งหมดไปที่ GLES
- ใช้อัลกอริทึมเพื่อมอบสิทธิ์การคอมโพสให้กับ HWC ทีละรายการ เช่น มอบสิทธิ์เฉพาะ 3 หรือ 4 พื้นผิวแรกให้กับการวางซ้อน ฮาร์ดแวร์ของ HWC
- เพิ่มประสิทธิภาพ 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 ส่งผลให้มีการเปลี่ยนแปลงเนื้อหาที่แสดง
สำหรับการจัดองค์ประกอบใหม่ 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 ตรวจสอบว่ารั้วการซิงค์มีสัญญาณหรือไม่ และมี กันชน
โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับรั้วการซิงค์ที่หัวข้อเครื่องมือเขียนฮาร์ดแวร์ การผสานรวม