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

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

  • Các 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ú pháp cấu hình thiết bị cho nhiều tốc độ làm mới và đặt tốc độ làm mới mong muốn
  • SDK và API NDK mới cho phép ứng dụng đặt tốc độ khung hình mong muốn

Triển khai

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

Nhóm cấu hình

Thêm một thuộc tính mới CONFIG_GROUP vào IComposerClient::Attribute có thể truy vấn bằng API getDisplayAttribute_2_4. Thuộc tính này cho phép nhà cung cấp nhóm các cấu hình hiển thị 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 các cấu hình đó trong hầu hết các trường hợp. Nền tảng sử dụng nhóm cấu hình để phân biệt những cấu hình nào có thể chuyển đổi giữa các cấu hình đó 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 một cấu hình.

Hãy xem xét ví dụ sau đây minh hoạ lợi ích của việc sử dụng nhóm cấu hình với một thiết bị hỗ trợ 4 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 nhưng màn hình hoạt động ở chế độ khác và việc chuyển từ 60Hz sang 72Hz sẽ thay đổi cấu hình màn hình từ 1080p sang 1080i, đây có thể không phải là hành vi mong muốn. Bạn có thể giải quyết vấn đề này bằng cách sử dụng nhóm cấu hình. Bằng cách nhóm 60Hz và 90Hz 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 mình có thể chuyển đổi giữa 60Hz và 90Hz cũng như 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 về cấu hình thay vì chỉ thay đổi tốc độ làm mới.

Nội dung cập nhật về Composer API

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 (theo khoảng thời gian vsync) mà màn hình hoạt động. Điều này đặc biệt hữu ích trong khi chuyển đổi giữa tốc độ làm mới và tốc độ làm mới hiện tại mà nền tảng cần để quyết định thời điểm bắt đầu khung hình tiếp theo.
setActiveConfigWithConstraints
Phương thức setActiveConfigWithConstraints là một phần mở rộng mới của phương thức setActiveConfig hiện có và cung cấp thêm thông tin về thay đổi về cấu hình. Các quy tắc ràng buộc được cung cấp như một phần của tham số vsyncPeriodChangeConstraints và chứa các tham số sau.
    desiredTimeNanos
    Thời gian trong CLOCK_MONOTONIC sau đó khoảng thời gian vsync có thể thay đổi (tức là khoảng thời gian vsync không được thay đổi trước thời điểm này). Điều này rất 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 đã có một số vùng đệm trong hàng đợi để hiển thị. Nền tảng sẽ đặt thời gian này cho phù hợp để tính đến các vùng đệm đó và đảm bảo quá trình chuyển đổi tốc độ làm mới diễn ra mượt mà nhất có thể.
    seamlessRequired
    Nếu đúng, yêu cầu việc thay đổi khoảng thời gian vsync phải diễn ra liền mạch mà không cần cấu phần phần mềm hình ảnh đá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ị ở trạng thái rảnh và ảnh động bắt đầu). Điều này giúp nhà cung cấp có cơ hội không cho phép một số thay đổi cấu hình nhất định khi những thay đổi đó có thể dẫn đến hiện tượng hình ảnh đáng chú ý. Nếu không thể thay đổi cấu hình một cách liền mạch và đặt seamlessRequired 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ấu hình tương tự có thể thay đổi một cách liền mạch.

Sau khi 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. Bạn cần đặt các tham số newVsyncAppliedTimeNanos thành thời gian trong CLOCK_MONOTONIC khi màn hình mới bắt đầu làm mới theo chu kỳ 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 ứng dụng cho tốc độ làm mới mới. Việc này cho phép chuyển đổi liền mạch tốc độ làm mới.

Một số cách triển khai yêu cầu gửi khung làm mới trước khi có thể gửi tốc độ làm mới. Do đó, HAL có tham số refreshRequired để cho biết cần có khung làm mới và refreshTimeNanos để cho biết vsync đầu tiên mà khung làm mới cần được gửi sau đó.

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

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

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

DisplayManager
DisplayManager đặt chính sách cấp cao liên quan đến tốc độ làm mới. Phương thức này đặt cấu hình hiển thị mặc định, giống với cấu hình HAL của trình soạn nhạc. Ngoài ra, tuỳ chọn này còn đặ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.
Lớp phủ bề mặt
Xác định tốc độ làm mới bằng cách đặt một cấu hình nằm 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 nằm trong phạm vi tối thiểu/tối đa.

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

  • Tìm mã cấu hình mặc định bằng cách truy vấn cấu hình đang hoạt động trong 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
    • Chế độ 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 dùng để xác định tốc độ làm mới thiết bị tiêu chuẩn cho ảnh động và các lượt tương tác chạm.
    • Chế độ 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 chế độ cài đặt hiện tại của thiết bị (chẳng hạn như từ một tuỳ chọn trong trình đơn). Giá trị mặc định được đặt trong lớp phủ cấu hình R.integer.config_defaultPeakRefreshRate.
    • Chế độ 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. Bạn có thể thay đổi giá trị này trong thời gian chạy để phản ánh chế độ cài đặt hiện tại của thiết bị (chẳng hạn như từ một tuỳ chọn trong trình đơn). Giá trị mặc định là 0, vì vậy không có giá trị tối thiểu mặc định.
    • ModeId do ứng dụng yêu cầu: Ứng dụng có thể đặt WindowManager.LayoutParams.preferredDisplayModeId để phản ánh cấu hình ưu tiên mà màn hình sẽ hoạt động. Trong hầu hết điều kiện, DisplayManager sẽ đặt mã cấu hình mặc định sao cho phù hợp, đồng thời đặt tốc độ làm mới tối thiểu và tối đa sao cho khớp với tốc độ làm mới của cấu hình.
    • Trình tiết kiệm pin: Tốc độ làm mới bị giới hạn ở 60 Hz trở xuống khi thiết bị ở chế độ tiết kiệm pin, đượ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 một giá trị là hệ số của tốc độ đó. Ví dụ: nếu 2 lớp hoạt động đặt tốc độ khung hình là 24 và 60, SurfaceFlinger sẽ chọn 120Hz nếu có. Nếu SurfaceFlinger không có tốc độ làm mới như vậy, thì SurfaceFlinger sẽ cố gắng chọn tốc độ làm mới có lỗi tối thiểu cho 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 developer.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 bạn đặt tốc độ làm mới, tốc độ này sẽ được quyết định dựa trên các lớp đang hoạt động, ngay cả khi bạn không đặt tốc độ khung hình. SurfaceFlinger duy trì một phương pháp phỏng đoán tìm ra tốc độ khung hình trung bình mà lớp đang đăng vùng đệm bằng cách xem dấu thời gian trình bày đính kèm vào vùng đệ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 thời gian chờ đã định cấu hình. Phương pháp phỏng đoán này được thực hiện để sẵn sàng với tốc độ làm mới mặc định cho ảnh động.
  • 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ó màn hình cập nhật nào cho thời gian chờ đã định cấu hình.
  • ro.surface_flinger.set_display_power_timer_ms: nếu > 0, thì 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 khoảng 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 đến 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 developer.android.com.

Tuỳ chọn cho nhà phát triển

Trình đơn đã thêm một tuỳ chọn mới dành cho nhà phát triển để bật/tắt lớp phủ trên màn hình bằng tốc độ làm mới hiện tại. Tuỳ chọn mới này nằm trong phần Cài đặt > Hệ thống > Tuỳ chọn cho nhà phát triển > Hiển thị tốc độ làm mới.