SDV Media: Quản lý màn hình

SDV Media cung cấp các màn hình có sẵn cho các ứng dụng OEM bằng API DRM của Linux.

Tương tác giữa các thành phần DRM

Hình 1. Tương tác giữa các thành phần DRM.

  • Framebuffer là một nguồn dữ liệu pixel, được hỗ trợ bởi một số vùng đệm bộ nhớ được phân bổ bên ngoài.

  • Plane là một nguồn hình ảnh mà CRTC sử dụng. Đối tượng này được liên kết với một vùng đệm khung và có thể biểu thị một khung hiển thị bị cắt của vùng đệm khung.

  • CRTC đại diện cho một quy trình hiển thị tổng thể. Nó có thể kết hợp nhiều mặt phẳng để tạo đầu ra video cuối cùng và điều phối đầu ra đến nhiều bộ mã hoá.

  • Bộ mã hoá chuyển đổi đầu ra video từ CRTC thành một dạng phù hợp với đầu nối cụ thể.

  • Trình kết nối đại diện cho một trình kết nối màn hình hiện có. Ví dụ: cổng HDMI.

Để biết nội dung mô tả chi tiết hơn, hãy tham khảo:

Nền tảng API

SDV Media cung cấp các giao diện DRM của Linux. Mặc dù có thể sử dụng trực tiếp bằng cách dùng lệnh gọi hệ thống ioctl, nhưng bạn nên dùng một thư viện trợ giúp không gian người dùng để phát triển ứng dụng. Ví dụ:

  • Crate drm-rs cho Rust (nên dùng),
  • libdrm cho C/C++. Trang drm-kms man cung cấp thông tin tổng quan chi tiết về các API và cách sử dụng chúng.

Thiết lập kết xuất cho một màn hình

  1. Mở một thiết bị DRM (/dev/dri/card*) và sử dụng các API DRM của Linux, chẳng hạn như thông qua libdrm, trên chỉ số mô tả tệp của thiết bị để chọn màn hình và chế độ của màn hình.

    Thông thường, hệ thống lưu trữ chỉ hiển thị một thiết bị GPU ảo duy nhất, xuất hiện dưới dạng /dev/dri/card0.

  2. Phân bổ bộ nhớ đệm trước và sau bằng API DRM của Linux.

    Bạn nên dùng gbm_bo_create() của minigbm và lấy chỉ số mô tả tệp DMA-BUF bằng gbm_bo_get_fd().

  3. Tạo framebuffer GL được hỗ trợ bởi các vùng đệm đã phân bổ.

    1. Tạo EGLImage từ vùng đệm DRM bằng eglCreateImageKHR với EGL_LINUX_DMA_BUF_EXT (từ tiện ích EGL_EXT_image_dma_buf_import).

    2. Tạo một kết cấu GL và dùng glEGLImageTargetTexture2DOES (từ tiện ích GL_OES_EGL_image) để đặt bộ nhớ của kết cấu thành EGLImage từ bước trước.

    3. Tạo một khung hình đệm GL và dùng glFramebufferTexture2D để đặt kết cấu hỗ trợ của khung hình đệm này thành kết cấu được tạo ở bước trước.

  4. Cách kết xuất một khung hình:

    1. Liên kết một trong các framebuffer GL đã tạo.

    2. Vẽ một khung hình bằng các API GLES thông thường.

    3. Hiển thị khung hình trên màn hình: sử dụng API DRM của Linux (drmModeAtomicCommit()) để gửi DRM_MODE_PAGE_FLIP_EVENT bằng chỉ số mô tả tệp DMA-BUF do khung hình đệm GL liên kết sử dụng.

Tạo đầu ra video từ nhiều lớp

Đối với thành phần nhiều lớp (nhiều mặt phẳng) được tăng tốc bằng phần cứng, chúng tôi dựa vào hệ thống máy chủ lưu trữ để hiển thị từng lớp dưới dạng một trình kết nối DRM riêng biệt (màn hình ảo) và ánh xạ các lớp đó đến đúng vị trí / pipeline phần cứng.

Hãy xem phần Thiết lập hoạt động kết xuất cho nhiều màn hình để biết thông tin chi tiết.

Thiết lập hoạt động kết xuất cho nhiều màn hình

  1. Mở thiết bị DRM /dev/dri/card* như trong quy trình một màn hình.

  2. Liệt kê các giắc cắm màn hình hiện có.

    Mỗi màn hình được hiển thị dưới dạng một trình kết nối DRM riêng biệt của thiết bị DRM.

  3. Đối với mỗi giắc cắm màn hình:

    1. Chọn một CRTC tương thích với giắc cắm. Mỗi đầu nối có một danh sách bộ mã hoá có sẵn và mỗi bộ mã hoá cho biết bộ mã hoá đó có thể được dùng với CRTC nào. Luôn có ít nhất một CRTC tương thích.

      1. Chọn một gói cước tương thích với CRTC.

      2. Tạo các khung hình DRM được hỗ trợ bởi các vùng đệm GPU. Quy trình này giống như đối với biến thể một màn hình.

      3. Kết nối mặt phẳng, CRTC và đầu nối, đồng thời đặt chế độ video trên CRTC.

        Bạn có thể đặt chế độ của nhiều màn hình cùng một lúc bằng cách sử dụng API nguyên tử để đặt các thuộc tính DRM sau đây cho từng bộ kết nối, CRTC và mặt phẳng.

    Danh sách đầy đủ các thuộc tính cần thiết:

    Mục tiêu Thuộc tínhLoạiMô tả
    Cầu nối cộng đồngCRTC_IDMã nhận dạng CRTCMã của CRTC cần chỉ định cho trình kết nối
    CRTCMODE_IDMã nhận dạng blob Mã nhận dạng của một blob thuộc tính được tạo bằng drmModeCreatePropertyBlob, chứa cấu trúc drmModeModeInfo của chế độ video đã chọn
    CRTCACTIVEBooleantrue để đánh dấu CRTC là đang hoạt động
    Máy bayFB_IDMã FramebufferMã nhận dạng của vùng đệm khung DRM để hiển thị trên màn hình
    Máy baySRC_XPixelToạ độ X của hình chữ nhật hình ảnh nguồn vùng đệm khung
    Máy baySRC_YPixelToạ độ Y của hình chữ nhật hình ảnh nguồn bộ đệm khung
    Máy baySRC_WSố cố định 16.16Chiều rộng của hình chữ nhật hình ảnh nguồn bộ đệm khung (pixel được dịch chuyển sang trái 16 bit)
    Máy baySRC_HSố cố định 16.16Chiều cao của hình chữ nhật hình ảnh nguồn framebuffer (pixel được dịch chuyển sang trái 16 bit)
    Máy bayCRTC_XPixelToạ độ X của hình chữ nhật hình ảnh đích CRTC
    Máy bayCRTC_YPixelToạ độ Y của hình chữ nhật hình ảnh đích CRTC
    Máy bayCRTC_WPixelChiều rộng của hình chữ nhật hình ảnh đích CRTC
    Máy bayCRTC_HPixelChiều cao của hình chữ nhật hình ảnh đích của CRTC
  4. Nhập vòng lặp kết xuất:

    1. Đợi sự kiện lật trang trên CRTC trước khi kết xuất khung hình tiếp theo.

    2. Kết xuất một khung hình và hiển thị khung hình đó trên màn hình bằng cách lên lịch lật trang cho CRTC + vùng đệm khung hình đã cho.