Nhiều tốc độ làm mới

Android 11 bổ sung hỗ trợ cho các thiết bị có nhiều tốc độ làm mới. Có ba thành phần chính cho tính năng này:

  • API HAL mới được giới thiệu trong android.hardware.graphics.composer@2.4 .
  • Mã nền tảng để phân tích cấu hình thiết bị cho các tốc độ làm mới khác nhau và đặt tốc độ làm mới mong muốn
  • API SDK và NDK mới để cho phép ứng dụng đặt tốc độ khung hình mong muốn

Thực hiện

Hỗ trợ chuyên dụng cho việc chuyển đổi tốc độ làm mới đã được thêm vào android.hardware.graphics.composer@2.4 HAL . Chúng tôi thực sự khuyên bạn nên sử dụng phiên bản này vì các phiên bản trước của nhà soạn nhạc HAL có hỗ trợ hạn chế cho việc chuyển đổi tốc độ làm mới.

Nhóm cấu hình

Một thuộc tính mới CONFIG_GROUP đã được thêm vào IComposerClient::Attribute có thể truy vấn bằng API getDisplayAttribute_2_4 . Thuộc tính này cho phép các nhà cung cấp nhóm các cấu hình hiển thị lại với nhau. Các cấu hình trong cùng một nhóm cho phép chuyển đổi liền mạch giữa chúng trong hầu hết các trường hợp. Nhóm cấu hình được nền tảng sử dụng để phân biệt cấu hình nào có thể được chuyển đổi giữa chúng nhằm chuyển đổi tốc độ làm mới chứ không phải các thuộc tính khác cho cấu hình.

Hãy xem xét ví dụ sau đây minh họa lợi ích của việc sử dụng nhóm cấu hình với thiết bị hỗ trợ bốn cấu hình hiển thị:

  • 1080p@60Hz
  • 1080p@90Hz
  • 1080i@72Hz
  • 1080i@48Hz

Mặc dù thiết bị hỗ trợ tốc độ làm mới 48Hz, 60Hz, 72Hz và 90Hz, màn hình vẫn hoạt động ở một chế độ khác và việc chuyển từ 60Hz sang 72Hz sẽ thay đổi cấu hình hiển thị từ 1080p thành 1080i, đây có thể không phải là hành vi mong muốn. Điều này được giải quyết bằng cách sử dụng các nhóm cấu hình. Bằng cách nhóm 60Hz và 90Hz lại với nhau trong một nhóm cấu hình và 48Hz và 72Hz trong một nhóm cấu hình khác. Nền tảng này biết rằng nó có thể chuyển đổi giữa 60Hz và 90Hz và giữa 48Hz và 72Hz nhưng không thể chuyển đổi giữa 60Hz và 72Hz vì điều này sẽ dẫn đến thay đổi cấu hình thay vì chỉ thay đổi tốc độ làm mới.

Cập nhật API của nhà soạn nhạc

getDisplayVsyncPeriod
Để kiểm soát và dự đoán tốt hơn khi thay đổi tốc độ làm mới, getDisplayVsyncPeriod đã được thêm vào. getDisplayVsyncPeriod trả về tốc độ làm mới hiện tại (tính theo chu kỳ vsync) mà màn hình hoạt động. Điều này đặc biệt hữu ích khi nền tảng cần chuyển đổi giữa tốc độ làm mới và tốc độ làm mới hiện tại để quyết định thời điểm bắt đầu khung hình tiếp theo.
setActiveConfigWithConstraints
Phương thức setActiveConfigWithConstraints là phần mở rộng mới cho phương thức setActiveConfig hiện có và cung cấp thêm thông tin về thay đổi cấu hình. Các ràng buộc được đưa ra như một phần của tham số vsyncPeriodChangeConstraints và chứa các tham số sau.
    mong muốnThời gianNanos
    Thời gian tính bằng CLOCK_MONOTONIC mà sau đó khoảng thời gian vsync có thể thay đổi (nghĩa là khoảng thời gian vsync không được thay đổi trước thời điểm này). Điều này hữu ích khi nền tảng muốn lên kế hoạch trước cho việc thay đổi tốc độ làm mới nhưng nó đã có sẵn một số vùng đệm trong hàng đợi để trình bày. Nền tảng đặt thời gian này phù hợp để tính đến các bộ đệm đó và đảm bảo rằng quá trình chuyển đổi tốc độ làm mới sẽ diễn ra suôn sẻ nhất có thể.
    liền mạchBắt buộc
    Nếu đúng, yêu cầu thay đổi chu kỳ vsync phải diễn ra liền mạch mà không có tạo tác trực quan đáng chú ý. Cờ này được nền tảng sử dụng khi cần thay đổi tốc độ làm mới do thay đổi nội dung (ví dụ: thiết bị không hoạt động và hoạt ảnh bắt đầu). Điều này mang lại cho nhà cung cấp cơ hội không cho phép một số thay đổi cấu hình nhất định khi chúng có thể dẫn đến tạo tác hình ảnh đáng chú ý. Nếu cấu hình không thể thay đổi liền mạch và seamlessRequired được đặt thành true thì quá trình triển khai dự kiến ​​sẽ trả về SEAMLESS_NOT_POSSIBLE làm mã trả về và gọi lệnh gọi lại onSeamlessPossible mới khi có thể thực hiện liền mạch cùng một thay đổi cấu hình.

Sau khi triển khai thành công, quá trình triển khai sẽ trả về một VsyncPeriodChangeTimeline cho nền tảng biết thời điểm dự kiến ​​thay đổi tốc độ làm mới sẽ xảy ra. Các tham số newVsyncAppliedTimeNanos cần được đặt thành thời gian tính bằng CLOCK_MONOTONIC khi màn hình mới sẽ bắt đầu làm mới ở khoảng thời gian vsync mới. Điều này cùng với desiredTimeNanos cho phép nền tảng lên kế hoạch trước cho việc chuyển đổi tốc độ làm mới và bắt đầu đánh dấu trước các ứng dụng để có tốc độ làm mới mới. Điều này cho phép chuyển đổi liền mạch tốc độ làm mới.

Một số triển khai yêu cầu phải gửi khung làm mới trước khi có thể gửi tốc độ làm mới. Để làm được điều đó, HAL có tham số refreshRequired để chỉ ra rằng cần có khung làm mới và refreshTimeNanos để chỉ ra vsync đầu tiên nơi khung làm mới cần được gửi sau đó.

onVsyncPeriodTimingChanged [gọi lại]
Một lệnh gọi lại mới có thể được HAL gọi để cho nền tảng biết rằng một số tham số của dòng thời gian đã thay đổi và nền tảng cần điều chỉnh dòng thời gian của nó. Lệnh gọi lại này dự kiến ​​sẽ được gọi nếu vì lý do nào đó mà dòng thời gian cũ bị bỏ lỡ do thời gian xử lý lâu trên HAL hoặc khung làm mới muộn.

Nền tảng quyết định thay đổi tốc độ làm mới như thế nào?

Việc lựa chọn tốc độ làm mới diễn ra trong hai dịch vụ hệ thống sau:

Quản lý hiển thị
Trình DisplayManager đặt chính sách cấp cao xung quanh tốc độ làm mới. Nó đặt cấu hình hiển thị mặc định, giống như cấu hình HAL của nhà soạn nhạc. Ngoài ra, nó đặt một phạm vi giá trị tối thiểu và tối đa để SurfaceFlinger chọn làm tốc độ làm mới.
bề mặtFlinger
Xác định tốc độ làm mới bằng cách đặt cấu hình trong cùng nhóm cấu hình với cấu hình mặc định và có tốc độ làm mới trong phạm vi tối thiểu/tối đa.

Trình quản lý hiển thị thực hiện các bước sau để xác định chính sách:

  • Tìm ID cấu hình mặc định bằng cách truy vấn cấu hình hoạt động từ SurfaceFlinger
  • Hạn chế phạm vi giá trị tối thiểu và tối đa bằng cách lặp lại các điều kiện hệ thống
    • Cài đặt tốc độ làm mới mặc định : Giá trị tốc độ làm mới mặc định được đặt trong lớp phủ cấu hình R.integer.config_defaultRefreshRate . Giá trị này được sử dụng để xác định tốc độ làm mới thiết bị tiêu chuẩn cho hoạt ảnh và tương tác cảm ứng.
    • Cài đặt tốc độ làm mới cao nhất : Giá trị tốc độ làm mới cao nhất được đọc từ Settings.System.PEAK_REFRESH_RATE . Giá trị này được thay đổi trong thời gian chạy để phản ánh cài đặt thiết bị hiện tại (chẳng hạn như từ tùy chọn menu). Giá trị mặc định được đặt trong lớp phủ cấu hình R.integer.config_defaultPeakRefreshRate .
    • Cài đặt tốc độ làm mới tối thiểu : Giá trị tốc độ làm mới tối thiểu được đọc từ Settings.System.MIN_REFRESH_RATE . Giá trị này có thể được thay đổi trong thời gian chạy để phản ánh cài đặt thiết bị hiện tại (chẳng hạn như từ tùy chọn menu). Giá trị mặc định là 0, do đó không có mức tối thiểu mặc định.
    • Ứng dụng được yêu cầu ModeId : Ứng dụng có thể đặt WindowManager.LayoutParams.preferredDisplayModeId để phản ánh cấu hình ưa thích mà màn hình sẽ hoạt động. Trong hầu hết các điều kiện, DisplayManager sẽ đặt ID cấu hình mặc định tương ứng và đặt tốc độ làm mới tối thiểu và tối đa để phù hợp với tốc độ làm mới của cấu hình.
    • Tiết kiệm pin : Tốc độ làm mới bị giới hạn ở 60Hz hoặc thấp hơn khi thiết bị ở chế độ năng lượng thấp, được biểu thị thông qua Settings.Global.LOW_POWER_MODE.

Sau khi DisplayManager đặt chính sách, SurfaceFlinger sẽ đặt tốc độ làm mới dựa trên các lớp đang hoạt động (các lớp xếp hàng cập nhật khung). Nếu chủ sở hữu của lớp đặt tốc độ khung hình , SurfaceFlinger sẽ cố gắng đặt tốc độ làm mới thành hệ số nhân của tốc độ đó. Ví dụ: nếu hai lớp đang hoạt động, hãy đặt tốc độ khung hình của chúng thành 24 và 60 SurfaceFlinger sẽ chọn 120Hz nếu có. Nếu tốc độ làm mới như vậy không có sẵn cho SurfaceFlinger, nó sẽ cố gắng chọn tốc độ làm mới có lỗi tối thiểu đối với tốc độ khung hình. Để biết thêm thông tin, hãy xem tài liệu dành cho nhà phát triển trên dev.android.com

SurfaceFlinger duy trì các cờ sau để kiểm soát cách quyết định tốc độ làm mới:

  • ro.surface_flinger.use_content_detection_for_refresh_rate: Nếu được đặt, tốc độ làm mới được quyết định dựa trên các lớp đang hoạt động, ngay cả khi tốc độ khung hình không được đặt. SurfaceFlinger duy trì một phương pháp phỏng đoán trong đó nó tìm thấy khung hình/giây trung bình mà lớp đang đăng bộ đệm bằng cách xem dấu thời gian trình bày được gắn vào bộ đệm.
  • ro.surface_flinger.set_touch_timer_ms : nếu > 0, tốc độ làm mới mặc định sẽ được sử dụng khi người dùng chạm vào màn hình trong khoảng thời gian chờ đã định cấu hình. Heuristic này được thực hiện để sẵn sàng với tốc độ làm mới mặc định cho hoạt ảnh.
  • ro.surface_flinger.set_idle_timer_ms : nếu > 0, tốc độ làm mới tối thiểu sẽ được sử dụng khi không có bản cập nhật màn hình nào cho thời gian chờ đã định cấu hình.
  • ro.surface_flinger.set_display_power_timer_ms : nếu > 0, tốc độ làm mới mặc định sẽ được sử dụng khi bật màn hình (hoặc khi thoát khỏi AOD) trong thời gian chờ đã định cấu hình.

API tốc độ khung hình

API tốc độ khung hình cho phép ứng dụng thông báo cho nền tảng Android về tốc độ khung hình dự kiến ​​và có sẵn trên các ứng dụng nhắm mục tiêu Android 11. Để tìm hiểu thêm về API tốc độ khung hình, hãy xem tài liệu dành cho nhà phát triển trên dev.android.com .

Tùy chọn nhà phát triển

Một tùy chọn nhà phát triển mới đã được thêm vào menu chuyển đổi lớp phủ trên màn hình với tốc độ làm mới hiện tại. Tùy chọn mới nằm trong Cài đặt > Hệ thống > Tùy chọn nhà phát triển > Hiển thị tốc độ làm mới.