SDV Media: gestione dei display

SDV Media espone i display disponibili alle applicazioni OEM con l'API DRM di Linux.

Interazione tra i componenti DRM

  • Il framebuffer è un'origine di dati pixel, supportata da un buffer di memoria allocato esternamente.

  • Il piano è un'origine immagine utilizzata da CRTC. È associato a un framebuffer e può rappresentare una visualizzazione ritagliata del framebuffer.

  • CRTC rappresenta una pipeline di visualizzazione complessiva. Può combinare più piani per creare l'output video finale e inviare l'output a più codificatori.

  • Il codificatore converte l'output video da CRTC in un formato adatto a un connettore specifico.

  • Il connettore rappresenta un connettore di visualizzazione disponibile. Ad esempio, una porta HDMI.

Per una descrizione più approfondita, consulta:

Piattaforma API

SDV Media fornisce le interfacce DRM di Linux. Sebbene sia possibile utilizzarle direttamente tramite la chiamata di sistema ioctl, per lo sviluppo di applicazioni è consigliabile utilizzare una libreria di assistenza dello spazio utente. Ad esempio:

Configurare il rendering su un singolo display

  1. Apri un dispositivo DRM (/dev/dri/card*) e utilizza le API DRM di Linux (ad es. tramite libdrm) sul relativo descrittore di file per selezionare il display e la relativa modalità.

    In genere, il sistema host espone un solo dispositivo GPU virtuale, che viene visualizzato come /dev/dri/card0.

  2. Alloca i buffer anteriori e posteriori con l'API DRM di Linux.

    Ti consigliamo di utilizzare minigbm's gbm_bo_create() e di recuperare il descrittore del file DMA-BUF con gbm_bo_get_fd().

  3. Crea framebuffer GL supportati dai buffer allocati.

    1. Crea un EGLImage dal buffer DRM con eglCreateImageKHR con EGL_LINUX_DMA_BUF_EXT (dall'EGL_EXT_image_dma_buf_import estensione).

    2. Crea una texture GL e utilizza glEGLImageTargetTexture2DOES (dall' GL_OES_EGL_image estensione) per impostare l'archiviazione della texture su EGLImage dal passaggio precedente.

    3. Crea un framebuffer GL e utilizza glFramebufferTexture2D per impostare la sua texture di supporto su quella creata nel passaggio precedente.

  4. Per eseguire il rendering di un frame:

    1. Collega uno dei framebuffer GL creati.

    2. Disegna un frame con le normali API GLES.

    3. Visualizza il frame su uno schermo: utilizza l'API DRM di Linux (drmModeAtomicCommit()) per inviare un DRM_MODE_PAGE_FLIP_EVENT con il descrittore di file DMA-BUF utilizzato dal framebuffer GL collegato.

Comporre l'output video da più livelli

Per la composizione multilivello (multipiano) con accelerazione hardware, ci affidiamo al sistema host che espone ogni livello come un connettore DRM separato (display virtuale) e li mappa alla posizione / pipeline hardware corretta.

Per maggiori dettagli, consulta Configurare il rendering su più display.

Configurare il rendering su più display

  1. Apri il dispositivo DRM /dev/dri/card* come nel flusso a display singolo.

  2. Elenca i connettori di visualizzazione disponibili.

    Ogni display viene esposto come un connettore DRM separato del dispositivo DRM.

  3. Per ogni connettore di visualizzazione:

    1. Seleziona un CRTC compatibile con il connettore. Ogni connettore ha un elenco di codificatori disponibili e ogni codificatore indica con quali CRTC può essere utilizzato. Sarà sempre presente almeno un CRTC compatibile.

      1. Seleziona un piano compatibile con il CRTC.

      2. Crea framebuffer DRM supportati dai buffer GPU. Questa procedura è identica a quella della variante a display singolo.

      3. Collega il piano, il CRTC e il connettore e imposta la modalità video sul CRTC.

        È possibile impostare la modalità di più display contemporaneamente utilizzando l'API atomica per impostare le seguenti proprietà DRM per ogni set di connettori, CRTC e piani.

    L'elenco completo delle proprietà necessarie:

    Target Proprietà Tipo Descrizione
    connettore CRTC_ID ID CRTC ID del CRTC da assegnare al connettore
    CRTC MODE_ID ID blob ID di un blob di proprietà creato utilizzando drmModeCreatePropertyBlob, contenente la struttura drmModeModeInfo della modalità video selezionata
    CRTC ACTIVE bool true per contrassegnare il CRTC come attivo
    piano FB_ID ID framebuffer ID del framebuffer DRM da visualizzare sullo schermo
    piano SRC_X pixel Coordinata X del rettangolo dell'immagine di origine del framebuffer
    piano SRC_Y pixel Coordinata Y del rettangolo dell'immagine di origine del framebuffer
    piano SRC_W Punto fisso 16.16 Larghezza del rettangolo dell'immagine di origine del framebuffer (pixel spostati a sinistra di 16 bit)
    piano SRC_H Punto fisso 16.16 Altezza del rettangolo dell'immagine di origine del framebuffer (pixel spostati a sinistra di 16 bit)
    piano CRTC_X pixel Coordinata X del rettangolo dell'immagine di destinazione CRTC
    piano CRTC_Y pixel Coordinata Y del rettangolo dell'immagine di destinazione CRTC
    piano CRTC_W pixel Larghezza del rettangolo dell'immagine di destinazione CRTC
    piano CRTC_H pixel Altezza del rettangolo dell'immagine di destinazione CRTC
  4. Inserisci il loop di rendering:

    1. Attendi l'evento di inversione di pagina su un CRTC prima di eseguire il rendering del frame successivo.

    2. Esegui il rendering di un frame e visualizzalo sullo schermo pianificando un'inversione di pagina per il CRTC+framebuffer specificato.