Media SDV: Mengelola layar

SDV Media mengekspos tampilan yang tersedia ke aplikasi OEM dengan Linux DRM API.

Interaksi antara komponen DRM

Gambar 1. Interaksi antara komponen DRM.

  • Framebuffer adalah sumber data piksel, yang didukung oleh beberapa buffer memori yang dialokasikan secara eksternal.

  • Bidang adalah sumber gambar yang digunakan oleh CRTC. Objek ini dikaitkan dengan framebuffer, dan dapat merepresentasikan tampilan framebuffer yang dipangkas.

  • CRTC merepresentasikan keseluruhan pipeline tampilan. Layanan ini dapat menggabungkan beberapa bidang untuk membuat output video akhir, dan mengirimkan output ke beberapa encoder.

  • Encoder mengonversi output video dari CRTC menjadi bentuk yang sesuai untuk konektor tertentu.

  • Konektor mewakili konektor layar yang tersedia. Misalnya, port HDMI.

Untuk deskripsi yang lebih mendalam, lihat:

Platform API

SDV Media menyediakan antarmuka DRM Linux. Meskipun dapat digunakan secara langsung menggunakan syscall ioctl, untuk pengembangan aplikasi, sebaiknya gunakan library helper ruang pengguna. Contoh:

  • Crate drm-rs untuk Rust (direkomendasikan),
  • libdrm untuk C/C++. drm-kms man page memberikan ringkasan yang komprehensif tentang API dan penggunaannya.

Menyiapkan rendering ke satu layar

  1. Buka perangkat DRM (/dev/dri/card*) dan gunakan API DRM Linux, misalnya, melalui libdrm, pada deskriptor filenya untuk memilih tampilan dan modenya.

    Biasanya, sistem host hanya mengekspos satu perangkat GPU virtual, yang muncul sebagai /dev/dri/card0.

  2. Mengalokasikan buffer depan dan belakang dengan Linux DRM API.

    Sebaiknya gunakan gbm_bo_create() minigbm dan dapatkan deskriptor file DMA-BUF dengan gbm_bo_get_fd().

  3. Buat framebuffer GL yang didukung oleh buffer yang dialokasikan.

    1. Buat EGLImage dari buffer DRM dengan eglCreateImageKHR dengan EGL_LINUX_DMA_BUF_EXT (dari ekstensi EGL_EXT_image_dma_buf_import).

    2. Buat tekstur GL dan gunakan glEGLImageTargetTexture2DOES (dari ekstensi GL_OES_EGL_image) untuk menyetel penyimpanan tekstur ke EGLImage dari langkah sebelumnya.

    3. Buat framebuffer GL dan gunakan glFramebufferTexture2D untuk menyetel tekstur pendukungnya ke tekstur yang dibuat pada langkah sebelumnya.

  4. Untuk merender frame:

    1. Ikat salah satu framebuffer GL yang dibuat.

    2. Gambar frame dengan API GLES biasa.

    3. Menampilkan frame di layar: gunakan Linux DRM API (drmModeAtomicCommit()) untuk mengirim DRM_MODE_PAGE_FLIP_EVENT dengan deskriptor file DMA-BUF yang digunakan oleh framebuffer GL terikat.

Menyusun output video dari beberapa lapisan

Untuk komposisi multi-layer (multi-plane) yang dipercepat hardware, kami mengandalkan sistem host yang mengekspos setiap layer sebagai konektor DRM terpisah (tampilan virtual), dan memetakannya ke lokasi / pipeline hardware yang tepat.

Lihat Menyiapkan rendering ke beberapa layar untuk mengetahui detailnya.

Menyiapkan rendering ke beberapa layar

  1. Buka perangkat DRM /dev/dri/card* seperti pada alur satu layar.

  2. Mencantumkan konektor layar yang tersedia.

    Setiap layar diekspos sebagai konektor DRM terpisah dari perangkat DRM.

  3. Untuk setiap konektor layar:

    1. Pilih CRTC yang kompatibel dengan konektor. Setiap konektor memiliki daftar encoder yang tersedia, dan setiap encoder menunjukkan CRTC yang dapat digunakan. Selalu ada minimal satu CRTC yang kompatibel.

      1. Pilih pesawat yang kompatibel dengan CRTC.

      2. Buat framebuffer DRM yang didukung oleh buffer GPU. Proses ini terlihat sama seperti untuk varian layar tunggal.

      3. Hubungkan bidang, CRTC, dan konektor, lalu tetapkan mode video di CRTC.

        Anda dapat menyetel mode beberapa layar secara bersamaan dengan menggunakan API atomik untuk menyetel properti DRM berikut untuk setiap konektor, CRTC, dan set bidang.

    Daftar lengkap properti yang diperlukan:

    Target PropertiJenisDeskripsi
    PemersatuCRTC_IDID CRTCID CRTC yang akan ditetapkan ke konektor
    CRTCMODE_IDID Blob ID blob properti yang dibuat menggunakan drmModeCreatePropertyBlob, yang berisi struct drmModeModeInfo dari mode video yang dipilih
    CRTCACTIVEBooleantrue untuk menandai CRTC sebagai aktif
    PesawatFB_IDID FramebufferID framebuffer DRM yang akan ditampilkan di layar
    PesawatSRC_XPikselKoordinat X persegi panjang gambar sumber framebuffer
    PesawatSRC_YPikselKoordinat Y persegi panjang gambar sumber framebuffer
    PesawatSRC_WTitik tetap 16.16Lebar persegi panjang gambar sumber framebuffer (piksel digeser ke kiri sebesar 16 bit)
    PesawatSRC_HTitik tetap 16.16Tinggi persegi panjang gambar sumber framebuffer (piksel digeser ke kiri sebesar 16 bit)
    PesawatCRTC_XPikselKoordinat X persegi panjang gambar tujuan CRTC
    PesawatCRTC_YPikselKoordinat Y persegi panjang gambar tujuan CRTC
    PesawatCRTC_WPikselLebar persegi panjang gambar tujuan CRTC
    PesawatCRTC_HPikselTinggi persegi panjang gambar tujuan CRTC
  4. Masukkan loop render:

    1. Tunggu peristiwa balik halaman di CRTC sebelum merender frame berikutnya.

    2. Merender frame dan menampilkannya di layar dengan menjadwalkan penggantian halaman untuk CRTC+framebuffer tertentu.