Mídia SDV: gerenciar telas

A SDV Media expõe telas disponíveis para apps OEM com a API Linux DRM.

Interação entre componentes de DRM

Figura 1. Interação entre componentes de DRM.

  • Um framebuffer é uma fonte de dados de pixel, com suporte de um buffer de memória alocado externamente.

  • Um plano é uma origem de imagem usada pelo CRTC. Ele está associado a um framebuffer e pode representar uma visualização cortada dele.

  • CRTC representa um pipeline de exibição geral. Ele pode combinar vários planos para criar o vídeo final e enviar a saída para vários codificadores.

  • Um codificador converte a saída de vídeo do CRTC em um formato adequado para um conector específico.

  • Um conector representa um conector de tela disponível. Por exemplo, uma porta HDMI.

Para uma descrição mais detalhada, consulte:

Superfície da API

A SDV Media fornece as interfaces DRM do Linux. Embora possam ser usadas diretamente com a chamada de sistema ioctl, para o desenvolvimento de aplicativos, recomendamos usar uma biblioteca auxiliar do espaço do usuário. Exemplo:

Configurar a renderização para uma única tela

  1. Abra um dispositivo DRM (/dev/dri/card*) e use APIs DRM do Linux, por exemplo, por libdrm, no descritor do arquivo para selecionar a tela e o modo dela.

    Normalmente, o sistema host expõe apenas um único dispositivo de GPU virtual, que aparece como /dev/dri/card0.

  2. Alocar buffers frontais e traseiros com a API DRM do Linux.

    Recomendamos usar gbm_bo_create() do minigbm e receber o descritor do arquivo DMA-BUF com gbm_bo_get_fd().

  3. Crie framebuffers GL com suporte dos buffers alocados.

    1. Crie um EGLImage do buffer de DRM com eglCreateImageKHR e EGL_LINUX_DMA_BUF_EXT (da extensão EGL_EXT_image_dma_buf_import ).

    2. Crie uma textura GL e use glEGLImageTargetTexture2DOES (da extensão GL_OES_EGL_image) para definir o armazenamento da textura como o EGLImage da etapa anterior.

    3. Crie um framebuffer do GL e use glFramebufferTexture2D para definir a textura de apoio como a criada na etapa anterior.

  4. Para renderizar um frame:

    1. Vincule um dos framebuffers GL criados.

    2. Desenhe um frame com as APIs GLES comuns.

    3. Mostre o frame em uma tela: use a API DRM do Linux (drmModeAtomicCommit()) para enviar um DRM_MODE_PAGE_FLIP_EVENT com o descritor de arquivo DMA-BUF usado pelo framebuffer GL vinculado.

Compor a saída de vídeo de várias camadas

Para composição multicamada (multiplano) acelerada por hardware, dependemos do sistema host que expõe cada camada como um conector DRM separado (display virtual) e as mapeia para o local / pipeline de hardware correto.

Consulte Configurar a renderização em várias telas para mais detalhes.

Configurar a renderização em várias telas

  1. Abra o dispositivo DRM /dev/dri/card* como no fluxo de tela única.

  2. Listar os conectores de exibição disponíveis.

    Cada tela é exposta como um conector separado do dispositivo DRM.

  3. Para cada conector de tela:

    1. Selecione um CRTC compatível com o conector. Cada conector tem uma lista de codificadores disponíveis, e cada codificador indica com quais CRTCs ele pode ser usado. Sempre há pelo menos um CRTC compatível.

      1. Selecione um avião compatível com o CRTC.

      2. Cria framebuffers DRM com suporte de buffers de GPU. Esse processo é igual ao da variante de tela única.

      3. Conecte o plano, o CRTC e o conector e defina o modo de vídeo no CRTC.

        É possível definir o modo de várias telas ao mesmo tempo usando a API atômica para definir as seguintes propriedades de DRM para cada conector, CRTC e conjunto de planos.

    A lista completa de propriedades necessárias:

    Destino PropriedadeTipoDescrição
    ConectorCRTC_IDID da CRTCID do CRTC a ser atribuído ao conector
    CRTCMODE_IDID do blob ID de um blob de propriedade criado usando drmModeCreatePropertyBlob, que contém a struct drmModeModeInfo do modo de vídeo selecionado.
    CRTCACTIVEBooleanotrue para marcar o CRTC como ativo
    AviãoFB_IDID do framebufferID do framebuffer DRM a ser mostrado na tela.
    AviãoSRC_XPixelsCoordenada X do retângulo da imagem de origem do framebuffer.
    AviãoSRC_YPixelsCoordenada Y do retângulo da imagem de origem do framebuffer.
    AviãoSRC_W16.16 ponto fixoLargura do retângulo da imagem de origem do framebuffer (pixels deslocados para a esquerda em 16 bits)
    AviãoSRC_H16.16 ponto fixoAltura do retângulo da imagem de origem do framebuffer (pixels deslocados para a esquerda em 16 bits)
    AviãoCRTC_XPixelsCoordenada X do retângulo da imagem de destino do CRTC
    AviãoCRTC_YPixelsCoordenada Y do retângulo da imagem de destino do CRTC
    AviãoCRTC_WPixelsLargura do retângulo da imagem de destino do CRTC
    AviãoCRTC_HPixelsAltura do retângulo da imagem de destino do CRTC
  4. Insira o loop de renderização:

    1. Aguarde o evento de troca de página em um CRTC antes de renderizar o próximo frame.

    2. Renderize um frame e mostre-o na tela programando uma troca de página para determinado CRTC + framebuffer.