Android 11 รองรับอุปกรณ์ที่มีอัตราการรีเฟรชหลายระดับ ฟีเจอร์นี้มีองค์ประกอบหลัก 3 อย่าง ได้แก่
- HAL API ใหม่ที่เปิดตัวใน
android.hardware.graphics.composer@2.4
- โค้ดแพลตฟอร์มเพื่อแยกวิเคราะห์การกำหนดค่าอุปกรณ์สำหรับอัตราการรีเฟรชที่แตกต่างกันและตั้งค่าอัตราการรีเฟรชที่ต้องการ
- SDK และ NDK API ใหม่เพื่ออนุญาตให้แอปตั้งค่าอัตราเฟรมที่ต้องการ
การใช้งาน
เราได้เพิ่มการรองรับการเปลี่ยนอัตราการรีเฟรชโดยเฉพาะใน android.hardware.graphics.composer@2.4 HAL
เราขอแนะนําอย่างยิ่งให้ใช้เวอร์ชันนี้ เนื่องจาก HAL ของคอมโพเซอร์เวอร์ชันก่อนหน้ารองรับการเปลี่ยนอัตราการรีเฟรชอย่างจํากัด
กลุ่มการกําหนดค่า
มีการเพิ่มแอตทริบิวต์ใหม่ CONFIG_GROUP
ลงใน IComposerClient::Attribute
ซึ่งค้นหาได้โดยใช้ getDisplayAttribute_2_4
API แอตทริบิวต์นี้ช่วยให้ผู้ให้บริการจัดกลุ่มการกำหนดค่าการแสดงผลเข้าด้วยกันได้ การกำหนดค่าในกลุ่มเดียวกันช่วยให้สลับระหว่างการกำหนดค่าต่างๆ ได้อย่างราบรื่นในเกือบทุกกรณี แพลตฟอร์มใช้กลุ่มการกําหนดค่าเพื่อแยกความแตกต่างระหว่างการกําหนดค่าที่เปลี่ยนได้ เพื่อเปลี่ยนอัตราการรีเฟรช ไม่ใช่แอตทริบิวต์อื่นๆ สำหรับการกําหนดค่า
พิจารณาตัวอย่างต่อไปนี้ซึ่งแสดงประโยชน์ของการใช้กลุ่มการกําหนดค่ากับอุปกรณ์ที่รองรับการกําหนดค่าการแสดงผล 4 แบบ
- 1080p@60Hz
- 1080p@90Hz
- 1080i@72Hz
- 1080i@48Hz
แม้ว่าอุปกรณ์จะรองรับอัตราการรีเฟรช 48Hz, 60Hz, 72Hz และ 90Hz แต่จอแสดงผลจะทำงานในโหมดอื่น และการเปลี่ยนจาก 60Hz เป็น 72Hz จะเปลี่ยนการกำหนดค่าจอแสดงผลจาก 1080p เป็น 1080i ซึ่งอาจไม่ใช่ลักษณะการทำงานที่ต้องการ ปัญหานี้แก้ไขได้โดยใช้กลุ่มการกําหนดค่า โดยจัดกลุ่ม 60Hz และ 90Hz ไว้ด้วยกันในกลุ่มการกําหนดค่ากลุ่มหนึ่ง และ 48Hz และ 72Hz ไว้ในกลุ่มการกําหนดค่าอีกกลุ่มหนึ่ง แพลตฟอร์มทราบว่าสามารถสลับระหว่าง 60Hz กับ 90Hz และระหว่าง 48Hz กับ 72Hz แต่สลับระหว่าง 60Hz กับ 72Hz ไม่ได้เนื่องจากจะส่งผลให้มีการเปลี่ยนแปลงการกําหนดค่าแทนที่จะเปลี่ยนอัตราการรีเฟรช


การอัปเดต Composer API
- getDisplayVsyncPeriod
- เพิ่ม
getDisplayVsyncPeriod
เพื่อให้ควบคุมและคาดการณ์ได้ดีขึ้นเมื่อเปลี่ยนอัตราการรีเฟรชgetDisplayVsyncPeriod
จะแสดงอัตราการรีเฟรชปัจจุบัน (ในแง่ของระยะเวลา vsync) ที่จอแสดงผลทำงาน ซึ่งจะเป็นประโยชน์อย่างยิ่งในระหว่างการเปลี่ยนระหว่างอัตราการรีเฟรช และแพลตฟอร์มต้องใช้อัตราการรีเฟรชปัจจุบันเพื่อตัดสินใจว่าจะเริ่มเฟรมถัดไปเมื่อใด - setActiveConfigWithConstraints
- เมธอด
setActiveConfigWithConstraints
เป็นส่วนขยายใหม่ของเมธอดsetActiveConfig
ที่มีอยู่และจะให้ข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงการกําหนดค่า ข้อจำกัดจะระบุเป็นส่วนหนึ่งของพารามิเตอร์vsyncPeriodChangeConstraints
และมีพารามิเตอร์ต่อไปนี้ - desiredTimeNanos
- เวลาที่
CLOCK_MONOTONIC
ซึ่งหลังจากนั้นระยะเวลา vsync อาจเปลี่ยนแปลง (นั่นคือ ระยะเวลา vsync ต้องไม่เปลี่ยนแปลงก่อนเวลานี้) ซึ่งมีประโยชน์เมื่อแพลตฟอร์มต้องการวางแผนล่วงหน้าสำหรับการเปลี่ยนแปลงอัตราการรีเฟรช แต่มีบัฟเฟอร์บางส่วนในคิวที่จะแสดงอยู่แล้ว แพลตฟอร์มจะกำหนดเวลานี้ให้สอดคล้องกันเพื่อพิจารณาบัฟเฟอร์เหล่านั้นและตรวจสอบว่าการเปลี่ยนอัตราการรีเฟรชเป็นไปอย่างราบรื่นที่สุด - seamlessRequired
- หากเป็นจริง การเปลี่ยนแปลงระยะเวลา vsync จะต้องเกิดขึ้นอย่างราบรื่นโดยไม่มีภาพรบกวนให้เห็น แพลตฟอร์มจะใช้ Flag นี้เมื่อจำเป็นต้องเปลี่ยนอัตราการรีเฟรชเนื่องจากการเปลี่ยนแปลงเนื้อหา (เช่น อุปกรณ์ไม่มีการใช้งานและภาพเคลื่อนไหวเริ่มขึ้น) ซึ่งช่วยให้ผู้ให้บริการมีโอกาสที่จะไม่อนุญาตให้ทำการเปลี่ยนแปลงการกำหนดค่าบางอย่างเมื่ออาจทำให้เกิดข้อบกพร่องที่มองเห็นได้ หากเปลี่ยนการกําหนดค่าไม่ได้อย่างราบรื่นและตั้งค่า
seamlessRequired
เป็นtrue
ระบบจะแสดงผลSEAMLESS_NOT_POSSIBLE
เป็นรหัสผลลัพธ์และเรียกใช้การเรียกกลับonSeamlessPossible
ใหม่เมื่อเปลี่ยนการกําหนดค่าเดียวกันได้อย่างราบรื่น เมื่อติดตั้งใช้งานสำเร็จ ระบบจะแสดง
VsyncPeriodChangeTimeline
ซึ่งบอกให้แพลตฟอร์มทราบว่าควรคาดหวังการเปลี่ยนแปลงอัตราการรีเฟรชเมื่อใด พารามิเตอร์newVsyncAppliedTimeNanos
ต้องตั้งค่าเป็นเวลาที่CLOCK_MONOTONIC
เมื่อจอแสดงผลใหม่จะเริ่มรีเฟรชตามระยะเวลา vsync ใหม่ ข้อมูลนี้ร่วมกับdesiredTimeNanos
จะช่วยให้แพลตฟอร์มวางแผนการเปลี่ยนอัตราการรีเฟรชล่วงหน้าและเริ่มเลือกแอปสำหรับอัตราการรีเฟรชใหม่ล่วงหน้าได้ ซึ่งจะช่วยให้อัตราการรีเฟรชเปลี่ยนได้อย่างราบรื่นการติดตั้งใช้งานบางรายการต้องส่งเฟรมรีเฟรชก่อนจึงจะส่งอัตราการรีเฟรชได้ HAL จึงมีพารามิเตอร์
refreshRequired
เพื่อระบุว่าจำเป็นต้องมีเฟรมรีเฟรช และrefreshTimeNanos
เพื่อระบุ vsync แรกที่ต้องส่งเฟรมรีเฟรชหลังจากนั้น- onVsyncPeriodTimingChanged [callback]
- การเรียกกลับใหม่ที่ HAL สามารถเรียกใช้เพื่อแจ้งให้แพลตฟอร์มทราบว่าพารามิเตอร์บางอย่างของไทม์ไลน์มีการเปลี่ยนแปลงและแพลตฟอร์มต้องปรับไทม์ไลน์ ระบบจะเรียกใช้การเรียกกลับนี้หากพลาดไทม์ไลน์เดิมเนื่องจากเวลาในการประมวลผล HAL นานหรือเฟรมรีเฟรชช้า
แพลตฟอร์มตัดสินใจเปลี่ยนอัตราการรีเฟรชอย่างไร
การเลือกอัตราการรีเฟรชจะเกิดขึ้นในบริการของระบบ 2 รายการต่อไปนี้
- DisplayManager
DisplayManager
จะกำหนดนโยบายระดับสูงเกี่ยวกับอัตรารีเฟรช โดยจะตั้งค่าการแสดงผลเริ่มต้น ซึ่งเหมือนกับการกำหนดค่า HAL ของคอมโพเซอร์ นอกจากนี้ ยังกำหนดช่วงค่าต่ำสุดและสูงสุดสำหรับSurfaceFlinger
ให้เลือกเป็นอัตรารีเฟรช- SurfaceFlinger
- กำหนดอัตราการรีเฟรชโดยการตั้งค่าที่อยู่ในกลุ่มการกําหนดค่าเดียวกับการกําหนดค่าเริ่มต้นและมีอัตราการรีเฟรชอยู่ในช่วงขั้นต่ำ/สูงสุด
เครื่องมือจัดการ Display จะทําตามขั้นตอนต่อไปนี้เพื่อกําหนดนโยบาย
- ค้นหารหัสการกําหนดค่าเริ่มต้นโดยการค้นหาการกําหนดค่าที่ใช้งานอยู่จาก
SurfaceFlinger
- การจํากัดช่วงของค่าต่ำสุดและสูงสุดโดยการวนซ้ำเงื่อนไขของระบบ
- การตั้งค่าอัตราการรีเฟรชเริ่มต้น: ค่าอัตราการรีเฟรชเริ่มต้นจะกำหนดไว้ในการวางซ้อนการกําหนดค่า
R.integer.config_defaultRefreshRate
ค่านี้ใช้เพื่อกำหนดอัตราการรีเฟรชมาตรฐานของอุปกรณ์สำหรับภาพเคลื่อนไหวและการโต้ตอบด้วยการสัมผัส - การตั้งค่าอัตราการรีเฟรชสูงสุด: ระบบจะอ่านค่าอัตราการรีเฟรชสูงสุดจาก
Settings.System.PEAK_REFRESH_RATE
ค่านี้จะเปลี่ยนแปลงขณะรันไทม์เพื่อให้สอดคล้องกับการตั้งค่าอุปกรณ์ปัจจุบัน (เช่น จากตัวเลือกเมนู) ค่าเริ่มต้นจะตั้งค่าไว้ในการวางซ้อนการกําหนดค่าR.integer.config_defaultPeakRefreshRate
- การตั้งค่าอัตราการรีเฟรชขั้นต่ำ: ระบบจะอ่านค่าอัตราการรีเฟรชขั้นต่ำจาก
Settings.System.MIN_REFRESH_RATE
ค่านี้สามารถเปลี่ยนแปลงได้ในรันไทม์เพื่อให้สอดคล้องกับการตั้งค่าอุปกรณ์ปัจจุบัน (เช่น จากตัวเลือกเมนู) ค่าเริ่มต้นคือ 0 จึงไม่มีค่าต่ำสุดเริ่มต้น - Application requested ModeId: แอปสามารถตั้งค่า
WindowManager.LayoutParams.preferredDisplayModeId
เพื่อแสดงการกำหนดค่าที่ต้องการให้จอแสดงผลทำงาน ในเงื่อนไขส่วนใหญ่DisplayManager
จะตั้งค่ารหัสการกําหนดค่าเริ่มต้นตามความเหมาะสม และตั้งค่าอัตราการรีเฟรชขั้นต่ำและสูงสุดให้ตรงกับอัตราการรีเฟรชของการกําหนดค่า - โหมดประหยัดแบตเตอรี่: ระบบจะจำกัดอัตราการรีเฟรชไว้ที่ 60 Hz หรือต่ำกว่าเมื่ออุปกรณ์อยู่ในโหมดพลังงานต่ำ ซึ่งจะแสดงผ่าน
Settings.Global.LOW_POWER_MODE.
- การตั้งค่าอัตราการรีเฟรชเริ่มต้น: ค่าอัตราการรีเฟรชเริ่มต้นจะกำหนดไว้ในการวางซ้อนการกําหนดค่า
เมื่อ DisplayManager
ตั้งค่านโยบายแล้ว SurfaceFlinger
จะตั้งค่าอัตราการรีเฟรชตามเลเยอร์ที่มีการใช้งาน (เลเยอร์ที่จัดคิวการอัปเดตเฟรม) หากเจ้าของเลเยอร์ตั้งค่าอัตราเฟรม SurfaceFlinger จะพยายามตั้งค่าอัตราการรีเฟรชเป็นค่าที่คูณกับอัตราดังกล่าว
เช่น หากเลเยอร์ที่ใช้งานอยู่ 2 เลเยอร์ตั้งค่าอัตราเฟรมเป็น 24 และ 60 SurfaceFlinger จะเลือก 120Hz หากมี หาก SurfaceFlinger ไม่สามารถใช้อัตราการรีเฟรชดังกล่าวได้ ก็จะพยายามเลือกอัตราการรีเฟรชที่มีความผิดพลาดน้อยที่สุดสำหรับอัตราเฟรม ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบสำหรับนักพัฒนาแอปใน developer.android.com
SurfaceFlinger
รักษา Flag ต่อไปนี้เพื่อควบคุมวิธีกำหนดอัตราการรีเฟรช
ro.surface_flinger.use_content_detection_for_refresh_rate:
หากตั้งค่า ระบบจะกำหนดอัตราการรีเฟรชตามเลเยอร์ที่มีการใช้งาน แม้ว่าจะไม่ได้ตั้งค่าอัตราเฟรมก็ตาม SurfaceFlinger จะรักษาการหาค่าประมาณซึ่งจะค้นหา fps เฉลี่ยที่เลเยอร์โพสต์บัฟเฟอร์โดยดูการประทับเวลาของการแสดงผลที่แนบมากับบัฟเฟอร์ro.surface_flinger.set_touch_timer_ms
: หากมีค่ามากกว่า 0 ระบบจะใช้อัตราการรีเฟรชเริ่มต้นเมื่อผู้ใช้แตะหน้าจอตามการหมดเวลาที่กําหนดค่าไว้ การประเมินนี้ทำขึ้นเพื่อเตรียมพร้อมสำหรับอัตรารีเฟรชเริ่มต้นสำหรับภาพเคลื่อนไหวro.surface_flinger.set_idle_timer_ms
: หากมีค่ามากกว่า 0 ระบบจะใช้อัตราการรีเฟรชขั้นต่ำเมื่อไม่มีการรีเฟรชหน้าจอตามระยะหมดเวลาที่กําหนดค่าไว้ro.surface_flinger.set_display_power_timer_ms
: หากมีค่ามากกว่า 0 ระบบจะใช้อัตราการรีเฟรชเริ่มต้นเมื่อเปิดจอแสดงผล (หรือเมื่อออกจาก AOD) สำหรับระยะหมดเวลาที่กําหนดค่าไว้
Frame Rate API
API อัตราเฟรมช่วยให้แอปแจ้งแพลตฟอร์ม Android เกี่ยวกับอัตราเฟรมที่ต้องการ และใช้ได้ในแอปที่กำหนดเป้าหมายเป็น Android 11 ดูข้อมูลเพิ่มเติมเกี่ยวกับ API อัตราเฟรมได้ที่เอกสารประกอบสําหรับนักพัฒนาซอฟต์แวร์ใน developer.android.com
ตัวเลือกสำหรับนักพัฒนาแอป

มีการเพิ่มตัวเลือกสำหรับนักพัฒนาแอปใหม่ลงในเมนูที่เปิด/ปิดการวางซ้อนบนจอแสดงผลที่มีอัตราการรีเฟรชปัจจุบัน ตัวเลือกใหม่จะอยู่ในส่วนการตั้งค่า > ระบบ > ตัวเลือกสำหรับนักพัฒนาแอป > แสดงอัตราการรีเฟรช