SDV Media: ניהול תצוגות

‫SDV Media חושף את התצוגות הזמינות לאפליקציות OEM עם Linux DRM API.

אינטראקציה בין רכיבי DRM

  • Framebuffer הוא מקור של נתוני פיקסלים, שמגובה על ידי מאגר זיכרון שהוקצה חיצונית.

  • Plane הוא מקור תמונות שמשמש את CRTC. הוא משויך למאגר מסגרות, ועשוי לייצג תצוגה חתוכה של מאגר המסגרות.

  • CRTC מייצג צינור כולל של תצוגה. יכול להיות שהמערכת תשלב כמה מישורים כדי ליצור את פלט הסרטון הסופי, ותשלח את הפלט לכמה מקודדים.

  • מקודד ממיר את פלט הווידאו מ-CRTC לפורמט שמתאים לחיבור ספציפי.

  • Connector מייצג מחבר תצוגה זמין. לדוגמה, יציאת HDMI.

לתיאור מפורט יותר, אפשר לעיין במאמרים הבאים:

פלטפורמת ה-API

‫SDV Media מספקת את ממשקי ה-DRM של Linux. אפשר להשתמש בהם ישירות באמצעות ioctl syscall, אבל מומלץ להשתמש בספריית עזר במרחב המשתמשים לפיתוח אפליקציות. לדוגמה:

  • drm-rs crate ל-Rust (מומלץ),
  • libdrm ל-C/C++. בדף man של drm-kms מופיעה סקירה כללית מקיפה של ממשקי ה-API ושל אופן השימוש בהם.

הגדרת רינדור למסך אחד

  1. פותחים מכשיר DRM ‏ (/dev/dri/card*) ומשתמשים בממשקי API של Linux DRM (לדוגמה, דרך libdrm) בתיאור הקובץ שלו כדי לבחור את התצוגה ואת המצב שלה.

    בדרך כלל, מערכת המארח תחשוף רק מכשיר GPU וירטואלי אחד, שיוצג כ-/dev/dri/card0.

  2. הקצאת מאגרי חזיתיים ואחוריים באמצעות Linux DRM API.

    מומלץ להשתמש ב-minigbms gbm_bo_create() ולקבל את מתאר הקובץ DMA-BUF באמצעות gbm_bo_get_fd().

  3. יצירת מאגרי מסגרות GL שמגובים על ידי המאגרים שהוקצו.

    1. יוצרים EGLImage ממאגר ה-DRM באמצעות eglCreateImageKHR עם EGL_LINUX_DMA_BUF_EXT (מהתוסף EGL_EXT_image_dma_buf_import).

    2. יוצרים טקסטורה של GL ומשתמשים ב-glEGLImageTargetTexture2DOES (מהתוסף GL_OES_EGL_image) כדי להגדיר את האחסון של הטקסטורה ל-EGLImage מהשלב הקודם.

    3. יוצרים מאגר מסגרות GL ומשתמשים ב-glFramebufferTexture2D כדי להגדיר את מרקם הגיבוי שלו למרקם שנוצר בשלב הקודם.

  4. כדי לעבד פריים:

    1. מבצעים קישור לאחד ממאגרי הפריימים של GL שנוצרו.

    2. מציירים פריים באמצעות ממשקי ה-API הרגילים של GLES.

    3. הצגת הפריים במסך: משתמשים ב-Linux DRM API ‏(drmModeAtomicCommit()) כדי לשלוח DRM_MODE_PAGE_FLIP_EVENT עם מתאר קובץ DMA-BUF שמשמש את מאגר הפריים של GL.

הרכבת פלט של סרטון מכמה שכבות

כדי להשתמש בהרכבה מרובת שכבות (מרובת מישורים) עם האצת חומרה, אנחנו מסתמכים על כך שמערכת המארח חושפת כל שכבה כמחבר DRM נפרד (תצוגה וירטואלית), וממפה אותן למיקום החומרה או לצינור הנכונים.

פרטים נוספים זמינים במאמר הגדרת רינדור במספר מסכים.

הגדרה של רינדור בכמה מסכים

  1. פותחים את מכשיר ה-DRM כמו בתהליך של מסך יחיד./dev/dri/card*

  2. רשימת מחברי התצוגה הזמינים.

    כל מסך נחשף כמחבר נפרד של DRM במכשיר ה-DRM.

  3. לכל מחבר של מסך:

    1. בוחרים CRTC שתואם למחבר. לכל מחבר יש רשימה של מקודדים זמינים, וכל מקודד מציין את בקרי ה-CRTC שאפשר להשתמש בו איתם. תמיד יהיה לפחות CRTC אחד תואם.

      1. בוחרים תוכנית שמתאימה לדרישות של CRTC.

      2. יצירה של מאגרי מסגרות DRM שמגובים על ידי מאגרי GPU. התהליך הזה זהה לזה של וריאציה עם תצוגה אחת.

      3. מחברים את המישור, ה-CRTC והמחבר, ומגדירים את מצב הווידאו ב-CRTC.

        אפשר להגדיר את המצב של כמה מסכים בו-זמנית באמצעות ה-API האטומי להגדרת מאפייני DRM הבאים לכל מחבר, CRTC וקבוצת מישורים.

    הרשימה המלאה של המאפיינים הנדרשים:

    יעד מאפיין (property) סוג תיאור
    מחבר CRTC_ID CRTC ID המזהה של ה-CRTC שיוקצה למחבר
    CRTC MODE_ID מזהה blob המזהה של blob של מאפיין שנוצר באמצעות drmModeCreatePropertyBlob, שמכיל את מבנה הנתונים drmModeModeInfo של מצב הסרטון שנבחר
    CRTC ACTIVE bool true כדי לסמן את CRTC כפעיל
    מטוס FB_ID מזהה מקטע Frame buffer המזהה של מאגר המסגרות של DRM שיוצג על המסך
    מטוס SRC_X פיקסלים קואורדינטת ה-X של מלבן תמונת המקור של מאגר המסגרות
    מטוס SRC_Y פיקסלים קואורדינטת ה-Y של המלבן של תמונת המקור של מאגר המסגרות
    מטוס SRC_W נקודה קבועה 16.16 רוחב המלבן של תמונת המקור של מאגר המסגרות (פיקסלים שהוסטו שמאלה ב-16 ביטים)
    מטוס SRC_H נקודה קבועה 16.16 הגובה של המלבן של תמונת המקור של מאגר המסגרות (פיקסלים שהוסטו שמאלה ב-16 ביטים)
    מטוס CRTC_X פיקסלים קואורדינטת ה-X של המלבן של תמונת היעד ב-CRTC
    מטוס CRTC_Y פיקסלים קואורדינטת ה-Y של המלבן של תמונת היעד של CRTC
    מטוס CRTC_W פיקסלים רוחב המלבן של תמונת היעד של CRTC
    מטוס CRTC_H פיקסלים הגובה של המלבן של תמונת היעד ב-CRTC
  4. מזינים את לולאת הרינדור:

    1. צריך להמתין לאירוע של החלפת הדף ב-CRTC לפני שמבצעים רינדור של הפריים הבא.

    2. רינדור של פריים והצגה שלו במסך על ידי תזמון של החלפת דף עבור CRTC+framebuffer נתון.