khung đồng bộ hóa

Khung đồng bộ hóa mô tả rõ ràng sự phụ thuộc giữa các hoạt động không đồng bộ khác nhau trong hệ thống đồ họa Android. Khung này cung cấp một API cho phép các thành phần cho biết khi nào bộ đệm được giải phóng. Khung này cũng cho phép các nguyên hàm đồng bộ hóa được truyền giữa các trình điều khiển từ kernel đến không gian người dùng và giữa chính các quy trình không gian người dùng.

Ví dụ: một ứng dụng có thể xếp hàng công việc cần thực hiện trong GPU. GPU bắt đầu vẽ hình ảnh đó. Mặc dù hình ảnh chưa được đưa vào bộ nhớ nhưng con trỏ bộ đệm sẽ được chuyển tới bộ tổng hợp cửa sổ cùng với hàng rào cho biết khi nào công việc của GPU sẽ kết thúc. Bộ tổng hợp cửa sổ bắt đầu xử lý trước và chuyển công việc tới bộ điều khiển hiển thị. Theo cách tương tự, công việc của CPU được thực hiện trước thời hạn. Sau khi GPU kết thúc, bộ điều khiển hiển thị sẽ hiển thị ngay hình ảnh.

Khung đồng bộ hóa cũng cho phép người triển khai tận dụng tài nguyên đồng bộ hóa trong các thành phần phần cứng của riêng họ. Cuối cùng, khung này cung cấp khả năng hiển thị trong đường dẫn đồ họa để giúp gỡ lỗi.

Đồng bộ hóa rõ ràng

Đồng bộ hóa rõ ràng cho phép nhà sản xuất và người tiêu dùng bộ đệm đồ họa báo hiệu khi họ sử dụng xong bộ đệm. Đồng bộ hóa rõ ràng được thực hiện trong không gian kernel.

Lợi ích của việc đồng bộ hóa rõ ràng bao gồm:

  • Ít biến đổi hành vi giữa các thiết bị
  • Hỗ trợ gỡ lỗi tốt hơn
  • Cải thiện số liệu thử nghiệm

Khung đồng bộ hóa có ba loại đối tượng:

  • sync_timeline
  • sync_pt
  • sync_fence

đồng bộ_thời gian

sync_timeline là dòng thời gian tăng dần đều mà nhà cung cấp nên triển khai cho từng phiên bản trình điều khiển, chẳng hạn như ngữ cảnh GL, bộ điều khiển hiển thị hoặc bộ lọc 2D. sync_timeline đếm các công việc được gửi tới kernel cho một phần cứng cụ thể. sync_timeline cung cấp sự đảm bảo về thứ tự hoạt động và cho phép triển khai dành riêng cho phần cứng.

Thực hiện theo các nguyên tắc sau khi triển khai sync_timeline :

  • Cung cấp tên hữu ích cho tất cả trình điều khiển, mốc thời gian và hàng rào để đơn giản hóa việc gỡ lỗi.
  • Triển khai các toán tử timeline_value_strpt_value_str theo dòng thời gian để làm cho kết quả gỡ lỗi dễ đọc hơn.
  • Triển khai điền driver_data để cung cấp cho các thư viện không gian người dùng, chẳng hạn như thư viện GL, quyền truy cập vào dữ liệu dòng thời gian riêng tư, nếu muốn. data_driver cho phép nhà cung cấp chuyển thông tin về sync_fencesync_pts bất biến để xây dựng các dòng lệnh dựa trên chúng.
  • Không cho phép không gian người dùng tạo hoặc báo hiệu một hàng rào một cách rõ ràng. Việc tạo tín hiệu/hàng rào một cách rõ ràng sẽ dẫn đến một cuộc tấn công từ chối dịch vụ làm tạm dừng chức năng của đường ống.
  • Không truy cập rõ ràng các phần tử sync_timeline , sync_pt hoặc sync_fence . API cung cấp tất cả các chức năng cần thiết.

đồng bộ_pt

sync_pt là một giá trị hoặc một điểm trên sync_timeline . Một điểm có ba trạng thái: hoạt động, báo hiệu và lỗi. Các điểm bắt đầu ở trạng thái hoạt động và chuyển sang trạng thái báo hiệu hoặc lỗi. Ví dụ: khi người sử dụng hình ảnh không còn cần bộ đệm nữa, sync_pt sẽ được báo hiệu để nhà sản xuất hình ảnh biết rằng có thể ghi lại vào bộ đệm.

hàng rào đồng bộ

sync_fence là tập hợp các giá trị sync_pt thường có cha mẹ sync_timeline khác nhau (chẳng hạn như đối với bộ điều khiển hiển thị và GPU). sync_fence , sync_ptsync_timeline là các nguyên hàm chính mà trình điều khiển và không gian người dùng sử dụng để truyền đạt các phần phụ thuộc của chúng. Khi hàng rào được phát tín hiệu, tất cả các lệnh được đưa ra trước hàng rào được đảm bảo hoàn thành vì trình điều khiển hạt nhân hoặc khối phần cứng thực thi các lệnh theo thứ tự.

Khung đồng bộ hóa cho phép nhiều người tiêu dùng hoặc nhà sản xuất gửi tín hiệu khi họ sử dụng xong bộ đệm, truyền đạt thông tin phụ thuộc bằng một tham số chức năng. Hàng rào được hỗ trợ bởi bộ mô tả tệp và được chuyển từ không gian kernel sang không gian người dùng. Ví dụ: một hàng rào có thể chứa hai giá trị sync_pt biểu thị khi hai người sử dụng hình ảnh riêng biệt đọc xong bộ đệm. Khi hàng rào được phát tín hiệu, người sản xuất hình ảnh biết rằng cả hai người tiêu dùng đã tiêu thụ xong.

Hàng rào, như giá trị sync_pt , bắt đầu hoạt động và thay đổi trạng thái dựa trên trạng thái điểm của chúng. Nếu tất cả các giá trị sync_pt được báo hiệu thì sync_fence sẽ được báo hiệu. Nếu một sync_pt rơi vào trạng thái lỗi thì toàn bộ sync_fence cũng có trạng thái lỗi.

Tư cách thành viên trong sync_fence là bất biến sau khi hàng rào được tạo. Để có được nhiều hơn một điểm trong một hàng rào, việc hợp nhất được tiến hành trong đó các điểm từ hai hàng rào riêng biệt được thêm vào hàng rào thứ ba. Nếu một trong những điểm đó được báo hiệu ở hàng rào ban đầu còn điểm kia thì không, thì hàng rào thứ ba cũng sẽ không ở trạng thái được báo hiệu.

Để triển khai đồng bộ hóa rõ ràng, hãy cung cấp những thông tin sau:

  • Một hệ thống con không gian hạt nhân triển khai khung đồng bộ hóa cho một trình điều khiển phần cứng cụ thể. Các trình điều khiển cần nhận biết hàng rào thường là bất kỳ thứ gì truy cập hoặc giao tiếp với Trình soạn thảo phần cứng. Các tập tin chính bao gồm:
    • Thực hiện cốt lõi:
      • kernel/common/include/linux/sync.h
      • kernel/common/drivers/base/sync.c
    • Tài liệu tại kernel/common/Documentation/sync.txt
    • Thư viện để giao tiếp với không gian kernel trong platform/system/core/libsync
  • Nhà cung cấp phải cung cấp hàng rào đồng bộ hóa thích hợp làm tham số cho các hàm validateDisplay()presentDisplay() trong HAL.
  • Hai tiện ích mở rộng GL liên quan đến hàng rào ( EGL_ANDROID_native_fence_syncEGL_ANDROID_wait_sync ) và hỗ trợ hàng rào trong trình điều khiển đồ họa.

Nghiên cứu điển hình: Triển khai trình điều khiển hiển thị

Để sử dụng API hỗ trợ chức năng đồng bộ hóa, hãy phát triển trình điều khiển hiển thị có chức năng đệm hiển thị. Trước khi khung đồng bộ hóa tồn tại, chức năng này sẽ nhận các đối tượng dma-buf , đặt các bộ đệm đó trên màn hình và chặn trong khi bộ đệm hiển thị. Ví dụ:

/*
 * assumes buffer is ready to be displayed.  returns when buffer is no longer on
 * screen.
 */
void display_buffer(struct dma_buf *buffer);

Với khung đồng bộ hóa, hàm display_buffer phức tạp hơn. Trong khi hiển thị bộ đệm, bộ đệm được liên kết với một hàng rào cho biết khi nào bộ đệm sẽ sẵn sàng. Bạn có thể xếp hàng và bắt đầu công việc sau khi hàng rào được dọn sạch.

Xếp hàng và bắt đầu công việc sau khi hàng rào được dọn sạch không cản trở được điều gì. Bạn ngay lập tức trả lại hàng rào của riêng mình, điều này đảm bảo khi nào bộ đệm sẽ tắt khỏi màn hình. Khi bạn xếp hàng các bộ đệm, kernel sẽ liệt kê các phần phụ thuộc với khung đồng bộ hóa:

/*
 * displays buffer when fence is signaled.  returns immediately with a fence
 * that signals when buffer is no longer displayed.
 */
struct sync_fence* display_buffer(struct dma_buf *buffer, struct sync_fence
*fence);

Tích hợp đồng bộ hóa

Phần này giải thích cách tích hợp khung đồng bộ hóa không gian nhân với các phần không gian người dùng của khung Android và các trình điều khiển phải giao tiếp với nhau. Các đối tượng không gian hạt nhân được biểu diễn dưới dạng mô tả tệp trong không gian người dùng.

Quy ước tích hợp

Thực hiện theo các quy ước giao diện Android HAL:

  • Nếu API cung cấp bộ mô tả tệp tham chiếu đến sync_pt thì trình điều khiển của nhà cung cấp hoặc HAL sử dụng API phải đóng bộ mô tả tệp.
  • Nếu trình điều khiển của nhà cung cấp hoặc HAL chuyển bộ mô tả tệp có chứa sync_pt cho hàm API thì trình điều khiển của nhà cung cấp hoặc HAL không được đóng bộ mô tả tệp.
  • Để tiếp tục sử dụng bộ mô tả tệp hàng rào, trình điều khiển của nhà cung cấp hoặc HAL phải sao chép bộ mô tả.

Đối tượng hàng rào được đổi tên mỗi khi nó đi qua BufferQueue. Hỗ trợ hàng rào hạt nhân cho phép hàng rào có chuỗi tên, vì vậy khung đồng bộ hóa sử dụng tên cửa sổ và chỉ mục bộ đệm đang được xếp hàng đợi để đặt tên cho hàng rào, chẳng hạn như SurfaceView:0 . Điều này hữu ích trong việc gỡ lỗi nhằm xác định nguồn gốc của sự bế tắc khi tên xuất hiện trong đầu ra của /d/sync và báo cáo lỗi.

Tích hợp ANativeWindow

ANativeWindow có khả năng nhận biết hàng rào. dequeueBuffer , queueBuffercancelBuffer có các tham số hàng rào.

Tích hợp OpenGL ES

Tích hợp đồng bộ hóa OpenGL ES dựa trên hai tiện ích mở rộng EGL:

  • EGL_ANDROID_native_fence_sync cung cấp cách bao bọc hoặc tạo bộ mô tả tệp hàng rào Android gốc trong đối tượng EGLSyncKHR .
  • EGL_ANDROID_wait_sync cho phép dừng ở phía GPU thay vì phía CPU, khiến GPU phải chờ EGLSyncKHR . Tiện ích mở rộng EGL_ANDROID_wait_sync giống với tiện ích mở rộng EGL_KHR_wait_sync .

Để sử dụng các tiện ích mở rộng này một cách độc lập, hãy triển khai tiện ích mở rộng EGL_ANDROID_native_fence_sync cùng với hỗ trợ kernel liên quan. Tiếp theo, bật tiện ích mở rộng EGL_ANDROID_wait_sync trong trình điều khiển của bạn. Tiện ích mở rộng EGL_ANDROID_native_fence_sync bao gồm loại đối tượng EGLSyncKHR hàng rào riêng biệt. Do đó, các tiện ích mở rộng áp dụng cho các loại đối tượng EGLSyncKHR hiện tại không nhất thiết phải áp dụng cho các đối tượng EGL_ANDROID_native_fence , tránh các tương tác không mong muốn.

Tiện ích mở rộng EGL_ANDROID_native_fence_sync sử dụng thuộc tính mô tả tệp hàng rào gốc tương ứng chỉ có thể được đặt tại thời điểm tạo và không thể truy vấn trực tiếp trở đi từ đối tượng đồng bộ hóa hiện có. Thuộc tính này có thể được đặt thành một trong hai chế độ:

  • Bộ mô tả tệp hàng rào hợp lệ bao bọc bộ mô tả tệp hàng rào Android gốc hiện có trong đối tượng EGLSyncKHR .
  • -1 tạo bộ mô tả tệp hàng rào Android gốc từ đối tượng EGLSyncKHR .

Sử dụng lệnh gọi hàm DupNativeFenceFD() để trích xuất đối tượng EGLSyncKHR từ bộ mô tả tệp hàng rào gốc của Android. Điều này có kết quả tương tự như truy vấn thuộc tính đã đặt nhưng tuân thủ quy ước rằng người nhận sẽ đóng hàng rào (do đó có thao tác trùng lặp). Cuối cùng, việc hủy đối tượng EGLSyncKHR sẽ đóng thuộc tính hàng rào bên trong.

Tích hợp phần cứng Composer

Trình soạn thảo phần cứng xử lý ba loại hàng rào đồng bộ hóa:

  • Hàng rào thu thập được chuyển cùng với bộ đệm đầu vào cho các lệnh gọi setLayerBuffersetClientTarget . Chúng thể hiện quá trình ghi đang chờ xử lý vào bộ đệm và phải báo hiệu trước khi SurfaceFlinger hoặc HWC cố gắng đọc từ bộ đệm liên quan để thực hiện việc tổng hợp.
  • Hàng rào phát hành được truy xuất sau lệnh gọi tới presentDisplay bằng lệnh gọi getReleaseFences . Chúng thể hiện quá trình đọc đang chờ xử lý từ bộ đệm trước đó trên cùng một lớp. Hàng rào giải phóng báo hiệu khi HWC không còn sử dụng bộ đệm trước đó vì bộ đệm hiện tại đã thay thế bộ đệm trước đó trên màn hình. Hàng rào phát hành được chuyển trở lại ứng dụng cùng với vùng đệm trước đó sẽ được thay thế trong quá trình tổng hợp hiện tại. Ứng dụng phải đợi cho đến khi có tín hiệu hàng rào phát hành trước khi ghi nội dung mới vào bộ đệm được trả về cho chúng.
  • Hàng rào hiện tại được trả về, mỗi hàng rào cho mỗi khung hình, như một phần của lệnh gọi tới presentDisplay . Hàng rào hiện tại biểu thị thời điểm thành phần của khung này đã hoàn thành hoặc thay vào đó, khi kết quả thành phần của khung trước không còn cần thiết nữa. Đối với màn hình vật lý, presentDisplay trả về hàng rào hiện tại khi khung hình hiện tại xuất hiện trên màn hình. Sau khi hàng rào hiện tại được trả lại, bạn có thể ghi lại vào bộ đệm mục tiêu SurfaceFlinger một cách an toàn, nếu có. Đối với màn hình ảo, hàng rào hiện tại được trả về khi đọc an toàn từ bộ đệm đầu ra.