Media SDV: mengelola layar

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

Interaksi antara komponen DRM

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

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

  • CRTC merepresentasikan keseluruhan pipeline tampilan. Proses 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 DRM API Linux (misalnya melalui libdrm) pada deskriptor filenya untuk memilih layar dan modenya.

    Biasanya, sistem host hanya akan mengekspos satu perangkat GPU virtual, yang akan 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. Setidaknya akan selalu ada 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 Properti Jenis Deskripsi
    konektor CRTC_ID ID CRTC ID CRTC yang akan ditetapkan ke konektor
    CRTC MODE_ID ID blob ID blob properti yang dibuat menggunakan drmModeCreatePropertyBlob, yang berisi struct drmModeModeInfo dari mode video yang dipilih
    CRTC ACTIVE bool true untuk menandai CRTC sebagai aktif
    pesawat FB_ID ID framebuffer ID framebuffer DRM yang akan ditampilkan di layar
    pesawat SRC_X piksel Koordinat X persegi panjang gambar sumber framebuffer
    pesawat SRC_Y piksel Koordinat Y persegi panjang gambar sumber framebuffer
    pesawat SRC_W Titik tetap 16.16 lebar persegi panjang gambar sumber framebuffer (piksel digeser ke kiri sebesar 16 bit)
    pesawat SRC_H Titik tetap 16.16 tinggi persegi panjang gambar sumber framebuffer (piksel digeser ke kiri sebesar 16 bit)
    pesawat CRTC_X piksel Koordinat X persegi panjang gambar tujuan CRTC
    pesawat CRTC_Y piksel Koordinat Y persegi panjang gambar tujuan CRTC
    pesawat CRTC_W piksel lebar persegi panjang gambar tujuan CRTC
    pesawat CRTC_H piksel tinggi 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.