การใช้ฮาร์ดแวร์ Composer HAL

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

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

การใช้งาน HWC ควรสนับสนุน:

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

ในการดำเนินการ HWC:

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

HWC ดั้งเดิม

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

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

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

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

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

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

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

สำหรับเอกสารรายละเอียดเกี่ยวกับฟังก์ชั่นนักแต่งเพลง HAL และการทำงานของฟังก์ชั่น HWC passthrough ดู composer สำหรับรายละเอียดเกี่ยวกับเอกสาร HWC คำแนะนำการทำงานให้ดู hwcomposer2.h

ที่จับเลเยอร์และการแสดงผล

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

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

การแสดงผลทางกายภาพถูกสร้างขึ้นโดยการเสียบปลั๊ก เมื่อจอแสดงผลทางกายภาพถูกเสียบปลั๊ก HWC จะสร้างหมายเลขอ้างอิงและส่งผ่านหมายเลขอ้างอิงไปยัง SurfaceFlinger ผ่านการเรียกกลับของ Hotplug แสดงเสมือนถูกสร้างขึ้นโดย SurfaceFlinger โทร createVirtualDisplay() เพื่อขอการแสดงผล หาก HWC รองรับองค์ประกอบการแสดงผลเสมือน จะส่งคืนหมายเลขอ้างอิง จากนั้น SurfaceFlinger จะมอบหมายองค์ประกอบของจอแสดงผลให้กับ HWC หาก HWC ไม่รองรับองค์ประกอบการแสดงผลเสมือน SurfaceFlinger จะสร้างที่จับและประกอบการแสดงผล

แสดงการทำงานขององค์ประกอบ

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

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

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

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

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

สุดท้าย SurfaceFlinger เรียก presentDisplay จะบอก HWC ที่จะเสร็จสิ้นกระบวนการองค์ประกอบและแสดงผลสุดท้าย

จอแสดงผลหลายจอ

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

  • ก็สันนิษฐานว่ามีตรงหนึ่งแสดงผลภายใน จอแสดงผลภายในเป็นจอแสดงผลที่ฮอตปลั๊กเริ่มต้นรายงานระหว่างการบู๊ต หลังจากเสียบปลั๊กจอแสดงผลภายในแล้ว จะไม่สามารถตัดการเชื่อมต่อได้
  • นอกเหนือจากจอแสดงผลภายในแล้ว จอแสดงผลภายนอกจำนวนเท่าใดก็ได้อาจถูกเสียบฮ็อตเสียบระหว่างการทำงานปกติของอุปกรณ์ กรอบการอนุมานว่า hotplugs ทั้งหมดหลังจากที่แสดงผลภายในครั้งแรกที่มีจอแสดงผลภายนอกดังนั้นถ้ามีการแสดงภายในมีการเพิ่มพวกเขากำลังอยู่ในหมวดหมู่ไม่ถูกต้องเป็น 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 แทนที่จะไปที่หน้าจอ Hardware Composer (HWC) จะเขียนเอาต์พุตไปยังบัฟเฟอร์ จัดเตรียมรั้วให้เสร็จสมบูรณ์ และส่งบัฟเฟอร์ไปยังผู้ใช้บริการ (เช่น ตัวเข้ารหัสวิดีโอ, GPU, CPU และอื่นๆ) จอแสดงผลเสมือนสามารถใช้ 2D/blitter หรือโอเวอร์เลย์ได้ หากไปป์ไลน์การแสดงผลเขียนไปยังหน่วยความจำ

โหมด

แต่ละเฟรมเป็นหนึ่งในสามโหมดหลังจาก SurfaceFlinger เรียก validateDisplay() วิธี HWC:

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

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

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

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

รั้วประสาน

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

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

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

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับรั้วซิงค์เห็น บูรณาการแต่งเพลงฮาร์ดแวร์